blob: 8f4868f32844679d8891c739ce870e7ccb774429 [file] [log] [blame]
//! 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(
// FIXME: https://github.com/rust-lang-nursery/packed_simd/issues/210
target_endian = "big"
))]
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);
}
}
}
}
};
}