blob: a06ff0fab1f484a869923e4653a90b01dd06fd60 [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(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);
}
}
}
}
};
}