1 //! Vertical (lane-wise) vector comparisons returning vector masks.
2 
3 macro_rules! impl_cmp_vertical {
4     (
5         [$elem_ty:ident; $elem_count:expr]:
6         $id:ident,
7         $mask_ty:ident,
8         $is_mask:expr,($true:expr, $false:expr) | $test_tt:tt
9     ) => {
10         impl $id {
11             /// Lane-wise equality comparison.
12             #[inline]
13             pub fn eq(self, other: Self) -> $mask_ty {
14                 use crate::llvm::simd_eq;
15                 Simd(unsafe { simd_eq(self.0, other.0) })
16             }
17 
18             /// Lane-wise inequality comparison.
19             #[inline]
20             pub fn ne(self, other: Self) -> $mask_ty {
21                 use crate::llvm::simd_ne;
22                 Simd(unsafe { simd_ne(self.0, other.0) })
23             }
24 
25             /// Lane-wise less-than comparison.
26             #[inline]
27             pub fn lt(self, other: Self) -> $mask_ty {
28                 use crate::llvm::{simd_gt, simd_lt};
29                 if $is_mask {
30                     Simd(unsafe { simd_gt(self.0, other.0) })
31                 } else {
32                     Simd(unsafe { simd_lt(self.0, other.0) })
33                 }
34             }
35 
36             /// Lane-wise less-than-or-equals comparison.
37             #[inline]
38             pub fn le(self, other: Self) -> $mask_ty {
39                 use crate::llvm::{simd_ge, simd_le};
40                 if $is_mask {
41                     Simd(unsafe { simd_ge(self.0, other.0) })
42                 } else {
43                     Simd(unsafe { simd_le(self.0, other.0) })
44                 }
45             }
46 
47             /// Lane-wise greater-than comparison.
48             #[inline]
49             pub fn gt(self, other: Self) -> $mask_ty {
50                 use crate::llvm::{simd_gt, simd_lt};
51                 if $is_mask {
52                     Simd(unsafe { simd_lt(self.0, other.0) })
53                 } else {
54                     Simd(unsafe { simd_gt(self.0, other.0) })
55                 }
56             }
57 
58             /// Lane-wise greater-than-or-equals comparison.
59             #[inline]
60             pub fn ge(self, other: Self) -> $mask_ty {
61                 use crate::llvm::{simd_ge, simd_le};
62                 if $is_mask {
63                     Simd(unsafe { simd_le(self.0, other.0) })
64                 } else {
65                     Simd(unsafe { simd_ge(self.0, other.0) })
66                 }
67             }
68         }
69         test_if!{
70             $test_tt:
71             paste::item! {
72                 pub mod [<$id _cmp_vertical>] {
73                     use super::*;
74                     #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
75                     fn cmp() {
76                         let a = $id::splat($false);
77                         let b = $id::splat($true);
78 
79                         let r = a.lt(b);
80                         let e = $mask_ty::splat(true);
81                         assert!(r == e);
82                         let r = a.le(b);
83                         assert!(r == e);
84 
85                         let e = $mask_ty::splat(false);
86                         let r = a.gt(b);
87                         assert!(r == e);
88                         let r = a.ge(b);
89                         assert!(r == e);
90                         let r = a.eq(b);
91                         assert!(r == e);
92 
93                         let mut a = a;
94                         let mut b = b;
95                         let mut e = e;
96                         for i in 0..$id::lanes() {
97                             if i % 2 == 0 {
98                                 a = a.replace(i, $false);
99                                 b = b.replace(i, $true);
100                                 e = e.replace(i, true);
101                             } else {
102                                 a = a.replace(i, $true);
103                                 b = b.replace(i, $false);
104                                 e = e.replace(i, false);
105                             }
106                         }
107                         let r = a.lt(b);
108                         assert!(r == e);
109                     }
110                 }
111             }
112         }
113     };
114 }
115