diff --git a/crates/core_simd/src/first.rs b/crates/core_simd/src/first.rs index 50602829d48..f3f88f7aa44 100644 --- a/crates/core_simd/src/first.rs +++ b/crates/core_simd/src/first.rs @@ -3,26 +3,54 @@ macro_rules! impl_vector { { $name:ident, $type:ty } => { impl $name where Self: crate::LanesAtMost32 { /// Construct a SIMD vector by setting all lanes to the given value. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]); + /// let b = f32x4::splat(1.0); + /// assert_eq!(a, b); + /// ``` pub const fn splat(value: $type) -> Self { Self([value; LANES]) } /// Returns a slice containing the entire SIMD vector. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]); + /// let b = a.as_slice(); + /// ``` pub const fn as_slice(&self) -> &[$type] { &self.0 } /// Returns a mutable slice containing the entire SIMD vector. + /// ``` + /// # use core_simd::*; + /// let mut a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]); + /// let b = a.as_mut_slice(); + /// ``` pub fn as_mut_slice(&mut self) -> &mut [$type] { &mut self.0 } /// Converts an array to a SIMD vector. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]); + /// let b = f32x4::splat(1.0); + /// assert_eq!(a, b); + /// ``` pub const fn from_array(array: [$type; LANES]) -> Self { Self(array) } /// Converts a SIMD vector to an array. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]); + /// let b = [1.0, 1.0, 1.0, 1.0]; + /// assert_eq!(f32x4::to_array(a), b); + /// ``` pub const fn to_array(self) -> [$type; LANES] { // workaround for rust-lang/rust#80108 // TODO fix this @@ -47,6 +75,13 @@ macro_rules! impl_vector { impl Copy for $name where Self: crate::LanesAtMost32 {} impl Clone for $name where Self: crate::LanesAtMost32 { + /// Clone a SIMD vector. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([1.0, 1.0, 1.0, 1.0]); + /// assert_eq!(a, f32x4::clone(&a)); + /// assert_eq!(a, a.clone()); + /// ``` #[inline] fn clone(&self) -> Self { *self @@ -61,6 +96,12 @@ macro_rules! impl_vector { } impl PartialEq for $name where Self: crate::LanesAtMost32 { + /// ``` + /// # use core_simd::*; + /// let a = f32x4::splat(1.0); + /// let b = f32x4::splat(1.0); + /// assert!(a == b); + /// ``` #[inline] fn eq(&self, other: &Self) -> bool { // TODO use SIMD equality diff --git a/crates/core_simd/src/reduction.rs b/crates/core_simd/src/reduction.rs index 8687d1af516..1c053c4fde9 100644 --- a/crates/core_simd/src/reduction.rs +++ b/crates/core_simd/src/reduction.rs @@ -5,12 +5,26 @@ macro_rules! impl_integer_reductions { Self: crate::LanesAtMost32 { /// Horizontal wrapping add. Returns the sum of the lanes of the vector, with wrapping addition. + /// ``` + /// # use core_simd::*; + /// let a = u32x4::from_array([1, 2, 3, 4]).horizontal_sum(); + /// assert_eq!(10, a); + /// let b = u32x4::from_array([u32::MAX, 1, 0, 0]).horizontal_sum(); + /// assert_eq!(0, b); + /// ``` #[inline] pub fn horizontal_sum(self) -> $scalar { unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0) } } /// Horizontal wrapping multiply. Returns the product of the lanes of the vector, with wrapping multiplication. + /// ``` + /// # use core_simd::*; + /// let a = u32x4::from_array([2, 2, 2, 2]).horizontal_product(); + /// assert_eq!(16, a); + /// let b = u32x4::from_array([u32::MAX, 2, 1, 1]).horizontal_product(); + /// assert_eq!(u32::MAX, b + 1); // Because 2*u32::MAX wraps, and is 1 off from the u32::MAX + /// ``` #[inline] pub fn horizontal_product(self) -> $scalar { unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1) } @@ -18,6 +32,13 @@ macro_rules! impl_integer_reductions { /// Horizontal bitwise "and". Returns the cumulative bitwise "and" across the lanes of /// the vector. + /// ``` + /// # use core_simd::*; + /// let a = u32x4::from_array([3, 3, 3, 3]).horizontal_and(); + /// assert_eq!(3, a); + /// let b = u32x4::from_array([1, 1, 0, 0]).horizontal_and(); + /// assert_eq!(0, b); + /// ``` #[inline] pub fn horizontal_and(self) -> $scalar { unsafe { crate::intrinsics::simd_reduce_and(self) } @@ -25,6 +46,11 @@ macro_rules! impl_integer_reductions { /// Horizontal bitwise "or". Returns the cumulative bitwise "or" across the lanes of /// the vector. + /// ``` + /// # use core_simd::*; + /// let a = u32x4::from_array([1, 2, 0, 0]).horizontal_or(); + /// assert_eq!(3, a); + /// ``` #[inline] pub fn horizontal_or(self) -> $scalar { unsafe { crate::intrinsics::simd_reduce_or(self) } @@ -32,18 +58,33 @@ macro_rules! impl_integer_reductions { /// Horizontal bitwise "xor". Returns the cumulative bitwise "xor" across the lanes of /// the vector. + /// ``` + /// # use core_simd::*; + /// let a = u32x4::from_array([5, 5, 5, 0]).horizontal_xor(); + /// assert_eq!(5, a); + /// ``` #[inline] pub fn horizontal_xor(self) -> $scalar { unsafe { crate::intrinsics::simd_reduce_xor(self) } } /// Horizontal maximum. Returns the maximum lane in the vector. + /// ``` + /// # use core_simd::*; + /// let a = u32x4::from_array([1, 2, 42, 0]).horizontal_max(); + /// assert_eq!(42, a); + /// ``` #[inline] pub fn horizontal_max(self) -> $scalar { unsafe { crate::intrinsics::simd_reduce_max(self) } } /// Horizontal minimum. Returns the minimum lane in the vector. + /// ``` + /// # use core_simd::*; + /// let a = u32x4::from_array([1, 2, 42, 0]).horizontal_min(); + /// assert_eq!(0, a); + /// ``` #[inline] pub fn horizontal_min(self) -> $scalar { unsafe { crate::intrinsics::simd_reduce_min(self) } @@ -59,7 +100,14 @@ macro_rules! impl_float_reductions { Self: crate::LanesAtMost32 { - /// Horizontal add. Returns the sum of the lanes of the vector. + /// Horizontal add. Returns the sum of the lanes of the vector, with saturating addition. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([1.0, 2.0, 3.0, 4.0]).horizontal_sum(); + /// assert_eq!(10.0, a); + /// let b = f32x4::from_array([f32::MAX, 2.0, 0.0, 0.0]).horizontal_sum(); + /// assert_eq!(f32::MAX, b); + /// ``` #[inline] pub fn horizontal_sum(self) -> $scalar { // LLVM sum is inaccurate on i586 @@ -71,6 +119,13 @@ macro_rules! impl_float_reductions { } /// Horizontal multiply. Returns the product of the lanes of the vector. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([1.0, 2.0, 3.0, 4.0]).horizontal_product(); + /// assert_eq!(24.0, a); + /// let b = f32x4::from_array([f32::MAX, 2.0, 1.0, 1.0]).horizontal_product(); + /// assert_eq!(f32::MAX, b); + /// ``` #[inline] pub fn horizontal_product(self) -> $scalar { // LLVM product is inaccurate on i586 @@ -85,6 +140,13 @@ macro_rules! impl_float_reductions { /// /// Returns values based on equality, so a vector containing both `0.` and `-0.` may /// return either. This function will not return `NaN` unless all lanes are `NaN`. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([1.0, 2.0, 3.0, 4.0]).horizontal_max(); + /// assert_eq!(4.0, a); + /// let b = f32x4::from_array([f32::NAN, 2.0, 0.0, 0.0]).horizontal_max(); + /// assert_eq!(2.0, b); + /// ``` #[inline] pub fn horizontal_max(self) -> $scalar { unsafe { crate::intrinsics::simd_reduce_max(self) } @@ -94,6 +156,13 @@ macro_rules! impl_float_reductions { /// /// Returns values based on equality, so a vector containing both `0.` and `-0.` may /// return either. This function will not return `NaN` unless all lanes are `NaN`. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([1.0, 2.0, 3.0, 4.0]).horizontal_min(); + /// assert_eq!(1.0, a); + /// let b = f32x4::from_array([f32::NAN, 2.0, 0.0, 0.0]).horizontal_min(); + /// assert_eq!(0.0, b); + /// ``` #[inline] pub fn horizontal_min(self) -> $scalar { unsafe { crate::intrinsics::simd_reduce_min(self) } diff --git a/crates/core_simd/src/round.rs b/crates/core_simd/src/round.rs index 281851c68ac..7bd97f300ba 100644 --- a/crates/core_simd/src/round.rs +++ b/crates/core_simd/src/round.rs @@ -8,6 +8,13 @@ macro_rules! implement { Self: crate::LanesAtMost32, { /// Returns the smallest integer greater than or equal to each lane. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([-3.3, -0.7, 2.9, 0.2]); + /// let b = f32x4::from_array([-3.0, 0.0, 3.0, 1.0]); + /// let c = f32x4::ceil(a); + /// assert_eq!(c, b); + /// ``` #[must_use = "method returns a new vector and does not mutate the original value"] #[inline] pub fn ceil(self) -> Self { @@ -15,13 +22,27 @@ macro_rules! implement { } /// Returns the largest integer value less than or equal to each lane. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([-3.3, -0.7, 2.3, 1.3]); + /// let b = f32x4::from_array([-4.0, -1.0, 2.0, 1.0]); + /// let c = f32x4::floor(a); + /// assert_eq!(c, b); + /// ``` #[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) } } - /// Rounds to the nearest integer value. Ties round toward zero. + /// Rounds to the nearest integer value. Ties round away from zero. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([-3.6, -0.5, 2.5, 0.6]); + /// let b = f32x4::from_array([-4.0, -1.0, 3.0, 1.0]); + /// let c = f32x4::round(a); + /// assert_eq!(c, b); + /// ``` #[must_use = "method returns a new vector and does not mutate the original value"] #[inline] pub fn round(self) -> Self { @@ -29,6 +50,13 @@ macro_rules! implement { } /// Returns the floating point's integer value, with its fractional part removed. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([-3.47, -0.1234, 2.3, 0.1234]); + /// let b = f32x4::from_array([-3.0, -0.0, 2.0, 0.0]); + /// let c = f32x4::trunc(a); + /// assert_eq!(c, b); + /// ``` #[must_use = "method returns a new vector and does not mutate the original value"] #[inline] pub fn trunc(self) -> Self { @@ -36,6 +64,13 @@ macro_rules! implement { } /// Returns the floating point's fractional value, with its integer part removed. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([-3.25, -0.75, 2.5, 10.0]); + /// let b = f32x4::from_array([-0.25, -0.75, 0.5, 0.0]); + /// let c = f32x4::fract(a); + /// assert_eq!(c, b); + /// ``` #[must_use = "method returns a new vector and does not mutate the original value"] #[inline] pub fn fract(self) -> Self { diff --git a/crates/core_simd/src/vector/float.rs b/crates/core_simd/src/vector/float.rs index c4565a9dd90..73a834b9bb2 100644 --- a/crates/core_simd/src/vector/float.rs +++ b/crates/core_simd/src/vector/float.rs @@ -31,6 +31,13 @@ macro_rules! impl_float_vector { /// Produces a vector where every lane has the absolute value of the /// equivalently-indexed lane in `self`. + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([-3.0, -0.0, 2.0, 0.0]); + /// let b = f32x4::from_array([3.0, 0.0, 2.0, 0.0]); + /// let c = f32x4::abs(a); + /// assert_eq!(c, b); + /// ``` #[inline] pub fn abs(self) -> Self { unsafe { crate::intrinsics::simd_fabs(self) } @@ -38,6 +45,13 @@ macro_rules! impl_float_vector { /// Produces a vector where every lane has the square root value /// of the equivalently-indexed lane in `self` + /// ``` + /// # use core_simd::*; + /// let a = f32x4::from_array([9.0, 16.0, 4.0, 0.0]); + /// let b = f32x4::from_array([3.0, 4.0, 2.0, 0.0]); + /// let c = f32x4::sqrt(a); + /// assert_eq!(c, b); + /// ``` #[inline] #[cfg(feature = "std")] pub fn sqrt(self) -> Self {