diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index aee5a111a82f26ed0ca792714aaf8fd4c1a7b4ec..b7da4f341d171716125678cc03a560703ad275b3 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -7,6 +7,7 @@ mod assign; mod deref; +mod unary; impl core::ops::Index for Simd where @@ -65,25 +66,6 @@ impl core::ops::$trait<$rhs> for $type fn $fn($self_tok, $rhs_arg: $rhs_arg_ty) -> Self::Output $body } }; - - // unary op - { - impl core::ops::$trait:ident for $type:ty - where - LaneCount<$lanes2:ident>: SupportedLaneCount, - { - type Output = $output:ty; - fn $fn:ident($self_tok:ident) -> Self::Output $body:tt - } - } => { - impl core::ops::$trait for $type - where - LaneCount<$lanes2>: SupportedLaneCount, - { - type Output = $output; - fn $fn($self_tok) -> Self::Output $body - } - } } /// Automatically implements operators over vectors and scalars for a particular vector. @@ -119,34 +101,6 @@ fn $fn($self_tok) -> Self::Output $body impl_op! { @binary $scalar, BitXor::bitxor, simd_xor } }; - { impl Not for $scalar:ty } => { - impl_ref_ops! { - impl core::ops::Not for Simd<$scalar, LANES> - where - LaneCount: SupportedLaneCount, - { - type Output = Self; - fn not(self) -> Self::Output { - self ^ Self::splat(!<$scalar>::default()) - } - } - } - }; - - { impl Neg for $scalar:ty } => { - impl_ref_ops! { - impl core::ops::Neg for Simd<$scalar, LANES> - where - LaneCount: SupportedLaneCount, - { - type Output = Self; - fn neg(self) -> Self::Output { - unsafe { intrinsics::simd_neg(self) } - } - } - } - }; - // generic binary op with assignment when output is `Self` { @binary $scalar:ty, $trait:ident :: $trait_fn:ident, $intrinsic:ident } => { impl_ref_ops! { @@ -204,7 +158,6 @@ fn $trait_fn(self, rhs: Simd<$scalar, LANES>) -> Self::Output { impl_op! { impl Mul for $scalar } impl_op! { impl Div for $scalar } impl_op! { impl Rem for $scalar } - impl_op! { impl Neg for $scalar } )* }; } @@ -219,7 +172,6 @@ fn $trait_fn(self, rhs: Simd<$scalar, LANES>) -> Self::Output { impl_op! { impl BitAnd for $scalar } impl_op! { impl BitOr for $scalar } impl_op! { impl BitXor for $scalar } - impl_op! { impl Not for $scalar } // Integers panic on divide by 0 impl_ref_ops! { @@ -441,9 +393,6 @@ fn shr(self, rhs: $scalar) -> Self::Output { macro_rules! impl_signed_int_ops { { $($scalar:ty),* } => { impl_unsigned_int_ops! { $($scalar),* } - $( // scalar - impl_op! { impl Neg for $scalar } - )* }; } diff --git a/crates/core_simd/src/ops/unary.rs b/crates/core_simd/src/ops/unary.rs new file mode 100644 index 0000000000000000000000000000000000000000..4ebea560fc65fa51e3d7f0594506e03a0c27adfa --- /dev/null +++ b/crates/core_simd/src/ops/unary.rs @@ -0,0 +1,77 @@ +use crate::simd::intrinsics; +use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount}; +use core::ops::{Neg, Not}; // unary ops + +macro_rules! neg { + ($(impl Neg for Simd<$scalar:ty, LANES>)*) => { + $(impl Neg for Simd<$scalar, LANES> + where + $scalar: SimdElement, + LaneCount: SupportedLaneCount, + { + type Output = Self; + + #[inline] + #[must_use = "operator returns a new vector without mutating the input"] + fn neg(self) -> Self::Output { + unsafe { intrinsics::simd_neg(self) } + } + })* + } +} + +neg! { + impl Neg for Simd + + impl Neg for Simd + + impl Neg for Simd + + impl Neg for Simd + + impl Neg for Simd + + impl Neg for Simd + + impl Neg for Simd +} + +macro_rules! not { + ($(impl Not for Simd<$scalar:ty, LANES>)*) => { + $(impl Not for Simd<$scalar, LANES> + where + $scalar: SimdElement, + LaneCount: SupportedLaneCount, + { + type Output = Self; + + #[inline] + #[must_use = "operator returns a new vector without mutating the input"] + fn not(self) -> Self::Output { + self ^ (Simd::splat(!(0 as $scalar))) + } + })* + } +} + +not! { + impl Not for Simd + + impl Not for Simd + + impl Not for Simd + + impl Not for Simd + + impl Not for Simd + + impl Not for Simd + + impl Not for Simd + + impl Not for Simd + + impl Not for Simd + + impl Not for Simd +}