//! Bitmask API macro_rules! impl_bitmask { ($id:ident | $ibitmask_ty:ident | ($set:expr, $clear:expr) | $test_tt:tt) => { impl $id { /// Creates a bitmask with the MSB of each vector lane. /// /// If the vector has less than 8 lanes, the bits that do not /// correspond to any vector lanes are cleared. #[inline] pub fn bitmask(self) -> $ibitmask_ty { unsafe { codegen::llvm::simd_bitmask(self.0) } } } test_if! { $test_tt: paste::item! { #[cfg(not(any( // FIXME: https://github.com/rust-lang-nursery/packed_simd/issues/210 all(target_arch = "mips", target_endian = "big"), all(target_arch = "mips64", target_endian = "big"), target_arch = "sparc64", target_arch = "s390x", )))] pub mod [<$id _bitmask>] { use super::*; #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitmask() { // clear all lanes let vec = $id::splat($clear as _); let bitmask: $ibitmask_ty = 0; assert_eq!(vec.bitmask(), bitmask); // set even lanes let mut vec = $id::splat($clear as _); for i in 0..$id::lanes() { if i % 2 == 0 { vec = vec.replace(i, $set as _); } } // create bitmask with even lanes set: let mut bitmask: $ibitmask_ty = 0; for i in 0..$id::lanes() { if i % 2 == 0 { bitmask |= 1 << i; } } assert_eq!(vec.bitmask(), bitmask); // set odd lanes let mut vec = $id::splat($clear as _); for i in 0..$id::lanes() { if i % 2 != 0 { vec = vec.replace(i, $set as _); } } // create bitmask with odd lanes set: let mut bitmask: $ibitmask_ty = 0; for i in 0..$id::lanes() { if i % 2 != 0 { bitmask |= 1 << i; } } assert_eq!(vec.bitmask(), bitmask); // set all lanes let vec = $id::splat($set as _); let mut bitmask: $ibitmask_ty = 0; for i in 0..$id::lanes() { bitmask |= 1 << i; } assert_eq!(vec.bitmask(), bitmask); } } } } }; }