[][src]Macro safe_arch::shuffle_m128

macro_rules! shuffle_m128 {
    ($a:expr, $b:expr, $z:expr, $o:expr, $t:expr, $e:expr) => { ... };
    ($a:expr, $z:expr, $o:expr, $t:expr, $e:expr) => { ... };
}

Shuffles the lanes around.

This is a macro because the shuffle pattern must be a compile time constant, and Rust doesn't currently support that for functions.

Two m128 Inputs

You can provide two m128 arguments, in which case:

  • The low lanes of the output come from $a, as picked by $z and $o (Zero and One)
  • The high lanes of the output come from $b, as picked by $t and $e (Two and threE).
  • $a and $b must obviously be m128 expressions.
  • Each of the lane selection values is a lane index (0..4). They can be any integer type as long as all four lane indexes are the same type. Out of bounds index values are wrapped to just the low 2 bits.
  • The lane selection values are combined into a private const which is computed at compile time and then used at runtime. This means that you can use literals, but you can also use the names of other constants or even a const fn expression, if that is somehow is useful to you.
let a = m128::from_array([1.0, 2.0, 3.0, 4.0]);
let b = m128::from_array([5.0, 6.0, 7.0, 8.0]);
//
let c = shuffle_m128!(a, b, 0, 0, 0, 0).to_array();
assert_eq!(c, [1.0, 1.0, 5.0, 5.0]);
//
let c = shuffle_m128!(a, b, 0, 1, 2, 3).to_array();
assert_eq!(c, [1.0, 2.0, 7.0, 8.0]);
//
let c = shuffle_m128!(a, b, 0, 2, 2, 1).to_array();
assert_eq!(c, [1.0, 3.0, 7.0, 6.0]);

One m128 Input

You can provide one m128 argument, in which case the above variant is called with $a as the input to both sides of the shuffle (note that any potential side effects of evaluating $a are executed only once).

let a = m128::from_array([1.0, 2.0, 3.0, 4.0]);
//
let c = shuffle_m128!(a, 0, 0, 0, 0).to_array();
assert_eq!(c, [1.0, 1.0, 1.0, 1.0]);
//
let c = shuffle_m128!(a, 0, 1, 2, 3).to_array();
assert_eq!(c, [1.0, 2.0, 3.0, 4.0]);
//
let c = shuffle_m128!(a, 0, 2, 2, 1).to_array();
assert_eq!(c, [1.0, 3.0, 3.0, 2.0]);