5424140b66
This const generic implementation for certain lane sizes represents a more limited interface than what LLVM's shufflevector instruction can handle, as normally the length of U can be different from the length of T, but offers an interface that it is expected to be able to expand the capabilities of in the future.
30 lines
1.3 KiB
Rust
30 lines
1.3 KiB
Rust
macro_rules! impl_shuffle_lane {
|
|
{ $name:ident, $fn:ident, $n:literal } => {
|
|
impl $name<$n> {
|
|
/// A const SIMD shuffle that takes 2 SIMD vectors and produces another vector, using
|
|
/// the indices in the const parameter. The first or "self" vector will have its lanes
|
|
/// indexed from 0, and the second vector will have its first lane indexed at $n.
|
|
/// Indices must be in-bounds of either vector at compile time.
|
|
///
|
|
/// Some SIMD shuffle instructions can be quite slow, so avoiding them by loading data
|
|
/// into the desired patterns in advance is preferred, but shuffles are still faster
|
|
/// than storing and reloading from memory.
|
|
#[inline]
|
|
pub fn shuffle<const IDX: [u32; $n]>(self, second: Self) -> Self {
|
|
unsafe { crate::intrinsics::$fn(self, second, IDX) }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_shuffle_2pow_lanes {
|
|
{ $name:ident } => {
|
|
impl_shuffle_lane!{ $name, simd_shuffle2, 2 }
|
|
impl_shuffle_lane!{ $name, simd_shuffle4, 4 }
|
|
impl_shuffle_lane!{ $name, simd_shuffle8, 8 }
|
|
impl_shuffle_lane!{ $name, simd_shuffle16, 16 }
|
|
impl_shuffle_lane!{ $name, simd_shuffle32, 32 }
|
|
impl_shuffle_lane!{ $name, simd_shuffle64, 64 }
|
|
}
|
|
}
|