1 //! Bitmask API 2 3 macro_rules! impl_bitmask { 4 ($id:ident | $ibitmask_ty:ident | ($set:expr, $clear:expr) 5 | $test_tt:tt) => { 6 impl $id { 7 /// Creates a bitmask with the MSB of each vector lane. 8 /// 9 /// If the vector has less than 8 lanes, the bits that do not 10 /// correspond to any vector lanes are cleared. 11 #[inline] 12 pub fn bitmask(self) -> $ibitmask_ty { 13 unsafe { codegen::llvm::simd_bitmask(self.0) } 14 } 15 } 16 17 test_if! { 18 $test_tt: 19 paste::item! { 20 #[cfg(not(any( 21 // FIXME: https://github.com/rust-lang-nursery/packed_simd/issues/210 22 all(target_arch = "mips", target_endian = "big"), 23 all(target_arch = "mips64", target_endian = "big"), 24 target_arch = "sparc64", 25 target_arch = "s390x", 26 )))] 27 pub mod [<$id _bitmask>] { 28 use super::*; 29 #[cfg_attr(not(target_arch = "wasm32"), test)] 30 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] 31 fn bitmask() { 32 // clear all lanes 33 let vec = $id::splat($clear as _); 34 let bitmask: $ibitmask_ty = 0; 35 assert_eq!(vec.bitmask(), bitmask); 36 37 // set even lanes 38 let mut vec = $id::splat($clear as _); 39 for i in 0..$id::lanes() { 40 if i % 2 == 0 { 41 vec = vec.replace(i, $set as _); 42 } 43 } 44 // create bitmask with even lanes set: 45 let mut bitmask: $ibitmask_ty = 0; 46 for i in 0..$id::lanes() { 47 if i % 2 == 0 { 48 bitmask |= 1 << i; 49 } 50 } 51 assert_eq!(vec.bitmask(), bitmask); 52 53 54 // set odd lanes 55 let mut vec = $id::splat($clear as _); 56 for i in 0..$id::lanes() { 57 if i % 2 != 0 { 58 vec = vec.replace(i, $set as _); 59 } 60 } 61 // create bitmask with odd lanes set: 62 let mut bitmask: $ibitmask_ty = 0; 63 for i in 0..$id::lanes() { 64 if i % 2 != 0 { 65 bitmask |= 1 << i; 66 } 67 } 68 assert_eq!(vec.bitmask(), bitmask); 69 70 // set all lanes 71 let vec = $id::splat($set as _); 72 let mut bitmask: $ibitmask_ty = 0; 73 for i in 0..$id::lanes() { 74 bitmask |= 1 << i; 75 } 76 assert_eq!(vec.bitmask(), bitmask); 77 } 78 } 79 } 80 } 81 }; 82 } 83