//! Vertical (lane-wise) vector-vector bitwise operations. macro_rules! impl_ops_vector_bitwise { ( [$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt | ($true:expr, $false:expr) ) => { impl crate::ops::Not for $id { type Output = Self; #[inline] fn not(self) -> Self { Self::splat($true) ^ self } } impl crate::ops::BitXor for $id { type Output = Self; #[inline] fn bitxor(self, other: Self) -> Self { use crate::llvm::simd_xor; unsafe { Simd(simd_xor(self.0, other.0)) } } } impl crate::ops::BitAnd for $id { type Output = Self; #[inline] fn bitand(self, other: Self) -> Self { use crate::llvm::simd_and; unsafe { Simd(simd_and(self.0, other.0)) } } } impl crate::ops::BitOr for $id { type Output = Self; #[inline] fn bitor(self, other: Self) -> Self { use crate::llvm::simd_or; unsafe { Simd(simd_or(self.0, other.0)) } } } impl crate::ops::BitAndAssign for $id { #[inline] fn bitand_assign(&mut self, other: Self) { *self = *self & other; } } impl crate::ops::BitOrAssign for $id { #[inline] fn bitor_assign(&mut self, other: Self) { *self = *self | other; } } impl crate::ops::BitXorAssign for $id { #[inline] fn bitxor_assign(&mut self, other: Self) { *self = *self ^ other; } } test_if!{ $test_tt: paste::item! { pub mod [<$id _ops_vector_bitwise>] { use super::*; #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn ops_vector_bitwise() { let z = $id::splat(0 as $elem_ty); let o = $id::splat(1 as $elem_ty); let t = $id::splat(2 as $elem_ty); let m = $id::splat(!z.extract(0)); // Not: assert_eq!(!z, m); assert_eq!(!m, z); // BitAnd: assert_eq!(o & o, o); assert_eq!(o & z, z); assert_eq!(z & o, z); assert_eq!(z & z, z); assert_eq!(t & t, t); assert_eq!(t & o, z); assert_eq!(o & t, z); // BitOr: assert_eq!(o | o, o); assert_eq!(o | z, o); assert_eq!(z | o, o); assert_eq!(z | z, z); assert_eq!(t | t, t); assert_eq!(z | t, t); assert_eq!(t | z, t); // BitXOR: assert_eq!(o ^ o, z); assert_eq!(z ^ z, z); assert_eq!(z ^ o, o); assert_eq!(o ^ z, o); assert_eq!(t ^ t, z); assert_eq!(t ^ z, t); assert_eq!(z ^ t, t); { // AndAssign: let mut v = o; v &= t; assert_eq!(v, z); } { // OrAssign: let mut v = z; v |= o; assert_eq!(v, o); } { // XORAssign: let mut v = z; v ^= o; assert_eq!(v, o); } } } } } }; }