diff options
Diffstat (limited to 'third_party/rust/packed_simd/src/api/bitmask.rs')
-rw-r--r-- | third_party/rust/packed_simd/src/api/bitmask.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/third_party/rust/packed_simd/src/api/bitmask.rs b/third_party/rust/packed_simd/src/api/bitmask.rs new file mode 100644 index 0000000000..a06ff0fab1 --- /dev/null +++ b/third_party/rust/packed_simd/src/api/bitmask.rs @@ -0,0 +1,82 @@ +//! 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); + } + } + } + } + }; +} |