diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/packed_simd/src/api/cmp | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/packed_simd/src/api/cmp')
-rw-r--r-- | third_party/rust/packed_simd/src/api/cmp/eq.rs | 27 | ||||
-rw-r--r-- | third_party/rust/packed_simd/src/api/cmp/ord.rs | 43 | ||||
-rw-r--r-- | third_party/rust/packed_simd/src/api/cmp/partial_eq.rs | 65 | ||||
-rw-r--r-- | third_party/rust/packed_simd/src/api/cmp/partial_ord.rs | 230 | ||||
-rw-r--r-- | third_party/rust/packed_simd/src/api/cmp/vertical.rs | 114 |
5 files changed, 479 insertions, 0 deletions
diff --git a/third_party/rust/packed_simd/src/api/cmp/eq.rs b/third_party/rust/packed_simd/src/api/cmp/eq.rs new file mode 100644 index 0000000000..3c55d0dce5 --- /dev/null +++ b/third_party/rust/packed_simd/src/api/cmp/eq.rs @@ -0,0 +1,27 @@ +//! Implements `Eq` for vector types. + +macro_rules! impl_cmp_eq { + ( + [$elem_ty:ident; $elem_count:expr]: + $id:ident | $test_tt:tt | + ($true:expr, $false:expr) + ) => { + impl crate::cmp::Eq for $id {} + impl crate::cmp::Eq for LexicographicallyOrdered<$id> {} + + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _cmp_eq>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn eq() { + fn foo<E: crate::cmp::Eq>(_: E) {} + let a = $id::splat($false); + foo(a); + } + } + } + } + }; +} diff --git a/third_party/rust/packed_simd/src/api/cmp/ord.rs b/third_party/rust/packed_simd/src/api/cmp/ord.rs new file mode 100644 index 0000000000..e54ba3bfde --- /dev/null +++ b/third_party/rust/packed_simd/src/api/cmp/ord.rs @@ -0,0 +1,43 @@ +//! Implements `Ord` for vector types. + +macro_rules! impl_cmp_ord { + ( + [$elem_ty:ident; $elem_count:expr]: + $id:ident | $test_tt:tt | + ($true:expr, $false:expr) + ) => { + impl $id { + /// Returns a wrapper that implements `Ord`. + #[inline] + pub fn lex_ord(&self) -> LexicographicallyOrdered<$id> { + LexicographicallyOrdered(*self) + } + } + + impl crate::cmp::Ord for LexicographicallyOrdered<$id> { + #[inline] + fn cmp(&self, other: &Self) -> crate::cmp::Ordering { + match self.partial_cmp(other) { + Some(x) => x, + None => unsafe { crate::hint::unreachable_unchecked() }, + } + } + } + + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _cmp_ord>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn eq() { + fn foo<E: crate::cmp::Ord>(_: E) {} + let a = $id::splat($false); + foo(a.partial_lex_ord()); + foo(a.lex_ord()); + } + } + } + } + }; +} diff --git a/third_party/rust/packed_simd/src/api/cmp/partial_eq.rs b/third_party/rust/packed_simd/src/api/cmp/partial_eq.rs new file mode 100644 index 0000000000..d69dd47425 --- /dev/null +++ b/third_party/rust/packed_simd/src/api/cmp/partial_eq.rs @@ -0,0 +1,65 @@ +//! Implements `PartialEq` for vector types. + +macro_rules! impl_cmp_partial_eq { + ( + [$elem_ty:ident; $elem_count:expr]: + $id:ident | $test_tt:tt | + ($true:expr, $false:expr) + ) => { + // FIXME: https://github.com/rust-lang-nursery/rust-clippy/issues/2892 + #[allow(clippy::partialeq_ne_impl)] + impl crate::cmp::PartialEq<$id> for $id { + #[inline] + fn eq(&self, other: &Self) -> bool { + $id::eq(*self, *other).all() + } + #[inline] + fn ne(&self, other: &Self) -> bool { + $id::ne(*self, *other).any() + } + } + + // FIXME: https://github.com/rust-lang-nursery/rust-clippy/issues/2892 + #[allow(clippy::partialeq_ne_impl)] + impl crate::cmp::PartialEq<LexicographicallyOrdered<$id>> for LexicographicallyOrdered<$id> { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + #[inline] + fn ne(&self, other: &Self) -> bool { + self.0 != other.0 + } + } + + test_if! { + $test_tt: + paste::item! { + pub mod [<$id _cmp_PartialEq>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn partial_eq() { + let a = $id::splat($false); + let b = $id::splat($true); + + assert!(a != b); + assert!(!(a == b)); + assert!(a == a); + assert!(!(a != a)); + + if $id::lanes() > 1 { + let a = $id::splat($false).replace(0, $true); + let b = $id::splat($true); + + assert!(a != b); + assert!(!(a == b)); + assert!(a == a); + assert!(!(a != a)); + } + } + } + } + } + }; +} diff --git a/third_party/rust/packed_simd/src/api/cmp/partial_ord.rs b/third_party/rust/packed_simd/src/api/cmp/partial_ord.rs new file mode 100644 index 0000000000..76ed9ebe4e --- /dev/null +++ b/third_party/rust/packed_simd/src/api/cmp/partial_ord.rs @@ -0,0 +1,230 @@ +//! Implements `PartialOrd` for vector types. +//! +//! This implements a lexicographical order. + +macro_rules! impl_cmp_partial_ord { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + impl $id { + /// Returns a wrapper that implements `PartialOrd`. + #[inline] + pub fn partial_lex_ord(&self) -> LexicographicallyOrdered<$id> { + LexicographicallyOrdered(*self) + } + } + + impl crate::cmp::PartialOrd<LexicographicallyOrdered<$id>> for LexicographicallyOrdered<$id> { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option<crate::cmp::Ordering> { + if PartialEq::eq(self, other) { + Some(crate::cmp::Ordering::Equal) + } else if PartialOrd::lt(self, other) { + Some(crate::cmp::Ordering::Less) + } else if PartialOrd::gt(self, other) { + Some(crate::cmp::Ordering::Greater) + } else { + None + } + } + #[inline] + fn lt(&self, other: &Self) -> bool { + let m_lt = self.0.lt(other.0); + let m_eq = self.0.eq(other.0); + for i in 0..$id::lanes() { + if m_eq.extract(i) { + continue; + } + return m_lt.extract(i); + } + false + } + #[inline] + fn le(&self, other: &Self) -> bool { + self.lt(other) | PartialEq::eq(self, other) + } + #[inline] + fn ge(&self, other: &Self) -> bool { + self.gt(other) | PartialEq::eq(self, other) + } + #[inline] + fn gt(&self, other: &Self) -> bool { + let m_gt = self.0.gt(other.0); + let m_eq = self.0.eq(other.0); + for i in 0..$id::lanes() { + if m_eq.extract(i) { + continue; + } + return m_gt.extract(i); + } + false + } + } + }; +} + +macro_rules! test_cmp_partial_ord_int { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _cmp_PartialOrd>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn partial_lex_ord() { + use crate::testing::utils::{test_cmp}; + // constant values + let a = $id::splat(0); + let b = $id::splat(1); + + test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Less)); + test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Greater)); + test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + + // variable values: a = [0, 1, 2, 3]; b = [3, 2, 1, 0] + let mut a = $id::splat(0); + let mut b = $id::splat(0); + for i in 0..$id::lanes() { + a = a.replace(i, i as $elem_ty); + b = b.replace(i, ($id::lanes() - i) as $elem_ty); + } + test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Less)); + test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Greater)); + test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + + // variable values: a = [0, 1, 2, 3]; b = [0, 1, 2, 4] + let mut b = a; + b = b.replace( + $id::lanes() - 1, + a.extract($id::lanes() - 1) + 1 as $elem_ty + ); + test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Less)); + test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Greater)); + test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + + if $id::lanes() > 2 { + // variable values a = [0, 1, 0, 0]; b = [0, 1, 2, 3] + let b = a; + let mut a = $id::splat(0); + a = a.replace(1, 1 as $elem_ty); + test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Less)); + test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Greater)); + test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + + // variable values: a = [0, 1, 2, 3]; b = [0, 1, 3, 2] + let mut b = a; + b = b.replace( + 2, a.extract($id::lanes() - 1) + 1 as $elem_ty + ); + test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Less)); + test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Greater)); + test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), + Some(crate::cmp::Ordering::Equal)); + } + } + } + } + } + }; +} + +macro_rules! test_cmp_partial_ord_mask { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _cmp_PartialOrd>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn partial_lex_ord() { + use crate::testing::utils::{test_cmp}; + use crate::cmp::Ordering; + + // constant values + let a = $id::splat(false); + let b = $id::splat(true); + + test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), + Some(Ordering::Less)); + test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), + Some(Ordering::Greater)); + test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), + Some(Ordering::Equal)); + test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), + Some(Ordering::Equal)); + + // variable values: + // a = [false, false, false, false]; + // b = [false, false, false, true] + let a = $id::splat(false); + let mut b = $id::splat(false); + b = b.replace($id::lanes() - 1, true); + test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), + Some(Ordering::Less)); + test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), + Some(Ordering::Greater)); + test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), + Some(Ordering::Equal)); + test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), + Some(Ordering::Equal)); + + // variable values: + // a = [true, true, true, false]; + // b = [true, true, true, true] + let mut a = $id::splat(true); + let b = $id::splat(true); + a = a.replace($id::lanes() - 1, false); + test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), + Some(Ordering::Less)); + test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), + Some(Ordering::Greater)); + test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), + Some(Ordering::Equal)); + test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), + Some(Ordering::Equal)); + + if $id::lanes() > 2 { + // variable values + // a = [false, true, false, false]; + // b = [false, true, true, true] + let mut a = $id::splat(false); + let mut b = $id::splat(true); + a = a.replace(1, true); + b = b.replace(0, false); + test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), + Some(Ordering::Less)); + test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), + Some(Ordering::Greater)); + test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), + Some(Ordering::Equal)); + test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), + Some(Ordering::Equal)); + } + } + } + } + } + }; +} diff --git a/third_party/rust/packed_simd/src/api/cmp/vertical.rs b/third_party/rust/packed_simd/src/api/cmp/vertical.rs new file mode 100644 index 0000000000..ea4a0d1a34 --- /dev/null +++ b/third_party/rust/packed_simd/src/api/cmp/vertical.rs @@ -0,0 +1,114 @@ +//! Vertical (lane-wise) vector comparisons returning vector masks. + +macro_rules! impl_cmp_vertical { + ( + [$elem_ty:ident; $elem_count:expr]: + $id:ident, + $mask_ty:ident, + $is_mask:expr,($true:expr, $false:expr) | $test_tt:tt + ) => { + impl $id { + /// Lane-wise equality comparison. + #[inline] + pub fn eq(self, other: Self) -> $mask_ty { + use crate::llvm::simd_eq; + Simd(unsafe { simd_eq(self.0, other.0) }) + } + + /// Lane-wise inequality comparison. + #[inline] + pub fn ne(self, other: Self) -> $mask_ty { + use crate::llvm::simd_ne; + Simd(unsafe { simd_ne(self.0, other.0) }) + } + + /// Lane-wise less-than comparison. + #[inline] + pub fn lt(self, other: Self) -> $mask_ty { + use crate::llvm::{simd_gt, simd_lt}; + if $is_mask { + Simd(unsafe { simd_gt(self.0, other.0) }) + } else { + Simd(unsafe { simd_lt(self.0, other.0) }) + } + } + + /// Lane-wise less-than-or-equals comparison. + #[inline] + pub fn le(self, other: Self) -> $mask_ty { + use crate::llvm::{simd_ge, simd_le}; + if $is_mask { + Simd(unsafe { simd_ge(self.0, other.0) }) + } else { + Simd(unsafe { simd_le(self.0, other.0) }) + } + } + + /// Lane-wise greater-than comparison. + #[inline] + pub fn gt(self, other: Self) -> $mask_ty { + use crate::llvm::{simd_gt, simd_lt}; + if $is_mask { + Simd(unsafe { simd_lt(self.0, other.0) }) + } else { + Simd(unsafe { simd_gt(self.0, other.0) }) + } + } + + /// Lane-wise greater-than-or-equals comparison. + #[inline] + pub fn ge(self, other: Self) -> $mask_ty { + use crate::llvm::{simd_ge, simd_le}; + if $is_mask { + Simd(unsafe { simd_le(self.0, other.0) }) + } else { + Simd(unsafe { simd_ge(self.0, other.0) }) + } + } + } + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _cmp_vertical>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn cmp() { + let a = $id::splat($false); + let b = $id::splat($true); + + let r = a.lt(b); + let e = $mask_ty::splat(true); + assert!(r == e); + let r = a.le(b); + assert!(r == e); + + let e = $mask_ty::splat(false); + let r = a.gt(b); + assert!(r == e); + let r = a.ge(b); + assert!(r == e); + let r = a.eq(b); + assert!(r == e); + + let mut a = a; + let mut b = b; + let mut e = e; + for i in 0..$id::lanes() { + if i % 2 == 0 { + a = a.replace(i, $false); + b = b.replace(i, $true); + e = e.replace(i, true); + } else { + a = a.replace(i, $true); + b = b.replace(i, $false); + e = e.replace(i, false); + } + } + let r = a.lt(b); + assert!(r == e); + } + } + } + } + }; +} |