1 //! Vertical (lane-wise) vector-vector bitwise operations.
2 
3 macro_rules! impl_ops_vector_bitwise {
4     (
5         [$elem_ty:ident; $elem_count:expr]:
6         $id:ident | $test_tt:tt |
7         ($true:expr, $false:expr)
8     ) => {
9         impl crate::ops::Not for $id {
10             type Output = Self;
11             #[inline]
12             fn not(self) -> Self {
13                 Self::splat($true) ^ self
14             }
15         }
16         impl crate::ops::BitXor for $id {
17             type Output = Self;
18             #[inline]
19             fn bitxor(self, other: Self) -> Self {
20                 use crate::llvm::simd_xor;
21                 unsafe { Simd(simd_xor(self.0, other.0)) }
22             }
23         }
24         impl crate::ops::BitAnd for $id {
25             type Output = Self;
26             #[inline]
27             fn bitand(self, other: Self) -> Self {
28                 use crate::llvm::simd_and;
29                 unsafe { Simd(simd_and(self.0, other.0)) }
30             }
31         }
32         impl crate::ops::BitOr for $id {
33             type Output = Self;
34             #[inline]
35             fn bitor(self, other: Self) -> Self {
36                 use crate::llvm::simd_or;
37                 unsafe { Simd(simd_or(self.0, other.0)) }
38             }
39         }
40         impl crate::ops::BitAndAssign for $id {
41             #[inline]
42             fn bitand_assign(&mut self, other: Self) {
43                 *self = *self & other;
44             }
45         }
46         impl crate::ops::BitOrAssign for $id {
47             #[inline]
48             fn bitor_assign(&mut self, other: Self) {
49                 *self = *self | other;
50             }
51         }
52         impl crate::ops::BitXorAssign for $id {
53             #[inline]
54             fn bitxor_assign(&mut self, other: Self) {
55                 *self = *self ^ other;
56             }
57         }
58 
59         test_if!{
60             $test_tt:
61             paste::item! {
62                 pub mod [<$id _ops_vector_bitwise>] {
63                     use super::*;
64                     #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
65                     fn ops_vector_bitwise() {
66 
67                         let z = $id::splat(0 as $elem_ty);
68                         let o = $id::splat(1 as $elem_ty);
69                         let t = $id::splat(2 as $elem_ty);
70                         let m = $id::splat(!z.extract(0));
71 
72                         // Not:
73                         assert_eq!(!z, m);
74                         assert_eq!(!m, z);
75 
76                         // BitAnd:
77                         assert_eq!(o & o, o);
78                         assert_eq!(o & z, z);
79                         assert_eq!(z & o, z);
80                         assert_eq!(z & z, z);
81 
82                         assert_eq!(t & t, t);
83                         assert_eq!(t & o, z);
84                         assert_eq!(o & t, z);
85 
86                         // BitOr:
87                         assert_eq!(o | o, o);
88                         assert_eq!(o | z, o);
89                         assert_eq!(z | o, o);
90                         assert_eq!(z | z, z);
91 
92                         assert_eq!(t | t, t);
93                         assert_eq!(z | t, t);
94                         assert_eq!(t | z, t);
95 
96                         // BitXOR:
97                         assert_eq!(o ^ o, z);
98                         assert_eq!(z ^ z, z);
99                         assert_eq!(z ^ o, o);
100                         assert_eq!(o ^ z, o);
101 
102                         assert_eq!(t ^ t, z);
103                         assert_eq!(t ^ z, t);
104                         assert_eq!(z ^ t, t);
105 
106                         {
107                             // AndAssign:
108                             let mut v = o;
109                             v &= t;
110                             assert_eq!(v, z);
111                         }
112                         {
113                             // OrAssign:
114                             let mut v = z;
115                             v |= o;
116                             assert_eq!(v, o);
117                         }
118                         {
119                             // XORAssign:
120                             let mut v = z;
121                             v ^= o;
122                             assert_eq!(v, o);
123                         }
124                     }
125                 }
126             }
127         }
128     };
129 }
130