summaryrefslogtreecommitdiffstats
path: root/vendor/packed_simd/src/api/cmp
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/packed_simd/src/api/cmp')
-rw-r--r--vendor/packed_simd/src/api/cmp/eq.rs27
-rw-r--r--vendor/packed_simd/src/api/cmp/ord.rs43
-rw-r--r--vendor/packed_simd/src/api/cmp/partial_eq.rs65
-rw-r--r--vendor/packed_simd/src/api/cmp/partial_ord.rs230
-rw-r--r--vendor/packed_simd/src/api/cmp/vertical.rs114
5 files changed, 479 insertions, 0 deletions
diff --git a/vendor/packed_simd/src/api/cmp/eq.rs b/vendor/packed_simd/src/api/cmp/eq.rs
new file mode 100644
index 000000000..3c55d0dce
--- /dev/null
+++ b/vendor/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/vendor/packed_simd/src/api/cmp/ord.rs b/vendor/packed_simd/src/api/cmp/ord.rs
new file mode 100644
index 000000000..e54ba3bfd
--- /dev/null
+++ b/vendor/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/vendor/packed_simd/src/api/cmp/partial_eq.rs b/vendor/packed_simd/src/api/cmp/partial_eq.rs
new file mode 100644
index 000000000..d69dd4742
--- /dev/null
+++ b/vendor/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/vendor/packed_simd/src/api/cmp/partial_ord.rs b/vendor/packed_simd/src/api/cmp/partial_ord.rs
new file mode 100644
index 000000000..76ed9ebe4
--- /dev/null
+++ b/vendor/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/vendor/packed_simd/src/api/cmp/vertical.rs b/vendor/packed_simd/src/api/cmp/vertical.rs
new file mode 100644
index 000000000..ea4a0d1a3
--- /dev/null
+++ b/vendor/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);
+ }
+ }
+ }
+ }
+ };
+}