Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 18 additions & 28 deletions crates/core_simd/src/simd/cmp/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,32 @@ use crate::simd::{
};

/// Parallel `PartialEq`.
pub trait SimdPartialEq {
/// The mask type returned by each comparison.
type Mask;

pub trait SimdPartialEq<T, const N: usize>
where
T: SimdElement,
{
/// Test if each element is equal to the corresponding element in `other`.
#[must_use = "method returns a new mask and does not mutate the original value"]
fn simd_eq(self, other: Self) -> Self::Mask;
fn simd_eq(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;

/// Test if each element is not equal to the corresponding element in `other`.
#[must_use = "method returns a new mask and does not mutate the original value"]
fn simd_ne(self, other: Self) -> Self::Mask;
fn simd_ne(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;
}

macro_rules! impl_number {
{ $($number:ty),* } => {
$(
impl<const N: usize> SimdPartialEq for Simd<$number, N>
{
type Mask = Mask<<$number as SimdElement>::Mask, N>;

impl<const N: usize> SimdPartialEq<$number, N> for Simd<$number, N> {
#[inline]
fn simd_eq(self, other: Self) -> Self::Mask {
fn simd_eq(self, other: Self) -> Mask<<$number as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_eq(self, other)) }
}

#[inline]
fn simd_ne(self, other: Self) -> Self::Mask {
fn simd_ne(self, other: Self) -> Mask<<$number as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ne(self, other)) }
Expand All @@ -47,19 +44,16 @@ impl_number! { f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize }
macro_rules! impl_mask {
{ $($integer:ty),* } => {
$(
impl<const N: usize> SimdPartialEq for Mask<$integer, N>
{
type Mask = Self;

impl<const N: usize> SimdPartialEq<$integer, N> for Mask<$integer, N> {
#[inline]
fn simd_eq(self, other: Self) -> Self::Mask {
fn simd_eq(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_eq(self.to_simd(), other.to_simd())) }
}

#[inline]
fn simd_ne(self, other: Self) -> Self::Mask {
fn simd_ne(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ne(self.to_simd(), other.to_simd())) }
Expand All @@ -71,30 +65,26 @@ macro_rules! impl_mask {

impl_mask! { i8, i16, i32, i64, isize }

impl<T, const N: usize> SimdPartialEq for Simd<*const T, N> {
type Mask = Mask<isize, N>;

impl<T, const N: usize> SimdPartialEq<*const T, N> for Simd<*const T, N> {
#[inline]
fn simd_eq(self, other: Self) -> Self::Mask {
fn simd_eq(self, other: Self) -> Mask<isize, N> {
self.addr().simd_eq(other.addr())
}

#[inline]
fn simd_ne(self, other: Self) -> Self::Mask {
fn simd_ne(self, other: Self) -> Mask<isize, N> {
self.addr().simd_ne(other.addr())
}
}

impl<T, const N: usize> SimdPartialEq for Simd<*mut T, N> {
type Mask = Mask<isize, N>;

impl<T, const N: usize> SimdPartialEq<*mut T, N> for Simd<*mut T, N> {
#[inline]
fn simd_eq(self, other: Self) -> Self::Mask {
fn simd_eq(self, other: Self) -> Mask<isize, N> {
self.addr().simd_eq(other.addr())
}

#[inline]
fn simd_ne(self, other: Self) -> Self::Mask {
fn simd_ne(self, other: Self) -> Mask<isize, N> {
self.addr().simd_ne(other.addr())
}
}
78 changes: 42 additions & 36 deletions crates/core_simd/src/simd/cmp/ord.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
use crate::simd::{
Mask, Select, Simd,
Mask, Select, Simd, SimdElement,
cmp::SimdPartialEq,
ptr::{SimdConstPtr, SimdMutPtr},
};

/// Parallel `PartialOrd`.
pub trait SimdPartialOrd: SimdPartialEq {
pub trait SimdPartialOrd<T, const N: usize>: SimdPartialEq<T, N>
where
T: SimdElement,
{
/// Test if each element is less than the corresponding element in `other`.
#[must_use = "method returns a new mask and does not mutate the original value"]
fn simd_lt(self, other: Self) -> Self::Mask;
fn simd_lt(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;

/// Test if each element is less than or equal to the corresponding element in `other`.
#[must_use = "method returns a new mask and does not mutate the original value"]
fn simd_le(self, other: Self) -> Self::Mask;
fn simd_le(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;

/// Test if each element is greater than the corresponding element in `other`.
#[must_use = "method returns a new mask and does not mutate the original value"]
fn simd_gt(self, other: Self) -> Self::Mask;
fn simd_gt(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;

/// Test if each element is greater than or equal to the corresponding element in `other`.
#[must_use = "method returns a new mask and does not mutate the original value"]
fn simd_ge(self, other: Self) -> Self::Mask;
fn simd_ge(self, other: Self) -> Mask<<T as SimdElement>::Mask, N>;
}

/// Parallel `Ord`.
pub trait SimdOrd: SimdPartialOrd {
pub trait SimdOrd<T, const N: usize>: SimdPartialOrd<T, N>
where
T: SimdElement,
{
/// Returns the element-wise maximum with `other`.
#[must_use = "method returns a new vector and does not mutate the original value"]
fn simd_max(self, other: Self) -> Self;
Expand All @@ -48,38 +54,38 @@ pub trait SimdOrd: SimdPartialOrd {
macro_rules! impl_integer {
{ $($integer:ty),* } => {
$(
impl<const N: usize> SimdPartialOrd for Simd<$integer, N>
impl<const N: usize> SimdPartialOrd<$integer, N> for Simd<$integer, N>
{
#[inline]
fn simd_lt(self, other: Self) -> Self::Mask {
fn simd_lt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_lt(self, other)) }
}

#[inline]
fn simd_le(self, other: Self) -> Self::Mask {
fn simd_le(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_le(self, other)) }
}

#[inline]
fn simd_gt(self, other: Self) -> Self::Mask {
fn simd_gt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_gt(self, other)) }
}

#[inline]
fn simd_ge(self, other: Self) -> Self::Mask {
fn simd_ge(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ge(self, other)) }
}
}

impl<const N: usize> SimdOrd for Simd<$integer, N>
impl<const N: usize> SimdOrd<$integer, N> for Simd<$integer, N>
{
#[inline]
fn simd_max(self, other: Self) -> Self {
Expand Down Expand Up @@ -110,31 +116,31 @@ impl_integer! { u8, u16, u32, u64, usize, i8, i16, i32, i64, isize }
macro_rules! impl_float {
{ $($float:ty),* } => {
$(
impl<const N: usize> SimdPartialOrd for Simd<$float, N>
impl<const N: usize> SimdPartialOrd<$float, N> for Simd<$float, N>
{
#[inline]
fn simd_lt(self, other: Self) -> Self::Mask {
fn simd_lt(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_lt(self, other)) }
}

#[inline]
fn simd_le(self, other: Self) -> Self::Mask {
fn simd_le(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_le(self, other)) }
}

#[inline]
fn simd_gt(self, other: Self) -> Self::Mask {
fn simd_gt(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_gt(self, other)) }
}

#[inline]
fn simd_ge(self, other: Self) -> Self::Mask {
fn simd_ge(self, other: Self) -> Mask<<$float as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Mask::from_simd_unchecked(core::intrinsics::simd::simd_ge(self, other)) }
Expand All @@ -149,38 +155,38 @@ impl_float! { f32, f64 }
macro_rules! impl_mask {
{ $($integer:ty),* } => {
$(
impl<const N: usize> SimdPartialOrd for Mask<$integer, N>
impl<const N: usize> SimdPartialOrd<$integer, N> for Mask<$integer, N>
{
#[inline]
fn simd_lt(self, other: Self) -> Self::Mask {
fn simd_lt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_lt(self.to_simd(), other.to_simd())) }
}

#[inline]
fn simd_le(self, other: Self) -> Self::Mask {
fn simd_le(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_le(self.to_simd(), other.to_simd())) }
}

#[inline]
fn simd_gt(self, other: Self) -> Self::Mask {
fn simd_gt(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_gt(self.to_simd(), other.to_simd())) }
}

#[inline]
fn simd_ge(self, other: Self) -> Self::Mask {
fn simd_ge(self, other: Self) -> Mask<<$integer as SimdElement>::Mask, N> {
// Safety: `self` is a vector, and the result of the comparison
// is always a valid mask.
unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ge(self.to_simd(), other.to_simd())) }
}
}

impl<const N: usize> SimdOrd for Mask<$integer, N>
impl<const N: usize> SimdOrd<$integer, N> for Mask<$integer, N>
{
#[inline]
fn simd_max(self, other: Self) -> Self {
Expand Down Expand Up @@ -208,29 +214,29 @@ macro_rules! impl_mask {

impl_mask! { i8, i16, i32, i64, isize }

impl<T, const N: usize> SimdPartialOrd for Simd<*const T, N> {
impl<T, const N: usize> SimdPartialOrd<*const T, N> for Simd<*const T, N> {
#[inline]
fn simd_lt(self, other: Self) -> Self::Mask {
fn simd_lt(self, other: Self) -> Mask<isize, N> {
self.addr().simd_lt(other.addr())
}

#[inline]
fn simd_le(self, other: Self) -> Self::Mask {
fn simd_le(self, other: Self) -> Mask<isize, N> {
self.addr().simd_le(other.addr())
}

#[inline]
fn simd_gt(self, other: Self) -> Self::Mask {
fn simd_gt(self, other: Self) -> Mask<isize, N> {
self.addr().simd_gt(other.addr())
}

#[inline]
fn simd_ge(self, other: Self) -> Self::Mask {
fn simd_ge(self, other: Self) -> Mask<isize, N> {
self.addr().simd_ge(other.addr())
}
}

impl<T, const N: usize> SimdOrd for Simd<*const T, N> {
impl<T, const N: usize> SimdOrd<*const T, N> for Simd<*const T, N> {
#[inline]
fn simd_max(self, other: Self) -> Self {
self.simd_lt(other).select(other, self)
Expand All @@ -252,29 +258,29 @@ impl<T, const N: usize> SimdOrd for Simd<*const T, N> {
}
}

impl<T, const N: usize> SimdPartialOrd for Simd<*mut T, N> {
impl<T, const N: usize> SimdPartialOrd<*mut T, N> for Simd<*mut T, N> {
#[inline]
fn simd_lt(self, other: Self) -> Self::Mask {
fn simd_lt(self, other: Self) -> Mask<isize, N> {
self.addr().simd_lt(other.addr())
}

#[inline]
fn simd_le(self, other: Self) -> Self::Mask {
fn simd_le(self, other: Self) -> Mask<isize, N> {
self.addr().simd_le(other.addr())
}

#[inline]
fn simd_gt(self, other: Self) -> Self::Mask {
fn simd_gt(self, other: Self) -> Mask<isize, N> {
self.addr().simd_gt(other.addr())
}

#[inline]
fn simd_ge(self, other: Self) -> Self::Mask {
fn simd_ge(self, other: Self) -> Mask<isize, N> {
self.addr().simd_ge(other.addr())
}
}

impl<T, const N: usize> SimdOrd for Simd<*mut T, N> {
impl<T, const N: usize> SimdOrd<*mut T, N> for Simd<*mut T, N> {
#[inline]
fn simd_max(self, other: Self) -> Self {
self.simd_lt(other).select(other, self)
Expand Down
Loading
Loading