1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! Shuffle vector elements according to a dynamic vector of indices.
macro_rules! impl_shuffle1_dyn {
([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => {
impl $id {
/// Shuffle vector elements according to `indices`.
#[inline]
pub fn shuffle1_dyn<I>(self, indices: I) -> Self
where
Self: codegen::shuffle1_dyn::Shuffle1Dyn<Indices = I>,
{
codegen::shuffle1_dyn::Shuffle1Dyn::shuffle1_dyn(self, indices)
}
}
};
}
macro_rules! test_shuffle1_dyn {
([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => {
test_if! {
$test_tt:
paste::item! {
pub mod [<$id _shuffle1_dyn>] {
use super::*;
#[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn shuffle1_dyn() {
let increasing = {
let mut v = $id::splat(0 as $elem_ty);
for i in 0..$id::lanes() {
v = v.replace(i, i as $elem_ty);
}
v
};
let decreasing = {
let mut v = $id::splat(0 as $elem_ty);
for i in 0..$id::lanes() {
v = v.replace(i, ($id::lanes() - 1 - i) as $elem_ty);
}
v
};
type Indices = <$id as codegen::shuffle1_dyn::Shuffle1Dyn>::Indices;
let increasing_ids: Indices = increasing.cast();
let decreasing_ids: Indices = decreasing.cast();
assert_eq!(increasing.shuffle1_dyn(increasing_ids), increasing, "(i,i)=>i");
assert_eq!(decreasing.shuffle1_dyn(increasing_ids), decreasing, "(d,i)=>d");
assert_eq!(increasing.shuffle1_dyn(decreasing_ids), decreasing, "(i,d)=>d");
assert_eq!(decreasing.shuffle1_dyn(decreasing_ids), increasing, "(d,d)=>i");
for i in 0..$id::lanes() {
let v_ids: Indices = $id::splat(i as $elem_ty).cast();
assert_eq!(increasing.shuffle1_dyn(v_ids),
$id::splat(increasing.extract(i)));
assert_eq!(decreasing.shuffle1_dyn(v_ids),
$id::splat(decreasing.extract(i)));
assert_eq!($id::splat(i as $elem_ty).shuffle1_dyn(increasing_ids),
$id::splat(i as $elem_ty));
assert_eq!($id::splat(i as $elem_ty).shuffle1_dyn(decreasing_ids),
$id::splat(i as $elem_ty));
}
}
}
}
}
};
}
macro_rules! test_shuffle1_dyn_mask {
([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => {
test_if! {
$test_tt:
paste::item! {
pub mod [<$id _shuffle1_dyn>] {
use super::*;
#[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn shuffle1_dyn() {
// alternating = [true, false, true, false, ...]
let mut alternating = $id::splat(false);
for i in 0..$id::lanes() {
if i % 2 == 0 {
alternating = alternating.replace(i, true);
}
}
type Indices = <$id as codegen::shuffle1_dyn::Shuffle1Dyn>::Indices;
// even = [0, 0, 2, 2, 4, 4, ..]
let even = {
let mut v = Indices::splat(0);
for i in 0..$id::lanes() {
if i % 2 == 0 {
v = v.replace(i, (i as u8).into());
} else {
v = v.replace(i, (i as u8 - 1).into());
}
}
v
};
// odd = [1, 1, 3, 3, 5, 5, ...]
let odd = {
let mut v = Indices::splat(0);
for i in 0..$id::lanes() {
if i % 2 != 0 {
v = v.replace(i, (i as u8).into());
} else {
v = v.replace(i, (i as u8 + 1).into());
}
}
v
};
assert_eq!(alternating.shuffle1_dyn(even), $id::splat(true));
if $id::lanes() > 1 {
assert_eq!(alternating.shuffle1_dyn(odd), $id::splat(false));
}
}
}
}
}
};
}