core/stdarch/crates/core_arch/src/s390x/
vector.rs

1//! s390x vector intrinsics.
2//!
3//! For more info see the [Reference Summary] or the online [IBM docs].
4//!
5//! [Reference Summary]: https://www.ibm.com/support/pages/sites/default/files/2021-05/SA22-7871-10.pdf
6//! [IBM docs]: https://www.ibm.com/docs/en/zos/2.4.0?topic=support-vector-built-in-functions
7
8#![allow(non_camel_case_types)]
9
10use crate::{core_arch::simd::*, intrinsics::simd::*, mem::MaybeUninit, mem::transmute};
11
12#[cfg(test)]
13use stdarch_test::assert_instr;
14
15use super::macros::*;
16
17types! {
18    #![unstable(feature = "stdarch_s390x", issue = "135681")]
19
20    /// s390x-specific 128-bit wide vector of sixteen packed `i8`
21    pub struct vector_signed_char(16 x i8);
22    /// s390x-specific 128-bit wide vector of sixteen packed `u8`
23    pub struct vector_unsigned_char(16 x u8);
24    /// s390x-specific 128-bit wide vector mask of sixteen packed elements
25    pub struct vector_bool_char(16 x i8);
26
27    /// s390x-specific 128-bit wide vector of eight packed `i16`
28    pub struct vector_signed_short(8 x i16);
29    /// s390x-specific 128-bit wide vector of eight packed `u16`
30    pub struct vector_unsigned_short(8 x u16);
31    /// s390x-specific 128-bit wide vector mask of eight packed elements
32    pub struct vector_bool_short(8 x i16);
33
34    /// s390x-specific 128-bit wide vector of four packed `i32`
35    pub struct vector_signed_int(4 x i32);
36    /// s390x-specific 128-bit wide vector of four packed `u32`
37    pub struct vector_unsigned_int(4 x u32);
38    /// s390x-specific 128-bit wide vector mask of four packed elements
39    pub struct vector_bool_int(4 x i32);
40
41    /// s390x-specific 128-bit wide vector of two packed `i64`
42    pub struct vector_signed_long_long(2 x i64);
43    /// s390x-specific 128-bit wide vector of two packed `u64`
44    pub struct vector_unsigned_long_long(2 x u64);
45    /// s390x-specific 128-bit wide vector mask of two packed elements
46    pub struct vector_bool_long_long(2 x i64);
47
48    /// s390x-specific 128-bit wide vector of four packed `f32`
49    pub struct vector_float(4 x f32);
50    /// s390x-specific 128-bit wide vector of two packed `f64`
51    pub struct vector_double(2 x f64);
52}
53
54#[repr(C, packed)]
55struct PackedTuple<T, U> {
56    x: T,
57    y: U,
58}
59
60#[allow(improper_ctypes)]
61#[rustfmt::skip]
62unsafe extern "unadjusted" {
63    #[link_name = "llvm.nearbyint.v4f32"] fn nearbyint_v4f32(a: vector_float) -> vector_float;
64    #[link_name = "llvm.nearbyint.v2f64"] fn nearbyint_v2f64(a: vector_double) -> vector_double;
65
66    #[link_name = "llvm.roundeven.v4f32"] fn roundeven_v4f32(a: vector_float) -> vector_float;
67    #[link_name = "llvm.roundeven.v2f64"] fn roundeven_v2f64(a: vector_double) -> vector_double;
68
69    #[link_name = "llvm.s390.vsra"] fn vsra(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
70    #[link_name = "llvm.s390.vsrl"] fn vsrl(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
71    #[link_name = "llvm.s390.vsl"] fn vsl(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
72
73    #[link_name = "llvm.s390.vsrab"] fn vsrab(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
74    #[link_name = "llvm.s390.vsrlb"] fn vsrlb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
75    #[link_name = "llvm.s390.vslb"] fn vslb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
76
77    #[link_name = "llvm.s390.vsrd"] fn vsrd(a: i8x16, b: i8x16, c: u32) -> i8x16;
78
79    #[link_name = "llvm.s390.verimb"] fn verimb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char, d: i32) -> vector_signed_char;
80    #[link_name = "llvm.s390.verimh"] fn verimh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short, d: i32) -> vector_signed_short;
81    #[link_name = "llvm.s390.verimf"] fn verimf(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int, d: i32) -> vector_signed_int;
82    #[link_name = "llvm.s390.verimg"] fn verimg(a: vector_signed_long_long, b: vector_signed_long_long, c: vector_signed_long_long, d: i32) -> vector_signed_long_long;
83
84    #[link_name = "llvm.s390.vperm"] fn vperm(a: vector_signed_char, b: vector_signed_char, c: vector_unsigned_char) -> vector_signed_char;
85
86    #[link_name = "llvm.s390.vsumb"] fn vsumb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_int;
87    #[link_name = "llvm.s390.vsumh"] fn vsumh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int;
88
89    #[link_name = "llvm.s390.vsumgh"] fn vsumgh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_long_long;
90    #[link_name = "llvm.s390.vsumgf"] fn vsumgf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long;
91
92    #[link_name = "llvm.s390.vsumqf"] fn vsumqf(a: vector_unsigned_int, b: vector_unsigned_int) -> u128;
93    #[link_name = "llvm.s390.vsumqg"] fn vsumqg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> u128;
94
95    #[link_name = "llvm.s390.vaccq"] fn vaccq(a: u128, b: u128) -> u128;
96    #[link_name = "llvm.s390.vacccq"] fn vacccq(a: u128, b: u128, c: u128) -> u128;
97
98    #[link_name = "llvm.s390.vscbiq"] fn vscbiq(a: u128, b: u128) -> u128;
99    #[link_name = "llvm.s390.vsbiq"] fn vsbiq(a: u128, b: u128, c: u128) -> u128;
100    #[link_name = "llvm.s390.vsbcbiq"] fn vsbcbiq(a: u128, b: u128, c: u128) -> u128;
101
102    #[link_name = "llvm.s390.vacq"] fn vacq(a: u128, b: u128, c: u128) -> u128;
103
104    #[link_name = "llvm.s390.vscbib"] fn vscbib(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
105    #[link_name = "llvm.s390.vscbih"] fn vscbih(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
106    #[link_name = "llvm.s390.vscbif"] fn vscbif(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
107    #[link_name = "llvm.s390.vscbig"] fn vscbig(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long;
108
109    #[link_name = "llvm.s390.vfaeb"] fn vfaeb(a: vector_signed_char, b: vector_signed_char, c: i32) -> vector_signed_char;
110    #[link_name = "llvm.s390.vfaeh"] fn vfaeh(a: vector_signed_short, b: vector_signed_short, c: i32) -> vector_signed_short;
111    #[link_name = "llvm.s390.vfaef"] fn vfaef(a: vector_signed_int, b: vector_signed_int, c: i32) -> vector_signed_int;
112
113    #[link_name = "llvm.s390.vfaezb"] fn vfaezb(a: vector_signed_char, b: vector_signed_char, c: i32) -> vector_signed_char;
114    #[link_name = "llvm.s390.vfaezh"] fn vfaezh(a: vector_signed_short, b: vector_signed_short, c: i32) -> vector_signed_short;
115    #[link_name = "llvm.s390.vfaezf"] fn vfaezf(a: vector_signed_int, b: vector_signed_int, c: i32) -> vector_signed_int;
116
117    #[link_name = "llvm.s390.vfaebs"] fn vfaebs(a: vector_signed_char, b: vector_signed_char, c: i32) -> PackedTuple<vector_signed_char, i32>;
118    #[link_name = "llvm.s390.vfaehs"] fn vfaehs(a: vector_signed_short, b: vector_signed_short, c: i32) -> PackedTuple<vector_signed_short, i32>;
119    #[link_name = "llvm.s390.vfaefs"] fn vfaefs(a: vector_signed_int, b: vector_signed_int, c: i32) -> PackedTuple<vector_signed_int, i32>;
120
121    #[link_name = "llvm.s390.vfaezbs"] fn vfaezbs(a: vector_signed_char, b: vector_signed_char, c: i32) -> PackedTuple<vector_signed_char, i32>;
122    #[link_name = "llvm.s390.vfaezhs"] fn vfaezhs(a: vector_signed_short, b: vector_signed_short, c: i32) -> PackedTuple<vector_signed_short, i32>;
123    #[link_name = "llvm.s390.vfaezfs"] fn vfaezfs(a: vector_signed_int, b: vector_signed_int, c: i32) -> PackedTuple<vector_signed_int, i32>;
124
125    #[link_name = "llvm.s390.vll"] fn vll(a: u32, b: *const u8) -> vector_signed_char;
126    #[link_name = "llvm.s390.vstl"] fn vstl(a: vector_signed_char, b: u32, c: *mut u8);
127
128    #[link_name = "llvm.s390.vlrl"] fn vlrl(a: u32, b: *const u8) -> vector_unsigned_char;
129    #[link_name = "llvm.s390.vstrl"] fn vstrl(a: vector_unsigned_char, b: u32, c: *mut u8);
130
131    #[link_name = "llvm.s390.lcbb"] fn lcbb(a: *const u8, b: u32) -> u32;
132    #[link_name = "llvm.s390.vlbb"] fn vlbb(a: *const u8, b: u32) -> MaybeUninit<vector_signed_char>;
133
134    #[link_name = "llvm.s390.vpksh"] fn vpksh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_char;
135    #[link_name = "llvm.s390.vpksf"] fn vpksf(a: vector_signed_int, b: vector_signed_int) -> vector_signed_short;
136    #[link_name = "llvm.s390.vpksg"] fn vpksg(a: vector_signed_long_long, b: vector_signed_long_long) -> vector_signed_int;
137
138    #[link_name = "llvm.s390.vpklsh"] fn vpklsh(a: vector_signed_short, b: vector_signed_short) -> vector_unsigned_char;
139    #[link_name = "llvm.s390.vpklsf"] fn vpklsf(a: vector_signed_int, b: vector_signed_int) -> vector_unsigned_short;
140    #[link_name = "llvm.s390.vpklsg"] fn vpklsg(a: vector_signed_long_long, b: vector_signed_long_long) -> vector_unsigned_int;
141
142    #[link_name = "llvm.s390.vpkshs"] fn vpkshs(a: vector_signed_short, b: vector_signed_short) -> PackedTuple<vector_signed_char, i32>;
143    #[link_name = "llvm.s390.vpksfs"] fn vpksfs(a: vector_signed_int, b: vector_signed_int) -> PackedTuple<vector_signed_short, i32>;
144    #[link_name = "llvm.s390.vpksgs"] fn vpksgs(a: vector_signed_long_long, b: vector_signed_long_long) -> PackedTuple<vector_signed_int, i32>;
145
146    #[link_name = "llvm.s390.vpklshs"] fn vpklshs(a: vector_unsigned_short, b: vector_unsigned_short) -> PackedTuple<vector_unsigned_char, i32>;
147    #[link_name = "llvm.s390.vpklsfs"] fn vpklsfs(a: vector_unsigned_int, b: vector_unsigned_int) -> PackedTuple<vector_unsigned_short, i32>;
148    #[link_name = "llvm.s390.vpklsgs"] fn vpklsgs(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> PackedTuple<vector_unsigned_int, i32>;
149
150    #[link_name = "llvm.s390.vavgb"] fn vavgb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
151    #[link_name = "llvm.s390.vavgh"] fn vavgh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short;
152    #[link_name = "llvm.s390.vavgf"] fn vavgf(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
153    #[link_name = "llvm.s390.vavgg"] fn vavgg(a: vector_signed_long_long, b: vector_signed_long_long) -> vector_signed_long_long;
154
155    #[link_name = "llvm.s390.vavglb"] fn vavglb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
156    #[link_name = "llvm.s390.vavglh"] fn vavglh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
157    #[link_name = "llvm.s390.vavglf"] fn vavglf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
158    #[link_name = "llvm.s390.vavglg"] fn vavglg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long;
159
160    #[link_name = "llvm.s390.vcksm"] fn vcksm(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
161
162    #[link_name = "llvm.s390.vmhb"] fn vmhb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
163    #[link_name = "llvm.s390.vmhh"] fn vmhh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short;
164    #[link_name = "llvm.s390.vmhf"] fn vmhf(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
165
166    #[link_name = "llvm.s390.vmlhb"] fn vmlhb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
167    #[link_name = "llvm.s390.vmlhh"] fn vmlhh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
168    #[link_name = "llvm.s390.vmlhf"] fn vmlhf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
169
170    #[link_name = "llvm.s390.vmaeb"] fn vmaeb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_short) -> vector_signed_short;
171    #[link_name = "llvm.s390.vmaeh"] fn vmaeh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_int) -> vector_signed_int;
172    #[link_name = "llvm.s390.vmaef"] fn vmaef(a: vector_signed_int, b: vector_signed_int, c: vector_signed_long_long) -> vector_signed_long_long;
173
174    #[link_name = "llvm.s390.vmaleb"] fn vmaleb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_short) -> vector_unsigned_short;
175    #[link_name = "llvm.s390.vmaleh"] fn vmaleh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_int) -> vector_unsigned_int;
176    #[link_name = "llvm.s390.vmalef"] fn vmalef(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_long_long) -> vector_unsigned_long_long;
177
178    #[link_name = "llvm.s390.vmaob"] fn vmaob(a: vector_signed_char, b: vector_signed_char, c: vector_signed_short) -> vector_signed_short;
179    #[link_name = "llvm.s390.vmaoh"] fn vmaoh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_int) -> vector_signed_int;
180    #[link_name = "llvm.s390.vmaof"] fn vmaof(a: vector_signed_int, b: vector_signed_int, c: vector_signed_long_long) -> vector_signed_long_long;
181
182    #[link_name = "llvm.s390.vmalob"] fn vmalob(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_short) -> vector_unsigned_short;
183    #[link_name = "llvm.s390.vmaloh"] fn vmaloh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_int) -> vector_unsigned_int;
184    #[link_name = "llvm.s390.vmalof"] fn vmalof(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_long_long) -> vector_unsigned_long_long;
185
186    #[link_name = "llvm.s390.vmahb"] fn vmahb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char) -> vector_signed_char;
187    #[link_name = "llvm.s390.vmahh"] fn vmahh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short) -> vector_signed_short;
188    #[link_name = "llvm.s390.vmahf"] fn vmahf(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int) -> vector_signed_int;
189
190    #[link_name = "llvm.s390.vmalhb"] fn vmalhb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> vector_unsigned_char;
191    #[link_name = "llvm.s390.vmalhh"] fn vmalhh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short;
192    #[link_name = "llvm.s390.vmalhf"] fn vmalhf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int;
193
194    #[link_name = "llvm.s390.vmalb"] fn vmalb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char) -> vector_signed_char;
195    #[link_name = "llvm.s390.vmalh"] fn vmalh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short) -> vector_signed_short;
196    #[link_name = "llvm.s390.vmalf"] fn vmalf(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int) -> vector_signed_int;
197
198    #[link_name = "llvm.s390.vmallb"] fn vmallb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> vector_unsigned_char;
199    #[link_name = "llvm.s390.vmallh"] fn vmallh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short;
200    #[link_name = "llvm.s390.vmallf"] fn vmallf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int;
201
202    #[link_name = "llvm.s390.vgfmb"] fn vgfmb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_short;
203    #[link_name = "llvm.s390.vgfmh"] fn vgfmh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int;
204    #[link_name = "llvm.s390.vgfmf"] fn vgfmf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long;
205    #[link_name = "llvm.s390.vgfmg"] fn vgfmg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> u128;
206
207    #[link_name = "llvm.s390.vgfmab"] fn vgfmab(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_short) -> vector_unsigned_short;
208    #[link_name = "llvm.s390.vgfmah"] fn vgfmah(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_int) -> vector_unsigned_int;
209    #[link_name = "llvm.s390.vgfmaf"] fn vgfmaf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_long_long) -> vector_unsigned_long_long;
210    #[link_name = "llvm.s390.vgfmag"] fn vgfmag(a: vector_unsigned_long_long, b: vector_unsigned_long_long, c: u128) -> u128;
211
212    #[link_name = "llvm.s390.vbperm"] fn vbperm(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_long_long;
213
214    #[link_name = "llvm.s390.vftcisb"] fn vftcisb(a: vector_float, b: u32) -> PackedTuple<vector_bool_int, i32>;
215    #[link_name = "llvm.s390.vftcidb"] fn vftcidb(a: vector_double, b: u32) -> PackedTuple<vector_bool_long_long, i32>;
216
217    #[link_name = "llvm.s390.vtm"] fn vtm(a: i8x16, b: i8x16) -> i32;
218
219    #[link_name = "llvm.s390.vstrsb"] fn vstrsb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> PackedTuple<vector_unsigned_char, i32>;
220    #[link_name = "llvm.s390.vstrsh"] fn vstrsh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_char) -> PackedTuple<vector_unsigned_char, i32>;
221    #[link_name = "llvm.s390.vstrsf"] fn vstrsf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_char) -> PackedTuple<vector_unsigned_char, i32>;
222
223    #[link_name = "llvm.s390.vstrszb"] fn vstrszb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> PackedTuple<vector_unsigned_char, i32>;
224    #[link_name = "llvm.s390.vstrszh"] fn vstrszh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_char) -> PackedTuple<vector_unsigned_char, i32>;
225    #[link_name = "llvm.s390.vstrszf"] fn vstrszf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_char) -> PackedTuple<vector_unsigned_char, i32>;
226
227    #[link_name = "llvm.s390.vistrb"] fn vistrb(a: vector_unsigned_char) -> vector_unsigned_char;
228    #[link_name = "llvm.s390.vistrh"] fn vistrh(a: vector_unsigned_short) -> vector_unsigned_short;
229    #[link_name = "llvm.s390.vistrf"] fn vistrf(a: vector_unsigned_int) -> vector_unsigned_int;
230
231    #[link_name = "llvm.s390.vistrbs"] fn vistrbs(a: vector_unsigned_char) -> PackedTuple<vector_unsigned_char, i32>;
232    #[link_name = "llvm.s390.vistrhs"] fn vistrhs(a: vector_unsigned_short) -> PackedTuple<vector_unsigned_short, i32>;
233    #[link_name = "llvm.s390.vistrfs"] fn vistrfs(a: vector_unsigned_int) -> PackedTuple<vector_unsigned_int, i32>;
234
235    #[link_name = "llvm.s390.vmslg"] fn vmslg(a: vector_unsigned_long_long, b: vector_unsigned_long_long, c: u128, d: u32) -> u128;
236
237    #[link_name = "llvm.s390.vstrcb"] fn vstrcb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char, d: u32) -> vector_bool_char;
238    #[link_name = "llvm.s390.vstrch"] fn vstrch(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short, d: u32) -> vector_bool_short;
239    #[link_name = "llvm.s390.vstrcf"] fn vstrcf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int, d: u32) -> vector_bool_int;
240
241    #[link_name = "llvm.s390.vstrcbs"] fn vstrcbs(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char, d: u32) -> PackedTuple<vector_bool_char, i32>;
242    #[link_name = "llvm.s390.vstrchs"] fn vstrchs(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short, d: u32) -> PackedTuple<vector_bool_short, i32>;
243    #[link_name = "llvm.s390.vstrcfs"] fn vstrcfs(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int, d: u32) -> PackedTuple<vector_bool_int, i32>;
244
245    #[link_name = "llvm.s390.vstrczb"] fn vstrczb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char, d: u32) -> vector_bool_char;
246    #[link_name = "llvm.s390.vstrczh"] fn vstrczh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short, d: u32) -> vector_bool_short;
247    #[link_name = "llvm.s390.vstrczf"] fn vstrczf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int, d: u32) -> vector_bool_int;
248
249    #[link_name = "llvm.s390.vstrczbs"] fn vstrczbs(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char, d: u32) -> PackedTuple<vector_bool_char, i32>;
250    #[link_name = "llvm.s390.vstrczhs"] fn vstrczhs(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short, d: u32) -> PackedTuple<vector_bool_short, i32>;
251    #[link_name = "llvm.s390.vstrczfs"] fn vstrczfs(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int, d: u32) -> PackedTuple<vector_bool_int, i32>;
252
253    #[link_name = "llvm.s390.vfeeb"] fn vfeeb(a: i8x16, b: i8x16) -> i8x16;
254    #[link_name = "llvm.s390.vfeeh"] fn vfeeh(a: i16x8, b: i16x8) -> i16x8;
255    #[link_name = "llvm.s390.vfeef"] fn vfeef(a: i32x4, b: i32x4) -> i32x4;
256
257    #[link_name = "llvm.s390.vfeezb"] fn vfeezb(a: i8x16, b: i8x16) -> i8x16;
258    #[link_name = "llvm.s390.vfeezh"] fn vfeezh(a: i16x8, b: i16x8) -> i16x8;
259    #[link_name = "llvm.s390.vfeezf"] fn vfeezf(a: i32x4, b: i32x4) -> i32x4;
260
261    #[link_name = "llvm.s390.vfeebs"] fn vfeebs(a: i8x16, b: i8x16) -> PackedTuple<i8x16, i32>;
262    #[link_name = "llvm.s390.vfeehs"] fn vfeehs(a: i16x8, b: i16x8) -> PackedTuple<i16x8, i32>;
263    #[link_name = "llvm.s390.vfeefs"] fn vfeefs(a: i32x4, b: i32x4) -> PackedTuple<i32x4, i32>;
264
265    #[link_name = "llvm.s390.vfeezbs"] fn vfeezbs(a: i8x16, b: i8x16) -> PackedTuple<i8x16, i32>;
266    #[link_name = "llvm.s390.vfeezhs"] fn vfeezhs(a: i16x8, b: i16x8) -> PackedTuple<i16x8, i32>;
267    #[link_name = "llvm.s390.vfeezfs"] fn vfeezfs(a: i32x4, b: i32x4) -> PackedTuple<i32x4, i32>;
268
269    #[link_name = "llvm.s390.vfeneb"] fn vfeneb(a: i8x16, b: i8x16) -> i8x16;
270    #[link_name = "llvm.s390.vfeneh"] fn vfeneh(a: i16x8, b: i16x8) -> i16x8;
271    #[link_name = "llvm.s390.vfenef"] fn vfenef(a: i32x4, b: i32x4) -> i32x4;
272
273    #[link_name = "llvm.s390.vfenezb"] fn vfenezb(a: i8x16, b: i8x16) -> i8x16;
274    #[link_name = "llvm.s390.vfenezh"] fn vfenezh(a: i16x8, b: i16x8) -> i16x8;
275    #[link_name = "llvm.s390.vfenezf"] fn vfenezf(a: i32x4, b: i32x4) -> i32x4;
276
277    #[link_name = "llvm.s390.vfenebs"] fn vfenebs(a: i8x16, b: i8x16) -> PackedTuple<i8x16, i32>;
278    #[link_name = "llvm.s390.vfenehs"] fn vfenehs(a: i16x8, b: i16x8) -> PackedTuple<i16x8, i32>;
279    #[link_name = "llvm.s390.vfenefs"] fn vfenefs(a: i32x4, b: i32x4) -> PackedTuple<i32x4, i32>;
280
281    #[link_name = "llvm.s390.vfenezbs"] fn vfenezbs(a: i8x16, b: i8x16) -> PackedTuple<i8x16, i32>;
282    #[link_name = "llvm.s390.vfenezhs"] fn vfenezhs(a: i16x8, b: i16x8) -> PackedTuple<i16x8, i32>;
283    #[link_name = "llvm.s390.vfenezfs"] fn vfenezfs(a: i32x4, b: i32x4) -> PackedTuple<i32x4, i32>;
284}
285
286impl_from! { i8x16, u8x16,  i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 }
287
288impl_neg! { i8x16 : 0 }
289impl_neg! { i16x8 : 0 }
290impl_neg! { i32x4 : 0 }
291impl_neg! { i64x2 : 0 }
292impl_neg! { f32x4 : 0f32 }
293impl_neg! { f64x2 : 0f64 }
294
295#[repr(simd)]
296struct ShuffleMask<const N: usize>([u32; N]);
297
298impl<const N: usize> ShuffleMask<N> {
299    const fn reverse() -> Self {
300        let mut index = [0; N];
301        let mut i = 0;
302        while i < N {
303            index[i] = (N - i - 1) as u32;
304            i += 1;
305        }
306        ShuffleMask(index)
307    }
308
309    const fn merge_low() -> Self {
310        let mut mask = [0; N];
311        let mut i = N / 2;
312        let mut index = 0;
313        while index < N {
314            mask[index] = i as u32;
315            mask[index + 1] = (i + N) as u32;
316
317            i += 1;
318            index += 2;
319        }
320        ShuffleMask(mask)
321    }
322
323    const fn merge_high() -> Self {
324        let mut mask = [0; N];
325        let mut i = 0;
326        let mut index = 0;
327        while index < N {
328            mask[index] = i as u32;
329            mask[index + 1] = (i + N) as u32;
330
331            i += 1;
332            index += 2;
333        }
334        ShuffleMask(mask)
335    }
336
337    const fn even() -> Self {
338        let mut mask = [0; N];
339        let mut i = 0;
340        let mut index = 0;
341        while index < N {
342            mask[index] = i as u32;
343
344            i += 2;
345            index += 1;
346        }
347        ShuffleMask(mask)
348    }
349
350    const fn odd() -> Self {
351        let mut mask = [0; N];
352        let mut i = 1;
353        let mut index = 0;
354        while index < N {
355            mask[index] = i as u32;
356
357            i += 2;
358            index += 1;
359        }
360        ShuffleMask(mask)
361    }
362
363    const fn pack() -> Self {
364        Self::odd()
365    }
366
367    const fn unpack_low() -> Self {
368        let mut mask = [0; N];
369        let mut i = 0;
370        while i < N {
371            mask[i] = (N + i) as u32;
372            i += 1;
373        }
374        ShuffleMask(mask)
375    }
376
377    const fn unpack_high() -> Self {
378        let mut mask = [0; N];
379        let mut i = 0;
380        while i < N {
381            mask[i] = i as u32;
382            i += 1;
383        }
384        ShuffleMask(mask)
385    }
386}
387
388const fn genmask<const MASK: u16>() -> [u8; 16] {
389    let mut bits = MASK;
390    let mut elements = [0u8; 16];
391
392    let mut i = 0;
393    while i < 16 {
394        elements[i] = match bits & (1u16 << 15) {
395            0 => 0,
396            _ => 0xFF,
397        };
398
399        bits <<= 1;
400        i += 1;
401    }
402
403    elements
404}
405
406const fn genmasks(bit_width: u32, a: u8, b: u8) -> u64 {
407    let bit_width = bit_width as u8;
408    let a = a % bit_width;
409    let mut b = b % bit_width;
410    if a > b {
411        b = bit_width - 1;
412    }
413
414    // of course these indices start from the left
415    let a = (bit_width - 1) - a;
416    let b = (bit_width - 1) - b;
417
418    ((1u64.wrapping_shl(a as u32 + 1)) - 1) & !((1u64.wrapping_shl(b as u32)) - 1)
419}
420
421const fn validate_block_boundary(block_boundary: u16) -> u32 {
422    assert!(
423        block_boundary.is_power_of_two() && block_boundary >= 64 && block_boundary <= 4096,
424        "block boundary must be a constant power of 2 from 64 to 4096",
425    );
426
427    // so that 64 is encoded as 0, 128 as 1, ect.
428    block_boundary as u32 >> 7
429}
430
431enum FindImm {
432    Eq = 4,
433    Ne = 12,
434    EqIdx = 0,
435    NeIdx = 8,
436}
437
438#[macro_use]
439mod sealed {
440    use super::*;
441
442    #[unstable(feature = "stdarch_s390x", issue = "135681")]
443    pub trait VectorAdd<Other> {
444        type Result;
445        unsafe fn vec_add(self, other: Other) -> Self::Result;
446    }
447
448    macro_rules! impl_add {
449        ($name:ident, $a:ty, $instr:ident) => {
450            impl_add!($name, $a, $a, $a, $instr);
451        };
452        ($name:ident, $a:ty, $b:ty, $c:ty, $instr:ident) => {
453            #[inline]
454            #[target_feature(enable = "vector")]
455            #[cfg_attr(test, assert_instr($instr))]
456            pub unsafe fn $name(a: $a, b: $b) -> $c {
457                transmute(simd_add(transmute(a), b))
458            }
459
460            #[unstable(feature = "stdarch_s390x", issue = "135681")]
461            impl VectorAdd<$b> for $a {
462                type Result = $c;
463
464                #[inline]
465                #[target_feature(enable = "vector")]
466                unsafe fn vec_add(self, other: $b) -> Self::Result {
467                    $name(self, other)
468                }
469            }
470        };
471    }
472
473    #[rustfmt::skip]
474    mod impl_add {
475        use super::*;
476
477        impl_add!(va_sc, vector_signed_char, vab);
478        impl_add!(va_uc, vector_unsigned_char, vab);
479        impl_add!(va_sh, vector_signed_short, vah);
480        impl_add!(va_uh, vector_unsigned_short, vah);
481        impl_add!(va_sf, vector_signed_int, vaf);
482        impl_add!(va_uf, vector_unsigned_int, vaf);
483        impl_add!(va_sg, vector_signed_long_long, vag);
484        impl_add!(va_ug, vector_unsigned_long_long, vag);
485
486        impl_add!(va_sc_bc, vector_signed_char, vector_bool_char, vector_signed_char, vab);
487        impl_add!(va_uc_bc, vector_unsigned_char, vector_bool_char, vector_unsigned_char, vab);
488        impl_add!(va_sh_bh, vector_signed_short, vector_bool_short, vector_signed_short, vah);
489        impl_add!(va_uh_bh, vector_unsigned_short, vector_bool_short, vector_unsigned_short, vah);
490        impl_add!(va_sf_bf, vector_signed_int, vector_bool_int, vector_signed_int, vaf);
491        impl_add!(va_uf_bf, vector_unsigned_int, vector_bool_int, vector_unsigned_int, vaf);
492        impl_add!(va_sg_bg, vector_signed_long_long, vector_bool_long_long, vector_signed_long_long, vag);
493        impl_add!(va_ug_bg, vector_unsigned_long_long, vector_bool_long_long, vector_unsigned_long_long, vag);
494
495        impl_add!(va_bc_sc, vector_bool_char, vector_signed_char, vector_signed_char, vab);
496        impl_add!(va_bc_uc, vector_bool_char, vector_unsigned_char, vector_unsigned_char, vab);
497        impl_add!(va_bh_sh, vector_bool_short, vector_signed_short, vector_signed_short, vah);
498        impl_add!(va_bh_uh, vector_bool_short, vector_unsigned_short, vector_unsigned_short, vah);
499        impl_add!(va_bf_sf, vector_bool_int, vector_signed_int, vector_signed_int, vaf);
500        impl_add!(va_bf_uf, vector_bool_int, vector_unsigned_int, vector_unsigned_int, vaf);
501        impl_add!(va_bg_sg, vector_bool_long_long, vector_signed_long_long, vector_signed_long_long, vag);
502        impl_add!(va_bg_ug, vector_bool_long_long, vector_unsigned_long_long, vector_unsigned_long_long, vag);
503
504        impl_add!(va_double, vector_double, vfadb);
505
506        #[inline]
507        #[target_feature(enable = "vector")]
508        #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vfasb))]
509        pub unsafe fn va_float(a: vector_float, b: vector_float) -> vector_float {
510            transmute(simd_add(a, b))
511        }
512
513        #[unstable(feature = "stdarch_s390x", issue = "135681")]
514        impl VectorAdd<Self> for vector_float {
515            type Result = Self;
516
517            #[inline]
518            #[target_feature(enable = "vector")]
519            unsafe fn vec_add(self, other: Self) -> Self::Result {
520                va_float(self, other)
521            }
522        }
523    }
524
525    #[unstable(feature = "stdarch_s390x", issue = "135681")]
526    pub trait VectorSub<Other> {
527        type Result;
528        unsafe fn vec_sub(self, other: Other) -> Self::Result;
529    }
530
531    macro_rules! impl_sub {
532        ($name:ident, $a:ty, $instr:ident) => {
533            impl_sub!($name, $a, $a, $a, $instr);
534        };
535        ($name:ident, $a:ty, $b:ty, $c:ty, $instr:ident) => {
536            #[inline]
537            #[target_feature(enable = "vector")]
538            #[cfg_attr(test, assert_instr($instr))]
539            pub unsafe fn $name(a: $a, b: $b) -> $c {
540                transmute(simd_sub(transmute(a), b))
541            }
542
543            #[unstable(feature = "stdarch_s390x", issue = "135681")]
544            impl VectorSub<$b> for $a {
545                type Result = $c;
546
547                #[inline]
548                #[target_feature(enable = "vector")]
549                unsafe fn vec_sub(self, other: $b) -> Self::Result {
550                    $name(self, other)
551                }
552            }
553        };
554    }
555
556    #[rustfmt::skip]
557    mod impl_sub {
558        use super::*;
559
560        impl_sub!(vs_sc, vector_signed_char, vsb);
561        impl_sub!(vs_uc, vector_unsigned_char, vsb);
562        impl_sub!(vs_sh, vector_signed_short, vsh);
563        impl_sub!(vs_uh, vector_unsigned_short, vsh);
564        impl_sub!(vs_sf, vector_signed_int, vsf);
565        impl_sub!(vs_uf, vector_unsigned_int, vsf);
566        impl_sub!(vs_sg, vector_signed_long_long, vsg);
567        impl_sub!(vs_ug, vector_unsigned_long_long, vsg);
568
569        impl_sub!(vs_sc_bc, vector_signed_char, vector_bool_char, vector_signed_char, vsb);
570        impl_sub!(vs_uc_bc, vector_unsigned_char, vector_bool_char, vector_unsigned_char, vsb);
571        impl_sub!(vs_sh_bh, vector_signed_short, vector_bool_short, vector_signed_short, vsh);
572        impl_sub!(vs_uh_bh, vector_unsigned_short, vector_bool_short, vector_unsigned_short, vsh);
573        impl_sub!(vs_sf_bf, vector_signed_int, vector_bool_int, vector_signed_int, vsf);
574        impl_sub!(vs_uf_bf, vector_unsigned_int, vector_bool_int, vector_unsigned_int, vsf);
575        impl_sub!(vs_sg_bg, vector_signed_long_long, vector_bool_long_long, vector_signed_long_long, vsg);
576        impl_sub!(vs_ug_bg, vector_unsigned_long_long, vector_bool_long_long, vector_unsigned_long_long, vsg);
577
578        impl_sub!(vs_bc_sc, vector_bool_char, vector_signed_char, vector_signed_char, vsb);
579        impl_sub!(vs_bc_uc, vector_bool_char, vector_unsigned_char, vector_unsigned_char, vsb);
580        impl_sub!(vs_bh_sh, vector_bool_short, vector_signed_short, vector_signed_short, vsh);
581        impl_sub!(vs_bh_uh, vector_bool_short, vector_unsigned_short, vector_unsigned_short, vsh);
582        impl_sub!(vs_bf_sf, vector_bool_int, vector_signed_int, vector_signed_int, vsf);
583        impl_sub!(vs_bf_uf, vector_bool_int, vector_unsigned_int, vector_unsigned_int, vsf);
584        impl_sub!(vs_bg_sg, vector_bool_long_long, vector_signed_long_long, vector_signed_long_long, vsg);
585        impl_sub!(vs_bg_ug, vector_bool_long_long, vector_unsigned_long_long, vector_unsigned_long_long, vsg);
586
587        impl_sub!(vs_double, vector_double, vfsdb);
588
589        #[inline]
590        #[target_feature(enable = "vector")]
591        #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vfssb))]
592        pub unsafe fn vs_float(a: vector_float, b: vector_float) -> vector_float {
593            transmute(simd_sub(a, b))
594        }
595
596        #[unstable(feature = "stdarch_s390x", issue = "135681")]
597        impl VectorSub<Self> for vector_float {
598            type Result = Self;
599
600            #[inline]
601            #[target_feature(enable = "vector")]
602            unsafe fn vec_sub(self, other: Self) -> Self::Result {
603                vs_float(self, other)
604            }
605        }
606    }
607
608    #[unstable(feature = "stdarch_s390x", issue = "135681")]
609    pub trait VectorMul {
610        unsafe fn vec_mul(self, b: Self) -> Self;
611    }
612
613    macro_rules! impl_mul {
614        ($name:ident, $a:ty, std_simd) => {
615            #[unstable(feature = "stdarch_s390x", issue = "135681")]
616            impl VectorMul for $a {
617                #[inline]
618                #[target_feature(enable = "vector")]
619                unsafe fn vec_mul(self, other: Self) -> Self {
620                    transmute(simd_mul(transmute(self), other))
621                }
622            }
623        };
624        ($name:ident, $a:ty, $instr:ident) => {
625            #[inline]
626            #[target_feature(enable = "vector")]
627            #[cfg_attr(test, assert_instr($instr))]
628            pub unsafe fn $name(a: $a, b: $a) -> $a {
629                transmute(simd_mul(transmute(a), b))
630            }
631
632            #[unstable(feature = "stdarch_s390x", issue = "135681")]
633            impl VectorMul for $a {
634                #[inline]
635                #[target_feature(enable = "vector")]
636                unsafe fn vec_mul(self, other: Self) -> Self {
637                    $name(self, other)
638                }
639            }
640        };
641    }
642
643    #[rustfmt::skip]
644    mod impl_mul {
645        use super::*;
646
647        impl_mul!(vml_sc, vector_signed_char, vmlb);
648        impl_mul!(vml_uc, vector_unsigned_char, vmlb);
649        impl_mul!(vml_sh, vector_signed_short, vmlhw);
650        impl_mul!(vml_uh, vector_unsigned_short, vmlhw);
651        impl_mul!(vml_sf, vector_signed_int, vmlf);
652        impl_mul!(vml_uf, vector_unsigned_int, vmlf);
653        impl_mul!(vml_sg, vector_signed_long_long, std_simd);
654        impl_mul!(vml_ug, vector_unsigned_long_long, std_simd);
655
656        impl_mul!(vml_float, vector_float, std_simd);
657        impl_mul!(vml_double, vector_double, vfmdb);
658    }
659
660    #[unstable(feature = "stdarch_s390x", issue = "135681")]
661    pub trait VectorMax<Other> {
662        type Result;
663        unsafe fn vec_max(self, b: Other) -> Self::Result;
664    }
665
666    macro_rules! impl_max {
667        ($name:ident, $a:ty, $instr:ident) => {
668            #[inline]
669            #[target_feature(enable = "vector")]
670            #[cfg_attr(test, assert_instr($instr))]
671            pub unsafe fn $name(a: $a, b: $a) -> $a {
672                simd_select(simd_ge::<_, $a>(a, b), a, b)
673            }
674
675            #[unstable(feature = "stdarch_s390x", issue = "135681")]
676            impl VectorMax<Self> for $a {
677                type Result = Self;
678
679                #[inline]
680                #[target_feature(enable = "vector")]
681                unsafe fn vec_max(self, other: Self) -> Self {
682                    $name(self, other)
683                }
684            }
685        };
686    }
687
688    mod impl_max {
689        use super::*;
690
691        impl_max!(vec_vmxsc, vector_signed_char, vmxb);
692        impl_max!(vec_vmxslc, vector_unsigned_char, vmxlb);
693        impl_max!(vec_vmxsh, vector_signed_short, vmxh);
694        impl_max!(vec_vmxslh, vector_unsigned_short, vmxlh);
695        impl_max!(vec_vmxsf, vector_signed_int, vmxf);
696        impl_max!(vec_vmxslf, vector_unsigned_int, vmxlf);
697        impl_max!(vec_vmxsg, vector_signed_long_long, vmxg);
698        impl_max!(vec_vmxslg, vector_unsigned_long_long, vmxlg);
699    }
700
701    test_impl! { vec_vfmaxsb (a: vector_float, b: vector_float) -> vector_float [simd_fmax, "vector-enhancements-1" vfmaxsb ] }
702    test_impl! { vec_vfmaxdb (a: vector_double, b: vector_double) -> vector_double [simd_fmax, "vector-enhancements-1" vfmaxdb] }
703
704    impl_vec_trait!([VectorMax vec_max] vec_vfmaxsb (vector_float, vector_float) -> vector_float);
705    impl_vec_trait!([VectorMax vec_max] vec_vfmaxdb (vector_double, vector_double) -> vector_double);
706
707    #[unstable(feature = "stdarch_s390x", issue = "135681")]
708    pub trait VectorMin<Other> {
709        type Result;
710        unsafe fn vec_min(self, b: Other) -> Self::Result;
711    }
712
713    macro_rules! impl_min {
714        ($name:ident, $a:ty, $instr:ident) => {
715            #[inline]
716            #[target_feature(enable = "vector")]
717            #[cfg_attr(test, assert_instr($instr))]
718            pub unsafe fn $name(a: $a, b: $a) -> $a {
719                simd_select(simd_le::<_, $a>(a, b), a, b)
720            }
721
722            #[unstable(feature = "stdarch_s390x", issue = "135681")]
723            impl VectorMin<Self> for $a {
724                type Result = Self;
725
726                #[inline]
727                #[target_feature(enable = "vector")]
728                unsafe fn vec_min(self, other: Self) -> Self {
729                    $name(self, other)
730                }
731            }
732        };
733    }
734
735    mod impl_min {
736        use super::*;
737
738        impl_min!(vec_vmnsc, vector_signed_char, vmnb);
739        impl_min!(vec_vmnslc, vector_unsigned_char, vmnlb);
740        impl_min!(vec_vmnsh, vector_signed_short, vmnh);
741        impl_min!(vec_vmnslh, vector_unsigned_short, vmnlh);
742        impl_min!(vec_vmnsf, vector_signed_int, vmnf);
743        impl_min!(vec_vmnslf, vector_unsigned_int, vmnlf);
744        impl_min!(vec_vmnsg, vector_signed_long_long, vmng);
745        impl_min!(vec_vmnslg, vector_unsigned_long_long, vmnlg);
746    }
747
748    test_impl! { vec_vfminsb (a: vector_float, b: vector_float) -> vector_float [simd_fmin, "vector-enhancements-1" vfminsb]  }
749    test_impl! { vec_vfmindb (a: vector_double, b: vector_double) -> vector_double [simd_fmin, "vector-enhancements-1" vfmindb]  }
750
751    impl_vec_trait!([VectorMin vec_min] vec_vfminsb (vector_float, vector_float) -> vector_float);
752    impl_vec_trait!([VectorMin vec_min] vec_vfmindb (vector_double, vector_double) -> vector_double);
753
754    #[unstable(feature = "stdarch_s390x", issue = "135681")]
755    pub trait VectorAbs {
756        unsafe fn vec_abs(self) -> Self;
757    }
758
759    macro_rules! impl_abs {
760        ($name:ident, $ty:ident) => {
761            #[inline]
762            #[target_feature(enable = "vector")]
763            unsafe fn $name(v: s_t_l!($ty)) -> s_t_l!($ty) {
764                v.vec_max(-v)
765            }
766
767            impl_vec_trait! { [VectorAbs vec_abs] $name (s_t_l!($ty)) }
768        };
769    }
770
771    impl_abs! { vec_abs_i8, i8x16 }
772    impl_abs! { vec_abs_i16, i16x8 }
773    impl_abs! { vec_abs_i32, i32x4 }
774    impl_abs! { vec_abs_i64, i64x2 }
775
776    test_impl! { vec_abs_f32 (v: vector_float) -> vector_float [ simd_fabs, "vector-enhancements-1" vflpsb ] }
777    test_impl! { vec_abs_f64 (v: vector_double) -> vector_double [ simd_fabs, vflpdb ] }
778
779    impl_vec_trait! { [VectorAbs vec_abs] vec_abs_f32 (vector_float) }
780    impl_vec_trait! { [VectorAbs vec_abs] vec_abs_f64 (vector_double) }
781
782    #[unstable(feature = "stdarch_s390x", issue = "135681")]
783    pub trait VectorNabs {
784        unsafe fn vec_nabs(self) -> Self;
785    }
786
787    #[inline]
788    #[target_feature(enable = "vector")]
789    #[cfg_attr(
790        all(test, target_feature = "vector-enhancements-1"),
791        assert_instr(vflnsb)
792    )]
793    unsafe fn vec_nabs_f32(a: vector_float) -> vector_float {
794        simd_neg(simd_fabs(a))
795    }
796
797    #[inline]
798    #[target_feature(enable = "vector")]
799    #[cfg_attr(test, assert_instr(vflndb))]
800    unsafe fn vec_nabs_f64(a: vector_double) -> vector_double {
801        simd_neg(simd_fabs(a))
802    }
803
804    impl_vec_trait! { [VectorNabs vec_nabs] vec_nabs_f32 (vector_float) }
805    impl_vec_trait! { [VectorNabs vec_nabs] vec_nabs_f64 (vector_double) }
806
807    #[unstable(feature = "stdarch_s390x", issue = "135681")]
808    pub trait VectorNmsub {
809        unsafe fn vec_nmsub(self, b: Self, c: Self) -> Self;
810    }
811
812    #[inline]
813    #[target_feature(enable = "vector")]
814    #[cfg_attr(
815        all(test, target_feature = "vector-enhancements-2"),
816        assert_instr(vfnmssb)
817    )]
818    unsafe fn vec_nmsub_f32(a: vector_float, b: vector_float, c: vector_float) -> vector_float {
819        simd_neg(simd_fma(a, b, simd_neg(c)))
820    }
821
822    #[unstable(feature = "stdarch_s390x", issue = "135681")]
823    impl VectorNmsub for vector_float {
824        #[target_feature(enable = "vector")]
825        unsafe fn vec_nmsub(self, b: Self, c: Self) -> Self {
826            vec_nmsub_f32(self, b, c)
827        }
828    }
829
830    #[inline]
831    #[target_feature(enable = "vector")]
832    #[cfg_attr(
833        all(test, target_feature = "vector-enhancements-2"),
834        assert_instr(vfnmsdb)
835    )]
836    unsafe fn vec_nmsub_f64(a: vector_double, b: vector_double, c: vector_double) -> vector_double {
837        simd_neg(simd_fma(a, b, simd_neg(c)))
838    }
839
840    #[unstable(feature = "stdarch_s390x", issue = "135681")]
841    impl VectorNmsub for vector_double {
842        #[target_feature(enable = "vector")]
843        unsafe fn vec_nmsub(self, b: Self, c: Self) -> Self {
844            vec_nmsub_f64(self, b, c)
845        }
846    }
847
848    #[unstable(feature = "stdarch_s390x", issue = "135681")]
849    pub trait VectorNmadd {
850        unsafe fn vec_nmadd(self, b: Self, c: Self) -> Self;
851    }
852
853    #[inline]
854    #[target_feature(enable = "vector")]
855    #[cfg_attr(
856        all(test, target_feature = "vector-enhancements-2"),
857        assert_instr(vfnmasb)
858    )]
859    unsafe fn vec_nmadd_f32(a: vector_float, b: vector_float, c: vector_float) -> vector_float {
860        simd_neg(simd_fma(a, b, c))
861    }
862
863    #[unstable(feature = "stdarch_s390x", issue = "135681")]
864    impl VectorNmadd for vector_float {
865        #[target_feature(enable = "vector")]
866        unsafe fn vec_nmadd(self, b: Self, c: Self) -> Self {
867            vec_nmadd_f32(self, b, c)
868        }
869    }
870
871    #[inline]
872    #[target_feature(enable = "vector")]
873    #[cfg_attr(
874        all(test, target_feature = "vector-enhancements-2"),
875        assert_instr(vfnmadb)
876    )]
877    unsafe fn vec_nmadd_f64(a: vector_double, b: vector_double, c: vector_double) -> vector_double {
878        simd_neg(simd_fma(a, b, c))
879    }
880
881    #[unstable(feature = "stdarch_s390x", issue = "135681")]
882    impl VectorNmadd for vector_double {
883        #[target_feature(enable = "vector")]
884        unsafe fn vec_nmadd(self, b: Self, c: Self) -> Self {
885            vec_nmadd_f64(self, b, c)
886        }
887    }
888
889    #[unstable(feature = "stdarch_s390x", issue = "135681")]
890    pub trait VectorSplat {
891        unsafe fn vec_splat<const IMM: u32>(self) -> Self;
892    }
893
894    #[inline]
895    #[target_feature(enable = "vector")]
896    #[cfg_attr(test, assert_instr(vrepb, IMM2 = 1))]
897    unsafe fn vrepb<const IMM2: u32>(a: vector_signed_char) -> vector_signed_char {
898        static_assert_uimm_bits!(IMM2, 4);
899        simd_shuffle!(a, a, [IMM2; 16])
900    }
901
902    #[inline]
903    #[target_feature(enable = "vector")]
904    #[cfg_attr(test, assert_instr(vreph, IMM2 = 1))]
905    unsafe fn vreph<const IMM2: u32>(a: vector_signed_short) -> vector_signed_short {
906        static_assert_uimm_bits!(IMM2, 3);
907        simd_shuffle!(a, a, [IMM2; 8])
908    }
909
910    #[inline]
911    #[target_feature(enable = "vector")]
912    #[cfg_attr(test, assert_instr(vrepf, IMM2 = 1))]
913    unsafe fn vrepf<const IMM2: u32>(a: vector_signed_int) -> vector_signed_int {
914        static_assert_uimm_bits!(IMM2, 2);
915        simd_shuffle!(a, a, [IMM2; 4])
916    }
917
918    #[inline]
919    #[target_feature(enable = "vector")]
920    #[cfg_attr(test, assert_instr(vrepg, IMM2 = 1))]
921    unsafe fn vrepg<const IMM2: u32>(a: vector_signed_long_long) -> vector_signed_long_long {
922        static_assert_uimm_bits!(IMM2, 1);
923        simd_shuffle!(a, a, [IMM2; 2])
924    }
925
926    macro_rules! impl_vec_splat {
927        ($ty:ty, $fun:ident) => {
928            #[unstable(feature = "stdarch_s390x", issue = "135681")]
929            impl VectorSplat for $ty {
930                #[inline]
931                #[target_feature(enable = "vector")]
932                unsafe fn vec_splat<const IMM: u32>(self) -> Self {
933                    transmute($fun::<IMM>(transmute(self)))
934                }
935            }
936        };
937    }
938
939    impl_vec_splat! { vector_signed_char, vrepb }
940    impl_vec_splat! { vector_unsigned_char, vrepb }
941    impl_vec_splat! { vector_bool_char, vrepb }
942    impl_vec_splat! { vector_signed_short, vreph }
943    impl_vec_splat! { vector_unsigned_short, vreph }
944    impl_vec_splat! { vector_bool_short, vreph }
945    impl_vec_splat! { vector_signed_int, vrepf }
946    impl_vec_splat! { vector_unsigned_int, vrepf }
947    impl_vec_splat! { vector_bool_int, vrepf }
948    impl_vec_splat! { vector_signed_long_long, vrepg }
949    impl_vec_splat! { vector_unsigned_long_long, vrepg }
950    impl_vec_splat! { vector_bool_long_long, vrepg }
951
952    impl_vec_splat! { vector_float, vrepf }
953    impl_vec_splat! { vector_double, vrepg }
954
955    #[unstable(feature = "stdarch_s390x", issue = "135681")]
956    pub trait VectorSplats<Output> {
957        unsafe fn vec_splats(self) -> Output;
958    }
959
960    macro_rules! impl_vec_splats {
961        ($(($fn:ident ($ty:ty, $shortty:tt) $instr:ident)),*) => {
962            $(
963                #[inline]
964                #[target_feature(enable = "vector")]
965                #[cfg_attr(test, assert_instr($instr))]
966                pub unsafe fn $fn(v: $ty) -> s_t_l!($shortty) {
967                    transmute($shortty::splat(v))
968                }
969
970                #[unstable(feature = "stdarch_s390x", issue = "135681")]
971                impl VectorSplats<s_t_l!($shortty)> for $ty {
972                    #[inline]
973                    #[target_feature(enable = "vector")]
974                    unsafe fn vec_splats(self) -> s_t_l!($shortty) {
975                        $fn (self)
976                    }
977                }
978            )*
979        }
980    }
981
982    impl_vec_splats! {
983        (vec_splats_u8 (u8, u8x16) vrepb),
984        (vec_splats_i8 (i8, i8x16) vrepb),
985        (vec_splats_u16 (u16, u16x8) vreph),
986        (vec_splats_i16 (i16, i16x8) vreph),
987        (vec_splats_u32 (u32, u32x4) vrepf),
988        (vec_splats_i32 (i32, i32x4) vrepf),
989        (vec_splats_u64 (u64, u64x2) vlvgp),
990        (vec_splats_i64 (i64, i64x2) vlvgp),
991        (vec_splats_f32 (f32, f32x4) vrepf),
992        (vec_splats_f64 (f64, f64x2) vrepg)
993    }
994
995    macro_rules! impl_bool_vec_splats {
996        ($(($ty:ty, $shortty:tt, $boolty:ty)),*) => {
997            $(
998                #[unstable(feature = "stdarch_s390x", issue = "135681")]
999                impl VectorSplats<$boolty> for $ty {
1000                    #[inline]
1001                    #[target_feature(enable = "vector")]
1002                    unsafe fn vec_splats(self) -> $boolty {
1003                        transmute($shortty::splat(self))
1004                    }
1005                }
1006            )*
1007        }
1008    }
1009
1010    impl_bool_vec_splats! {
1011        (u8, u8x16, vector_bool_char),
1012        (i8, i8x16, vector_bool_char),
1013        (u16, u16x8, vector_bool_short),
1014        (i16, i16x8, vector_bool_short),
1015        (u32, u32x4, vector_bool_int),
1016        (i32, i32x4, vector_bool_int),
1017        (u64, u64x2, vector_bool_long_long),
1018        (i64, i64x2, vector_bool_long_long)
1019    }
1020
1021    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1022    pub trait CountBits {
1023        type Result;
1024
1025        unsafe fn vec_cntlz(self) -> Self::Result;
1026        unsafe fn vec_cnttz(self) -> Self::Result;
1027        unsafe fn vec_popcnt(self) -> Self::Result;
1028    }
1029
1030    macro_rules! impl_count_bits {
1031        ($ty:tt) => {
1032            #[unstable(feature = "stdarch_s390x", issue = "135681")]
1033            impl CountBits for $ty {
1034                type Result = t_u!($ty);
1035
1036                #[inline]
1037                #[target_feature(enable = "vector")]
1038                unsafe fn vec_cntlz(self) -> Self::Result {
1039                    transmute(simd_ctlz(self))
1040                }
1041
1042                #[inline]
1043                #[target_feature(enable = "vector")]
1044                unsafe fn vec_cnttz(self) -> Self::Result {
1045                    transmute(simd_cttz(self))
1046                }
1047
1048                #[inline]
1049                #[target_feature(enable = "vector")]
1050                unsafe fn vec_popcnt(self) -> Self::Result {
1051                    transmute(simd_ctpop(self))
1052                }
1053            }
1054        };
1055    }
1056
1057    impl_count_bits!(vector_signed_char);
1058    impl_count_bits!(vector_unsigned_char);
1059    impl_count_bits!(vector_signed_short);
1060    impl_count_bits!(vector_unsigned_short);
1061    impl_count_bits!(vector_signed_int);
1062    impl_count_bits!(vector_unsigned_int);
1063    impl_count_bits!(vector_signed_long_long);
1064    impl_count_bits!(vector_unsigned_long_long);
1065
1066    test_impl! { vec_clzb_signed +(a: vector_signed_char) -> vector_unsigned_char [simd_ctlz, vclzb] }
1067    test_impl! { vec_clzh_signed +(a: vector_signed_short) -> vector_unsigned_short [simd_ctlz, vclzh] }
1068    test_impl! { vec_clzf_signed +(a: vector_signed_int) -> vector_unsigned_int [simd_ctlz, vclzf] }
1069    test_impl! { vec_clzg_signed +(a: vector_signed_long_long) -> vector_unsigned_long_long [simd_ctlz, vclzg] }
1070
1071    test_impl! { vec_clzb_unsigned +(a: vector_unsigned_char) -> vector_unsigned_char [simd_ctlz, vclzb] }
1072    test_impl! { vec_clzh_unsigned +(a: vector_unsigned_short) -> vector_unsigned_short [simd_ctlz, vclzh] }
1073    test_impl! { vec_clzf_unsigned +(a: vector_unsigned_int) -> vector_unsigned_int [simd_ctlz, vclzf] }
1074    test_impl! { vec_clzg_unsigned +(a: vector_unsigned_long_long) -> vector_unsigned_long_long [simd_ctlz, vclzg] }
1075
1076    test_impl! { vec_ctzb_signed +(a: vector_signed_char) -> vector_unsigned_char [simd_cttz, vctzb] }
1077    test_impl! { vec_ctzh_signed +(a: vector_signed_short) -> vector_unsigned_short [simd_cttz, vctzh] }
1078    test_impl! { vec_ctzf_signed +(a: vector_signed_int) -> vector_unsigned_int [simd_cttz, vctzf] }
1079    test_impl! { vec_ctzg_signed +(a: vector_signed_long_long) -> vector_unsigned_long_long [simd_cttz, vctzg] }
1080
1081    test_impl! { vec_ctzb_unsigned +(a: vector_unsigned_char) -> vector_unsigned_char [simd_cttz, vctzb] }
1082    test_impl! { vec_ctzh_unsigned +(a: vector_unsigned_short) -> vector_unsigned_short [simd_cttz, vctzh] }
1083    test_impl! { vec_ctzf_unsigned +(a: vector_unsigned_int) -> vector_unsigned_int [simd_cttz, vctzf] }
1084    test_impl! { vec_ctzg_unsigned +(a: vector_unsigned_long_long) -> vector_unsigned_long_long [simd_cttz, vctzg] }
1085
1086    test_impl! { vec_vpopctb_signed +(a: vector_signed_char) -> vector_signed_char [simd_ctpop, vpopctb] }
1087    test_impl! { vec_vpopcth_signed +(a: vector_signed_short) -> vector_signed_short [simd_ctpop, "vector-enhancements-1" vpopcth] }
1088    test_impl! { vec_vpopctf_signed +(a: vector_signed_int) -> vector_signed_int [simd_ctpop, "vector-enhancements-1" vpopctf] }
1089    test_impl! { vec_vpopctg_signed +(a: vector_signed_long_long) -> vector_signed_long_long [simd_ctpop, "vector-enhancements-1" vpopctg] }
1090
1091    test_impl! { vec_vpopctb_unsigned +(a: vector_unsigned_char) -> vector_unsigned_char [simd_ctpop, vpopctb] }
1092    test_impl! { vec_vpopcth_unsigned +(a: vector_unsigned_short) -> vector_unsigned_short [simd_ctpop, "vector-enhancements-1" vpopcth] }
1093    test_impl! { vec_vpopctf_unsigned +(a: vector_unsigned_int) -> vector_unsigned_int [simd_ctpop, "vector-enhancements-1" vpopctf] }
1094    test_impl! { vec_vpopctg_unsigned +(a: vector_unsigned_long_long) -> vector_unsigned_long_long [simd_ctpop, "vector-enhancements-1" vpopctg] }
1095
1096    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1097    pub trait VectorAnd<Other> {
1098        type Result;
1099        unsafe fn vec_and(self, b: Other) -> Self::Result;
1100    }
1101
1102    impl_vec_trait! { [VectorAnd vec_and] ~(simd_and) }
1103
1104    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1105    pub trait VectorOr<Other> {
1106        type Result;
1107        unsafe fn vec_or(self, b: Other) -> Self::Result;
1108    }
1109
1110    impl_vec_trait! { [VectorOr vec_or] ~(simd_or) }
1111
1112    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1113    pub trait VectorXor<Other> {
1114        type Result;
1115        unsafe fn vec_xor(self, b: Other) -> Self::Result;
1116    }
1117
1118    impl_vec_trait! { [VectorXor vec_xor] ~(simd_xor) }
1119
1120    #[inline]
1121    #[target_feature(enable = "vector")]
1122    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vno))]
1123    unsafe fn nor(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
1124        let a: u8x16 = transmute(a);
1125        let b: u8x16 = transmute(b);
1126        transmute(simd_xor(simd_or(a, b), u8x16::splat(0xff)))
1127    }
1128
1129    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1130    pub trait VectorNor<Other> {
1131        type Result;
1132        unsafe fn vec_nor(self, b: Other) -> Self::Result;
1133    }
1134
1135    impl_vec_trait! { [VectorNor vec_nor]+ 2c (nor) }
1136
1137    #[inline]
1138    #[target_feature(enable = "vector")]
1139    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vnn))]
1140    unsafe fn nand(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
1141        let a: u8x16 = transmute(a);
1142        let b: u8x16 = transmute(b);
1143        transmute(simd_xor(simd_and(a, b), u8x16::splat(0xff)))
1144    }
1145
1146    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1147    pub trait VectorNand<Other> {
1148        type Result;
1149        unsafe fn vec_nand(self, b: Other) -> Self::Result;
1150    }
1151
1152    impl_vec_trait! { [VectorNand vec_nand]+ 2c (nand) }
1153
1154    #[inline]
1155    #[target_feature(enable = "vector")]
1156    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vnx))]
1157    unsafe fn eqv(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
1158        let a: u8x16 = transmute(a);
1159        let b: u8x16 = transmute(b);
1160        transmute(simd_xor(simd_xor(a, b), u8x16::splat(0xff)))
1161    }
1162
1163    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1164    pub trait VectorEqv<Other> {
1165        type Result;
1166        unsafe fn vec_eqv(self, b: Other) -> Self::Result;
1167    }
1168
1169    impl_vec_trait! { [VectorEqv vec_eqv]+ 2c (eqv) }
1170
1171    #[inline]
1172    #[target_feature(enable = "vector")]
1173    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vnc))]
1174    unsafe fn andc(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
1175        let a = transmute(a);
1176        let b = transmute(b);
1177        transmute(simd_and(simd_xor(u8x16::splat(0xff), b), a))
1178    }
1179
1180    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1181    pub trait VectorAndc<Other> {
1182        type Result;
1183        unsafe fn vec_andc(self, b: Other) -> Self::Result;
1184    }
1185
1186    impl_vec_trait! { [VectorAndc vec_andc]+ 2c (andc) }
1187
1188    #[inline]
1189    #[target_feature(enable = "vector")]
1190    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(voc))]
1191    unsafe fn orc(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
1192        let a = transmute(a);
1193        let b = transmute(b);
1194        transmute(simd_or(simd_xor(u8x16::splat(0xff), b), a))
1195    }
1196
1197    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1198    pub trait VectorOrc<Other> {
1199        type Result;
1200        unsafe fn vec_orc(self, b: Other) -> Self::Result;
1201    }
1202
1203    impl_vec_trait! { [VectorOrc vec_orc]+ 2c (orc) }
1204
1205    // Z vector intrinsic      C23 math.h  LLVM IR         ISO/IEC 60559 operation        inexact  vfidb parameters
1206    //
1207    // vec_rint                rint        llvm.rint       roundToIntegralExact           yes      0, 0
1208    // vec_roundc              nearbyint   llvm.nearbyint  n/a                            no       4, 0
1209    // vec_floor / vec_roundm  floor       llvm.floor      roundToIntegralTowardNegative  no       4, 7
1210    // vec_ceil / vec_roundp   ceil        llvm.ceil       roundToIntegralTowardPositive  no       4, 6
1211    // vec_trunc / vec_roundz  trunc       llvm.trunc      roundToIntegralTowardZero      no       4, 5
1212    // vec_round               roundeven   llvm.roundeven  roundToIntegralTiesToEven      no       4, 4
1213    // n/a                     round       llvm.round      roundToIntegralTiesAway        no       4, 1
1214
1215    // `simd_round_ties_even` is implemented as `llvm.rint`.
1216    test_impl! { vec_rint_f32 (a: vector_float) -> vector_float [simd_round_ties_even, "vector-enhancements-1" vfisb] }
1217    test_impl! { vec_rint_f64 (a: vector_double) -> vector_double [simd_round_ties_even, vfidb] }
1218
1219    test_impl! { vec_roundc_f32 (a: vector_float) -> vector_float [nearbyint_v4f32,  "vector-enhancements-1" vfisb] }
1220    test_impl! { vec_roundc_f64 (a: vector_double) -> vector_double [nearbyint_v2f64, vfidb] }
1221
1222    test_impl! { vec_round_f32 (a: vector_float) -> vector_float [roundeven_v4f32, "vector-enhancements-1" vfisb] }
1223    test_impl! { vec_round_f64 (a: vector_double) -> vector_double [roundeven_v2f64, vfidb] }
1224
1225    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1226    pub trait VectorRoundc {
1227        unsafe fn vec_roundc(self) -> Self;
1228    }
1229
1230    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1231    pub trait VectorRound {
1232        unsafe fn vec_round(self) -> Self;
1233    }
1234
1235    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1236    pub trait VectorRint {
1237        unsafe fn vec_rint(self) -> Self;
1238    }
1239
1240    impl_vec_trait! { [VectorRoundc vec_roundc] vec_roundc_f32 (vector_float) }
1241    impl_vec_trait! { [VectorRoundc vec_roundc] vec_roundc_f64 (vector_double) }
1242
1243    impl_vec_trait! { [VectorRound vec_round] vec_round_f32 (vector_float) }
1244    impl_vec_trait! { [VectorRound vec_round] vec_round_f64 (vector_double) }
1245
1246    impl_vec_trait! { [VectorRint vec_rint] simd_round_ties_even (vector_float) }
1247    impl_vec_trait! { [VectorRint vec_rint] simd_round_ties_even (vector_double) }
1248
1249    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1250    pub trait VectorTrunc {
1251        // same as vec_roundz
1252        unsafe fn vec_trunc(self) -> Self;
1253    }
1254
1255    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1256    pub trait VectorCeil {
1257        // same as vec_roundp
1258        unsafe fn vec_ceil(self) -> Self;
1259    }
1260
1261    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1262    pub trait VectorFloor {
1263        // same as vec_roundm
1264        unsafe fn vec_floor(self) -> Self;
1265    }
1266
1267    impl_vec_trait! { [VectorTrunc vec_trunc] simd_trunc (vector_float) }
1268    impl_vec_trait! { [VectorTrunc vec_trunc] simd_trunc (vector_double) }
1269
1270    impl_vec_trait! { [VectorCeil vec_ceil] simd_ceil (vector_float) }
1271    impl_vec_trait! { [VectorCeil vec_ceil] simd_ceil (vector_double) }
1272
1273    impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_float) }
1274    impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_double) }
1275
1276    macro_rules! impl_vec_shift {
1277        ([$Trait:ident $m:ident] ($b:ident, $h:ident, $w:ident, $g:ident)) => {
1278            impl_vec_trait!{ [$Trait $m]+ $b (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
1279            impl_vec_trait!{ [$Trait $m]+ $b (vector_signed_char, vector_unsigned_char) -> vector_signed_char }
1280            impl_vec_trait!{ [$Trait $m]+ $h (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
1281            impl_vec_trait!{ [$Trait $m]+ $h (vector_signed_short, vector_unsigned_short) -> vector_signed_short }
1282            impl_vec_trait!{ [$Trait $m]+ $w (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
1283            impl_vec_trait!{ [$Trait $m]+ $w (vector_signed_int, vector_unsigned_int) -> vector_signed_int }
1284            impl_vec_trait!{ [$Trait $m]+ $g (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long }
1285            impl_vec_trait!{ [$Trait $m]+ $g (vector_signed_long_long, vector_unsigned_long_long) -> vector_signed_long_long }
1286        };
1287    }
1288
1289    macro_rules! impl_shift {
1290        ($fun:ident $intr:ident $ty:ident) => {
1291            #[inline]
1292            #[target_feature(enable = "vector")]
1293            #[cfg_attr(test, assert_instr($fun))]
1294            unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) {
1295                let a = transmute(a);
1296                // use the remainder of b by the width of a's elements to prevent UB
1297                let b = simd_rem(transmute(b), <t_t_s!($ty)>::splat($ty::BITS as $ty));
1298
1299                transmute($intr(a, b))
1300            }
1301        };
1302    }
1303
1304    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1305    pub trait VectorSl<Other> {
1306        type Result;
1307        unsafe fn vec_sl(self, b: Other) -> Self::Result;
1308    }
1309
1310    impl_shift! { veslvb simd_shl u8 }
1311    impl_shift! { veslvh simd_shl u16 }
1312    impl_shift! { veslvf simd_shl u32 }
1313    impl_shift! { veslvg simd_shl u64 }
1314
1315    impl_vec_shift! { [VectorSl vec_sl] (veslvb, veslvh, veslvf, veslvg) }
1316
1317    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1318    pub trait VectorSr<Other> {
1319        type Result;
1320        unsafe fn vec_sr(self, b: Other) -> Self::Result;
1321    }
1322
1323    impl_shift! { vesrlvb simd_shr u8 }
1324    impl_shift! { vesrlvh simd_shr u16 }
1325    impl_shift! { vesrlvf simd_shr u32 }
1326    impl_shift! { vesrlvg simd_shr u64 }
1327
1328    impl_vec_shift! { [VectorSr vec_sr] (vesrlvb, vesrlvh, vesrlvf, vesrlvg) }
1329
1330    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1331    pub trait VectorSra<Other> {
1332        type Result;
1333        unsafe fn vec_sra(self, b: Other) -> Self::Result;
1334    }
1335
1336    impl_shift! { vesravb simd_shr i8 }
1337    impl_shift! { vesravh simd_shr i16 }
1338    impl_shift! { vesravf simd_shr i32 }
1339    impl_shift! { vesravg simd_shr i64 }
1340
1341    impl_vec_shift! { [VectorSra vec_sra] (vesravb, vesravh, vesravf, vesravg) }
1342
1343    macro_rules! impl_vec_shift_byte {
1344        ([$trait:ident $m:ident] ($f:ident)) => {
1345            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_signed_char) -> vector_unsigned_char }
1346            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
1347            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_char, vector_signed_char) -> vector_signed_char }
1348            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_char, vector_unsigned_char) -> vector_signed_char }
1349            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_short, vector_signed_short) -> vector_unsigned_short }
1350            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
1351            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_short, vector_signed_short) -> vector_signed_short }
1352            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_short, vector_unsigned_short) -> vector_signed_short }
1353            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_int, vector_signed_int) -> vector_unsigned_int }
1354            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
1355            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_int, vector_signed_int) -> vector_signed_int }
1356            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_int, vector_unsigned_int) -> vector_signed_int }
1357            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_long_long, vector_signed_long_long) -> vector_unsigned_long_long }
1358            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long }
1359            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_long_long, vector_signed_long_long) -> vector_signed_long_long }
1360            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_long_long, vector_unsigned_long_long) -> vector_signed_long_long }
1361            impl_vec_trait!{ [$trait $m]+ $f (vector_float, vector_signed_int) -> vector_float }
1362            impl_vec_trait!{ [$trait $m]+ $f (vector_float, vector_unsigned_int) -> vector_float }
1363            impl_vec_trait!{ [$trait $m]+ $f (vector_double, vector_signed_long_long) -> vector_double }
1364            impl_vec_trait!{ [$trait $m]+ $f (vector_double, vector_unsigned_long_long) -> vector_double }
1365        };
1366    }
1367
1368    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1369    pub trait VectorSlb<Other> {
1370        type Result;
1371        unsafe fn vec_slb(self, b: Other) -> Self::Result;
1372    }
1373
1374    impl_vec_shift_byte! { [VectorSlb vec_slb] (vslb) }
1375
1376    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1377    pub trait VectorSrab<Other> {
1378        type Result;
1379        unsafe fn vec_srab(self, b: Other) -> Self::Result;
1380    }
1381
1382    impl_vec_shift_byte! { [VectorSrab vec_srab] (vsrab) }
1383
1384    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1385    pub trait VectorSrb<Other> {
1386        type Result;
1387        unsafe fn vec_srb(self, b: Other) -> Self::Result;
1388    }
1389
1390    impl_vec_shift_byte! { [VectorSrb vec_srb] (vsrlb) }
1391
1392    macro_rules! impl_vec_shift_long {
1393        ([$trait:ident $m:ident] ($f:ident)) => {
1394            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
1395            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_char, vector_unsigned_char) -> vector_signed_char }
1396            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_short, vector_unsigned_char) -> vector_unsigned_short }
1397            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_short, vector_unsigned_char) -> vector_signed_short }
1398            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_int, vector_unsigned_char) -> vector_unsigned_int }
1399            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_int, vector_unsigned_char) -> vector_signed_int }
1400            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_long_long, vector_unsigned_char) -> vector_unsigned_long_long }
1401            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_long_long, vector_unsigned_char) -> vector_signed_long_long }
1402        };
1403    }
1404
1405    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1406    pub trait VectorSrl<Other> {
1407        type Result;
1408        unsafe fn vec_srl(self, b: Other) -> Self::Result;
1409    }
1410
1411    impl_vec_shift_long! { [VectorSrl vec_srl] (vsrl) }
1412
1413    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1414    pub trait VectorSral<Other> {
1415        type Result;
1416        unsafe fn vec_sral(self, b: Other) -> Self::Result;
1417    }
1418
1419    impl_vec_shift_long! { [VectorSral vec_sral] (vsra) }
1420
1421    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1422    pub trait VectorSll<Other> {
1423        type Result;
1424        unsafe fn vec_sll(self, b: Other) -> Self::Result;
1425    }
1426
1427    impl_vec_shift_long! { [VectorSll vec_sll] (vsl) }
1428
1429    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1430    pub trait VectorRl<Other> {
1431        type Result;
1432        unsafe fn vec_rl(self, b: Other) -> Self::Result;
1433    }
1434
1435    macro_rules! impl_rot {
1436        ($fun:ident $ty:ident) => {
1437            #[inline]
1438            #[target_feature(enable = "vector")]
1439            #[cfg_attr(test, assert_instr($fun))]
1440            unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) {
1441                simd_funnel_shl(a, a, b)
1442            }
1443        };
1444    }
1445
1446    impl_rot! { verllvb u8 }
1447    impl_rot! { verllvh u16 }
1448    impl_rot! { verllvf u32 }
1449    impl_rot! { verllvg u64 }
1450
1451    impl_vec_shift! { [VectorRl vec_rl] (verllvb, verllvh, verllvf, verllvg) }
1452
1453    macro_rules! test_rot_imm {
1454        ($fun:ident $instr:ident $ty:ident) => {
1455            #[inline]
1456            #[target_feature(enable = "vector")]
1457            #[cfg_attr(test, assert_instr($instr))]
1458            unsafe fn $fun(a: t_t_l!($ty), bits: core::ffi::c_ulong) -> t_t_l!($ty) {
1459                // mod by the number of bits in a's element type to prevent UB
1460                let bits = (bits % $ty::BITS as core::ffi::c_ulong) as $ty;
1461                let b = <t_t_s!($ty)>::splat(bits);
1462
1463                simd_funnel_shl(a, a, transmute(b))
1464            }
1465        };
1466    }
1467
1468    test_rot_imm! { verllvb_imm verllb u8 }
1469    test_rot_imm! { verllvh_imm verllh u16 }
1470    test_rot_imm! { verllvf_imm verllf u32 }
1471    test_rot_imm! { verllvg_imm verllg u64 }
1472
1473    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1474    pub trait VectorRli {
1475        unsafe fn vec_rli(self, bits: core::ffi::c_ulong) -> Self;
1476    }
1477
1478    macro_rules! impl_rot_imm {
1479        ($($ty:ident, $intr:ident),*) => {
1480            $(
1481                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1482                impl VectorRli for $ty {
1483                    #[inline]
1484                    #[target_feature(enable = "vector")]
1485                    unsafe fn vec_rli(self, bits: core::ffi::c_ulong) -> Self {
1486                        transmute($intr(transmute(self), bits))
1487                    }
1488                }
1489
1490                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1491                impl VectorRli for t_u!($ty) {
1492                    #[inline]
1493                    #[target_feature(enable = "vector")]
1494                    unsafe fn vec_rli(self, bits: core::ffi::c_ulong) -> Self {
1495                        $intr(self, bits)
1496                    }
1497                }
1498            )*
1499        }
1500    }
1501
1502    impl_rot_imm! {
1503        vector_signed_char, verllvb_imm,
1504        vector_signed_short, verllvh_imm,
1505        vector_signed_int, verllvf_imm,
1506        vector_signed_long_long, verllvg_imm
1507    }
1508
1509    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1510    pub trait VectorRlMask<Other> {
1511        unsafe fn vec_rl_mask<const IMM8: u8>(self, other: Other) -> Self;
1512    }
1513
1514    macro_rules! impl_rl_mask {
1515        ($($ty:ident, $intr:ident, $fun:ident),*) => {
1516            $(
1517                #[inline]
1518                #[target_feature(enable = "vector")]
1519                #[cfg_attr(test, assert_instr($intr, IMM8 = 6))]
1520                unsafe fn $fun<const IMM8: u8>(a: $ty, b: t_u!($ty)) -> $ty {
1521                    // mod by the number of bits in a's element type to prevent UB
1522                    $intr(a, a, transmute(b), const { (IMM8 % <l_t_t!($ty)>::BITS as u8) as i32 })
1523                }
1524
1525                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1526                impl VectorRlMask<t_u!($ty)> for $ty {
1527                    #[inline]
1528                    #[target_feature(enable = "vector")]
1529                    unsafe fn vec_rl_mask<const IMM8: u8>(self, other: t_u!($ty)) -> Self {
1530                        $fun::<IMM8>(self, other)
1531                    }
1532                }
1533
1534                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1535                impl VectorRlMask<t_u!($ty)> for t_u!($ty) {
1536                    #[inline]
1537                    #[target_feature(enable = "vector")]
1538                    unsafe fn vec_rl_mask<const IMM8: u8>(self, other: t_u!($ty)) -> Self {
1539                        transmute($fun::<IMM8>(transmute(self), transmute(other)))
1540                    }
1541                }
1542            )*
1543        }
1544    }
1545
1546    impl_rl_mask! {
1547        vector_signed_char, verimb, test_verimb,
1548        vector_signed_short, verimh, test_verimh,
1549        vector_signed_int, verimf, test_verimf,
1550        vector_signed_long_long, verimg, test_verimg
1551    }
1552
1553    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1554    pub trait VectorReve {
1555        unsafe fn vec_reve(self) -> Self;
1556    }
1557
1558    #[repr(simd)]
1559    struct ReverseMask<const N: usize>([u32; N]);
1560
1561    impl<const N: usize> ReverseMask<N> {
1562        const fn new() -> Self {
1563            let mut index = [0; N];
1564            let mut i = 0;
1565            while i < N {
1566                index[i] = (N - i - 1) as u32;
1567                i += 1;
1568            }
1569            ReverseMask(index)
1570        }
1571    }
1572
1573    macro_rules! impl_reve {
1574        ($($ty:ident, $fun:ident, $instr:ident),*) => {
1575            $(
1576                #[inline]
1577                #[target_feature(enable = "vector")]
1578                #[cfg_attr(test, assert_instr($instr))]
1579                unsafe fn $fun(a: $ty) -> $ty {
1580                    const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::<l_t_t!($ty)>();
1581                    simd_shuffle(a, a, const { ShuffleMask::<N>::reverse() })
1582                }
1583
1584                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1585                impl VectorReve for $ty {
1586                    #[inline]
1587                    #[target_feature(enable = "vector")]
1588                    unsafe fn vec_reve(self) -> Self {
1589                        $fun(self)
1590                    }
1591                }
1592
1593                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1594                impl VectorReve for t_u!($ty) {
1595                    #[inline]
1596                    #[target_feature(enable = "vector")]
1597                    unsafe fn vec_reve(self) -> Self {
1598                        transmute($fun(transmute(self)))
1599                    }
1600                }
1601
1602                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1603                impl VectorReve for t_b!($ty) {
1604                    #[inline]
1605                    #[target_feature(enable = "vector")]
1606                    unsafe fn vec_reve(self) -> Self {
1607                        transmute($fun(transmute(self)))
1608                    }
1609                }
1610            )*
1611        }
1612    }
1613
1614    impl_reve! {
1615        vector_signed_char, reveb, vperm,
1616        vector_signed_short, reveh, vperm,
1617        vector_signed_int, revef, vperm,
1618        vector_signed_long_long, reveg, vpdi
1619    }
1620
1621    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1622    impl VectorReve for vector_float {
1623        #[inline]
1624        #[target_feature(enable = "vector")]
1625        unsafe fn vec_reve(self) -> Self {
1626            transmute(transmute::<_, vector_signed_int>(self).vec_reve())
1627        }
1628    }
1629
1630    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1631    impl VectorReve for vector_double {
1632        #[inline]
1633        #[target_feature(enable = "vector")]
1634        unsafe fn vec_reve(self) -> Self {
1635            transmute(transmute::<_, vector_signed_long_long>(self).vec_reve())
1636        }
1637    }
1638
1639    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1640    pub trait VectorRevb {
1641        unsafe fn vec_revb(self) -> Self;
1642    }
1643
1644    test_impl! { bswapb (a: vector_signed_char) -> vector_signed_char [simd_bswap, _] }
1645    test_impl! { bswaph (a: vector_signed_short) -> vector_signed_short [simd_bswap, vperm] }
1646    test_impl! { bswapf (a: vector_signed_int) -> vector_signed_int [simd_bswap, vperm] }
1647    test_impl! { bswapg (a: vector_signed_long_long) -> vector_signed_long_long [simd_bswap, vperm] }
1648
1649    impl_vec_trait! { [VectorRevb vec_revb]+ bswapb (vector_unsigned_char) }
1650    impl_vec_trait! { [VectorRevb vec_revb]+ bswapb (vector_signed_char) }
1651    impl_vec_trait! { [VectorRevb vec_revb]+ bswaph (vector_unsigned_short) }
1652    impl_vec_trait! { [VectorRevb vec_revb]+ bswaph (vector_signed_short) }
1653    impl_vec_trait! { [VectorRevb vec_revb]+ bswapf (vector_unsigned_int) }
1654    impl_vec_trait! { [VectorRevb vec_revb]+ bswapf (vector_signed_int) }
1655    impl_vec_trait! { [VectorRevb vec_revb]+ bswapg (vector_unsigned_long_long) }
1656    impl_vec_trait! { [VectorRevb vec_revb]+ bswapg (vector_signed_long_long) }
1657
1658    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1659    impl VectorRevb for vector_float {
1660        #[inline]
1661        #[target_feature(enable = "vector")]
1662        unsafe fn vec_revb(self) -> Self {
1663            transmute(transmute::<_, vector_signed_int>(self).vec_revb())
1664        }
1665    }
1666
1667    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1668    impl VectorRevb for vector_double {
1669        #[inline]
1670        #[target_feature(enable = "vector")]
1671        unsafe fn vec_revb(self) -> Self {
1672            transmute(transmute::<_, vector_signed_long_long>(self).vec_revb())
1673        }
1674    }
1675
1676    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1677    pub trait VectorMergel {
1678        unsafe fn vec_mergel(self, other: Self) -> Self;
1679    }
1680
1681    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1682    pub trait VectorMergeh {
1683        unsafe fn vec_mergeh(self, other: Self) -> Self;
1684    }
1685
1686    macro_rules! impl_merge {
1687        ($($ty:ident, $mergel:ident, $mergeh:ident),*) => {
1688            $(
1689                #[inline]
1690                #[target_feature(enable = "vector")]
1691                #[cfg_attr(test, assert_instr($mergel))]
1692                unsafe fn $mergel(a: $ty, b: $ty) -> $ty {
1693                    const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::<l_t_t!($ty)>();
1694                    simd_shuffle(a, b, const { ShuffleMask::<N>::merge_low() })
1695                }
1696
1697                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1698                impl VectorMergel for $ty {
1699                    #[inline]
1700                    #[target_feature(enable = "vector")]
1701                    unsafe fn vec_mergel(self, other: Self) -> Self {
1702                        $mergel(self, other)
1703                    }
1704                }
1705
1706                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1707                impl VectorMergel for t_u!($ty) {
1708                    #[inline]
1709                    #[target_feature(enable = "vector")]
1710                    unsafe fn vec_mergel(self, other: Self) -> Self {
1711                        transmute($mergel(transmute(self), transmute(other)))
1712                    }
1713                }
1714
1715                #[inline]
1716                #[target_feature(enable = "vector")]
1717                #[cfg_attr(test, assert_instr($mergeh))]
1718                unsafe fn $mergeh(a: $ty, b: $ty) -> $ty {
1719                    const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::<l_t_t!($ty)>();
1720                    simd_shuffle(a, b, const { ShuffleMask::<N>::merge_high() })
1721                }
1722
1723                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1724                impl VectorMergeh for $ty {
1725                    #[inline]
1726                    #[target_feature(enable = "vector")]
1727                    unsafe fn vec_mergeh(self, other: Self) -> Self {
1728                        $mergeh(self, other)
1729                    }
1730                }
1731
1732                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1733                impl VectorMergeh for t_u!($ty) {
1734                    #[inline]
1735                    #[target_feature(enable = "vector")]
1736                    unsafe fn vec_mergeh(self, other: Self) -> Self {
1737                        transmute($mergeh(transmute(self), transmute(other)))
1738                    }
1739                }
1740            )*
1741        }
1742    }
1743
1744    impl_merge! {
1745        vector_signed_char, vmrlb, vmrhb,
1746        vector_signed_short, vmrlh, vmrhh,
1747        vector_signed_int, vmrlf, vmrhf,
1748        vector_signed_long_long, vmrlg, vmrhg
1749    }
1750
1751    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1752    pub trait VectorPerm {
1753        unsafe fn vec_perm(self, other: Self, c: vector_unsigned_char) -> Self;
1754    }
1755
1756    macro_rules! impl_merge {
1757        ($($ty:ident),*) => {
1758            $(
1759                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1760                impl VectorPerm for $ty {
1761                    #[inline]
1762                    #[target_feature(enable = "vector")]
1763                    unsafe fn vec_perm(self, other: Self, c: vector_unsigned_char) -> Self {
1764                        transmute(vperm(transmute(self), transmute(other), c))
1765                    }
1766                }
1767            )*
1768        }
1769    }
1770
1771    impl_merge! {
1772        vector_signed_char,
1773        vector_signed_short,
1774        vector_signed_int,
1775        vector_signed_long_long,
1776        vector_unsigned_char,
1777        vector_unsigned_short,
1778        vector_unsigned_int,
1779        vector_unsigned_long_long,
1780        vector_bool_char,
1781        vector_bool_short,
1782        vector_bool_int,
1783        vector_bool_long_long,
1784        vector_float,
1785        vector_double
1786    }
1787
1788    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1789    pub trait VectorSumU128 {
1790        unsafe fn vec_sum_u128(self, other: Self) -> vector_unsigned_char;
1791    }
1792
1793    #[inline]
1794    #[target_feature(enable = "vector")]
1795    #[cfg_attr(test, assert_instr(vsumqf))]
1796    pub unsafe fn vec_vsumqf(a: vector_unsigned_int, b: vector_unsigned_int) -> u128 {
1797        transmute(vsumqf(a, b))
1798    }
1799
1800    #[inline]
1801    #[target_feature(enable = "vector")]
1802    #[cfg_attr(test, assert_instr(vsumqg))]
1803    pub unsafe fn vec_vsumqg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> u128 {
1804        transmute(vsumqg(a, b))
1805    }
1806
1807    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1808    impl VectorSumU128 for vector_unsigned_int {
1809        #[inline]
1810        #[target_feature(enable = "vector")]
1811        unsafe fn vec_sum_u128(self, other: Self) -> vector_unsigned_char {
1812            transmute(vec_vsumqf(self, other))
1813        }
1814    }
1815
1816    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1817    impl VectorSumU128 for vector_unsigned_long_long {
1818        #[inline]
1819        #[target_feature(enable = "vector")]
1820        unsafe fn vec_sum_u128(self, other: Self) -> vector_unsigned_char {
1821            transmute(vec_vsumqg(self, other))
1822        }
1823    }
1824
1825    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1826    pub trait VectorSum2 {
1827        unsafe fn vec_sum2(self, other: Self) -> vector_unsigned_long_long;
1828    }
1829
1830    test_impl! { vec_vsumgh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_long_long [vsumgh, vsumgh] }
1831    test_impl! { vec_vsumgf (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long [vsumgf, vsumgf] }
1832
1833    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1834    impl VectorSum2 for vector_unsigned_short {
1835        #[inline]
1836        #[target_feature(enable = "vector")]
1837        unsafe fn vec_sum2(self, other: Self) -> vector_unsigned_long_long {
1838            vec_vsumgh(self, other)
1839        }
1840    }
1841
1842    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1843    impl VectorSum2 for vector_unsigned_int {
1844        #[inline]
1845        #[target_feature(enable = "vector")]
1846        unsafe fn vec_sum2(self, other: Self) -> vector_unsigned_long_long {
1847            vec_vsumgf(self, other)
1848        }
1849    }
1850
1851    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1852    pub trait VectorSum4 {
1853        unsafe fn vec_sum4(self, other: Self) -> vector_unsigned_int;
1854    }
1855
1856    test_impl! { vec_vsumb (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_int [vsumb, vsumb] }
1857    test_impl! { vec_vsumh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int [vsumh, vsumh] }
1858
1859    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1860    impl VectorSum4 for vector_unsigned_char {
1861        #[inline]
1862        #[target_feature(enable = "vector")]
1863        unsafe fn vec_sum4(self, other: Self) -> vector_unsigned_int {
1864            vec_vsumb(self, other)
1865        }
1866    }
1867
1868    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1869    impl VectorSum4 for vector_unsigned_short {
1870        #[inline]
1871        #[target_feature(enable = "vector")]
1872        unsafe fn vec_sum4(self, other: Self) -> vector_unsigned_int {
1873            vec_vsumh(self, other)
1874        }
1875    }
1876
1877    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1878    pub trait VectorSubc<Other> {
1879        type Result;
1880        unsafe fn vec_subc(self, b: Other) -> Self::Result;
1881    }
1882
1883    test_impl! { vec_vscbib (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [vscbib, vscbib] }
1884    test_impl! { vec_vscbih (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [vscbih, vscbih] }
1885    test_impl! { vec_vscbif (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vscbif, vscbif] }
1886    test_impl! { vec_vscbig (a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long [vscbig, vscbig] }
1887
1888    impl_vec_trait! {[VectorSubc vec_subc] vec_vscbib (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
1889    impl_vec_trait! {[VectorSubc vec_subc] vec_vscbih (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
1890    impl_vec_trait! {[VectorSubc vec_subc] vec_vscbif (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
1891    impl_vec_trait! {[VectorSubc vec_subc] vec_vscbig (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long }
1892
1893    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1894    pub trait VectorSqrt {
1895        unsafe fn vec_sqrt(self) -> Self;
1896    }
1897
1898    test_impl! { vec_sqrt_f32 (v: vector_float) -> vector_float [ simd_fsqrt, "vector-enhancements-1" vfsqsb ] }
1899    test_impl! { vec_sqrt_f64 (v: vector_double) -> vector_double [ simd_fsqrt, vfsqdb ] }
1900
1901    impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f32 (vector_float) }
1902    impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f64 (vector_double) }
1903
1904    macro_rules! vfae_wrapper {
1905        ($($name:ident $ty:ident)*) => {
1906            $(
1907                #[inline]
1908                #[target_feature(enable = "vector")]
1909                #[cfg_attr(test, assert_instr($name, IMM = 0))]
1910                unsafe fn $name<const IMM: i32>(
1911                    a: $ty,
1912                    b: $ty,
1913                ) -> $ty {
1914                    super::$name(a, b, IMM)
1915                }
1916            )*
1917        }
1918     }
1919
1920    vfae_wrapper! {
1921       vfaeb vector_signed_char
1922       vfaeh vector_signed_short
1923       vfaef vector_signed_int
1924
1925       vfaezb vector_signed_char
1926       vfaezh vector_signed_short
1927       vfaezf vector_signed_int
1928    }
1929
1930    macro_rules! impl_vfae {
1931        ([idx_cc $Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => {
1932            impl_vfae! { [idx_cc $Trait $m] $imm
1933                $b vector_signed_char vector_signed_char
1934                $b vector_unsigned_char vector_unsigned_char
1935                $b vector_bool_char vector_unsigned_char
1936
1937                $h vector_signed_short vector_signed_short
1938                $h vector_unsigned_short vector_unsigned_short
1939                $h vector_bool_short vector_unsigned_short
1940
1941                $f vector_signed_int vector_signed_int
1942                $f vector_unsigned_int vector_unsigned_int
1943                $f vector_bool_int vector_unsigned_int
1944            }
1945        };
1946        ([idx_cc $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident $r:ident)*) => {
1947            $(
1948                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1949                impl $Trait<Self> for $ty {
1950                    type Result = $r;
1951                    #[inline]
1952                    #[target_feature(enable = "vector")]
1953                    unsafe fn $m(self, b: Self) -> (Self::Result, i32) {
1954                        let PackedTuple { x, y } = $fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b));
1955                        (transmute(x), y)
1956                    }
1957                }
1958            )*
1959        };
1960        ([cc $Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => {
1961            impl_vfae! { [cc $Trait $m] $imm
1962                $b vector_signed_char
1963                $b vector_unsigned_char
1964                $b vector_bool_char
1965
1966                $h vector_signed_short
1967                $h vector_unsigned_short
1968                $h vector_bool_short
1969
1970                $f vector_signed_int
1971                $f vector_unsigned_int
1972                $f vector_bool_int
1973            }
1974        };
1975        ([cc $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident)*) => {
1976            $(
1977                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1978                impl $Trait<Self> for $ty {
1979                    type Result = t_b!($ty);
1980                    #[inline]
1981                    #[target_feature(enable = "vector")]
1982                    unsafe fn $m(self, b: Self) -> (Self::Result, i32) {
1983                        let PackedTuple { x, y } = $fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b));
1984                        (transmute(x), y)
1985                    }
1986                }
1987            )*
1988        };
1989        ([idx $Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => {
1990            impl_vfae! { [idx $Trait $m] $imm
1991                $b vector_signed_char vector_signed_char
1992                $b vector_unsigned_char vector_unsigned_char
1993                $b vector_bool_char vector_unsigned_char
1994
1995                $h vector_signed_short vector_signed_short
1996                $h vector_unsigned_short vector_unsigned_short
1997                $h vector_bool_short vector_unsigned_short
1998
1999                $f vector_signed_int vector_signed_int
2000                $f vector_unsigned_int vector_unsigned_int
2001                $f vector_bool_int vector_unsigned_int
2002            }
2003        };
2004        ([idx $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident $r:ident)*) => {
2005            $(
2006                #[unstable(feature = "stdarch_s390x", issue = "135681")]
2007                impl $Trait<Self> for $ty {
2008                    type Result = $r;
2009                    #[inline]
2010                    #[target_feature(enable = "vector")]
2011                    unsafe fn $m(self, b: Self) -> Self::Result {
2012                        transmute($fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b)))
2013                    }
2014                }
2015            )*
2016        };
2017        ([$Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => {
2018            impl_vfae! { [$Trait $m] $imm
2019                $b vector_signed_char
2020                $b vector_unsigned_char
2021                $b vector_bool_char
2022
2023                $h vector_signed_short
2024                $h vector_unsigned_short
2025                $h vector_bool_short
2026
2027                $f vector_signed_int
2028                $f vector_unsigned_int
2029                $f vector_bool_int
2030            }
2031        };
2032        ([$Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident)*) => {
2033            $(
2034                #[unstable(feature = "stdarch_s390x", issue = "135681")]
2035                impl $Trait<Self> for $ty {
2036                    type Result = t_b!($ty);
2037                    #[inline]
2038                    #[target_feature(enable = "vector")]
2039                    unsafe fn $m(self, b: Self) -> Self::Result {
2040                        transmute($fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b)))
2041                    }
2042                }
2043            )*
2044        };
2045    }
2046
2047    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2048    pub trait VectorFindAnyEq<Other> {
2049        type Result;
2050        unsafe fn vec_find_any_eq(self, other: Other) -> Self::Result;
2051    }
2052
2053    impl_vfae! { [VectorFindAnyEq vec_find_any_eq] Eq vfaeb vfaeh vfaef }
2054
2055    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2056    pub trait VectorFindAnyNe<Other> {
2057        type Result;
2058        unsafe fn vec_find_any_ne(self, other: Other) -> Self::Result;
2059    }
2060
2061    impl_vfae! { [VectorFindAnyNe vec_find_any_ne] Ne vfaeb vfaeh vfaef }
2062
2063    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2064    pub trait VectorFindAnyEqOrZeroIdx<Other> {
2065        type Result;
2066        unsafe fn vec_find_any_eq_or_0_idx(self, other: Other) -> Self::Result;
2067    }
2068
2069    impl_vfae! { [idx VectorFindAnyEqOrZeroIdx vec_find_any_eq_or_0_idx] EqIdx
2070        vfaezb vector_signed_char vector_signed_char
2071        vfaezb vector_unsigned_char vector_unsigned_char
2072        vfaezb vector_bool_char vector_unsigned_char
2073
2074        vfaezh vector_signed_short vector_signed_short
2075        vfaezh vector_unsigned_short vector_unsigned_short
2076        vfaezh vector_bool_short vector_unsigned_short
2077
2078        vfaezf vector_signed_int vector_signed_int
2079        vfaezf vector_unsigned_int vector_unsigned_int
2080        vfaezf vector_bool_int vector_unsigned_int
2081    }
2082
2083    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2084    pub trait VectorFindAnyNeOrZeroIdx<Other> {
2085        type Result;
2086        unsafe fn vec_find_any_ne_or_0_idx(self, other: Other) -> Self::Result;
2087    }
2088
2089    impl_vfae! { [idx VectorFindAnyNeOrZeroIdx vec_find_any_ne_or_0_idx] NeIdx
2090        vfaezb vector_signed_char vector_signed_char
2091        vfaezb vector_unsigned_char vector_unsigned_char
2092        vfaezb vector_bool_char vector_unsigned_char
2093
2094        vfaezh vector_signed_short vector_signed_short
2095        vfaezh vector_unsigned_short vector_unsigned_short
2096        vfaezh vector_bool_short vector_unsigned_short
2097
2098        vfaezf vector_signed_int vector_signed_int
2099        vfaezf vector_unsigned_int vector_unsigned_int
2100        vfaezf vector_bool_int vector_unsigned_int
2101    }
2102
2103    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2104    pub trait VectorFindAnyEqIdx<Other> {
2105        type Result;
2106        unsafe fn vec_find_any_eq_idx(self, other: Other) -> Self::Result;
2107    }
2108
2109    impl_vfae! { [idx VectorFindAnyEqIdx vec_find_any_eq_idx] EqIdx vfaeb vfaeh vfaef }
2110
2111    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2112    pub trait VectorFindAnyNeIdx<Other> {
2113        type Result;
2114        unsafe fn vec_find_any_ne_idx(self, other: Other) -> Self::Result;
2115    }
2116
2117    impl_vfae! { [idx VectorFindAnyNeIdx vec_find_any_ne_idx] NeIdx vfaeb vfaeh vfaef }
2118
2119    macro_rules! vfaes_wrapper {
2120        ($($name:ident $ty:ident)*) => {
2121            $(
2122                #[inline]
2123                #[target_feature(enable = "vector")]
2124                #[cfg_attr(test, assert_instr($name, IMM = 0))]
2125                unsafe fn $name<const IMM: i32>(
2126                    a: $ty,
2127                    b: $ty,
2128                ) -> PackedTuple<$ty, i32> {
2129                    super::$name(a, b, IMM)
2130                }
2131            )*
2132        }
2133     }
2134
2135    vfaes_wrapper! {
2136        vfaebs vector_signed_char
2137        vfaehs vector_signed_short
2138        vfaefs vector_signed_int
2139
2140        vfaezbs vector_signed_char
2141        vfaezhs vector_signed_short
2142        vfaezfs vector_signed_int
2143    }
2144
2145    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2146    pub trait VectorFindAnyEqCC<Other> {
2147        type Result;
2148        unsafe fn vec_find_any_eq_cc(self, other: Other) -> (Self::Result, i32);
2149    }
2150
2151    impl_vfae! { [cc VectorFindAnyEqCC vec_find_any_eq_cc] Eq vfaebs vfaehs vfaefs }
2152
2153    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2154    pub trait VectorFindAnyNeCC<Other> {
2155        type Result;
2156        unsafe fn vec_find_any_ne_cc(self, other: Other) -> (Self::Result, i32);
2157    }
2158
2159    impl_vfae! { [cc VectorFindAnyNeCC vec_find_any_ne_cc] Ne vfaebs vfaehs vfaefs }
2160
2161    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2162    pub trait VectorFindAnyEqIdxCC<Other> {
2163        type Result;
2164        unsafe fn vec_find_any_eq_idx_cc(self, other: Other) -> (Self::Result, i32);
2165    }
2166
2167    impl_vfae! { [idx_cc VectorFindAnyEqIdxCC vec_find_any_eq_idx_cc] EqIdx vfaebs vfaehs vfaefs }
2168
2169    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2170    pub trait VectorFindAnyNeIdxCC<Other> {
2171        type Result;
2172        unsafe fn vec_find_any_ne_idx_cc(self, other: Other) -> (Self::Result, i32);
2173    }
2174
2175    impl_vfae! { [idx_cc VectorFindAnyNeIdxCC vec_find_any_ne_idx_cc] NeIdx vfaebs vfaehs vfaefs }
2176
2177    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2178    pub trait VectorFindAnyEqOrZeroIdxCC<Other> {
2179        type Result;
2180        unsafe fn vec_find_any_eq_or_0_idx_cc(self, other: Other) -> (Self::Result, i32);
2181    }
2182
2183    impl_vfae! { [idx_cc VectorFindAnyEqOrZeroIdxCC vec_find_any_eq_or_0_idx_cc] EqIdx vfaezbs vfaezhs vfaezfs }
2184
2185    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2186    pub trait VectorFindAnyNeOrZeroIdxCC<Other> {
2187        type Result;
2188        unsafe fn vec_find_any_ne_or_0_idx_cc(self, other: Other) -> (Self::Result, i32);
2189    }
2190
2191    impl_vfae! { [idx_cc VectorFindAnyNeOrZeroIdxCC vec_find_any_ne_or_0_idx_cc] NeIdx vfaezbs vfaezhs vfaezfs }
2192
2193    #[inline]
2194    #[target_feature(enable = "vector")]
2195    #[cfg_attr(test, assert_instr(vl))]
2196    unsafe fn test_vector_load(offset: isize, ptr: *const i32) -> vector_signed_int {
2197        ptr.byte_offset(offset)
2198            .cast::<vector_signed_int>()
2199            .read_unaligned()
2200    }
2201
2202    #[inline]
2203    #[target_feature(enable = "vector")]
2204    #[cfg_attr(test, assert_instr(vst))]
2205    unsafe fn test_vector_store(vector: vector_signed_int, offset: isize, ptr: *mut i32) {
2206        ptr.byte_offset(offset)
2207            .cast::<vector_signed_int>()
2208            .write_unaligned(vector)
2209    }
2210
2211    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2212    pub trait VectorLoad: Sized {
2213        type ElementType;
2214
2215        #[inline]
2216        #[target_feature(enable = "vector")]
2217        unsafe fn vec_xl(offset: isize, ptr: *const Self::ElementType) -> Self {
2218            ptr.byte_offset(offset).cast::<Self>().read_unaligned()
2219        }
2220
2221        unsafe fn vec_load_len(ptr: *const Self::ElementType, byte_count: u32) -> Self;
2222
2223        unsafe fn vec_load_bndry<const BLOCK_BOUNDARY: u16>(
2224            ptr: *const Self::ElementType,
2225        ) -> MaybeUninit<Self>;
2226    }
2227
2228    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2229    pub trait VectorStore: Sized {
2230        type ElementType;
2231
2232        #[inline]
2233        #[target_feature(enable = "vector")]
2234        unsafe fn vec_xst(self, offset: isize, ptr: *mut Self::ElementType) {
2235            ptr.byte_offset(offset).cast::<Self>().write_unaligned(self)
2236        }
2237
2238        unsafe fn vec_store_len(self, ptr: *mut Self::ElementType, byte_count: u32);
2239    }
2240
2241    macro_rules! impl_load_store {
2242        ($($ty:ident)*) => {
2243            $(
2244                #[unstable(feature = "stdarch_s390x", issue = "135681")]
2245                impl VectorLoad for t_t_l!($ty) {
2246                    type ElementType = $ty;
2247
2248                    #[inline]
2249                    #[target_feature(enable = "vector")]
2250                    unsafe fn vec_load_len(ptr: *const Self::ElementType, byte_count: u32) -> Self {
2251                        transmute(vll( byte_count, ptr.cast(),))
2252                    }
2253
2254                    #[inline]
2255                    #[target_feature(enable = "vector")]
2256                    unsafe fn vec_load_bndry<const BLOCK_BOUNDARY: u16>(ptr: *const Self::ElementType) -> MaybeUninit<Self> {
2257                        transmute(vlbb(ptr.cast(), const { validate_block_boundary(BLOCK_BOUNDARY) }))
2258                    }
2259
2260                }
2261
2262                #[unstable(feature = "stdarch_s390x", issue = "135681")]
2263                impl VectorStore for t_t_l!($ty) {
2264                    type ElementType = $ty;
2265
2266                    #[inline]
2267                    #[target_feature(enable = "vector")]
2268                    unsafe fn vec_store_len(self, ptr: *mut Self::ElementType, byte_count: u32) {
2269                        vstl(transmute(self), byte_count, ptr.cast())
2270                    }
2271                }
2272            )*
2273        }
2274    }
2275
2276    impl_load_store! { i8 u8 i16 u16 i32 u32 i64 u64 f32 f64 }
2277
2278    #[inline]
2279    #[target_feature(enable = "vector")]
2280    #[cfg_attr(test, assert_instr(vll))]
2281    unsafe fn test_vec_load_len(ptr: *const i32, byte_count: u32) -> vector_signed_int {
2282        vector_signed_int::vec_load_len(ptr, byte_count)
2283    }
2284
2285    #[inline]
2286    #[target_feature(enable = "vector")]
2287    #[cfg_attr(test, assert_instr(vlbb))]
2288    unsafe fn test_vec_load_bndry(ptr: *const i32) -> MaybeUninit<vector_signed_int> {
2289        vector_signed_int::vec_load_bndry::<512>(ptr)
2290    }
2291
2292    #[inline]
2293    #[target_feature(enable = "vector")]
2294    #[cfg_attr(test, assert_instr(vstl))]
2295    unsafe fn test_vec_store_len(vector: vector_signed_int, ptr: *mut i32, byte_count: u32) {
2296        vector.vec_store_len(ptr, byte_count)
2297    }
2298
2299    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2300    pub trait VectorLoadPair: Sized {
2301        type ElementType;
2302
2303        unsafe fn vec_load_pair(a: Self::ElementType, b: Self::ElementType) -> Self;
2304    }
2305
2306    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2307    impl VectorLoadPair for vector_signed_long_long {
2308        type ElementType = i64;
2309
2310        #[inline]
2311        #[target_feature(enable = "vector")]
2312        unsafe fn vec_load_pair(a: i64, b: i64) -> Self {
2313            vector_signed_long_long([a, b])
2314        }
2315    }
2316
2317    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2318    impl VectorLoadPair for vector_unsigned_long_long {
2319        type ElementType = u64;
2320
2321        #[inline]
2322        #[target_feature(enable = "vector")]
2323        unsafe fn vec_load_pair(a: u64, b: u64) -> Self {
2324            vector_unsigned_long_long([a, b])
2325        }
2326    }
2327
2328    #[inline]
2329    #[target_feature(enable = "vector")]
2330    unsafe fn pack<T, const N: usize>(a: T, b: T) -> T {
2331        simd_shuffle(a, b, const { ShuffleMask::<N>::pack() })
2332    }
2333
2334    #[inline]
2335    #[target_feature(enable = "vector")]
2336    #[cfg_attr(test, assert_instr(vpkh))]
2337    unsafe fn vpkh(a: i16x8, b: i16x8) -> i8x16 {
2338        let a: i8x16 = transmute(a);
2339        let b: i8x16 = transmute(b);
2340        simd_shuffle(a, b, const { ShuffleMask::<16>::pack() })
2341    }
2342    #[inline]
2343    #[target_feature(enable = "vector")]
2344    #[cfg_attr(test, assert_instr(vpkf))]
2345    unsafe fn vpkf(a: i32x4, b: i32x4) -> i16x8 {
2346        let a: i16x8 = transmute(a);
2347        let b: i16x8 = transmute(b);
2348        simd_shuffle(a, b, const { ShuffleMask::<8>::pack() })
2349    }
2350    #[inline]
2351    #[target_feature(enable = "vector")]
2352    #[cfg_attr(test, assert_instr(vpkg))]
2353    unsafe fn vpkg(a: i64x2, b: i64x2) -> i32x4 {
2354        let a: i32x4 = transmute(a);
2355        let b: i32x4 = transmute(b);
2356        simd_shuffle(a, b, const { ShuffleMask::<4>::pack() })
2357    }
2358
2359    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2360    pub trait VectorPack<Other> {
2361        type Result;
2362        unsafe fn vec_pack(self, b: Other) -> Self::Result;
2363    }
2364
2365    impl_vec_trait! { [VectorPack vec_pack]+ vpkh (vector_signed_short, vector_signed_short) -> vector_signed_char }
2366    impl_vec_trait! { [VectorPack vec_pack]+ vpkh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_char }
2367    impl_vec_trait! { [VectorPack vec_pack]+ vpkh (vector_bool_short, vector_bool_short) -> vector_bool_char }
2368    impl_vec_trait! { [VectorPack vec_pack]+ vpkf (vector_signed_int, vector_signed_int) -> vector_signed_short }
2369    impl_vec_trait! { [VectorPack vec_pack]+ vpkf (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_short }
2370    impl_vec_trait! { [VectorPack vec_pack]+ vpkf (vector_bool_int, vector_bool_int) -> vector_bool_short }
2371    impl_vec_trait! { [VectorPack vec_pack]+ vpkg (vector_signed_long_long, vector_signed_long_long) -> vector_signed_int }
2372    impl_vec_trait! { [VectorPack vec_pack]+ vpkg (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_int }
2373    impl_vec_trait! { [VectorPack vec_pack]+ vpkg (vector_bool_long_long, vector_bool_long_long) -> vector_bool_int }
2374
2375    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2376    pub trait VectorPacks<Other> {
2377        type Result;
2378        unsafe fn vec_packs(self, b: Other) -> Self::Result;
2379    }
2380
2381    // FIXME(llvm): https://github.com/llvm/llvm-project/issues/153655
2382    // Other targets can use a min/max for the saturation + a truncation.
2383
2384    impl_vec_trait! { [VectorPacks vec_packs] vpksh (vector_signed_short, vector_signed_short) -> vector_signed_char }
2385    impl_vec_trait! { [VectorPacks vec_packs] vpklsh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_char }
2386    impl_vec_trait! { [VectorPacks vec_packs] vpksf (vector_signed_int, vector_signed_int) -> vector_signed_short }
2387    impl_vec_trait! { [VectorPacks vec_packs] vpklsf (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_short }
2388    impl_vec_trait! { [VectorPacks vec_packs] vpksg (vector_signed_long_long, vector_signed_long_long) -> vector_signed_int }
2389    impl_vec_trait! { [VectorPacks vec_packs] vpklsg (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_int }
2390
2391    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2392    pub trait VectorPacksu<Other> {
2393        type Result;
2394        unsafe fn vec_packsu(self, b: Other) -> Self::Result;
2395    }
2396
2397    #[inline]
2398    #[target_feature(enable = "vector")]
2399    #[cfg_attr(test, assert_instr(vpklsh))]
2400    unsafe fn vpacksuh(a: vector_signed_short, b: vector_signed_short) -> vector_unsigned_char {
2401        vpklsh(
2402            vec_max(a, vector_signed_short([0; 8])),
2403            vec_max(b, vector_signed_short([0; 8])),
2404        )
2405    }
2406    #[inline]
2407    #[target_feature(enable = "vector")]
2408    #[cfg_attr(test, assert_instr(vpklsf))]
2409    unsafe fn vpacksuf(a: vector_signed_int, b: vector_signed_int) -> vector_unsigned_short {
2410        vpklsf(
2411            vec_max(a, vector_signed_int([0; 4])),
2412            vec_max(b, vector_signed_int([0; 4])),
2413        )
2414    }
2415    #[inline]
2416    #[target_feature(enable = "vector")]
2417    #[cfg_attr(test, assert_instr(vpklsg))]
2418    unsafe fn vpacksug(
2419        a: vector_signed_long_long,
2420        b: vector_signed_long_long,
2421    ) -> vector_unsigned_int {
2422        vpklsg(
2423            vec_max(a, vector_signed_long_long([0; 2])),
2424            vec_max(b, vector_signed_long_long([0; 2])),
2425        )
2426    }
2427
2428    impl_vec_trait! { [VectorPacksu vec_packsu] vpacksuh (vector_signed_short, vector_signed_short) -> vector_unsigned_char }
2429    impl_vec_trait! { [VectorPacksu vec_packsu] vpklsh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_char }
2430    impl_vec_trait! { [VectorPacksu vec_packsu] vpacksuf (vector_signed_int, vector_signed_int) -> vector_unsigned_short }
2431    impl_vec_trait! { [VectorPacksu vec_packsu] vpklsf (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_short }
2432    impl_vec_trait! { [VectorPacksu vec_packsu] vpacksug (vector_signed_long_long, vector_signed_long_long) -> vector_unsigned_int }
2433    impl_vec_trait! { [VectorPacksu vec_packsu] vpklsg (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_int }
2434
2435    macro_rules! impl_vector_packs_cc {
2436        ($($intr:ident $ty:ident $outty:ident)*) => {
2437            $(
2438                #[inline]
2439                #[target_feature(enable = "vector")]
2440                #[cfg_attr(test, assert_instr($intr))]
2441                unsafe fn $intr(
2442                    a: $ty,
2443                    b: $ty,
2444                ) -> ($outty, i32) {
2445                    let PackedTuple { x, y } = super::$intr(a, b);
2446                    (x, y)
2447                }
2448
2449                #[unstable(feature = "stdarch_s390x", issue = "135681")]
2450                impl VectorPacksCC for $ty {
2451                    type Result = $outty;
2452
2453                    #[inline]
2454                    #[target_feature(enable = "vector")]
2455                    unsafe fn vec_packs_cc(self, b: Self) -> (Self::Result, i32) {
2456                        $intr(self, b)
2457                    }
2458                }
2459            )*
2460        }
2461    }
2462
2463    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2464    pub trait VectorPacksCC {
2465        type Result;
2466        unsafe fn vec_packs_cc(self, b: Self) -> (Self::Result, i32);
2467    }
2468
2469    impl_vector_packs_cc! {
2470        vpkshs vector_signed_short vector_signed_char
2471        vpklshs vector_unsigned_short vector_unsigned_char
2472        vpksfs vector_signed_int vector_signed_short
2473        vpklsfs vector_unsigned_int vector_unsigned_short
2474        vpksgs vector_signed_long_long vector_signed_int
2475        vpklsgs vector_unsigned_long_long vector_unsigned_int
2476    }
2477
2478    macro_rules! impl_vector_packsu_cc {
2479        ($($intr:ident $ty:ident $outty:ident)*) => {
2480            $(
2481                #[unstable(feature = "stdarch_s390x", issue = "135681")]
2482                impl VectorPacksuCC for $ty {
2483                    type Result = $outty;
2484
2485                    #[inline]
2486                    #[target_feature(enable = "vector")]
2487                    unsafe fn vec_packsu_cc(self, b: Self) -> (Self::Result, i32) {
2488                        $intr(self, b)
2489                    }
2490                }
2491            )*
2492        }
2493    }
2494
2495    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2496    pub trait VectorPacksuCC {
2497        type Result;
2498        unsafe fn vec_packsu_cc(self, b: Self) -> (Self::Result, i32);
2499    }
2500
2501    impl_vector_packsu_cc! {
2502        vpklshs vector_unsigned_short vector_unsigned_char
2503        vpklsfs vector_unsigned_int vector_unsigned_short
2504        vpklsgs vector_unsigned_long_long vector_unsigned_int
2505    }
2506
2507    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2508    pub trait VectorMadd {
2509        unsafe fn vec_madd(self, b: Self, c: Self) -> Self;
2510        unsafe fn vec_msub(self, b: Self, c: Self) -> Self;
2511    }
2512
2513    test_impl! { vfmasb (a: vector_float, b: vector_float, c: vector_float) -> vector_float [simd_fma, "vector-enhancements-1" vfmasb] }
2514    test_impl! { vfmadb (a: vector_double, b: vector_double, c: vector_double) -> vector_double [simd_fma, vfmadb] }
2515
2516    #[inline]
2517    unsafe fn simd_fms<T>(a: T, b: T, c: T) -> T {
2518        simd_fma(a, b, simd_neg(c))
2519    }
2520
2521    test_impl! { vfmssb (a: vector_float, b: vector_float, c: vector_float) -> vector_float [simd_fms, "vector-enhancements-1" vfmssb] }
2522    test_impl! { vfmsdb (a: vector_double, b: vector_double, c: vector_double) -> vector_double [simd_fms, vfmsdb] }
2523
2524    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2525    impl VectorMadd for vector_float {
2526        #[inline]
2527        #[target_feature(enable = "vector")]
2528        unsafe fn vec_madd(self, b: Self, c: Self) -> Self {
2529            vfmasb(self, b, c)
2530        }
2531
2532        #[inline]
2533        #[target_feature(enable = "vector")]
2534        unsafe fn vec_msub(self, b: Self, c: Self) -> Self {
2535            vfmssb(self, b, c)
2536        }
2537    }
2538
2539    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2540    impl VectorMadd for vector_double {
2541        #[inline]
2542        #[target_feature(enable = "vector")]
2543        unsafe fn vec_madd(self, b: Self, c: Self) -> Self {
2544            vfmadb(self, b, c)
2545        }
2546
2547        #[inline]
2548        #[target_feature(enable = "vector")]
2549        unsafe fn vec_msub(self, b: Self, c: Self) -> Self {
2550            vfmsdb(self, b, c)
2551        }
2552    }
2553
2554    macro_rules! impl_vec_unpack {
2555        ($mask:ident $instr:ident $src:ident $shuffled:ident $dst:ident $width:literal) => {
2556            #[inline]
2557            #[target_feature(enable = "vector")]
2558            #[cfg_attr(test, assert_instr($instr))]
2559            unsafe fn $instr(a: $src) -> $dst {
2560                simd_as(simd_shuffle::<_, _, $shuffled>(
2561                    a,
2562                    a,
2563                    const { ShuffleMask::<$width>::$mask() },
2564                ))
2565            }
2566        };
2567    }
2568
2569    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2570    pub trait VectorUnpackh {
2571        type Result;
2572        unsafe fn vec_unpackh(self) -> Self::Result;
2573    }
2574
2575    impl_vec_unpack!(unpack_high vuphb vector_signed_char i8x8 vector_signed_short 8);
2576    impl_vec_unpack!(unpack_high vuphh vector_signed_short i16x4 vector_signed_int 4);
2577    impl_vec_unpack!(unpack_high vuphf vector_signed_int i32x2 vector_signed_long_long 2);
2578
2579    impl_vec_unpack!(unpack_high vuplhb vector_unsigned_char u8x8 vector_unsigned_short 8);
2580    impl_vec_unpack!(unpack_high vuplhh vector_unsigned_short u16x4 vector_unsigned_int 4);
2581    impl_vec_unpack!(unpack_high vuplhf vector_unsigned_int u32x2 vector_unsigned_long_long 2);
2582
2583    impl_vec_trait! {[VectorUnpackh vec_unpackh] vuphb (vector_signed_char) -> vector_signed_short}
2584    impl_vec_trait! {[VectorUnpackh vec_unpackh] vuphh (vector_signed_short) -> vector_signed_int}
2585    impl_vec_trait! {[VectorUnpackh vec_unpackh] vuphf (vector_signed_int) -> vector_signed_long_long}
2586
2587    impl_vec_trait! {[VectorUnpackh vec_unpackh] vuplhb (vector_unsigned_char) -> vector_unsigned_short}
2588    impl_vec_trait! {[VectorUnpackh vec_unpackh] vuplhh (vector_unsigned_short) -> vector_unsigned_int}
2589    impl_vec_trait! {[VectorUnpackh vec_unpackh] vuplhf (vector_unsigned_int) -> vector_unsigned_long_long}
2590
2591    impl_vec_trait! {[VectorUnpackh vec_unpackh]+ vuplhb (vector_bool_char) -> vector_bool_short}
2592    impl_vec_trait! {[VectorUnpackh vec_unpackh]+ vuplhh (vector_bool_short) -> vector_bool_int}
2593    impl_vec_trait! {[VectorUnpackh vec_unpackh]+ vuplhf (vector_bool_int) -> vector_bool_long_long}
2594
2595    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2596    pub trait VectorUnpackl {
2597        type Result;
2598        unsafe fn vec_unpackl(self) -> Self::Result;
2599    }
2600
2601    // NOTE: `vuplh` is used for "unpack logical high", hence `vuplhw`.
2602    impl_vec_unpack!(unpack_low vuplb vector_signed_char i8x8 vector_signed_short 8);
2603    impl_vec_unpack!(unpack_low vuplhw vector_signed_short i16x4 vector_signed_int 4);
2604    impl_vec_unpack!(unpack_low vuplf vector_signed_int i32x2 vector_signed_long_long 2);
2605
2606    impl_vec_unpack!(unpack_low vupllb vector_unsigned_char u8x8 vector_unsigned_short 8);
2607    impl_vec_unpack!(unpack_low vupllh vector_unsigned_short u16x4 vector_unsigned_int 4);
2608    impl_vec_unpack!(unpack_low vupllf vector_unsigned_int u32x2 vector_unsigned_long_long 2);
2609
2610    impl_vec_trait! {[VectorUnpackl vec_unpackl] vuplb (vector_signed_char) -> vector_signed_short}
2611    impl_vec_trait! {[VectorUnpackl vec_unpackl] vuplhw (vector_signed_short) -> vector_signed_int}
2612    impl_vec_trait! {[VectorUnpackl vec_unpackl] vuplf (vector_signed_int) -> vector_signed_long_long}
2613
2614    impl_vec_trait! {[VectorUnpackl vec_unpackl] vupllb (vector_unsigned_char) -> vector_unsigned_short}
2615    impl_vec_trait! {[VectorUnpackl vec_unpackl] vupllh (vector_unsigned_short) -> vector_unsigned_int}
2616    impl_vec_trait! {[VectorUnpackl vec_unpackl] vupllf (vector_unsigned_int) -> vector_unsigned_long_long}
2617
2618    impl_vec_trait! {[VectorUnpackl vec_unpackl]+ vupllb (vector_bool_char) -> vector_bool_short}
2619    impl_vec_trait! {[VectorUnpackl vec_unpackl]+ vupllh (vector_bool_short) -> vector_bool_int}
2620    impl_vec_trait! {[VectorUnpackl vec_unpackl]+ vupllf (vector_bool_int) -> vector_bool_long_long}
2621
2622    test_impl! { vec_vavgb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [ vavgb, vavgb ] }
2623    test_impl! { vec_vavgh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [ vavgh, vavgh ] }
2624    test_impl! { vec_vavgf(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [ vavgf, vavgf ] }
2625    test_impl! { vec_vavgg(a: vector_signed_long_long, b: vector_signed_long_long) -> vector_signed_long_long [ vavgg, vavgg ] }
2626
2627    test_impl! { vec_vavglb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [ vavglb, vavglb ] }
2628    test_impl! { vec_vavglh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [ vavglh, vavglh ] }
2629    test_impl! { vec_vavglf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [ vavglf, vavglf ] }
2630    test_impl! { vec_vavglg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long [ vavglg, vavglg ] }
2631
2632    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2633    pub trait VectorAvg<Other> {
2634        type Result;
2635        unsafe fn vec_avg(self, b: Other) -> Self::Result;
2636    }
2637
2638    impl_vec_trait! { [VectorAvg vec_avg] 2 (vec_vavglb, vec_vavgb, vec_vavglh, vec_vavgh, vec_vavglf, vec_vavgf, vec_vavglg, vec_vavgg) }
2639
2640    macro_rules! impl_mul {
2641        ([$Trait:ident $m:ident] $fun:ident ($a:ty, $b:ty) -> $r:ty) => {
2642            #[unstable(feature = "stdarch_s390x", issue = "135681")]
2643            impl $Trait<$r> for $a {
2644                #[inline]
2645                #[target_feature(enable = "vector")]
2646                unsafe fn $m(self, b: $b) -> $r {
2647                    $fun(transmute(self), transmute(b))
2648                }
2649            }
2650        };
2651        ([$Trait:ident $m:ident] $fun:ident ($a:ty, $b:ty, $c:ty) -> $r:ty) => {
2652            #[unstable(feature = "stdarch_s390x", issue = "135681")]
2653            impl $Trait for $a {
2654                type Result = $r;
2655                #[inline]
2656                #[target_feature(enable = "vector")]
2657                unsafe fn $m(self, b: $b, c: $c) -> $r {
2658                    $fun(self, b, c)
2659                }
2660            }
2661        };
2662    }
2663
2664    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2665    pub trait VectorMule<Result> {
2666        unsafe fn vec_mule(self, b: Self) -> Result;
2667    }
2668
2669    macro_rules! impl_vec_mul_even_odd {
2670        ($mask:ident $instr:ident $src:ident $shuffled:ident $dst:ident $width:literal) => {
2671            #[inline]
2672            #[target_feature(enable = "vector")]
2673            #[cfg_attr(test, assert_instr($instr))]
2674            unsafe fn $instr(a: $src, b: $src) -> $dst {
2675                let elems_a: $dst = simd_as(simd_shuffle::<_, _, $shuffled>(
2676                    a,
2677                    a, // this argument is ignored entirely.
2678                    const { ShuffleMask::<$width>::$mask() },
2679                ));
2680
2681                let elems_b: $dst = simd_as(simd_shuffle::<_, _, $shuffled>(
2682                    b,
2683                    b, // this argument is ignored entirely.
2684                    const { ShuffleMask::<$width>::$mask() },
2685                ));
2686
2687                simd_mul(elems_a, elems_b)
2688            }
2689        };
2690    }
2691
2692    impl_vec_mul_even_odd! { even vmeb vector_signed_char i8x8 vector_signed_short 8 }
2693    impl_vec_mul_even_odd! { even vmeh vector_signed_short i16x4 vector_signed_int 4 }
2694    impl_vec_mul_even_odd! { even vmef vector_signed_int i32x2 vector_signed_long_long 2 }
2695
2696    impl_vec_mul_even_odd! { even vmleb vector_unsigned_char u8x8 vector_unsigned_short 8 }
2697    impl_vec_mul_even_odd! { even vmleh vector_unsigned_short u16x4 vector_unsigned_int 4 }
2698    impl_vec_mul_even_odd! { even vmlef vector_unsigned_int u32x2 vector_unsigned_long_long 2 }
2699
2700    impl_mul!([VectorMule vec_mule] vmeb (vector_signed_char, vector_signed_char) -> vector_signed_short );
2701    impl_mul!([VectorMule vec_mule] vmeh (vector_signed_short, vector_signed_short) -> vector_signed_int);
2702    impl_mul!([VectorMule vec_mule] vmef (vector_signed_int, vector_signed_int) -> vector_signed_long_long );
2703
2704    impl_mul!([VectorMule vec_mule] vmleb (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_short );
2705    impl_mul!([VectorMule vec_mule] vmleh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_int);
2706    impl_mul!([VectorMule vec_mule] vmlef (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_long_long );
2707
2708    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2709    pub trait VectorMulo<Result> {
2710        unsafe fn vec_mulo(self, b: Self) -> Result;
2711    }
2712
2713    impl_vec_mul_even_odd! { odd vmob vector_signed_char i8x8 vector_signed_short 8 }
2714    impl_vec_mul_even_odd! { odd vmoh vector_signed_short i16x4 vector_signed_int 4 }
2715    impl_vec_mul_even_odd! { odd vmof vector_signed_int i32x2 vector_signed_long_long 2 }
2716
2717    impl_vec_mul_even_odd! { odd vmlob vector_unsigned_char u8x8 vector_unsigned_short 8 }
2718    impl_vec_mul_even_odd! { odd vmloh vector_unsigned_short u16x4 vector_unsigned_int 4 }
2719    impl_vec_mul_even_odd! { odd vmlof vector_unsigned_int u32x2 vector_unsigned_long_long 2 }
2720
2721    impl_mul!([VectorMulo vec_mulo] vmob (vector_signed_char, vector_signed_char) -> vector_signed_short );
2722    impl_mul!([VectorMulo vec_mulo] vmoh (vector_signed_short, vector_signed_short) -> vector_signed_int);
2723    impl_mul!([VectorMulo vec_mulo] vmof (vector_signed_int, vector_signed_int) -> vector_signed_long_long );
2724
2725    impl_mul!([VectorMulo vec_mulo] vmlob (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_short );
2726    impl_mul!([VectorMulo vec_mulo] vmloh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_int);
2727    impl_mul!([VectorMulo vec_mulo] vmlof (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_long_long );
2728
2729    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2730    pub trait VectorMulh<Result> {
2731        unsafe fn vec_mulh(self, b: Self) -> Result;
2732    }
2733
2734    test_impl! { vec_vmhb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [ vmhb, vmhb ] }
2735    test_impl! { vec_vmhh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [ vmhh, vmhh ] }
2736    test_impl! { vec_vmhf(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [ vmhf, vmhf ] }
2737
2738    test_impl! { vec_vmlhb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [ vmlhb, vmlhb ] }
2739    test_impl! { vec_vmlhh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [ vmlhh, vmlhh ] }
2740    test_impl! { vec_vmlhf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [ vmlhf, vmlhf ] }
2741
2742    impl_mul!([VectorMulh vec_mulh] vec_vmhb (vector_signed_char, vector_signed_char) -> vector_signed_char);
2743    impl_mul!([VectorMulh vec_mulh] vec_vmhh (vector_signed_short, vector_signed_short) -> vector_signed_short);
2744    impl_mul!([VectorMulh vec_mulh] vec_vmhf (vector_signed_int, vector_signed_int) -> vector_signed_int);
2745
2746    impl_mul!([VectorMulh vec_mulh] vec_vmlhb (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char);
2747    impl_mul!([VectorMulh vec_mulh] vec_vmlhh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short);
2748    impl_mul!([VectorMulh vec_mulh] vec_vmlhf (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int);
2749
2750    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2751    pub trait VectorMeadd {
2752        type Result;
2753        unsafe fn vec_meadd(self, b: Self, c: Self::Result) -> Self::Result;
2754    }
2755
2756    test_impl! { vec_vmaeb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_short) -> vector_signed_short [ vmaeb, vmaeb ] }
2757    test_impl! { vec_vmaeh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_int) -> vector_signed_int[ vmaeh, vmaeh ] }
2758    test_impl! { vec_vmaef(a: vector_signed_int, b: vector_signed_int, c: vector_signed_long_long) -> vector_signed_long_long [ vmaef, vmaef ] }
2759
2760    test_impl! { vec_vmaleb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_short) -> vector_unsigned_short [ vmaleb, vmaleb ] }
2761    test_impl! { vec_vmaleh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_int) -> vector_unsigned_int[ vmaleh, vmaleh ] }
2762    test_impl! { vec_vmalef(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_long_long) -> vector_unsigned_long_long [ vmalef, vmalef ] }
2763
2764    impl_mul!([VectorMeadd vec_meadd] vec_vmaeb (vector_signed_char, vector_signed_char, vector_signed_short) -> vector_signed_short );
2765    impl_mul!([VectorMeadd vec_meadd] vec_vmaeh (vector_signed_short, vector_signed_short, vector_signed_int) -> vector_signed_int);
2766    impl_mul!([VectorMeadd vec_meadd] vec_vmaef (vector_signed_int, vector_signed_int, vector_signed_long_long) -> vector_signed_long_long );
2767
2768    impl_mul!([VectorMeadd vec_meadd] vec_vmaleb (vector_unsigned_char, vector_unsigned_char, vector_unsigned_short) -> vector_unsigned_short );
2769    impl_mul!([VectorMeadd vec_meadd] vec_vmaleh (vector_unsigned_short, vector_unsigned_short, vector_unsigned_int) -> vector_unsigned_int);
2770    impl_mul!([VectorMeadd vec_meadd] vec_vmalef (vector_unsigned_int, vector_unsigned_int, vector_unsigned_long_long) -> vector_unsigned_long_long );
2771
2772    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2773    pub trait VectorMoadd {
2774        type Result;
2775        unsafe fn vec_moadd(self, b: Self, c: Self::Result) -> Self::Result;
2776    }
2777
2778    test_impl! { vec_vmaob(a: vector_signed_char, b: vector_signed_char, c: vector_signed_short) -> vector_signed_short [ vmaob, vmaob ] }
2779    test_impl! { vec_vmaoh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_int) -> vector_signed_int[ vmaoh, vmaoh ] }
2780    test_impl! { vec_vmaof(a: vector_signed_int, b: vector_signed_int, c: vector_signed_long_long) -> vector_signed_long_long [ vmaof, vmaof ] }
2781
2782    test_impl! { vec_vmalob(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_short) -> vector_unsigned_short [ vmalob, vmalob ] }
2783    test_impl! { vec_vmaloh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_int) -> vector_unsigned_int[ vmaloh, vmaloh ] }
2784    test_impl! { vec_vmalof(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_long_long) -> vector_unsigned_long_long [ vmalof, vmalof ] }
2785
2786    impl_mul!([VectorMoadd vec_moadd] vec_vmaob (vector_signed_char, vector_signed_char, vector_signed_short) -> vector_signed_short );
2787    impl_mul!([VectorMoadd vec_moadd] vec_vmaoh (vector_signed_short, vector_signed_short, vector_signed_int) -> vector_signed_int);
2788    impl_mul!([VectorMoadd vec_moadd] vec_vmaof (vector_signed_int, vector_signed_int, vector_signed_long_long) -> vector_signed_long_long );
2789
2790    impl_mul!([VectorMoadd vec_moadd] vec_vmalob (vector_unsigned_char, vector_unsigned_char, vector_unsigned_short) -> vector_unsigned_short );
2791    impl_mul!([VectorMoadd vec_moadd] vec_vmaloh (vector_unsigned_short, vector_unsigned_short, vector_unsigned_int) -> vector_unsigned_int);
2792    impl_mul!([VectorMoadd vec_moadd] vec_vmalof (vector_unsigned_int, vector_unsigned_int, vector_unsigned_long_long) -> vector_unsigned_long_long );
2793
2794    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2795    pub trait VectorMhadd {
2796        type Result;
2797        unsafe fn vec_mhadd(self, b: Self, c: Self::Result) -> Self::Result;
2798    }
2799
2800    test_impl! { vec_vmahb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char) -> vector_signed_char [ vmahb, vmahb ] }
2801    test_impl! { vec_vmahh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short) -> vector_signed_short[ vmahh, vmahh ] }
2802    test_impl! { vec_vmahf(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int) -> vector_signed_int [ vmahf, vmahf ] }
2803
2804    test_impl! { vec_vmalhb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> vector_unsigned_char [ vmalhb, vmalhb ] }
2805    test_impl! { vec_vmalhh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short[ vmalhh, vmalhh ] }
2806    test_impl! { vec_vmalhf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int [ vmalhf, vmalhf ] }
2807
2808    impl_mul!([VectorMhadd vec_mhadd] vec_vmahb (vector_signed_char, vector_signed_char, vector_signed_char) -> vector_signed_char );
2809    impl_mul!([VectorMhadd vec_mhadd] vec_vmahh (vector_signed_short, vector_signed_short, vector_signed_short) -> vector_signed_short);
2810    impl_mul!([VectorMhadd vec_mhadd] vec_vmahf (vector_signed_int, vector_signed_int, vector_signed_int) -> vector_signed_int );
2811
2812    impl_mul!([VectorMhadd vec_mhadd] vec_vmalhb (vector_unsigned_char, vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char );
2813    impl_mul!([VectorMhadd vec_mhadd] vec_vmalhh (vector_unsigned_short, vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short);
2814    impl_mul!([VectorMhadd vec_mhadd] vec_vmalhf (vector_unsigned_int, vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int );
2815
2816    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2817    pub trait VectorMladd {
2818        type Result;
2819        unsafe fn vec_mladd(self, b: Self, c: Self::Result) -> Self::Result;
2820    }
2821
2822    #[inline]
2823    #[target_feature(enable = "vector")]
2824    unsafe fn simd_mladd<T>(a: T, b: T, c: T) -> T {
2825        simd_add(simd_mul(a, b), c)
2826    }
2827
2828    test_impl! { vec_vmal_ib(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char) -> vector_signed_char [simd_mladd, vmalb ] }
2829    test_impl! { vec_vmal_ih(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short) -> vector_signed_short[simd_mladd, vmalhw ] }
2830    test_impl! { vec_vmal_if(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int) -> vector_signed_int [simd_mladd, vmalf ] }
2831
2832    test_impl! { vec_vmal_ub(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> vector_unsigned_char [simd_mladd, vmalb ] }
2833    test_impl! { vec_vmal_uh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short[simd_mladd, vmalhw ] }
2834    test_impl! { vec_vmal_uf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int [simd_mladd, vmalf ] }
2835
2836    impl_mul!([VectorMladd vec_mladd] vec_vmal_ib (vector_signed_char, vector_signed_char, vector_signed_char) -> vector_signed_char );
2837    impl_mul!([VectorMladd vec_mladd] vec_vmal_ih (vector_signed_short, vector_signed_short, vector_signed_short) -> vector_signed_short);
2838    impl_mul!([VectorMladd vec_mladd] vec_vmal_if (vector_signed_int, vector_signed_int, vector_signed_int) -> vector_signed_int );
2839
2840    impl_mul!([VectorMladd vec_mladd] vec_vmal_ub (vector_unsigned_char, vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char );
2841    impl_mul!([VectorMladd vec_mladd] vec_vmal_uh (vector_unsigned_short, vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short);
2842    impl_mul!([VectorMladd vec_mladd] vec_vmal_uf (vector_unsigned_int, vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int );
2843
2844    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2845    pub trait VectorGfmsum<Result> {
2846        unsafe fn vec_gfmsum(self, b: Self) -> Result;
2847    }
2848
2849    test_impl! { vec_vgfmb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_short [ vgfmb, vgfmb ] }
2850    test_impl! { vec_vgfmh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int[ vgfmh, vgfmh] }
2851    test_impl! { vec_vgfmf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long [ vgfmf, vgfmf ] }
2852
2853    impl_mul!([VectorGfmsum vec_gfmsum] vec_vgfmb (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_short );
2854    impl_mul!([VectorGfmsum vec_gfmsum] vec_vgfmh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_int);
2855    impl_mul!([VectorGfmsum vec_gfmsum] vec_vgfmf (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_long_long );
2856
2857    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2858    pub trait VectorGfmsumAccum {
2859        type Result;
2860        unsafe fn vec_gfmsum_accum(self, b: Self, c: Self::Result) -> Self::Result;
2861    }
2862
2863    test_impl! { vec_vgfmab(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_short) -> vector_unsigned_short [ vgfmab, vgfmab ] }
2864    test_impl! { vec_vgfmah(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_int) -> vector_unsigned_int[ vgfmah, vgfmah] }
2865    test_impl! { vec_vgfmaf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_long_long) -> vector_unsigned_long_long [ vgfmaf, vgfmaf ] }
2866
2867    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2868    impl VectorGfmsumAccum for vector_unsigned_char {
2869        type Result = vector_unsigned_short;
2870        #[inline]
2871        #[target_feature(enable = "vector")]
2872        unsafe fn vec_gfmsum_accum(self, b: Self, c: Self::Result) -> Self::Result {
2873            vec_vgfmab(self, b, c)
2874        }
2875    }
2876    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2877    impl VectorGfmsumAccum for vector_unsigned_short {
2878        type Result = vector_unsigned_int;
2879        #[inline]
2880        #[target_feature(enable = "vector")]
2881        unsafe fn vec_gfmsum_accum(self, b: Self, c: Self::Result) -> Self::Result {
2882            vec_vgfmah(self, b, c)
2883        }
2884    }
2885    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2886    impl VectorGfmsumAccum for vector_unsigned_int {
2887        type Result = vector_unsigned_long_long;
2888        #[inline]
2889        #[target_feature(enable = "vector")]
2890        unsafe fn vec_gfmsum_accum(self, b: Self, c: Self::Result) -> Self::Result {
2891            vec_vgfmaf(self, b, c)
2892        }
2893    }
2894
2895    #[inline]
2896    #[target_feature(enable = "vector")]
2897    #[cfg_attr(test, assert_instr(vgef, D = 3))]
2898    unsafe fn vgef<const D: u32>(
2899        a: vector_unsigned_int,
2900        b: vector_unsigned_int,
2901        c: *const u32,
2902    ) -> vector_unsigned_int {
2903        static_assert_uimm_bits!(D, 2);
2904        let offset: u32 = simd_extract(b, D);
2905        let ptr = c.byte_add(offset as usize);
2906        let value = ptr.read();
2907        simd_insert(a, D, value)
2908    }
2909
2910    #[inline]
2911    #[target_feature(enable = "vector")]
2912    #[cfg_attr(test, assert_instr(vgeg, D = 1))]
2913    unsafe fn vgeg<const D: u32>(
2914        a: vector_unsigned_long_long,
2915        b: vector_unsigned_long_long,
2916        c: *const u64,
2917    ) -> vector_unsigned_long_long {
2918        static_assert_uimm_bits!(D, 1);
2919        let offset: u64 = simd_extract(b, D);
2920        let ptr = c.byte_add(offset as usize);
2921        let value = ptr.read();
2922        simd_insert(a, D, value)
2923    }
2924
2925    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2926    pub trait VectorGatherElement {
2927        type Element;
2928        type Offset;
2929        unsafe fn vec_gather_element<const D: u32>(
2930            self,
2931            b: Self::Offset,
2932            c: *const Self::Element,
2933        ) -> Self;
2934    }
2935
2936    macro_rules! impl_vec_gather_element {
2937        ($($instr:ident $ty:ident)*) => {
2938            $(
2939                #[unstable(feature = "stdarch_s390x", issue = "135681")]
2940                impl VectorGatherElement for $ty {
2941                    type Element = l_t_t!($ty);
2942                    type Offset = t_u!($ty);
2943
2944                    #[inline]
2945                    #[target_feature(enable = "vector")]
2946                    unsafe fn vec_gather_element<const D: u32>(self, b: Self::Offset, c: *const Self::Element) -> Self {
2947                        transmute($instr::<D>(transmute(self), b, c.cast()))
2948                    }
2949                }
2950            )*
2951        }
2952    }
2953
2954    impl_vec_gather_element! {
2955        vgef vector_signed_int
2956        vgef vector_bool_int
2957        vgef vector_unsigned_int
2958
2959        vgeg vector_signed_long_long
2960        vgeg vector_bool_long_long
2961        vgeg vector_unsigned_long_long
2962
2963        vgef vector_float
2964        vgeg vector_double
2965    }
2966
2967    #[inline]
2968    #[target_feature(enable = "vector")]
2969    #[cfg_attr(test, assert_instr(vscef, D = 3))]
2970    unsafe fn vscef<const D: u32>(a: vector_unsigned_int, b: vector_unsigned_int, c: *mut u32) {
2971        static_assert_uimm_bits!(D, 2);
2972        let value = simd_extract(a, D);
2973        let offset: u32 = simd_extract(b, D);
2974        let ptr = c.byte_add(offset as usize);
2975        ptr.write(value);
2976    }
2977
2978    #[inline]
2979    #[target_feature(enable = "vector")]
2980    #[cfg_attr(test, assert_instr(vsceg, D = 1))]
2981    unsafe fn vsceg<const D: u32>(
2982        a: vector_unsigned_long_long,
2983        b: vector_unsigned_long_long,
2984        c: *mut u64,
2985    ) {
2986        static_assert_uimm_bits!(D, 1);
2987        let value = simd_extract(a, D);
2988        let offset: u64 = simd_extract(b, D);
2989        let ptr = c.byte_add(offset as usize);
2990        ptr.write(value);
2991    }
2992
2993    #[unstable(feature = "stdarch_s390x", issue = "135681")]
2994    pub trait VectorScatterElement {
2995        type Element;
2996        type Offset;
2997        unsafe fn vec_scatter_element<const D: u32>(self, b: Self::Offset, c: *mut Self::Element);
2998    }
2999
3000    macro_rules! impl_vec_scatter_element {
3001        ($($instr:ident $ty:ident)*) => {
3002            $(
3003                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3004                impl VectorScatterElement for $ty {
3005                    type Element = l_t_t!($ty);
3006                    type Offset = t_u!($ty);
3007
3008                    #[inline]
3009                    #[target_feature(enable = "vector")]
3010                    unsafe fn vec_scatter_element<const D: u32>(self, b: Self::Offset, c: *mut Self::Element) {
3011                        $instr::<D>(transmute(self), b, c.cast())
3012                    }
3013                }
3014            )*
3015        }
3016    }
3017
3018    impl_vec_scatter_element! {
3019        vscef vector_signed_int
3020        vscef vector_bool_int
3021        vscef vector_unsigned_int
3022
3023        vsceg vector_signed_long_long
3024        vsceg vector_bool_long_long
3025        vsceg vector_unsigned_long_long
3026
3027        vscef vector_float
3028        vsceg vector_double
3029    }
3030
3031    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3032    pub trait VectorSel<Mask>: Sized {
3033        unsafe fn vec_sel(self, b: Self, c: Mask) -> Self;
3034    }
3035
3036    macro_rules! impl_vec_sel {
3037        ($($ty:ident)*) => {
3038            $(
3039                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3040                impl VectorSel<t_u!($ty)> for $ty {
3041                    #[inline]
3042                    #[target_feature(enable = "vector")]
3043                    unsafe fn vec_sel(self, b: Self, c: t_u!($ty)) -> Self {
3044                        let b = simd_and(transmute(b), c);
3045                        let a = simd_and(transmute(self), simd_xor(c, transmute(vector_signed_char([!0; 16]))));
3046                        transmute(simd_or(a, b))
3047                    }
3048                }
3049
3050                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3051                impl VectorSel<t_b!($ty)> for $ty {
3052                    #[inline]
3053                    #[target_feature(enable = "vector")]
3054                    unsafe fn vec_sel(self, b: Self, c: t_b!($ty)) -> Self {
3055                        // defer to the implementation with an unsigned mask
3056                        self.vec_sel(b, transmute::<_, t_u!($ty)>(c))
3057                    }
3058                }
3059            )*
3060        }
3061    }
3062
3063    impl_vec_sel! {
3064        vector_signed_char
3065        vector_signed_short
3066        vector_signed_int
3067        vector_signed_long_long
3068
3069        vector_unsigned_char
3070        vector_unsigned_short
3071        vector_unsigned_int
3072        vector_unsigned_long_long
3073
3074        vector_bool_char
3075        vector_bool_short
3076        vector_bool_int
3077        vector_bool_long_long
3078
3079        vector_float
3080        vector_double
3081    }
3082
3083    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3084    pub trait VectorFpTestDataClass {
3085        type Result;
3086        unsafe fn vec_fp_test_data_class<const CLASS: u32>(self) -> (Self::Result, i32);
3087    }
3088
3089    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3090    impl VectorFpTestDataClass for vector_float {
3091        type Result = vector_bool_int;
3092
3093        #[inline]
3094        #[target_feature(enable = "vector")]
3095        unsafe fn vec_fp_test_data_class<const CLASS: u32>(self) -> (Self::Result, i32) {
3096            let PackedTuple { x, y } = vftcisb(self, CLASS);
3097            (x, y)
3098        }
3099    }
3100
3101    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3102    impl VectorFpTestDataClass for vector_double {
3103        type Result = vector_bool_long_long;
3104
3105        #[inline]
3106        #[target_feature(enable = "vector")]
3107        unsafe fn vec_fp_test_data_class<const CLASS: u32>(self) -> (Self::Result, i32) {
3108            let PackedTuple { x, y } = vftcidb(self, CLASS);
3109            (x, y)
3110        }
3111    }
3112
3113    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3114    pub trait VectorCompare {
3115        unsafe fn vec_all_lt(self, other: Self) -> i32;
3116        unsafe fn vec_all_le(self, other: Self) -> i32;
3117        unsafe fn vec_all_gt(self, other: Self) -> i32;
3118        unsafe fn vec_all_ge(self, other: Self) -> i32;
3119    }
3120
3121    // NOTE: this implementation is currently non-optimal, but it does work for floats even with
3122    // only `vector` enabled.
3123    //
3124    // - https://github.com/llvm/llvm-project/issues/129434
3125    // - https://github.com/llvm/llvm-project/issues/130424
3126    macro_rules! impl_vec_compare {
3127        ($($ty:ident)*) => {
3128            $(
3129                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3130                impl VectorCompare for $ty {
3131                    #[inline]
3132                    #[target_feature(enable = "vector")]
3133                    unsafe fn vec_all_lt(self, other: Self) -> i32 {
3134                        simd_reduce_all(simd_lt::<_, t_b!($ty)>(self, other)) as i32
3135                    }
3136                    #[inline]
3137                    #[target_feature(enable = "vector")]
3138                    unsafe fn vec_all_le(self, other: Self) -> i32 {
3139                        simd_reduce_all(simd_le::<_, t_b!($ty)>(self, other)) as i32
3140                    }
3141                    #[inline]
3142                    #[target_feature(enable = "vector")]
3143                    unsafe fn vec_all_gt(self, other: Self) -> i32 {
3144                        simd_reduce_all(simd_gt::<_, t_b!($ty)>(self, other)) as i32
3145                    }
3146                    #[inline]
3147                    #[target_feature(enable = "vector")]
3148                    unsafe fn vec_all_ge(self, other: Self) -> i32 {
3149                        simd_reduce_all(simd_ge::<_, t_b!($ty)>(self, other)) as i32
3150                    }
3151                }
3152            )*
3153        }
3154    }
3155
3156    impl_vec_compare! {
3157        vector_signed_char
3158        vector_unsigned_char
3159
3160        vector_signed_short
3161        vector_unsigned_short
3162
3163        vector_signed_int
3164        vector_unsigned_int
3165        vector_float
3166
3167        vector_signed_long_long
3168        vector_unsigned_long_long
3169        vector_double
3170    }
3171
3172    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3173    pub trait VectorTestMask {
3174        type Mask;
3175        unsafe fn vec_test_mask(self, other: Self::Mask) -> i32;
3176    }
3177
3178    macro_rules! impl_vec_test_mask {
3179        ($($instr:ident $ty:ident)*) => {
3180            $(
3181                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3182                impl VectorTestMask for $ty {
3183                    type Mask = t_u!($ty);
3184
3185                    #[inline]
3186                    #[target_feature(enable = "vector")]
3187                    unsafe fn vec_test_mask(self, other: Self::Mask) -> i32 {
3188                        vtm(transmute(self), transmute(other))
3189                    }
3190                }
3191            )*
3192        }
3193    }
3194
3195    impl_vec_test_mask! {
3196        vector_signed_char
3197        vector_signed_short
3198        vector_signed_int
3199        vector_signed_long_long
3200
3201        vector_unsigned_char
3202        vector_unsigned_short
3203        vector_unsigned_int
3204        vector_unsigned_long_long
3205
3206        vector_float
3207        vector_double
3208    }
3209
3210    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3211    pub trait VectorSearchString {
3212        unsafe fn vec_search_string_cc(
3213            self,
3214            b: Self,
3215            c: vector_unsigned_char,
3216        ) -> (vector_unsigned_char, i32);
3217
3218        unsafe fn vec_search_string_until_zero_cc(
3219            self,
3220            b: Self,
3221            c: vector_unsigned_char,
3222        ) -> (vector_unsigned_char, i32);
3223    }
3224
3225    macro_rules! impl_vec_search_string{
3226        ($($intr_s:ident $intr_sz:ident $ty:ident)*) => {
3227            $(
3228                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3229                impl VectorSearchString for $ty {
3230                    #[inline]
3231                    #[target_feature(enable = "vector-enhancements-2")]
3232                    unsafe fn vec_search_string_cc(self, b: Self, c: vector_unsigned_char) -> (vector_unsigned_char, i32) {
3233                        let PackedTuple { x,y } = $intr_s(transmute(self), transmute(b), c);
3234                        (x, y)
3235                    }
3236
3237                    #[inline]
3238                    #[target_feature(enable = "vector-enhancements-2")]
3239                    unsafe fn vec_search_string_until_zero_cc(self, b: Self, c: vector_unsigned_char) -> (vector_unsigned_char, i32) {
3240                        let PackedTuple { x,y } = $intr_sz(transmute(self), transmute(b), c);
3241                        (x, y)
3242                    }
3243                }
3244
3245            )*
3246        }
3247    }
3248
3249    impl_vec_search_string! {
3250        vstrsb vstrszb vector_signed_char
3251        vstrsb vstrszb vector_bool_char
3252        vstrsb vstrszb vector_unsigned_char
3253
3254        vstrsh vstrszh vector_signed_short
3255        vstrsh vstrszh vector_bool_short
3256        vstrsh vstrszh vector_unsigned_short
3257
3258        vstrsf vstrszf vector_signed_int
3259        vstrsf vstrszf vector_bool_int
3260        vstrsf vstrszf vector_unsigned_int
3261    }
3262
3263    #[inline]
3264    #[target_feature(enable = "vector")]
3265    #[cfg_attr(test, assert_instr(vcdgb))]
3266    pub unsafe fn vcdgb(a: vector_signed_long_long) -> vector_double {
3267        simd_as(a)
3268    }
3269
3270    #[inline]
3271    #[target_feature(enable = "vector")]
3272    #[cfg_attr(test, assert_instr(vcdlgb))]
3273    pub unsafe fn vcdlgb(a: vector_unsigned_long_long) -> vector_double {
3274        simd_as(a)
3275    }
3276
3277    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3278    pub trait VectorDouble {
3279        unsafe fn vec_double(self) -> vector_double;
3280    }
3281
3282    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3283    impl VectorDouble for vector_signed_long_long {
3284        #[inline]
3285        #[target_feature(enable = "vector")]
3286        unsafe fn vec_double(self) -> vector_double {
3287            vcdgb(self)
3288        }
3289    }
3290
3291    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3292    impl VectorDouble for vector_unsigned_long_long {
3293        #[inline]
3294        #[target_feature(enable = "vector")]
3295        unsafe fn vec_double(self) -> vector_double {
3296            vcdlgb(self)
3297        }
3298    }
3299
3300    #[inline]
3301    #[target_feature(enable = "vector")]
3302    #[cfg_attr(
3303        all(test, target_feature = "vector-enhancements-2"),
3304        assert_instr(vcefb)
3305    )]
3306    pub unsafe fn vcefb(a: vector_signed_int) -> vector_float {
3307        simd_as(a)
3308    }
3309
3310    #[inline]
3311    #[target_feature(enable = "vector")]
3312    #[cfg_attr(
3313        all(test, target_feature = "vector-enhancements-2"),
3314        assert_instr(vcelfb)
3315    )]
3316    pub unsafe fn vcelfb(a: vector_unsigned_int) -> vector_float {
3317        simd_as(a)
3318    }
3319
3320    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3321    pub trait VectorFloat {
3322        unsafe fn vec_float(self) -> vector_float;
3323    }
3324
3325    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3326    impl VectorFloat for vector_signed_int {
3327        #[inline]
3328        #[target_feature(enable = "vector")]
3329        unsafe fn vec_float(self) -> vector_float {
3330            vcefb(self)
3331        }
3332    }
3333
3334    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3335    impl VectorFloat for vector_unsigned_int {
3336        #[inline]
3337        #[target_feature(enable = "vector")]
3338        unsafe fn vec_float(self) -> vector_float {
3339            vcelfb(self)
3340        }
3341    }
3342
3343    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3344    pub trait VectorExtendSigned64 {
3345        unsafe fn vec_extend_s64(self) -> vector_signed_long_long;
3346    }
3347
3348    #[inline]
3349    #[target_feature(enable = "vector")]
3350    #[cfg_attr(test, assert_instr(vsegb))]
3351    pub unsafe fn vsegb(a: vector_signed_char) -> vector_signed_long_long {
3352        simd_as(simd_shuffle::<_, _, i8x2>(
3353            a,
3354            a,
3355            const { u32x2::from_array([7, 15]) },
3356        ))
3357    }
3358
3359    #[inline]
3360    #[target_feature(enable = "vector")]
3361    #[cfg_attr(test, assert_instr(vsegh))]
3362    pub unsafe fn vsegh(a: vector_signed_short) -> vector_signed_long_long {
3363        simd_as(simd_shuffle::<_, _, i16x2>(
3364            a,
3365            a,
3366            const { u32x2::from_array([3, 7]) },
3367        ))
3368    }
3369
3370    #[inline]
3371    #[target_feature(enable = "vector")]
3372    #[cfg_attr(test, assert_instr(vsegf))]
3373    pub unsafe fn vsegf(a: vector_signed_int) -> vector_signed_long_long {
3374        simd_as(simd_shuffle::<_, _, i32x2>(
3375            a,
3376            a,
3377            const { u32x2::from_array([1, 3]) },
3378        ))
3379    }
3380
3381    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3382    impl VectorExtendSigned64 for vector_signed_char {
3383        #[inline]
3384        #[target_feature(enable = "vector")]
3385        unsafe fn vec_extend_s64(self) -> vector_signed_long_long {
3386            vsegb(self)
3387        }
3388    }
3389    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3390    impl VectorExtendSigned64 for vector_signed_short {
3391        #[inline]
3392        #[target_feature(enable = "vector")]
3393        unsafe fn vec_extend_s64(self) -> vector_signed_long_long {
3394            vsegh(self)
3395        }
3396    }
3397    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3398    impl VectorExtendSigned64 for vector_signed_int {
3399        #[inline]
3400        #[target_feature(enable = "vector")]
3401        unsafe fn vec_extend_s64(self) -> vector_signed_long_long {
3402            vsegf(self)
3403        }
3404    }
3405
3406    // NOTE: VectorSigned and VectorUnsigned make strong safety assumptions around floats.
3407    // This is what C provides, but even IBM does not clearly document these constraints.
3408    //
3409    // https://doc.rust-lang.org/std/intrinsics/simd/fn.simd_cast.html
3410
3411    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3412    pub trait VectorSigned {
3413        type Result;
3414        unsafe fn vec_signed(self) -> Self::Result;
3415    }
3416
3417    test_impl! { vcgsb (a: vector_float) -> vector_signed_int [simd_cast, "vector-enhancements-2" vcgsb] }
3418    test_impl! { vcgdb (a: vector_double) -> vector_signed_long_long [simd_cast, vcgdb] }
3419
3420    impl_vec_trait! { [VectorSigned vec_signed] vcgsb (vector_float) -> vector_signed_int }
3421    impl_vec_trait! { [VectorSigned vec_signed] vcgdb (vector_double) -> vector_signed_long_long }
3422
3423    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3424    pub trait VectorUnsigned {
3425        type Result;
3426        unsafe fn vec_unsigned(self) -> Self::Result;
3427    }
3428
3429    test_impl! { vclgsb (a: vector_float) -> vector_unsigned_int [simd_cast, "vector-enhancements-2" vclgsb] }
3430    test_impl! { vclgdb (a: vector_double) -> vector_unsigned_long_long [simd_cast, vclgdb] }
3431
3432    impl_vec_trait! { [VectorUnsigned vec_unsigned] vclgsb (vector_float) -> vector_unsigned_int }
3433    impl_vec_trait! { [VectorUnsigned vec_unsigned] vclgdb (vector_double) -> vector_unsigned_long_long }
3434
3435    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3436    pub trait VectorCopyUntilZero {
3437        unsafe fn vec_cp_until_zero(self) -> Self;
3438    }
3439
3440    test_impl! { vec_vistrb (a: vector_unsigned_char) -> vector_unsigned_char [vistrb, vistrb] }
3441    test_impl! { vec_vistrh (a: vector_unsigned_short) -> vector_unsigned_short [vistrh, vistrh] }
3442    test_impl! { vec_vistrf (a: vector_unsigned_int) -> vector_unsigned_int [vistrf, vistrf] }
3443
3444    impl_vec_trait! { [VectorCopyUntilZero vec_cp_until_zero]+ vec_vistrb (vector_signed_char) }
3445    impl_vec_trait! { [VectorCopyUntilZero vec_cp_until_zero]+ vec_vistrb (vector_bool_char) }
3446    impl_vec_trait! { [VectorCopyUntilZero vec_cp_until_zero]+ vec_vistrb (vector_unsigned_char) }
3447
3448    impl_vec_trait! { [VectorCopyUntilZero vec_cp_until_zero]+ vec_vistrh (vector_signed_short) }
3449    impl_vec_trait! { [VectorCopyUntilZero vec_cp_until_zero]+ vec_vistrh (vector_bool_short) }
3450    impl_vec_trait! { [VectorCopyUntilZero vec_cp_until_zero]+ vec_vistrh (vector_unsigned_short) }
3451
3452    impl_vec_trait! { [VectorCopyUntilZero vec_cp_until_zero]+ vec_vistrf (vector_signed_int) }
3453    impl_vec_trait! { [VectorCopyUntilZero vec_cp_until_zero]+ vec_vistrf (vector_bool_int) }
3454    impl_vec_trait! { [VectorCopyUntilZero vec_cp_until_zero]+ vec_vistrf (vector_unsigned_int) }
3455
3456    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3457    pub trait VectorCopyUntilZeroCC: Sized {
3458        unsafe fn vec_cp_until_zero_cc(self) -> (Self, i32);
3459    }
3460
3461    test_impl! { vec_vistrbs (a: vector_unsigned_char) -> PackedTuple<vector_unsigned_char, i32> [vistrbs, vistrbs] }
3462    test_impl! { vec_vistrhs (a: vector_unsigned_short) -> PackedTuple<vector_unsigned_short, i32> [vistrhs, vistrhs] }
3463    test_impl! { vec_vistrfs (a: vector_unsigned_int) -> PackedTuple<vector_unsigned_int, i32> [vistrfs, vistrfs] }
3464
3465    macro_rules! impl_vec_copy_until_zero_cc {
3466        ($($intr:ident $ty:ident)*) => {
3467            $(
3468                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3469                impl VectorCopyUntilZeroCC for $ty {
3470                    #[inline]
3471                    #[target_feature(enable = "vector")]
3472                    unsafe fn vec_cp_until_zero_cc(self) -> (Self, i32) {
3473                        let PackedTuple { x,y } = $intr(transmute(self));
3474                        (transmute(x), y)
3475                    }
3476                }
3477
3478            )*
3479        }
3480    }
3481
3482    impl_vec_copy_until_zero_cc! {
3483        vec_vistrbs vector_signed_char
3484        vec_vistrbs vector_bool_char
3485        vec_vistrbs vector_unsigned_char
3486
3487        vec_vistrhs vector_signed_short
3488        vec_vistrhs vector_bool_short
3489        vec_vistrhs vector_unsigned_short
3490
3491        vec_vistrfs vector_signed_int
3492        vec_vistrfs vector_bool_int
3493        vec_vistrfs vector_unsigned_int
3494    }
3495
3496    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3497    pub trait VectorSrdb {
3498        unsafe fn vec_srdb<const C: u32>(self, b: Self) -> Self;
3499    }
3500
3501    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3502    pub trait VectorSld {
3503        unsafe fn vec_sld<const C: u32>(self, b: Self) -> Self;
3504
3505        unsafe fn vec_sldw<const C: u32>(self, b: Self) -> Self;
3506
3507        unsafe fn vec_sldb<const C: u32>(self, b: Self) -> Self;
3508    }
3509
3510    #[inline]
3511    #[target_feature(enable = "vector")]
3512    #[cfg_attr(test, assert_instr(vsldb))]
3513    unsafe fn test_vec_sld(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
3514        a.vec_sld::<13>(b)
3515    }
3516
3517    #[inline]
3518    #[target_feature(enable = "vector")]
3519    #[cfg_attr(test, assert_instr(vsldb))]
3520    unsafe fn test_vec_sldw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
3521        a.vec_sldw::<3>(b)
3522    }
3523
3524    #[inline]
3525    #[target_feature(enable = "vector-enhancements-2")]
3526    #[cfg_attr(test, assert_instr(vsld))]
3527    unsafe fn test_vec_sldb(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
3528        a.vec_sldb::<7>(b)
3529    }
3530
3531    #[inline]
3532    #[target_feature(enable = "vector-enhancements-2")]
3533    #[cfg_attr(test, assert_instr(vsrd))]
3534    unsafe fn test_vec_srdb(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
3535        a.vec_srdb::<7>(b)
3536    }
3537
3538    macro_rules! impl_vec_sld {
3539        ($($ty:ident)*) => {
3540            $(
3541                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3542                impl VectorSld for $ty {
3543                    #[inline]
3544                    #[target_feature(enable = "vector")]
3545                    unsafe fn vec_sld<const C: u32>(self, b: Self) -> Self {
3546                        static_assert_uimm_bits!(C, 4);
3547                        transmute(u128::funnel_shl(transmute(self), transmute(b), C  * 8))
3548                    }
3549
3550                    #[inline]
3551                    #[target_feature(enable = "vector")]
3552                    unsafe fn vec_sldw<const C: u32>(self, b: Self) -> Self {
3553                        static_assert_uimm_bits!(C, 2);
3554                        transmute(u128::funnel_shl(transmute(self), transmute(b), C * 4 * 8))
3555                    }
3556
3557                    #[inline]
3558                    #[target_feature(enable = "vector-enhancements-2")]
3559                    unsafe fn vec_sldb<const C: u32>(self, b: Self) -> Self {
3560                        static_assert_uimm_bits!(C, 3);
3561                        transmute(u128::funnel_shl(transmute(self), transmute(b), C))
3562                    }
3563                }
3564
3565                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3566                impl VectorSrdb for $ty {
3567                    #[inline]
3568                    #[target_feature(enable = "vector-enhancements-2")]
3569                    unsafe fn vec_srdb<const C: u32>(self, b: Self) -> Self {
3570                        static_assert_uimm_bits!(C, 3);
3571                        transmute(vsrd(transmute(self), transmute(b), C))
3572                        // FIXME(llvm): https://github.com/llvm/llvm-project/issues/129955#issuecomment-3207488190
3573                        // LLVM currently rewrites `fshr` to `fshl`, and the logic in the s390x
3574                        // backend cannot deal with that yet.
3575                        // #[link_name = "llvm.fshr.i128"] fn fshr_i128(a: u128, b: u128, c: u128) -> u128;
3576                        // transmute(fshr_i128(transmute(self), transmute(b), const { C as u128 }))
3577                    }
3578                }
3579            )*
3580        }
3581    }
3582
3583    impl_vec_sld! {
3584        vector_signed_char
3585        vector_bool_char
3586        vector_unsigned_char
3587
3588        vector_signed_short
3589        vector_bool_short
3590        vector_unsigned_short
3591
3592        vector_signed_int
3593        vector_bool_int
3594        vector_unsigned_int
3595
3596        vector_signed_long_long
3597        vector_bool_long_long
3598        vector_unsigned_long_long
3599
3600        vector_float
3601        vector_double
3602    }
3603
3604    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3605    pub trait VectorCompareRange: Sized {
3606        type Result;
3607
3608        unsafe fn vstrc<const IMM: u32>(self, b: Self, c: Self) -> Self::Result;
3609        unsafe fn vstrcz<const IMM: u32>(self, b: Self, c: Self) -> Self::Result;
3610        unsafe fn vstrcs<const IMM: u32>(self, b: Self, c: Self) -> (Self::Result, i32);
3611        unsafe fn vstrczs<const IMM: u32>(self, b: Self, c: Self) -> (Self::Result, i32);
3612    }
3613
3614    const fn validate_compare_range_imm(imm: u32) {
3615        if !matches!(imm, 0 | 4 | 8 | 12) {
3616            panic!("IMM needs to be one of 0, 4, 8, 12");
3617        }
3618    }
3619
3620    macro_rules! impl_compare_range {
3621        ($($ty:ident $vstrc:ident $vstrcs:ident $vstrcz:ident $vstrczs:ident)*) => {
3622            $(
3623                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3624                impl VectorCompareRange for $ty {
3625                    type Result = t_b!($ty);
3626
3627                    #[inline]
3628                    #[target_feature(enable = "vector")]
3629                    unsafe fn vstrc<const IMM: u32>(self, b: Self, c: Self) -> Self::Result {
3630                        const { validate_compare_range_imm };
3631                        $vstrc(self, b, c, IMM)
3632                    }
3633
3634                    #[inline]
3635                    #[target_feature(enable = "vector")]
3636                    unsafe fn vstrcz<const IMM: u32>(self, b: Self, c: Self) -> Self::Result {
3637                        const { validate_compare_range_imm };
3638                        $vstrcz(self, b, c, IMM)
3639                    }
3640
3641                    #[inline]
3642                    #[target_feature(enable = "vector")]
3643                    unsafe fn vstrcs<const IMM: u32>(self, b: Self, c: Self) -> (Self::Result, i32) {
3644                        const { validate_compare_range_imm };
3645                        let PackedTuple { x, y } = $vstrcs(self, b, c, IMM);
3646                        (x,y)
3647                    }
3648
3649                    #[inline]
3650                    #[target_feature(enable = "vector")]
3651                    unsafe fn vstrczs<const IMM: u32>(self, b: Self, c: Self) -> (Self::Result, i32) {
3652                        const { validate_compare_range_imm };
3653                        let PackedTuple { x, y } = $vstrczs(self, b, c, IMM);
3654                        (x,y)
3655                    }
3656                }
3657            )*
3658        }
3659    }
3660
3661    impl_compare_range! {
3662        vector_unsigned_char    vstrcb vstrcbs vstrczb vstrczbs
3663        vector_unsigned_short   vstrch vstrchs vstrczh vstrczhs
3664        vector_unsigned_int     vstrcf vstrcfs vstrczf vstrczfs
3665    }
3666
3667    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3668    pub trait VectorComparePredicate: Sized {
3669        type Result;
3670
3671        #[inline]
3672        #[target_feature(enable = "vector")]
3673        unsafe fn vec_cmpgt(self, other: Self) -> Self::Result {
3674            simd_gt(self, other)
3675        }
3676
3677        #[inline]
3678        #[target_feature(enable = "vector")]
3679        unsafe fn vec_cmpge(self, other: Self) -> Self::Result {
3680            simd_ge(self, other)
3681        }
3682
3683        #[inline]
3684        #[target_feature(enable = "vector")]
3685        unsafe fn vec_cmplt(self, other: Self) -> Self::Result {
3686            simd_lt(self, other)
3687        }
3688
3689        #[inline]
3690        #[target_feature(enable = "vector")]
3691        unsafe fn vec_cmple(self, other: Self) -> Self::Result {
3692            simd_le(self, other)
3693        }
3694    }
3695
3696    macro_rules! impl_compare_predicate {
3697        ($($ty:ident)*) => {
3698            $(
3699                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3700                impl VectorComparePredicate for $ty {
3701                    type Result = t_b!($ty);
3702                }
3703            )*
3704        }
3705    }
3706
3707    impl_compare_predicate! {
3708        vector_signed_char
3709        vector_unsigned_char
3710
3711        vector_signed_short
3712        vector_unsigned_short
3713
3714        vector_signed_int
3715        vector_unsigned_int
3716        vector_float
3717
3718        vector_signed_long_long
3719        vector_unsigned_long_long
3720        vector_double
3721    }
3722
3723    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3724    pub trait VectorEquality: Sized {
3725        type Result;
3726
3727        #[inline]
3728        #[target_feature(enable = "vector")]
3729        unsafe fn vec_cmpeq(self, other: Self) -> Self::Result {
3730            simd_eq(self, other)
3731        }
3732
3733        #[inline]
3734        #[target_feature(enable = "vector")]
3735        unsafe fn vec_cmpne(self, other: Self) -> Self::Result {
3736            simd_ne(self, other)
3737        }
3738    }
3739
3740    macro_rules! impl_compare_equality {
3741        ($($ty:ident)*) => {
3742            $(
3743                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3744                impl VectorEquality for $ty {
3745                    type Result = t_b!($ty);
3746                }
3747            )*
3748        }
3749    }
3750
3751    impl_compare_equality! {
3752        vector_bool_char
3753        vector_signed_char
3754        vector_unsigned_char
3755
3756        vector_bool_short
3757        vector_signed_short
3758        vector_unsigned_short
3759
3760        vector_bool_int
3761        vector_signed_int
3762        vector_unsigned_int
3763        vector_float
3764
3765        vector_bool_long_long
3766        vector_signed_long_long
3767        vector_unsigned_long_long
3768        vector_double
3769    }
3770
3771    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3772    pub trait VectorEqualityIdx: Sized {
3773        type Result;
3774
3775        unsafe fn vec_cmpeq_idx(self, other: Self) -> Self::Result;
3776        unsafe fn vec_cmpne_idx(self, other: Self) -> Self::Result;
3777
3778        unsafe fn vec_cmpeq_idx_cc(self, other: Self) -> (Self::Result, i32);
3779        unsafe fn vec_cmpne_idx_cc(self, other: Self) -> (Self::Result, i32);
3780
3781        unsafe fn vec_cmpeq_or_0_idx(self, other: Self) -> Self::Result;
3782        unsafe fn vec_cmpne_or_0_idx(self, other: Self) -> Self::Result;
3783
3784        unsafe fn vec_cmpeq_or_0_idx_cc(self, other: Self) -> (Self::Result, i32);
3785        unsafe fn vec_cmpne_or_0_idx_cc(self, other: Self) -> (Self::Result, i32);
3786    }
3787
3788    macro_rules! impl_compare_equality_idx {
3789        ($($ty:ident $ret:ident
3790                $cmpeq:ident $cmpne:ident
3791                $cmpeq_or_0:ident $cmpne_or_0:ident
3792                $cmpeq_cc:ident $cmpne_cc:ident
3793                $cmpeq_or_0_cc:ident $cmpne_or_0_cc:ident
3794        )*) => {
3795            $(
3796                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3797                impl VectorEqualityIdx for $ty {
3798                    type Result = $ret;
3799
3800                    #[inline]
3801                    #[target_feature(enable = "vector")]
3802                    unsafe fn vec_cmpeq_idx(self, other: Self) -> Self::Result {
3803                        transmute($cmpeq(transmute(self), transmute(other)))
3804                    }
3805
3806                    #[inline]
3807                    #[target_feature(enable = "vector")]
3808                    unsafe fn vec_cmpne_idx(self, other: Self) -> Self::Result {
3809                        transmute($cmpne(transmute(self), transmute(other)))
3810                    }
3811
3812                    #[inline]
3813                    #[target_feature(enable = "vector")]
3814                    unsafe fn vec_cmpeq_or_0_idx(self, other: Self) -> Self::Result {
3815                        transmute($cmpeq_or_0(transmute(self), transmute(other)))
3816                    }
3817
3818                    #[inline]
3819                    #[target_feature(enable = "vector")]
3820                    unsafe fn vec_cmpne_or_0_idx(self, other: Self) -> Self::Result {
3821                        transmute($cmpne_or_0(transmute(self), transmute(other)))
3822                    }
3823
3824                    #[inline]
3825                    #[target_feature(enable = "vector")]
3826                    unsafe fn vec_cmpeq_idx_cc(self, other: Self) -> (Self::Result, i32) {
3827                        let PackedTuple { x, y } = $cmpeq_cc(transmute(self), transmute(other));
3828                        (transmute(x), y)
3829                    }
3830
3831                    #[inline]
3832                    #[target_feature(enable = "vector")]
3833                    unsafe fn vec_cmpne_idx_cc(self, other: Self) -> (Self::Result, i32) {
3834                        let PackedTuple { x, y } = $cmpne_cc(transmute(self), transmute(other));
3835                        (transmute(x),y)
3836                    }
3837
3838                    #[inline]
3839                    #[target_feature(enable = "vector")]
3840                    unsafe fn vec_cmpeq_or_0_idx_cc(self, other: Self) -> (Self::Result, i32) {
3841                        let PackedTuple { x, y } = $cmpeq_or_0_cc(transmute(self), transmute(other));
3842                        (transmute(x), y)
3843                    }
3844
3845                    #[inline]
3846                    #[target_feature(enable = "vector")]
3847                    unsafe fn vec_cmpne_or_0_idx_cc(self, other: Self) -> (Self::Result, i32) {
3848                        let PackedTuple { x, y } = $cmpne_or_0_cc(transmute(self), transmute(other));
3849                        (transmute(x),y)
3850                    }
3851                }
3852            )*
3853        }
3854    }
3855
3856    impl_compare_equality_idx! {
3857        vector_signed_char vector_signed_char               vfeeb vfeneb vfeezb vfenezb vfeebs vfenebs vfeezbs vfenezbs
3858        vector_bool_char vector_unsigned_char               vfeeb vfeneb vfeezb vfenezb vfeebs vfenebs vfeezbs vfenezbs
3859        vector_unsigned_char vector_unsigned_char           vfeeb vfeneb vfeezb vfenezb vfeebs vfenebs vfeezbs vfenezbs
3860        vector_signed_short vector_signed_short             vfeeh vfeneh vfeezh vfenezh vfeehs vfenehs vfeezhs vfenezhs
3861        vector_bool_short  vector_unsigned_short            vfeeh vfeneh vfeezh vfenezh vfeehs vfenehs vfeezhs vfenezhs
3862        vector_unsigned_short vector_unsigned_short         vfeeh vfeneh vfeezh vfenezh vfeehs vfenehs vfeezhs vfenezhs
3863        vector_signed_int vector_signed_int                 vfeef vfenef vfeezf vfenezf vfeefs vfenefs vfeezfs vfenezfs
3864        vector_bool_int  vector_unsigned_int                vfeef vfenef vfeezf vfenezf vfeefs vfenefs vfeezfs vfenezfs
3865        vector_unsigned_int vector_unsigned_int             vfeef vfenef vfeezf vfenezf vfeefs vfenefs vfeezfs vfenezfs
3866    }
3867
3868    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3869    pub trait VectorExtract {
3870        type ElementType;
3871
3872        unsafe fn vec_extract(a: Self, b: i32) -> Self::ElementType;
3873    }
3874
3875    #[inline]
3876    #[target_feature(enable = "vector")]
3877    #[cfg_attr(test, assert_instr(vlgvb))]
3878    unsafe fn vlgvb(a: vector_unsigned_char, b: i32) -> u8 {
3879        simd_extract_dyn(a, b as u32 % 16)
3880    }
3881
3882    #[inline]
3883    #[target_feature(enable = "vector")]
3884    #[cfg_attr(test, assert_instr(vlgvh))]
3885    unsafe fn vlgvh(a: vector_unsigned_short, b: i32) -> u16 {
3886        simd_extract_dyn(a, b as u32 % 8)
3887    }
3888
3889    #[inline]
3890    #[target_feature(enable = "vector")]
3891    #[cfg_attr(test, assert_instr(vlgvf))]
3892    unsafe fn vlgvf(a: vector_unsigned_int, b: i32) -> u32 {
3893        simd_extract_dyn(a, b as u32 % 4)
3894    }
3895
3896    #[inline]
3897    #[target_feature(enable = "vector")]
3898    #[cfg_attr(test, assert_instr(vlgvg))]
3899    unsafe fn vlgvg(a: vector_unsigned_long_long, b: i32) -> u64 {
3900        simd_extract_dyn(a, b as u32 % 2)
3901    }
3902
3903    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3904    pub trait VectorInsert {
3905        type ElementType;
3906
3907        unsafe fn vec_insert(a: Self::ElementType, b: Self, c: i32) -> Self;
3908    }
3909
3910    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3911    pub trait VectorPromote: Sized {
3912        type ElementType;
3913
3914        unsafe fn vec_promote(a: Self::ElementType, b: i32) -> MaybeUninit<Self>;
3915    }
3916
3917    #[inline]
3918    #[target_feature(enable = "vector")]
3919    #[cfg_attr(test, assert_instr(vlvgb))]
3920    unsafe fn vlvgb(a: u8, b: vector_unsigned_char, c: i32) -> vector_unsigned_char {
3921        simd_insert_dyn(b, c as u32 % 16, a)
3922    }
3923
3924    #[inline]
3925    #[target_feature(enable = "vector")]
3926    #[cfg_attr(test, assert_instr(vlvgh))]
3927    unsafe fn vlvgh(a: u16, b: vector_unsigned_short, c: i32) -> vector_unsigned_short {
3928        simd_insert_dyn(b, c as u32 % 8, a)
3929    }
3930
3931    #[inline]
3932    #[target_feature(enable = "vector")]
3933    #[cfg_attr(test, assert_instr(vlvgf))]
3934    unsafe fn vlvgf(a: u32, b: vector_unsigned_int, c: i32) -> vector_unsigned_int {
3935        simd_insert_dyn(b, c as u32 % 4, a)
3936    }
3937
3938    #[inline]
3939    #[target_feature(enable = "vector")]
3940    #[cfg_attr(test, assert_instr(vlvgg))]
3941    unsafe fn vlvgg(a: u64, b: vector_unsigned_long_long, c: i32) -> vector_unsigned_long_long {
3942        simd_insert_dyn(b, c as u32 % 2, a)
3943    }
3944
3945    #[unstable(feature = "stdarch_s390x", issue = "135681")]
3946    pub trait VectorInsertAndZero {
3947        type ElementType;
3948
3949        unsafe fn vec_insert_and_zero(a: *const Self::ElementType) -> Self;
3950    }
3951
3952    #[inline]
3953    #[target_feature(enable = "vector")]
3954    #[cfg_attr(test, assert_instr(vllezb))]
3955    unsafe fn vllezb(x: *const u8) -> vector_unsigned_char {
3956        vector_unsigned_char([0, 0, 0, 0, 0, 0, 0, *x, 0, 0, 0, 0, 0, 0, 0, 0])
3957    }
3958
3959    #[inline]
3960    #[target_feature(enable = "vector")]
3961    #[cfg_attr(test, assert_instr(vllezh))]
3962    unsafe fn vllezh(x: *const u16) -> vector_unsigned_short {
3963        vector_unsigned_short([0, 0, 0, *x, 0, 0, 0, 0])
3964    }
3965
3966    #[inline]
3967    #[target_feature(enable = "vector")]
3968    #[cfg_attr(test, assert_instr(vllezf))]
3969    unsafe fn vllezf(x: *const u32) -> vector_unsigned_int {
3970        vector_unsigned_int([0, *x, 0, 0])
3971    }
3972
3973    #[inline]
3974    #[target_feature(enable = "vector")]
3975    #[cfg_attr(test, assert_instr(vllezg))]
3976    unsafe fn vllezg(x: *const u64) -> vector_unsigned_long_long {
3977        vector_unsigned_long_long([*x, 0])
3978    }
3979
3980    macro_rules! impl_extract_insert {
3981        ($($ty:ident $extract_intr:ident $insert_intr:ident $insert_and_zero_intr:ident)*) => {
3982            $(
3983                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3984                impl VectorExtract for $ty {
3985                    type ElementType = l_t_t!($ty);
3986
3987                    #[inline]
3988                    #[target_feature(enable = "vector")]
3989                    unsafe fn vec_extract(a: Self, b: i32) -> Self::ElementType {
3990                        transmute($extract_intr(transmute(a), b))
3991                    }
3992                }
3993
3994                #[unstable(feature = "stdarch_s390x", issue = "135681")]
3995                impl VectorInsert for $ty {
3996                    type ElementType = l_t_t!($ty);
3997
3998                    #[inline]
3999                    #[target_feature(enable = "vector")]
4000                    unsafe fn vec_insert(a: Self::ElementType, b: Self, c: i32) -> Self {
4001                        transmute($insert_intr(transmute(a), transmute(b), c))
4002                    }
4003                }
4004
4005                #[unstable(feature = "stdarch_s390x", issue = "135681")]
4006                impl VectorInsertAndZero for $ty {
4007                    type ElementType = l_t_t!($ty);
4008
4009                    #[inline]
4010                    #[target_feature(enable = "vector")]
4011                    unsafe fn vec_insert_and_zero(a: *const Self::ElementType) -> Self {
4012                        transmute($insert_and_zero_intr(a.cast()))
4013                    }
4014                }
4015
4016                #[unstable(feature = "stdarch_s390x", issue = "135681")]
4017                impl VectorPromote for $ty {
4018                    type ElementType = l_t_t!($ty);
4019
4020                    #[inline]
4021                    #[target_feature(enable = "vector")]
4022                    unsafe fn vec_promote(a: Self::ElementType, c: i32) -> MaybeUninit<Self> {
4023                        // Rust does not currently support `MaybeUninit` element types to simd
4024                        // vectors. In C/LLVM that is allowed (using poison values). So rust will
4025                        // use an extra instruction to zero the memory.
4026                        let b = MaybeUninit::<$ty>::zeroed();
4027                        MaybeUninit::new(transmute($insert_intr(transmute(a), transmute(b), c)))
4028                    }
4029                }
4030            )*
4031        }
4032
4033    }
4034
4035    impl_extract_insert! {
4036        vector_signed_char          vlgvb vlvgb vllezb
4037        vector_unsigned_char        vlgvb vlvgb vllezb
4038        vector_signed_short         vlgvh vlvgh vllezh
4039        vector_unsigned_short       vlgvh vlvgh vllezh
4040        vector_signed_int           vlgvf vlvgf vllezf
4041        vector_unsigned_int         vlgvf vlvgf vllezf
4042        vector_signed_long_long     vlgvg vlvgg vllezg
4043        vector_unsigned_long_long   vlgvg vlvgg vllezg
4044        vector_float                vlgvf vlvgf vllezf
4045        vector_double               vlgvg vlvgg vllezg
4046    }
4047}
4048
4049/// Load Count to Block Boundary
4050#[inline]
4051#[target_feature(enable = "vector")]
4052#[unstable(feature = "stdarch_s390x", issue = "135681")]
4053#[cfg_attr(test, assert_instr(lcbb, BLOCK_BOUNDARY = 512))]
4054unsafe fn __lcbb<const BLOCK_BOUNDARY: u16>(ptr: *const u8) -> u32 {
4055    lcbb(ptr, const { validate_block_boundary(BLOCK_BOUNDARY) })
4056}
4057
4058/// Vector Add
4059#[inline]
4060#[target_feature(enable = "vector")]
4061#[unstable(feature = "stdarch_s390x", issue = "135681")]
4062pub unsafe fn vec_add<T: sealed::VectorAdd<U>, U>(a: T, b: U) -> T::Result {
4063    a.vec_add(b)
4064}
4065
4066/// Vector Subtract
4067#[inline]
4068#[target_feature(enable = "vector")]
4069#[unstable(feature = "stdarch_s390x", issue = "135681")]
4070pub unsafe fn vec_sub<T: sealed::VectorSub<U>, U>(a: T, b: U) -> T::Result {
4071    a.vec_sub(b)
4072}
4073
4074/// Vector Multiply
4075///
4076/// ## Purpose
4077/// Compute the products of corresponding elements of two vectors.
4078///
4079/// ## Result value
4080/// Each element of r receives the product of the corresponding elements of a and b.
4081#[inline]
4082#[target_feature(enable = "vector")]
4083#[unstable(feature = "stdarch_s390x", issue = "135681")]
4084pub unsafe fn vec_mul<T: sealed::VectorMul>(a: T, b: T) -> T {
4085    a.vec_mul(b)
4086}
4087
4088/// Vector Count Leading Zeros
4089#[inline]
4090#[target_feature(enable = "vector")]
4091#[unstable(feature = "stdarch_s390x", issue = "135681")]
4092pub unsafe fn vec_cntlz<T: sealed::CountBits>(a: T) -> T::Result {
4093    a.vec_cntlz()
4094}
4095
4096/// Vector Count Trailing Zeros
4097#[inline]
4098#[target_feature(enable = "vector")]
4099#[unstable(feature = "stdarch_s390x", issue = "135681")]
4100pub unsafe fn vec_cnttz<T: sealed::CountBits>(a: T) -> T::Result {
4101    a.vec_cnttz()
4102}
4103
4104/// Vector Population Count
4105///
4106/// Computes the population count (number of set bits) in each element of the input.
4107#[inline]
4108#[target_feature(enable = "vector")]
4109#[unstable(feature = "stdarch_s390x", issue = "135681")]
4110pub unsafe fn vec_popcnt<T: sealed::CountBits>(a: T) -> T::Result {
4111    a.vec_popcnt()
4112}
4113
4114/// Vector Maximum
4115#[inline]
4116#[target_feature(enable = "vector")]
4117#[unstable(feature = "stdarch_s390x", issue = "135681")]
4118pub unsafe fn vec_max<T: sealed::VectorMax<U>, U>(a: T, b: U) -> T::Result {
4119    a.vec_max(b)
4120}
4121
4122/// Vector  Minimum
4123#[inline]
4124#[target_feature(enable = "vector")]
4125#[unstable(feature = "stdarch_s390x", issue = "135681")]
4126pub unsafe fn vec_min<T: sealed::VectorMin<U>, U>(a: T, b: U) -> T::Result {
4127    a.vec_min(b)
4128}
4129
4130/// Vector Absolute
4131#[inline]
4132#[target_feature(enable = "vector")]
4133#[unstable(feature = "stdarch_s390x", issue = "135681")]
4134pub unsafe fn vec_abs<T: sealed::VectorAbs>(a: T) -> T {
4135    a.vec_abs()
4136}
4137
4138/// Vector Negative Absolute
4139#[inline]
4140#[target_feature(enable = "vector")]
4141#[unstable(feature = "stdarch_s390x", issue = "135681")]
4142pub unsafe fn vec_nabs<T: sealed::VectorNabs>(a: T) -> T {
4143    a.vec_nabs()
4144}
4145
4146/// Vector Negative Multiply Add
4147#[inline]
4148#[target_feature(enable = "vector")]
4149#[unstable(feature = "stdarch_s390x", issue = "135681")]
4150pub unsafe fn vec_nmadd<T: sealed::VectorNmadd>(a: T, b: T, c: T) -> T {
4151    a.vec_nmadd(b, c)
4152}
4153
4154/// Vector Negative Multiply Subtract
4155#[inline]
4156#[target_feature(enable = "vector")]
4157#[unstable(feature = "stdarch_s390x", issue = "135681")]
4158pub unsafe fn vec_nmsub<T: sealed::VectorNmsub>(a: T, b: T, c: T) -> T {
4159    a.vec_nmsub(b, c)
4160}
4161
4162/// Vector Square Root
4163#[inline]
4164#[target_feature(enable = "vector")]
4165#[unstable(feature = "stdarch_s390x", issue = "135681")]
4166pub unsafe fn vec_sqrt<T: sealed::VectorSqrt>(a: T) -> T {
4167    a.vec_sqrt()
4168}
4169
4170/// Vector Splat
4171#[inline]
4172#[target_feature(enable = "vector")]
4173#[unstable(feature = "stdarch_s390x", issue = "135681")]
4174pub unsafe fn vec_splat<T: sealed::VectorSplat, const IMM: u32>(a: T) -> T {
4175    a.vec_splat::<IMM>()
4176}
4177
4178/// Vector Splats
4179#[inline]
4180#[target_feature(enable = "vector")]
4181#[unstable(feature = "stdarch_s390x", issue = "135681")]
4182pub unsafe fn vec_splats<T: sealed::VectorSplats<U>, U>(a: T) -> U {
4183    a.vec_splats()
4184}
4185
4186/// Vector AND
4187#[inline]
4188#[target_feature(enable = "vector")]
4189#[unstable(feature = "stdarch_s390x", issue = "135681")]
4190pub unsafe fn vec_and<T: sealed::VectorAnd<U>, U>(a: T, b: U) -> T::Result {
4191    a.vec_and(b)
4192}
4193
4194/// Vector OR
4195#[inline]
4196#[target_feature(enable = "vector")]
4197#[unstable(feature = "stdarch_s390x", issue = "135681")]
4198pub unsafe fn vec_or<T: sealed::VectorOr<U>, U>(a: T, b: U) -> T::Result {
4199    a.vec_or(b)
4200}
4201
4202/// Vector XOR
4203#[inline]
4204#[target_feature(enable = "vector")]
4205#[unstable(feature = "stdarch_s390x", issue = "135681")]
4206pub unsafe fn vec_xor<T: sealed::VectorXor<U>, U>(a: T, b: U) -> T::Result {
4207    a.vec_xor(b)
4208}
4209
4210/// Vector NOR
4211#[inline]
4212#[target_feature(enable = "vector")]
4213#[unstable(feature = "stdarch_s390x", issue = "135681")]
4214pub unsafe fn vec_nor<T: sealed::VectorNor<U>, U>(a: T, b: U) -> T::Result {
4215    a.vec_nor(b)
4216}
4217
4218/// Vector NAND
4219#[inline]
4220#[target_feature(enable = "vector")]
4221#[unstable(feature = "stdarch_s390x", issue = "135681")]
4222pub unsafe fn vec_nand<T: sealed::VectorNand<U>, U>(a: T, b: U) -> T::Result {
4223    a.vec_nand(b)
4224}
4225
4226/// Vector XNOR
4227#[inline]
4228#[target_feature(enable = "vector")]
4229#[unstable(feature = "stdarch_s390x", issue = "135681")]
4230pub unsafe fn vec_eqv<T: sealed::VectorEqv<U>, U>(a: T, b: U) -> T::Result {
4231    a.vec_eqv(b)
4232}
4233
4234/// Vector ANDC
4235#[inline]
4236#[target_feature(enable = "vector")]
4237#[unstable(feature = "stdarch_s390x", issue = "135681")]
4238pub unsafe fn vec_andc<T: sealed::VectorAndc<U>, U>(a: T, b: U) -> T::Result {
4239    a.vec_andc(b)
4240}
4241
4242/// Vector OR with Complement
4243///
4244/// ## Purpose
4245/// Performs a bitwise OR of the first vector with the bitwise-complemented second vector.
4246///
4247/// ## Result value
4248/// r is the bitwise OR of a and the bitwise complement of b.
4249#[inline]
4250#[target_feature(enable = "vector")]
4251#[unstable(feature = "stdarch_s390x", issue = "135681")]
4252pub unsafe fn vec_orc<T: sealed::VectorOrc<U>, U>(a: T, b: U) -> T::Result {
4253    a.vec_orc(b)
4254}
4255
4256/// Vector Floor
4257#[inline]
4258#[target_feature(enable = "vector")]
4259#[unstable(feature = "stdarch_s390x", issue = "135681")]
4260pub unsafe fn vec_floor<T: sealed::VectorFloor>(a: T) -> T {
4261    a.vec_floor()
4262}
4263
4264/// Vector Ceil
4265#[inline]
4266#[target_feature(enable = "vector")]
4267#[unstable(feature = "stdarch_s390x", issue = "135681")]
4268pub unsafe fn vec_ceil<T: sealed::VectorCeil>(a: T) -> T {
4269    a.vec_ceil()
4270}
4271
4272/// Vector Truncate
4273///
4274/// Returns a vector containing the truncated values of the corresponding elements of the given vector.
4275/// Each element of the result contains the value of the corresponding element of a, truncated to an integral value.
4276#[inline]
4277#[target_feature(enable = "vector")]
4278#[unstable(feature = "stdarch_s390x", issue = "135681")]
4279pub unsafe fn vec_trunc<T: sealed::VectorTrunc>(a: T) -> T {
4280    a.vec_trunc()
4281}
4282
4283/// Vector Round
4284///
4285/// Returns a vector containing the rounded values to the nearest representable floating-point integer,
4286/// using IEEE round-to-nearest rounding, of the corresponding elements of the given vector
4287#[inline]
4288#[target_feature(enable = "vector")]
4289#[unstable(feature = "stdarch_s390x", issue = "135681")]
4290pub unsafe fn vec_round<T: sealed::VectorRound>(a: T) -> T {
4291    a.vec_round()
4292}
4293
4294/// Vector Round to Current
4295///
4296/// Returns a vector by using the current rounding mode to round every
4297/// floating-point element in the given vector to integer.
4298#[inline]
4299#[target_feature(enable = "vector")]
4300#[unstable(feature = "stdarch_s390x", issue = "135681")]
4301pub unsafe fn vec_roundc<T: sealed::VectorRoundc>(a: T) -> T {
4302    a.vec_roundc()
4303}
4304
4305/// Vector Round toward Negative Infinity
4306///
4307/// Returns a vector containing the largest representable floating-point integral values less
4308/// than or equal to the values of the corresponding elements of the given vector.
4309#[inline]
4310#[target_feature(enable = "vector")]
4311#[unstable(feature = "stdarch_s390x", issue = "135681")]
4312pub unsafe fn vec_roundm<T: sealed::VectorFloor>(a: T) -> T {
4313    // the IBM docs note
4314    //
4315    // > vec_roundm provides the same functionality as vec_floor, except that vec_roundz would not trigger the IEEE-inexact exception.
4316    //
4317    // but in practice `vec_floor` also does not trigger that exception, so both are equivalent
4318    a.vec_floor()
4319}
4320
4321/// Vector Round toward Positive Infinity
4322///
4323/// Returns a vector containing the smallest representable floating-point integral values greater
4324/// than or equal to the values of the corresponding elements of the given vector.
4325#[inline]
4326#[target_feature(enable = "vector")]
4327#[unstable(feature = "stdarch_s390x", issue = "135681")]
4328pub unsafe fn vec_roundp<T: sealed::VectorCeil>(a: T) -> T {
4329    // the IBM docs note
4330    //
4331    // > vec_roundp provides the same functionality as vec_ceil, except that vec_roundz would not trigger the IEEE-inexact exception.
4332    //
4333    // but in practice `vec_ceil` also does not trigger that exception, so both are equivalent
4334    a.vec_ceil()
4335}
4336
4337/// Vector Round toward Zero
4338///
4339/// Returns a vector containing the truncated values of the corresponding elements of the given vector.
4340/// Each element of the result contains the value of the corresponding element of a, truncated to an integral value.
4341#[inline]
4342#[target_feature(enable = "vector")]
4343#[unstable(feature = "stdarch_s390x", issue = "135681")]
4344pub unsafe fn vec_roundz<T: sealed::VectorTrunc>(a: T) -> T {
4345    // the IBM docs note
4346    //
4347    // > vec_roundz provides the same functionality as vec_trunc, except that vec_roundz would not trigger the IEEE-inexact exception.
4348    //
4349    // but in practice `vec_trunc` also does not trigger that exception, so both are equivalent
4350    a.vec_trunc()
4351}
4352
4353/// Vector Round to Integer
4354///
4355/// Returns a vector by using the current rounding mode to round every floating-point element in the given vector to integer.
4356#[inline]
4357#[target_feature(enable = "vector")]
4358#[unstable(feature = "stdarch_s390x", issue = "135681")]
4359pub unsafe fn vec_rint<T: sealed::VectorRint>(a: T) -> T {
4360    a.vec_rint()
4361}
4362
4363/// Vector Average
4364#[inline]
4365#[target_feature(enable = "vector")]
4366#[unstable(feature = "stdarch_s390x", issue = "135681")]
4367pub unsafe fn vec_avg<T: sealed::VectorAvg<U>, U>(a: T, b: U) -> T::Result {
4368    a.vec_avg(b)
4369}
4370
4371/// Vector Shift Left
4372#[inline]
4373#[target_feature(enable = "vector")]
4374#[unstable(feature = "stdarch_s390x", issue = "135681")]
4375pub unsafe fn vec_sl<T: sealed::VectorSl<U>, U>(a: T, b: U) -> T::Result {
4376    a.vec_sl(b)
4377}
4378
4379/// Vector Shift Right
4380#[inline]
4381#[target_feature(enable = "vector")]
4382#[unstable(feature = "stdarch_s390x", issue = "135681")]
4383pub unsafe fn vec_sr<T: sealed::VectorSr<U>, U>(a: T, b: U) -> T::Result {
4384    a.vec_sr(b)
4385}
4386
4387/// Vector Shift Right Algebraic
4388#[inline]
4389#[target_feature(enable = "vector")]
4390#[unstable(feature = "stdarch_s390x", issue = "135681")]
4391pub unsafe fn vec_sra<T: sealed::VectorSra<U>, U>(a: T, b: U) -> T::Result {
4392    a.vec_sra(b)
4393}
4394
4395/// Vector Shift Left by Byte
4396#[inline]
4397#[target_feature(enable = "vector")]
4398#[unstable(feature = "stdarch_s390x", issue = "135681")]
4399pub unsafe fn vec_slb<T: sealed::VectorSlb<U>, U>(a: T, b: U) -> T::Result {
4400    a.vec_slb(b)
4401}
4402
4403/// Vector Shift Right by Byte
4404#[inline]
4405#[target_feature(enable = "vector")]
4406#[unstable(feature = "stdarch_s390x", issue = "135681")]
4407pub unsafe fn vec_srb<T: sealed::VectorSrb<U>, U>(a: T, b: U) -> T::Result {
4408    a.vec_srb(b)
4409}
4410
4411/// Vector Shift Right Algebraic by Byte
4412#[inline]
4413#[target_feature(enable = "vector")]
4414#[unstable(feature = "stdarch_s390x", issue = "135681")]
4415pub unsafe fn vec_srab<T: sealed::VectorSrab<U>, U>(a: T, b: U) -> T::Result {
4416    a.vec_srab(b)
4417}
4418
4419/// Vector Element Rotate Left
4420#[inline]
4421#[target_feature(enable = "vector")]
4422#[unstable(feature = "stdarch_s390x", issue = "135681")]
4423pub unsafe fn vec_rl<T: sealed::VectorRl<U>, U>(a: T, b: U) -> T::Result {
4424    a.vec_rl(b)
4425}
4426
4427/// Vector Shift Left
4428///
4429/// Performs a left shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding
4430/// element of a left by the number of bits specified by the last 3 bits of every byte of b. The bits that are shifted out are replaced by zeros.
4431#[inline]
4432#[target_feature(enable = "vector")]
4433#[unstable(feature = "stdarch_s390x", issue = "135681")]
4434pub unsafe fn vec_sll<T>(a: T, b: vector_unsigned_char) -> T
4435where
4436    T: sealed::VectorSll<vector_unsigned_char, Result = T>,
4437{
4438    a.vec_sll(b)
4439}
4440
4441/// Vector Shift Right
4442///
4443/// Performs a right shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding
4444/// element of a right by the number of bits specified by the last 3 bits of every byte of b. The bits that are shifted out are replaced by zeros.
4445#[inline]
4446#[target_feature(enable = "vector")]
4447#[unstable(feature = "stdarch_s390x", issue = "135681")]
4448pub unsafe fn vec_srl<T>(a: T, b: vector_unsigned_char) -> T
4449where
4450    T: sealed::VectorSrl<vector_unsigned_char, Result = T>,
4451{
4452    a.vec_srl(b)
4453}
4454
4455/// Vector Shift Right Arithmetic
4456///
4457/// Performs an algebraic right shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding
4458/// element of a right by the number of bits specified by the last 3 bits of every byte of b. The bits that are shifted out are replaced by copies of
4459/// the most significant bit of the element of a.
4460#[inline]
4461#[target_feature(enable = "vector")]
4462#[unstable(feature = "stdarch_s390x", issue = "135681")]
4463pub unsafe fn vec_sral<T>(a: T, b: vector_unsigned_char) -> T
4464where
4465    T: sealed::VectorSral<vector_unsigned_char, Result = T>,
4466{
4467    a.vec_sral(b)
4468}
4469
4470/// Vector Element Rotate Left Immediate
4471///
4472/// Rotates each element of a vector left by a given number of bits. Each element of the result is obtained by rotating the corresponding element
4473/// of a left by the number of bits specified by b, modulo the number of bits in the element.
4474#[inline]
4475#[target_feature(enable = "vector")]
4476#[unstable(feature = "stdarch_s390x", issue = "135681")]
4477pub unsafe fn vec_rli<T: sealed::VectorRli>(a: T, bits: core::ffi::c_ulong) -> T {
4478    a.vec_rli(bits)
4479}
4480
4481/// Vector Reverse Elements
4482///
4483/// Returns a vector with the elements of the input vector in reversed order.
4484#[inline]
4485#[target_feature(enable = "vector")]
4486#[unstable(feature = "stdarch_s390x", issue = "135681")]
4487pub unsafe fn vec_reve<T: sealed::VectorReve>(a: T) -> T {
4488    a.vec_reve()
4489}
4490
4491/// Vector Byte Reverse
4492///
4493/// Returns a vector where each vector element contains the corresponding byte-reversed vector element of the input vector.
4494#[inline]
4495#[target_feature(enable = "vector")]
4496#[unstable(feature = "stdarch_s390x", issue = "135681")]
4497pub unsafe fn vec_revb<T: sealed::VectorRevb>(a: T) -> T {
4498    a.vec_revb()
4499}
4500
4501/// Vector Merge High
4502///
4503/// Merges the most significant ("high") halves of two vectors.
4504#[inline]
4505#[target_feature(enable = "vector")]
4506#[unstable(feature = "stdarch_s390x", issue = "135681")]
4507pub unsafe fn vec_mergeh<T: sealed::VectorMergeh>(a: T, b: T) -> T {
4508    a.vec_mergeh(b)
4509}
4510
4511/// Vector Merge Low
4512///
4513/// Merges the least significant ("low") halves of two vectors.
4514#[inline]
4515#[target_feature(enable = "vector")]
4516#[unstable(feature = "stdarch_s390x", issue = "135681")]
4517pub unsafe fn vec_mergel<T: sealed::VectorMergel>(a: T, b: T) -> T {
4518    a.vec_mergel(b)
4519}
4520
4521/// Vector Pack
4522#[inline]
4523#[target_feature(enable = "vector")]
4524#[unstable(feature = "stdarch_s390x", issue = "135681")]
4525pub unsafe fn vec_pack<T: sealed::VectorPack<U>, U>(a: T, b: U) -> T::Result {
4526    a.vec_pack(b)
4527}
4528
4529/// Vector Pack Saturated
4530#[inline]
4531#[target_feature(enable = "vector")]
4532#[unstable(feature = "stdarch_s390x", issue = "135681")]
4533pub unsafe fn vec_packs<T: sealed::VectorPacks<U>, U>(a: T, b: U) -> T::Result {
4534    a.vec_packs(b)
4535}
4536
4537/// Vector Pack Saturated Condition Code
4538#[inline]
4539#[target_feature(enable = "vector")]
4540#[unstable(feature = "stdarch_s390x", issue = "135681")]
4541pub unsafe fn vec_packs_cc<T: sealed::VectorPacksCC>(a: T, b: T) -> (T::Result, i32) {
4542    a.vec_packs_cc(b)
4543}
4544
4545/// Vector Pack Saturated Unsigned
4546#[inline]
4547#[target_feature(enable = "vector")]
4548#[unstable(feature = "stdarch_s390x", issue = "135681")]
4549pub unsafe fn vec_packsu<T: sealed::VectorPacksu<U>, U>(a: T, b: U) -> T::Result {
4550    a.vec_packsu(b)
4551}
4552
4553/// Vector Pack Saturated Unsigned Condition Code
4554#[inline]
4555#[target_feature(enable = "vector")]
4556#[unstable(feature = "stdarch_s390x", issue = "135681")]
4557pub unsafe fn vec_packsu_cc<T: sealed::VectorPacksuCC>(a: T, b: T) -> (T::Result, i32) {
4558    a.vec_packsu_cc(b)
4559}
4560
4561/// Vector Unpack High
4562#[inline]
4563#[target_feature(enable = "vector")]
4564#[unstable(feature = "stdarch_s390x", issue = "135681")]
4565pub unsafe fn vec_unpackh<T: sealed::VectorUnpackh>(a: T) -> <T as sealed::VectorUnpackh>::Result {
4566    a.vec_unpackh()
4567}
4568
4569/// Vector Unpack Low
4570#[inline]
4571#[target_feature(enable = "vector")]
4572#[unstable(feature = "stdarch_s390x", issue = "135681")]
4573pub unsafe fn vec_unpackl<T: sealed::VectorUnpackl>(a: T) -> <T as sealed::VectorUnpackl>::Result {
4574    a.vec_unpackl()
4575}
4576
4577/// Vector Generate Byte Mask
4578///
4579/// Generates byte masks for elements in the return vector. For each bit in a, if the bit is one, all bit positions
4580/// in the corresponding byte element of d are set to ones. Otherwise, if the bit is zero, the corresponding byte element is set to zero.
4581#[inline]
4582#[target_feature(enable = "vector")]
4583#[unstable(feature = "stdarch_s390x", issue = "135681")]
4584#[cfg_attr(test, assert_instr(vgbm, MASK = 0x00FF))]
4585pub unsafe fn vec_genmask<const MASK: u16>() -> vector_unsigned_char {
4586    vector_unsigned_char(const { genmask::<MASK>() })
4587}
4588
4589/// Vector Generate Mask (Byte)
4590#[inline]
4591#[target_feature(enable = "vector")]
4592#[unstable(feature = "stdarch_s390x", issue = "135681")]
4593#[cfg_attr(test, assert_instr(vrepib, L = 3, H = 5))]
4594pub unsafe fn vec_genmasks_8<const L: u8, const H: u8>() -> vector_unsigned_char {
4595    vector_unsigned_char(const { [genmasks(u8::BITS, L, H) as u8; 16] })
4596}
4597
4598/// Vector Generate Mask (Halfword)
4599#[inline]
4600#[target_feature(enable = "vector")]
4601#[unstable(feature = "stdarch_s390x", issue = "135681")]
4602#[cfg_attr(test, assert_instr(vrepih, L = 3, H = 5))]
4603pub unsafe fn vec_genmasks_16<const L: u8, const H: u8>() -> vector_unsigned_short {
4604    vector_unsigned_short(const { [genmasks(u16::BITS, L, H) as u16; 8] })
4605}
4606
4607/// Vector Generate Mask (Word)
4608#[inline]
4609#[target_feature(enable = "vector")]
4610#[unstable(feature = "stdarch_s390x", issue = "135681")]
4611#[cfg_attr(test, assert_instr(vgmf, L = 3, H = 5))]
4612pub unsafe fn vec_genmasks_32<const L: u8, const H: u8>() -> vector_unsigned_int {
4613    vector_unsigned_int(const { [genmasks(u32::BITS, L, H) as u32; 4] })
4614}
4615
4616/// Vector Generate Mask (Doubleword)
4617#[inline]
4618#[target_feature(enable = "vector")]
4619#[unstable(feature = "stdarch_s390x", issue = "135681")]
4620#[cfg_attr(test, assert_instr(vgmg, L = 3, H = 5))]
4621pub unsafe fn vec_genmasks_64<const L: u8, const H: u8>() -> vector_unsigned_long_long {
4622    vector_unsigned_long_long(const { [genmasks(u64::BITS, L, H); 2] })
4623}
4624
4625/// Vector Permute
4626///
4627/// Returns a vector that contains some elements of two vectors, in the order specified by a third vector.
4628/// Each byte of the result is selected by using the least significant 5 bits of the corresponding byte of c as an index into the concatenated bytes of a and b.
4629/// Note: The vector generate mask built-in function [`vec_genmask`] could help generate the mask c.
4630#[inline]
4631#[target_feature(enable = "vector")]
4632#[unstable(feature = "stdarch_s390x", issue = "135681")]
4633pub unsafe fn vec_perm<T: sealed::VectorPerm>(a: T, b: T, c: vector_unsigned_char) -> T {
4634    a.vec_perm(b, c)
4635}
4636
4637/// Vector Sum Across Quadword
4638///
4639/// Returns a vector containing the results of performing a sum across all the elements in each of the quadword of vector a,
4640/// and the rightmost word or doubleword element of the b. The result is an unsigned 128-bit integer.
4641#[inline]
4642#[target_feature(enable = "vector")]
4643#[unstable(feature = "stdarch_s390x", issue = "135681")]
4644pub unsafe fn vec_sum_u128<T: sealed::VectorSumU128>(a: T, b: T) -> vector_unsigned_char {
4645    a.vec_sum_u128(b)
4646}
4647
4648/// Vector Sum Across Doubleword
4649///
4650/// Returns a vector containing the results of performing a sum across all the elements in each of the doubleword of vector a,
4651/// and the rightmost sub-element of the corresponding doubleword of b.
4652#[inline]
4653#[target_feature(enable = "vector")]
4654#[unstable(feature = "stdarch_s390x", issue = "135681")]
4655pub unsafe fn vec_sum2<T: sealed::VectorSum2>(a: T, b: T) -> vector_unsigned_long_long {
4656    a.vec_sum2(b)
4657}
4658
4659/// Vector Sum Across Word
4660///
4661/// Returns a vector containing the results of performing a sum across all the elements in each of the word of vector a,
4662/// and the rightmost sub-element of the corresponding word of b.
4663#[inline]
4664#[target_feature(enable = "vector")]
4665#[unstable(feature = "stdarch_s390x", issue = "135681")]
4666pub unsafe fn vec_sum4<T: sealed::VectorSum4>(a: T, b: T) -> vector_unsigned_int {
4667    a.vec_sum4(b)
4668}
4669
4670/// Vector Addition unsigned 128-bits
4671///
4672/// Adds unsigned quadword values.
4673///
4674/// This function operates on the vectors as 128-bit unsigned integers. It returns low 128 bits of a + b.
4675#[inline]
4676#[target_feature(enable = "vector")]
4677#[unstable(feature = "stdarch_s390x", issue = "135681")]
4678#[cfg_attr(test, assert_instr(vaq))]
4679pub unsafe fn vec_add_u128(
4680    a: vector_unsigned_char,
4681    b: vector_unsigned_char,
4682) -> vector_unsigned_char {
4683    let a: u128 = transmute(a);
4684    let b: u128 = transmute(b);
4685    transmute(a.wrapping_add(b))
4686}
4687
4688/// Vector Subtract unsigned 128-bits
4689///
4690/// Subtracts unsigned quadword values.
4691///
4692/// This function operates on the vectors as 128-bit unsigned integers. It returns low 128 bits of a - b.
4693#[inline]
4694#[target_feature(enable = "vector")]
4695#[unstable(feature = "stdarch_s390x", issue = "135681")]
4696#[cfg_attr(test, assert_instr(vsq))]
4697pub unsafe fn vec_sub_u128(
4698    a: vector_unsigned_char,
4699    b: vector_unsigned_char,
4700) -> vector_unsigned_char {
4701    let a: u128 = transmute(a);
4702    let b: u128 = transmute(b);
4703
4704    transmute(a.wrapping_sub(b))
4705}
4706
4707/// Vector Subtract Carryout
4708///
4709/// Returns a vector containing the borrow produced by subtracting each of corresponding elements of b from a.
4710///
4711/// On each resulting element, the value is 0 if a borrow occurred, or 1 if no borrow occurred.
4712#[inline]
4713#[target_feature(enable = "vector")]
4714#[unstable(feature = "stdarch_s390x", issue = "135681")]
4715pub unsafe fn vec_subc<T: sealed::VectorSubc<U>, U>(a: T, b: U) -> T::Result {
4716    a.vec_subc(b)
4717}
4718
4719/// Vector Subtract Carryout unsigned 128-bits
4720///
4721/// Gets the carry bit of the 128-bit subtraction of two quadword values.
4722/// This function operates on the vectors as 128-bit unsigned integers. It returns a vector containing the borrow produced by subtracting b from a, as unsigned 128-bits integers.
4723/// If no borrow occurred, the bit 127 of d is 1; otherwise it is set to 0. All other bits of d are 0.
4724#[inline]
4725#[target_feature(enable = "vector")]
4726#[unstable(feature = "stdarch_s390x", issue = "135681")]
4727#[cfg_attr(test, assert_instr(vscbiq))]
4728pub unsafe fn vec_subc_u128(
4729    a: vector_unsigned_char,
4730    b: vector_unsigned_char,
4731) -> vector_unsigned_char {
4732    let a: u128 = transmute(a);
4733    let b: u128 = transmute(b);
4734    transmute(!a.overflowing_sub(b).1 as u128)
4735}
4736
4737/// Vector Add Compute Carryout unsigned 128-bits
4738#[inline]
4739#[target_feature(enable = "vector")]
4740#[unstable(feature = "stdarch_s390x", issue = "135681")]
4741#[cfg_attr(test, assert_instr(vaccq))]
4742pub unsafe fn vec_addc_u128(
4743    a: vector_unsigned_char,
4744    b: vector_unsigned_char,
4745) -> vector_unsigned_char {
4746    let a: u128 = transmute(a);
4747    let b: u128 = transmute(b);
4748    // FIXME(llvm) https://github.com/llvm/llvm-project/pull/153557
4749    // transmute(a.overflowing_add(b).1 as u128)
4750    transmute(vaccq(a, b))
4751}
4752
4753/// Vector Add With Carry unsigned 128-bits
4754#[inline]
4755#[target_feature(enable = "vector")]
4756#[unstable(feature = "stdarch_s390x", issue = "135681")]
4757#[cfg_attr(test, assert_instr(vacq))]
4758pub unsafe fn vec_adde_u128(
4759    a: vector_unsigned_char,
4760    b: vector_unsigned_char,
4761    c: vector_unsigned_char,
4762) -> vector_unsigned_char {
4763    let a: u128 = transmute(a);
4764    let b: u128 = transmute(b);
4765    let c: u128 = transmute(c);
4766    // FIXME(llvm) https://github.com/llvm/llvm-project/pull/153557
4767    //     let (d, _carry) = a.carrying_add(b, c & 1 != 0);
4768    //     transmute(d)
4769    transmute(vacq(a, b, c))
4770}
4771
4772/// Vector Add With Carry Compute Carry unsigned 128-bits
4773#[inline]
4774#[target_feature(enable = "vector")]
4775#[unstable(feature = "stdarch_s390x", issue = "135681")]
4776#[cfg_attr(test, assert_instr(vacccq))]
4777pub unsafe fn vec_addec_u128(
4778    a: vector_unsigned_char,
4779    b: vector_unsigned_char,
4780    c: vector_unsigned_char,
4781) -> vector_unsigned_char {
4782    let a: u128 = transmute(a);
4783    let b: u128 = transmute(b);
4784    let c: u128 = transmute(c);
4785    // FIXME(llvm) https://github.com/llvm/llvm-project/pull/153557
4786    // let (_d, carry) = a.carrying_add(b, c & 1 != 0);
4787    // transmute(carry as u128)
4788    transmute(vacccq(a, b, c))
4789}
4790
4791/// Vector Subtract with Carryout
4792///
4793/// Subtracts unsigned quadword values with carry bit from a previous operation.
4794///
4795/// This function operates on the vectors as 128-bit unsigned integers. It returns a vector containing the result of subtracting of b from a,
4796/// and the carryout bit from a previous operation.
4797///
4798/// Note: Only the borrow indication bit (127-bit) of c is used, and the other bits are ignored.
4799#[inline]
4800#[target_feature(enable = "vector")]
4801#[unstable(feature = "stdarch_s390x", issue = "135681")]
4802#[cfg_attr(test, assert_instr(vsbiq))]
4803pub unsafe fn vec_sube_u128(
4804    a: vector_unsigned_char,
4805    b: vector_unsigned_char,
4806    c: vector_unsigned_char,
4807) -> vector_unsigned_char {
4808    transmute(vsbiq(transmute(a), transmute(b), transmute(c)))
4809}
4810
4811/// Vector Subtract with Carryout, Carryout
4812///
4813/// Gets the carry bit of the 128-bit subtraction of two quadword values with carry bit from the previous operation.
4814///
4815/// It returns a vector containing the carryout produced from the result of subtracting of b from a,
4816/// and the carryout bit from a previous operation. If no borrow occurred, the 127-bit of d is 1, otherwise 0.
4817/// All other bits of d are 0.
4818///
4819/// Note: Only the borrow indication bit (127-bit) of c is used, and the other bits are ignored.
4820#[inline]
4821#[target_feature(enable = "vector")]
4822#[unstable(feature = "stdarch_s390x", issue = "135681")]
4823#[cfg_attr(test, assert_instr(vsbcbiq))]
4824pub unsafe fn vec_subec_u128(
4825    a: vector_unsigned_char,
4826    b: vector_unsigned_char,
4827    c: vector_unsigned_char,
4828) -> vector_unsigned_char {
4829    transmute(vsbcbiq(transmute(a), transmute(b), transmute(c)))
4830}
4831
4832/// Vector Splat Signed Byte
4833#[inline]
4834#[target_feature(enable = "vector")]
4835#[unstable(feature = "stdarch_s390x", issue = "135681")]
4836#[cfg_attr(test, assert_instr(vrepib, IMM = 42))]
4837pub unsafe fn vec_splat_s8<const IMM: i8>() -> vector_signed_char {
4838    vector_signed_char([IMM; 16])
4839}
4840
4841/// Vector Splat Signed Halfword
4842#[inline]
4843#[target_feature(enable = "vector")]
4844#[unstable(feature = "stdarch_s390x", issue = "135681")]
4845#[cfg_attr(test, assert_instr(vrepih, IMM = 42))]
4846pub unsafe fn vec_splat_s16<const IMM: i16>() -> vector_signed_short {
4847    vector_signed_short([IMM; 8])
4848}
4849
4850/// Vector Splat Signed Word
4851#[inline]
4852#[target_feature(enable = "vector")]
4853#[unstable(feature = "stdarch_s390x", issue = "135681")]
4854#[cfg_attr(test, assert_instr(vrepif, IMM = 42))]
4855pub unsafe fn vec_splat_s32<const IMM: i16>() -> vector_signed_int {
4856    vector_signed_int([IMM as i32; 4])
4857}
4858
4859/// Vector Splat Signed Doubleword
4860#[inline]
4861#[target_feature(enable = "vector")]
4862#[unstable(feature = "stdarch_s390x", issue = "135681")]
4863#[cfg_attr(test, assert_instr(vrepig, IMM = 42))]
4864pub unsafe fn vec_splat_s64<const IMM: i16>() -> vector_signed_long_long {
4865    vector_signed_long_long([IMM as i64; 2])
4866}
4867
4868/// Vector Splat Unsigned Byte
4869#[inline]
4870#[target_feature(enable = "vector")]
4871#[unstable(feature = "stdarch_s390x", issue = "135681")]
4872#[cfg_attr(test, assert_instr(vrepib, IMM = 42))]
4873pub unsafe fn vec_splat_u8<const IMM: u8>() -> vector_unsigned_char {
4874    vector_unsigned_char([IMM; 16])
4875}
4876
4877/// Vector Splat Unsigned Halfword
4878#[inline]
4879#[target_feature(enable = "vector")]
4880#[unstable(feature = "stdarch_s390x", issue = "135681")]
4881#[cfg_attr(test, assert_instr(vrepih, IMM = 42))]
4882pub unsafe fn vec_splat_u16<const IMM: i16>() -> vector_unsigned_short {
4883    vector_unsigned_short([IMM as u16; 8])
4884}
4885
4886/// Vector Splat Unsigned Word
4887#[inline]
4888#[target_feature(enable = "vector")]
4889#[unstable(feature = "stdarch_s390x", issue = "135681")]
4890#[cfg_attr(test, assert_instr(vrepif, IMM = 42))]
4891pub unsafe fn vec_splat_u32<const IMM: i16>() -> vector_unsigned_int {
4892    vector_unsigned_int([IMM as u32; 4])
4893}
4894
4895/// Vector Splat Unsigned Doubleword
4896#[inline]
4897#[target_feature(enable = "vector")]
4898#[unstable(feature = "stdarch_s390x", issue = "135681")]
4899#[cfg_attr(test, assert_instr(vrepig, IMM = 42))]
4900pub unsafe fn vec_splat_u64<const IMM: i16>() -> vector_unsigned_long_long {
4901    vector_unsigned_long_long([IMM as u64; 2])
4902}
4903
4904macro_rules! vec_find_any {
4905    ($($Trait:ident $fun:ident $doc:literal)*) => {
4906        $(
4907            #[inline]
4908            #[target_feature(enable = "vector")]
4909            #[unstable(feature = "stdarch_s390x", issue = "135681")]
4910            #[doc = $doc]
4911            pub unsafe fn $fun<T: sealed::$Trait<U>, U>(a: T, b: U) -> T::Result {
4912                a.$fun(b)
4913            }
4914        )*
4915    }
4916}
4917
4918vec_find_any! {
4919    VectorFindAnyEq vec_find_any_eq "Vector Find Any Element Equal with Condition Code"
4920    VectorFindAnyNe vec_find_any_ne "Vector Find Any Element Not Equal with Condition Code"
4921    VectorFindAnyEqIdx vec_find_any_eq_idx "Vector Find Any Element Equal Index with Condition Code"
4922    VectorFindAnyNeIdx vec_find_any_ne_idx "Vector Find Any Element Not Equal Index with Condition Code"
4923    VectorFindAnyEqOrZeroIdx vec_find_any_eq_or_0_idx "Vector Find Any Element Equal or Zero Index with Condition Code"
4924    VectorFindAnyNeOrZeroIdx vec_find_any_ne_or_0_idx "Vector Find Any Element Not Equal or Zero Index with Condition Code"
4925}
4926
4927macro_rules! vec_find_any_cc {
4928    ($($Trait:ident $fun:ident $doc:literal)*) => {
4929        $(
4930            #[inline]
4931            #[target_feature(enable = "vector")]
4932            #[unstable(feature = "stdarch_s390x", issue = "135681")]
4933            #[doc = $doc]
4934            pub unsafe fn $fun<T: sealed::$Trait<U>, U>(a: T, b: U) -> (T::Result, i32) {
4935                a.$fun(b)
4936            }
4937        )*
4938    }
4939}
4940
4941vec_find_any_cc! {
4942    VectorFindAnyEqCC vec_find_any_eq_cc "Vector Find Any Element Equal with Condition Code"
4943    VectorFindAnyNeCC vec_find_any_ne_cc "Vector Find Any Element Not Equal with Condition Code"
4944    VectorFindAnyEqIdxCC vec_find_any_eq_idx_cc "Vector Find Any Element Equal Index with Condition Code"
4945    VectorFindAnyNeIdxCC vec_find_any_ne_idx_cc "Vector Find Any Element Not Equal Index with Condition Code"
4946    VectorFindAnyEqOrZeroIdxCC vec_find_any_eq_or_0_idx_cc "Vector Find Any Element Equal or Zero Index with Condition Code"
4947    VectorFindAnyNeOrZeroIdxCC vec_find_any_ne_or_0_idx_cc "Vector Find Any Element Not Equal or Zero Index with Condition Code"
4948}
4949
4950/// Vector Load
4951#[inline]
4952#[target_feature(enable = "vector")]
4953#[unstable(feature = "stdarch_s390x", issue = "135681")]
4954pub unsafe fn vec_xl<T: sealed::VectorLoad>(offset: isize, ptr: *const T::ElementType) -> T {
4955    T::vec_xl(offset, ptr)
4956}
4957
4958/// Vector Load Pair
4959#[inline]
4960#[target_feature(enable = "vector")]
4961#[unstable(feature = "stdarch_s390x", issue = "135681")]
4962pub unsafe fn vec_load_pair<T: sealed::VectorLoadPair>(a: T::ElementType, b: T::ElementType) -> T {
4963    T::vec_load_pair(a, b)
4964}
4965
4966/// Vector Load to Block Boundary
4967#[inline]
4968#[target_feature(enable = "vector")]
4969#[unstable(feature = "stdarch_s390x", issue = "135681")]
4970pub unsafe fn vec_load_bndry<T: sealed::VectorLoad, const BLOCK_BOUNDARY: u16>(
4971    ptr: *const T::ElementType,
4972) -> MaybeUninit<T> {
4973    T::vec_load_bndry::<BLOCK_BOUNDARY>(ptr)
4974}
4975
4976/// Vector Store
4977#[inline]
4978#[target_feature(enable = "vector")]
4979#[unstable(feature = "stdarch_s390x", issue = "135681")]
4980pub unsafe fn vec_xst<T: sealed::VectorStore>(vector: T, offset: isize, ptr: *mut T::ElementType) {
4981    vector.vec_xst(offset, ptr)
4982}
4983
4984/// Vector Load with Length
4985#[inline]
4986#[target_feature(enable = "vector")]
4987#[unstable(feature = "stdarch_s390x", issue = "135681")]
4988pub unsafe fn vec_load_len<T: sealed::VectorLoad>(
4989    ptr: *const T::ElementType,
4990    byte_count: u32,
4991) -> T {
4992    T::vec_load_len(ptr, byte_count)
4993}
4994
4995/// Vector Store with Length
4996#[inline]
4997#[target_feature(enable = "vector")]
4998#[unstable(feature = "stdarch_s390x", issue = "135681")]
4999pub unsafe fn vec_store_len<T: sealed::VectorStore>(
5000    vector: T,
5001    ptr: *mut T::ElementType,
5002    byte_count: u32,
5003) {
5004    vector.vec_store_len(ptr, byte_count)
5005}
5006
5007/// Vector Load Rightmost with Length
5008#[inline]
5009#[target_feature(enable = "vector-packed-decimal")]
5010#[unstable(feature = "stdarch_s390x", issue = "135681")]
5011#[cfg_attr(test, assert_instr(vlrlr))]
5012pub unsafe fn vec_load_len_r(ptr: *const u8, byte_count: u32) -> vector_unsigned_char {
5013    vlrl(byte_count, ptr)
5014}
5015
5016/// Vector Store Rightmost with Length
5017#[inline]
5018#[target_feature(enable = "vector-packed-decimal")]
5019#[unstable(feature = "stdarch_s390x", issue = "135681")]
5020#[cfg_attr(test, assert_instr(vstrlr))]
5021pub unsafe fn vec_store_len_r(vector: vector_unsigned_char, ptr: *mut u8, byte_count: u32) {
5022    vstrl(vector, byte_count, ptr)
5023}
5024
5025/// Vector Multiply Add
5026#[inline]
5027#[target_feature(enable = "vector-packed-decimal")]
5028#[unstable(feature = "stdarch_s390x", issue = "135681")]
5029pub unsafe fn vec_madd<T: sealed::VectorMadd>(a: T, b: T, c: T) -> T {
5030    a.vec_madd(b, c)
5031}
5032
5033/// Vector Multiply Add
5034#[inline]
5035#[target_feature(enable = "vector-packed-decimal")]
5036#[unstable(feature = "stdarch_s390x", issue = "135681")]
5037pub unsafe fn vec_msub<T: sealed::VectorMadd>(a: T, b: T, c: T) -> T {
5038    a.vec_msub(b, c)
5039}
5040
5041/// Vector Multiply and Add Even
5042#[inline]
5043#[target_feature(enable = "vector-packed-decimal")]
5044#[unstable(feature = "stdarch_s390x", issue = "135681")]
5045pub unsafe fn vec_meadd<T: sealed::VectorMeadd>(a: T, b: T, c: T::Result) -> T::Result {
5046    a.vec_meadd(b, c)
5047}
5048
5049/// Vector Multiply and Add Odd
5050#[inline]
5051#[target_feature(enable = "vector-packed-decimal")]
5052#[unstable(feature = "stdarch_s390x", issue = "135681")]
5053pub unsafe fn vec_moadd<T: sealed::VectorMoadd>(a: T, b: T, c: T::Result) -> T::Result {
5054    a.vec_moadd(b, c)
5055}
5056
5057/// Vector Multiply and Add High
5058#[inline]
5059#[target_feature(enable = "vector-packed-decimal")]
5060#[unstable(feature = "stdarch_s390x", issue = "135681")]
5061pub unsafe fn vec_mhadd<T: sealed::VectorMhadd>(a: T, b: T, c: T::Result) -> T::Result {
5062    a.vec_mhadd(b, c)
5063}
5064
5065/// Vector Multiply and Add Low
5066#[inline]
5067#[target_feature(enable = "vector-packed-decimal")]
5068#[unstable(feature = "stdarch_s390x", issue = "135681")]
5069pub unsafe fn vec_mladd<T: sealed::VectorMladd>(a: T, b: T, c: T::Result) -> T::Result {
5070    a.vec_mladd(b, c)
5071}
5072
5073/// Vector Checksum
5074#[inline]
5075#[target_feature(enable = "vector")]
5076#[unstable(feature = "stdarch_s390x", issue = "135681")]
5077#[cfg_attr(test, assert_instr(vcksm))]
5078pub unsafe fn vec_checksum(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int {
5079    vcksm(a, b)
5080}
5081
5082/// Vector Multiply Even
5083#[inline]
5084#[target_feature(enable = "vector")]
5085#[unstable(feature = "stdarch_s390x", issue = "135681")]
5086pub unsafe fn vec_mule<T: sealed::VectorMule<U>, U>(a: T, b: T) -> U {
5087    a.vec_mule(b)
5088}
5089
5090/// Vector Multiply Odd
5091#[inline]
5092#[target_feature(enable = "vector")]
5093#[unstable(feature = "stdarch_s390x", issue = "135681")]
5094pub unsafe fn vec_mulo<T: sealed::VectorMulo<U>, U>(a: T, b: T) -> U {
5095    a.vec_mulo(b)
5096}
5097
5098/// Vector Multiply High
5099#[inline]
5100#[target_feature(enable = "vector")]
5101#[unstable(feature = "stdarch_s390x", issue = "135681")]
5102pub unsafe fn vec_mulh<T: sealed::VectorMulh<U>, U>(a: T, b: T) -> U {
5103    a.vec_mulh(b)
5104}
5105
5106/// Vector Galois Field Multiply Sum
5107#[inline]
5108#[target_feature(enable = "vector")]
5109#[unstable(feature = "stdarch_s390x", issue = "135681")]
5110pub unsafe fn vec_gfmsum<T: sealed::VectorGfmsum<U>, U>(a: T, b: T) -> U {
5111    a.vec_gfmsum(b)
5112}
5113
5114/// Vector Galois Field Multiply Sum
5115#[inline]
5116#[target_feature(enable = "vector")]
5117#[unstable(feature = "stdarch_s390x", issue = "135681")]
5118pub unsafe fn vec_gfmsum_accum<T: sealed::VectorGfmsumAccum>(
5119    a: T,
5120    b: T,
5121    c: T::Result,
5122) -> T::Result {
5123    a.vec_gfmsum_accum(b, c)
5124}
5125
5126/// Vector Galois Field Multiply Sum 128-bits
5127#[inline]
5128#[target_feature(enable = "vector")]
5129#[unstable(feature = "stdarch_s390x", issue = "135681")]
5130#[cfg_attr(test, assert_instr(vgfmg))]
5131pub unsafe fn vec_gfmsum_128(
5132    a: vector_unsigned_long_long,
5133    b: vector_unsigned_long_long,
5134) -> vector_unsigned_char {
5135    transmute(vgfmg(a, b))
5136}
5137
5138/// Vector Galois Field Multiply Sum and Accumulate 128-bits
5139#[inline]
5140#[target_feature(enable = "vector")]
5141#[unstable(feature = "stdarch_s390x", issue = "135681")]
5142#[cfg_attr(test, assert_instr(vgfmag))]
5143pub unsafe fn vec_gfmsum_accum_128(
5144    a: vector_unsigned_long_long,
5145    b: vector_unsigned_long_long,
5146    c: vector_unsigned_char,
5147) -> vector_unsigned_char {
5148    transmute(vgfmag(a, b, transmute(c)))
5149}
5150
5151/// Vector Bit Permute
5152#[inline]
5153#[target_feature(enable = "vector-enhancements-1")]
5154#[unstable(feature = "stdarch_s390x", issue = "135681")]
5155#[cfg_attr(test, assert_instr(vbperm))]
5156pub unsafe fn vec_bperm_u128(
5157    a: vector_unsigned_char,
5158    b: vector_unsigned_char,
5159) -> vector_unsigned_long_long {
5160    vbperm(a, b)
5161}
5162
5163/// Vector Gather Element
5164#[inline]
5165#[target_feature(enable = "vector")]
5166#[unstable(feature = "stdarch_s390x", issue = "135681")]
5167pub unsafe fn vec_gather_element<T: sealed::VectorGatherElement, const D: u32>(
5168    a: T,
5169    b: T::Offset,
5170    c: *const T::Element,
5171) -> T {
5172    a.vec_gather_element::<D>(b, c)
5173}
5174
5175/// Vector Select
5176#[inline]
5177#[target_feature(enable = "vector")]
5178#[unstable(feature = "stdarch_s390x", issue = "135681")]
5179pub unsafe fn vec_sel<T: sealed::VectorSel<U>, U>(a: T, b: T, c: U) -> T {
5180    a.vec_sel(b, c)
5181}
5182
5183#[unstable(feature = "stdarch_s390x", issue = "135681")]
5184pub const __VEC_CLASS_FP_ZERO_P: u32 = 1 << 11;
5185#[unstable(feature = "stdarch_s390x", issue = "135681")]
5186pub const __VEC_CLASS_FP_ZERO_N: u32 = 1 << 10;
5187#[unstable(feature = "stdarch_s390x", issue = "135681")]
5188pub const __VEC_CLASS_FP_ZERO: u32 = __VEC_CLASS_FP_ZERO_P | __VEC_CLASS_FP_ZERO_N;
5189#[unstable(feature = "stdarch_s390x", issue = "135681")]
5190pub const __VEC_CLASS_FP_NORMAL_P: u32 = 1 << 9;
5191#[unstable(feature = "stdarch_s390x", issue = "135681")]
5192pub const __VEC_CLASS_FP_NORMAL_N: u32 = 1 << 8;
5193#[unstable(feature = "stdarch_s390x", issue = "135681")]
5194pub const __VEC_CLASS_FP_NORMAL: u32 = __VEC_CLASS_FP_NORMAL_P | __VEC_CLASS_FP_NORMAL_N;
5195#[unstable(feature = "stdarch_s390x", issue = "135681")]
5196pub const __VEC_CLASS_FP_SUBNORMAL_P: u32 = 1 << 7;
5197#[unstable(feature = "stdarch_s390x", issue = "135681")]
5198pub const __VEC_CLASS_FP_SUBNORMAL_N: u32 = 1 << 6;
5199#[unstable(feature = "stdarch_s390x", issue = "135681")]
5200pub const __VEC_CLASS_FP_SUBNORMAL: u32 = __VEC_CLASS_FP_SUBNORMAL_P | __VEC_CLASS_FP_SUBNORMAL_N;
5201#[unstable(feature = "stdarch_s390x", issue = "135681")]
5202pub const __VEC_CLASS_FP_INFINITY_P: u32 = 1 << 5;
5203#[unstable(feature = "stdarch_s390x", issue = "135681")]
5204pub const __VEC_CLASS_FP_INFINITY_N: u32 = 1 << 4;
5205#[unstable(feature = "stdarch_s390x", issue = "135681")]
5206pub const __VEC_CLASS_FP_INFINITY: u32 = __VEC_CLASS_FP_INFINITY_P | __VEC_CLASS_FP_INFINITY_N;
5207#[unstable(feature = "stdarch_s390x", issue = "135681")]
5208pub const __VEC_CLASS_FP_QNAN_P: u32 = 1 << 3;
5209#[unstable(feature = "stdarch_s390x", issue = "135681")]
5210pub const __VEC_CLASS_FP_QNAN_N: u32 = 1 << 2;
5211#[unstable(feature = "stdarch_s390x", issue = "135681")]
5212pub const __VEC_CLASS_FP_QNAN: u32 = __VEC_CLASS_FP_QNAN_P | __VEC_CLASS_FP_QNAN_N;
5213#[unstable(feature = "stdarch_s390x", issue = "135681")]
5214pub const __VEC_CLASS_FP_SNAN_P: u32 = 1 << 1;
5215#[unstable(feature = "stdarch_s390x", issue = "135681")]
5216pub const __VEC_CLASS_FP_SNAN_N: u32 = 1 << 0;
5217#[unstable(feature = "stdarch_s390x", issue = "135681")]
5218pub const __VEC_CLASS_FP_SNAN: u32 = __VEC_CLASS_FP_SNAN_P | __VEC_CLASS_FP_SNAN_N;
5219#[unstable(feature = "stdarch_s390x", issue = "135681")]
5220pub const __VEC_CLASS_FP_NAN: u32 = __VEC_CLASS_FP_QNAN | __VEC_CLASS_FP_SNAN;
5221#[unstable(feature = "stdarch_s390x", issue = "135681")]
5222pub const __VEC_CLASS_FP_NOT_NORMAL: u32 =
5223    __VEC_CLASS_FP_NAN | __VEC_CLASS_FP_SUBNORMAL | __VEC_CLASS_FP_ZERO | __VEC_CLASS_FP_INFINITY;
5224
5225/// Vector Floating-Point Test Data Class
5226///
5227/// You can use the `__VEC_CLASS_FP_*` constants as the argument for this operand
5228#[inline]
5229#[target_feature(enable = "vector")]
5230#[unstable(feature = "stdarch_s390x", issue = "135681")]
5231pub unsafe fn vec_fp_test_data_class<T: sealed::VectorFpTestDataClass, const CLASS: u32>(
5232    a: T,
5233    c: *mut i32,
5234) -> T::Result {
5235    let (x, y) = a.vec_fp_test_data_class::<CLASS>();
5236    c.write(y);
5237    x
5238}
5239
5240/// All Elements Not a Number
5241#[inline]
5242#[target_feature(enable = "vector")]
5243#[unstable(feature = "stdarch_s390x", issue = "135681")]
5244pub unsafe fn vec_all_nan<T: sealed::VectorFpTestDataClass>(a: T) -> i32 {
5245    i32::from(a.vec_fp_test_data_class::<__VEC_CLASS_FP_NAN>().1 == 0)
5246}
5247
5248/// All Elements Numeric
5249#[inline]
5250#[target_feature(enable = "vector")]
5251#[unstable(feature = "stdarch_s390x", issue = "135681")]
5252pub unsafe fn vec_all_numeric<T: sealed::VectorFpTestDataClass>(a: T) -> i32 {
5253    i32::from(a.vec_fp_test_data_class::<__VEC_CLASS_FP_NAN>().1 == 3)
5254}
5255
5256/// Any Elements Not a Number
5257#[inline]
5258#[target_feature(enable = "vector")]
5259#[unstable(feature = "stdarch_s390x", issue = "135681")]
5260pub unsafe fn vec_any_nan<T: sealed::VectorFpTestDataClass>(a: T) -> i32 {
5261    i32::from(a.vec_fp_test_data_class::<__VEC_CLASS_FP_NAN>().1 != 3)
5262}
5263
5264/// Any Elements Numeric
5265#[inline]
5266#[target_feature(enable = "vector")]
5267#[unstable(feature = "stdarch_s390x", issue = "135681")]
5268pub unsafe fn vec_any_numeric<T: sealed::VectorFpTestDataClass>(a: T) -> i32 {
5269    i32::from(a.vec_fp_test_data_class::<__VEC_CLASS_FP_NAN>().1 != 0)
5270}
5271
5272/// Vector Test under Mask
5273#[inline]
5274#[target_feature(enable = "vector")]
5275#[unstable(feature = "stdarch_s390x", issue = "135681")]
5276pub unsafe fn vec_test_mask<T: sealed::VectorTestMask>(a: T, b: T::Mask) -> i32 {
5277    // I can't find much information about this, but this might just be a check for whether the
5278    // bitwise and of a and b is non-zero?
5279    a.vec_test_mask(b)
5280}
5281
5282/// Vector Search String
5283#[inline]
5284#[target_feature(enable = "vector")]
5285#[unstable(feature = "stdarch_s390x", issue = "135681")]
5286pub unsafe fn vec_search_string_cc<T: sealed::VectorSearchString>(
5287    a: T,
5288    b: T,
5289    c: vector_unsigned_char,
5290) -> (vector_unsigned_char, i32) {
5291    a.vec_search_string_cc(b, c)
5292}
5293
5294/// Vector Search String Until Zero
5295#[inline]
5296#[target_feature(enable = "vector")]
5297#[unstable(feature = "stdarch_s390x", issue = "135681")]
5298pub unsafe fn vec_search_string_until_zero_cc<T: sealed::VectorSearchString>(
5299    a: T,
5300    b: T,
5301    c: vector_unsigned_char,
5302) -> (vector_unsigned_char, i32) {
5303    a.vec_search_string_until_zero_cc(b, c)
5304}
5305
5306/// Vector Convert from float (even elements) to double
5307#[inline]
5308#[target_feature(enable = "vector-enhancements-1")]
5309#[unstable(feature = "stdarch_s390x", issue = "135681")]
5310// NOTE: `vflls` and `vldeb` are equivalent; our disassmbler prefers vflls.
5311#[cfg_attr(
5312    all(test, target_feature = "vector-enhancements-1"),
5313    assert_instr(vflls)
5314)]
5315pub unsafe fn vec_doublee(a: vector_float) -> vector_double {
5316    simd_as::<f32x2, vector_double>(simd_shuffle!(a, a, [0, 2]))
5317}
5318
5319/// Vector Convert from double to float (even elements)
5320#[inline]
5321#[target_feature(enable = "vector-enhancements-1")]
5322#[unstable(feature = "stdarch_s390x", issue = "135681")]
5323// FIXME: the C version uses a shuffle mask with poison; we can't do that
5324// #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vledb))]
5325pub unsafe fn vec_floate(a: vector_double) -> vector_float {
5326    let truncated: f32x2 = simd_as(a);
5327    simd_shuffle!(truncated, truncated, [0, 0, 1, 1])
5328}
5329
5330/// Vector Convert from int to float
5331#[inline]
5332#[target_feature(enable = "vector")]
5333#[unstable(feature = "stdarch_s390x", issue = "135681")]
5334pub unsafe fn vec_float(a: impl sealed::VectorFloat) -> vector_float {
5335    a.vec_float()
5336}
5337
5338/// Vector Convert from long long to double
5339#[inline]
5340#[target_feature(enable = "vector")]
5341#[unstable(feature = "stdarch_s390x", issue = "135681")]
5342pub unsafe fn vec_double(a: impl sealed::VectorDouble) -> vector_double {
5343    a.vec_double()
5344}
5345
5346/// Vector Sign Extend to Doubleword
5347#[inline]
5348#[target_feature(enable = "vector")]
5349#[unstable(feature = "stdarch_s390x", issue = "135681")]
5350pub unsafe fn vec_extend_s64(a: impl sealed::VectorExtendSigned64) -> vector_signed_long_long {
5351    a.vec_extend_s64()
5352}
5353
5354/// Vector Convert floating point to signed
5355#[inline]
5356#[target_feature(enable = "vector")]
5357#[unstable(feature = "stdarch_s390x", issue = "135681")]
5358pub unsafe fn vec_signed<T: sealed::VectorSigned>(a: T) -> T::Result {
5359    a.vec_signed()
5360}
5361
5362/// Vector Convert floating point to unsigned
5363#[inline]
5364#[target_feature(enable = "vector")]
5365#[unstable(feature = "stdarch_s390x", issue = "135681")]
5366pub unsafe fn vec_unsigned<T: sealed::VectorUnsigned>(a: T) -> T::Result {
5367    a.vec_unsigned()
5368}
5369
5370/// Vector Copy Until Zero
5371#[inline]
5372#[target_feature(enable = "vector")]
5373#[unstable(feature = "stdarch_s390x", issue = "135681")]
5374pub unsafe fn vec_cp_until_zero<T: sealed::VectorCopyUntilZero>(a: T) -> T {
5375    a.vec_cp_until_zero()
5376}
5377
5378/// Vector Copy Until Zero
5379#[inline]
5380#[target_feature(enable = "vector")]
5381#[unstable(feature = "stdarch_s390x", issue = "135681")]
5382pub unsafe fn vec_cp_until_zero_cc<T: sealed::VectorCopyUntilZeroCC>(a: T) -> (T, i32) {
5383    a.vec_cp_until_zero_cc()
5384}
5385
5386/// Vector Multiply Sum Logical
5387#[inline]
5388#[target_feature(enable = "vector-enhancements-1")]
5389#[unstable(feature = "stdarch_s390x", issue = "135681")]
5390#[cfg_attr(
5391    all(test, target_feature = "vector-enhancements-1"),
5392    assert_instr(vmslg, D = 4)
5393)]
5394pub unsafe fn vec_msum_u128<const D: u32>(
5395    a: vector_unsigned_long_long,
5396    b: vector_unsigned_long_long,
5397    c: vector_unsigned_char,
5398) -> vector_unsigned_char {
5399    const {
5400        if !matches!(D, 0 | 4 | 8 | 12) {
5401            panic!("D needs to be one of 0, 4, 8, 12");
5402        }
5403    };
5404    transmute(vmslg(a, b, transmute(c), D))
5405}
5406
5407/// Vector Shift Left Double by Byte
5408#[inline]
5409#[target_feature(enable = "vector")]
5410#[unstable(feature = "stdarch_s390x", issue = "135681")]
5411pub unsafe fn vec_sld<T: sealed::VectorSld, const C: u32>(a: T, b: T) -> T {
5412    static_assert_uimm_bits!(C, 4);
5413    a.vec_sld::<C>(b)
5414}
5415
5416/// Vector Shift Left Double by Word
5417#[inline]
5418#[target_feature(enable = "vector")]
5419#[unstable(feature = "stdarch_s390x", issue = "135681")]
5420pub unsafe fn vec_sldw<T: sealed::VectorSld, const C: u32>(a: T, b: T) -> T {
5421    static_assert_uimm_bits!(C, 2);
5422    a.vec_sldw::<C>(b)
5423}
5424
5425/// Vector Shift Left Double by Bit
5426#[inline]
5427#[target_feature(enable = "vector-enhancements-2")]
5428#[unstable(feature = "stdarch_s390x", issue = "135681")]
5429pub unsafe fn vec_sldb<T: sealed::VectorSld, const C: u32>(a: T, b: T) -> T {
5430    static_assert_uimm_bits!(C, 3);
5431    a.vec_sldb::<C>(b)
5432}
5433
5434/// Vector Shift Right Double by Bit
5435#[inline]
5436#[target_feature(enable = "vector-enhancements-2")]
5437#[unstable(feature = "stdarch_s390x", issue = "135681")]
5438pub unsafe fn vec_srdb<T: sealed::VectorSrdb, const C: u32>(a: T, b: T) -> T {
5439    static_assert_uimm_bits!(C, 3);
5440    a.vec_srdb::<C>(b)
5441}
5442
5443/// Vector Compare Ranges
5444#[inline]
5445#[target_feature(enable = "vector")]
5446#[unstable(feature = "stdarch_s390x", issue = "135681")]
5447pub unsafe fn vec_cmprg<T: sealed::VectorCompareRange>(a: T, b: T, c: T) -> T::Result {
5448    a.vstrc::<{ FindImm::Eq as u32 }>(b, c)
5449}
5450
5451/// Vector Compare Not in Ranges
5452#[inline]
5453#[target_feature(enable = "vector")]
5454#[unstable(feature = "stdarch_s390x", issue = "135681")]
5455pub unsafe fn vec_cmpnrg<T: sealed::VectorCompareRange>(a: T, b: T, c: T) -> T::Result {
5456    a.vstrc::<{ FindImm::Ne as u32 }>(b, c)
5457}
5458
5459/// Vector Compare Ranges Index
5460#[inline]
5461#[target_feature(enable = "vector")]
5462#[unstable(feature = "stdarch_s390x", issue = "135681")]
5463pub unsafe fn vec_cmprg_idx<T: sealed::VectorCompareRange>(a: T, b: T, c: T) -> T::Result {
5464    a.vstrc::<{ FindImm::EqIdx as u32 }>(b, c)
5465}
5466
5467/// Vector Compare Not in Ranges Index
5468#[inline]
5469#[target_feature(enable = "vector")]
5470#[unstable(feature = "stdarch_s390x", issue = "135681")]
5471pub unsafe fn vec_cmpnrg_idx<T: sealed::VectorCompareRange>(a: T, b: T, c: T) -> T::Result {
5472    a.vstrc::<{ FindImm::NeIdx as u32 }>(b, c)
5473}
5474
5475/// Vector Compare Ranges with Condition Code
5476#[inline]
5477#[target_feature(enable = "vector")]
5478#[unstable(feature = "stdarch_s390x", issue = "135681")]
5479pub unsafe fn vec_cmprg_cc<T: sealed::VectorCompareRange>(
5480    a: T,
5481    b: T,
5482    c: T,
5483    d: *mut i32,
5484) -> T::Result {
5485    let (x, y) = a.vstrcs::<{ FindImm::Eq as u32 }>(b, c);
5486    d.write(y);
5487    x
5488}
5489
5490/// Vector Compare Not in Ranges with Condition Code
5491#[inline]
5492#[target_feature(enable = "vector")]
5493#[unstable(feature = "stdarch_s390x", issue = "135681")]
5494pub unsafe fn vec_cmpnrg_cc<T: sealed::VectorCompareRange>(
5495    a: T,
5496    b: T,
5497    c: T,
5498    d: *mut i32,
5499) -> T::Result {
5500    let (x, y) = a.vstrcs::<{ FindImm::Ne as u32 }>(b, c);
5501    d.write(y);
5502    x
5503}
5504
5505/// Vector Compare Ranges Index with Condition Code
5506#[inline]
5507#[target_feature(enable = "vector")]
5508#[unstable(feature = "stdarch_s390x", issue = "135681")]
5509pub unsafe fn vec_cmprg_idx_cc<T: sealed::VectorCompareRange>(
5510    a: T,
5511    b: T,
5512    c: T,
5513    d: *mut i32,
5514) -> T::Result {
5515    let (x, y) = a.vstrcs::<{ FindImm::EqIdx as u32 }>(b, c);
5516    d.write(y);
5517    x
5518}
5519
5520/// Vector Compare Not in Ranges Index with Condition Code
5521#[inline]
5522#[target_feature(enable = "vector")]
5523#[unstable(feature = "stdarch_s390x", issue = "135681")]
5524pub unsafe fn vec_cmpnrg_idx_cc<T: sealed::VectorCompareRange>(
5525    a: T,
5526    b: T,
5527    c: T,
5528    d: *mut i32,
5529) -> T::Result {
5530    let (x, y) = a.vstrcs::<{ FindImm::NeIdx as u32 }>(b, c);
5531    d.write(y);
5532    x
5533}
5534
5535/// Vector Compare Ranges or Zero Index
5536#[inline]
5537#[target_feature(enable = "vector")]
5538#[unstable(feature = "stdarch_s390x", issue = "135681")]
5539pub unsafe fn vec_cmprg_or_0_idx<T: sealed::VectorCompareRange>(a: T, b: T, c: T) -> T::Result {
5540    a.vstrcz::<{ FindImm::EqIdx as u32 }>(b, c)
5541}
5542
5543/// Vector Compare Not in Ranges or Zero Index
5544#[inline]
5545#[target_feature(enable = "vector")]
5546#[unstable(feature = "stdarch_s390x", issue = "135681")]
5547pub unsafe fn vec_cmpnrg_or_0_idx<T: sealed::VectorCompareRange>(a: T, b: T, c: T) -> T::Result {
5548    a.vstrcz::<{ FindImm::NeIdx as u32 }>(b, c)
5549}
5550
5551/// Vector Compare Ranges or Zero Index with Condition Code
5552#[inline]
5553#[target_feature(enable = "vector")]
5554#[unstable(feature = "stdarch_s390x", issue = "135681")]
5555pub unsafe fn vec_cmprg_or_0_idx_cc<T: sealed::VectorCompareRange>(
5556    a: T,
5557    b: T,
5558    c: T,
5559    d: *mut i32,
5560) -> T::Result {
5561    let (x, y) = a.vstrczs::<{ FindImm::EqIdx as u32 }>(b, c);
5562    d.write(y);
5563    x
5564}
5565
5566/// Vector Compare Not in Ranges or Zero Index with Condition Code
5567#[inline]
5568#[target_feature(enable = "vector")]
5569#[unstable(feature = "stdarch_s390x", issue = "135681")]
5570pub unsafe fn vec_cmpnrg_or_0_idx_cc<T: sealed::VectorCompareRange>(
5571    a: T,
5572    b: T,
5573    c: T,
5574    d: *mut i32,
5575) -> T::Result {
5576    let (x, y) = a.vstrczs::<{ FindImm::NeIdx as u32 }>(b, c);
5577    d.write(y);
5578    x
5579}
5580
5581/// Vector Compare Equal
5582#[inline]
5583#[target_feature(enable = "vector")]
5584#[unstable(feature = "stdarch_s390x", issue = "135681")]
5585pub unsafe fn vec_cmpeq<T: sealed::VectorEquality>(a: T, b: T) -> T::Result {
5586    a.vec_cmpeq(b)
5587}
5588
5589/// Vector Compare Not Equal
5590#[inline]
5591#[target_feature(enable = "vector")]
5592#[unstable(feature = "stdarch_s390x", issue = "135681")]
5593pub unsafe fn vec_cmpne<T: sealed::VectorEquality>(a: T, b: T) -> T::Result {
5594    a.vec_cmpne(b)
5595}
5596
5597/// Vector Compare Greater Than
5598#[inline]
5599#[target_feature(enable = "vector")]
5600#[unstable(feature = "stdarch_s390x", issue = "135681")]
5601pub unsafe fn vec_cmpgt<T: sealed::VectorComparePredicate>(a: T, b: T) -> T::Result {
5602    a.vec_cmpgt(b)
5603}
5604
5605/// Vector Compare Greater Than or Equal
5606#[inline]
5607#[target_feature(enable = "vector")]
5608#[unstable(feature = "stdarch_s390x", issue = "135681")]
5609pub unsafe fn vec_cmpge<T: sealed::VectorComparePredicate>(a: T, b: T) -> T::Result {
5610    a.vec_cmpge(b)
5611}
5612
5613/// Vector Compare Less
5614#[inline]
5615#[target_feature(enable = "vector")]
5616#[unstable(feature = "stdarch_s390x", issue = "135681")]
5617pub unsafe fn vec_cmplt<T: sealed::VectorComparePredicate>(a: T, b: T) -> T::Result {
5618    a.vec_cmplt(b)
5619}
5620
5621/// Vector Compare Less Than or Equal
5622#[inline]
5623#[target_feature(enable = "vector")]
5624#[unstable(feature = "stdarch_s390x", issue = "135681")]
5625pub unsafe fn vec_cmple<T: sealed::VectorComparePredicate>(a: T, b: T) -> T::Result {
5626    a.vec_cmple(b)
5627}
5628
5629/// Vector Compare Equal Index
5630#[inline]
5631#[target_feature(enable = "vector")]
5632#[unstable(feature = "stdarch_s390x", issue = "135681")]
5633pub unsafe fn vec_cmpeq_idx<T: sealed::VectorEqualityIdx>(a: T, b: T) -> T::Result {
5634    a.vec_cmpeq_idx(b)
5635}
5636/// Vector Compare Not Equal Index
5637#[inline]
5638#[target_feature(enable = "vector")]
5639#[unstable(feature = "stdarch_s390x", issue = "135681")]
5640pub unsafe fn vec_cmpne_idx<T: sealed::VectorEqualityIdx>(a: T, b: T) -> T::Result {
5641    a.vec_cmpne_idx(b)
5642}
5643/// Vector Compare Equal Index with Condition Code
5644#[inline]
5645#[target_feature(enable = "vector")]
5646#[unstable(feature = "stdarch_s390x", issue = "135681")]
5647pub unsafe fn vec_cmpeq_idx_cc<T: sealed::VectorEqualityIdx>(a: T, b: T) -> (T::Result, i32) {
5648    a.vec_cmpeq_idx_cc(b)
5649}
5650/// Vector Compare Not Equal Index with Condition Code
5651#[inline]
5652#[target_feature(enable = "vector")]
5653#[unstable(feature = "stdarch_s390x", issue = "135681")]
5654pub unsafe fn vec_cmpne_idx_cc<T: sealed::VectorEqualityIdx>(a: T, b: T) -> (T::Result, i32) {
5655    a.vec_cmpne_idx_cc(b)
5656}
5657/// Vector Compare Equal or Zero Index
5658#[inline]
5659#[target_feature(enable = "vector")]
5660#[unstable(feature = "stdarch_s390x", issue = "135681")]
5661pub unsafe fn vec_cmpeq_or_0_idx<T: sealed::VectorEqualityIdx>(a: T, b: T) -> T::Result {
5662    a.vec_cmpeq_or_0_idx(b)
5663}
5664/// Vector Compare Not Equal or Zero Index
5665#[inline]
5666#[target_feature(enable = "vector")]
5667#[unstable(feature = "stdarch_s390x", issue = "135681")]
5668pub unsafe fn vec_cmpne_or_0_idx<T: sealed::VectorEqualityIdx>(a: T, b: T) -> T::Result {
5669    a.vec_cmpne_or_0_idx(b)
5670}
5671/// Vector Compare Equal or Zero Index with Condition Code
5672#[inline]
5673#[target_feature(enable = "vector")]
5674#[unstable(feature = "stdarch_s390x", issue = "135681")]
5675pub unsafe fn vec_cmpeq_or_0_idx_cc<T: sealed::VectorEqualityIdx>(a: T, b: T) -> (T::Result, i32) {
5676    a.vec_cmpeq_or_0_idx_cc(b)
5677}
5678/// Vector Compare Not Equal or Zero Index with Condition Code
5679#[inline]
5680#[target_feature(enable = "vector")]
5681#[unstable(feature = "stdarch_s390x", issue = "135681")]
5682pub unsafe fn vec_cmpne_or_0_idx_cc<T: sealed::VectorEqualityIdx>(a: T, b: T) -> (T::Result, i32) {
5683    a.vec_cmpne_or_0_idx_cc(b)
5684}
5685
5686/// All Elements Equal
5687#[inline]
5688#[target_feature(enable = "vector")]
5689#[unstable(feature = "stdarch_s390x", issue = "135681")]
5690pub unsafe fn vec_all_eq<T: sealed::VectorEquality>(a: T, b: T) -> i32 {
5691    simd_reduce_all(vec_cmpeq(a, b)) as i32 as i32
5692}
5693
5694/// All Elements Not Equal
5695#[inline]
5696#[target_feature(enable = "vector")]
5697#[unstable(feature = "stdarch_s390x", issue = "135681")]
5698pub unsafe fn vec_all_ne<T: sealed::VectorEquality>(a: T, b: T) -> i32 {
5699    simd_reduce_all(vec_cmpne(a, b)) as i32
5700}
5701
5702/// Any Element Equal
5703#[inline]
5704#[target_feature(enable = "vector")]
5705#[unstable(feature = "stdarch_s390x", issue = "135681")]
5706pub unsafe fn vec_any_eq<T: sealed::VectorEquality>(a: T, b: T) -> i32 {
5707    simd_reduce_any(vec_cmpeq(a, b)) as i32
5708}
5709
5710/// Any Element Not Equal
5711#[inline]
5712#[target_feature(enable = "vector")]
5713#[unstable(feature = "stdarch_s390x", issue = "135681")]
5714pub unsafe fn vec_any_ne<T: sealed::VectorEquality>(a: T, b: T) -> i32 {
5715    simd_reduce_any(vec_cmpne(a, b)) as i32
5716}
5717
5718/// All Elements Less Than
5719#[inline]
5720#[target_feature(enable = "vector")]
5721#[unstable(feature = "stdarch_s390x", issue = "135681")]
5722pub unsafe fn vec_all_lt<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5723    a.vec_all_lt(b)
5724}
5725
5726/// All Elements Less Than or Equal
5727#[inline]
5728#[target_feature(enable = "vector")]
5729#[unstable(feature = "stdarch_s390x", issue = "135681")]
5730pub unsafe fn vec_all_le<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5731    a.vec_all_le(b)
5732}
5733
5734/// All Elements Greater Than
5735#[inline]
5736#[target_feature(enable = "vector")]
5737#[unstable(feature = "stdarch_s390x", issue = "135681")]
5738pub unsafe fn vec_all_gt<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5739    a.vec_all_gt(b)
5740}
5741
5742/// All Elements Greater Than or Equal
5743#[inline]
5744#[target_feature(enable = "vector")]
5745#[unstable(feature = "stdarch_s390x", issue = "135681")]
5746pub unsafe fn vec_all_ge<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5747    a.vec_all_ge(b)
5748}
5749
5750/// All Elements Not Less Than
5751#[inline]
5752#[target_feature(enable = "vector")]
5753#[unstable(feature = "stdarch_s390x", issue = "135681")]
5754pub unsafe fn vec_all_nlt<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5755    vec_all_ge(a, b)
5756}
5757
5758/// All Elements Not Less Than or Equal
5759#[inline]
5760#[target_feature(enable = "vector")]
5761#[unstable(feature = "stdarch_s390x", issue = "135681")]
5762pub unsafe fn vec_all_nle<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5763    vec_all_gt(a, b)
5764}
5765
5766/// All Elements Not Greater Than
5767#[inline]
5768#[target_feature(enable = "vector")]
5769#[unstable(feature = "stdarch_s390x", issue = "135681")]
5770pub unsafe fn vec_all_ngt<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5771    vec_all_le(a, b)
5772}
5773
5774/// All Elements Not Greater Than or Equal
5775#[inline]
5776#[target_feature(enable = "vector")]
5777#[unstable(feature = "stdarch_s390x", issue = "135681")]
5778pub unsafe fn vec_all_nge<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5779    vec_all_lt(a, b)
5780}
5781
5782/// Any Elements Less Than
5783#[inline]
5784#[target_feature(enable = "vector")]
5785#[unstable(feature = "stdarch_s390x", issue = "135681")]
5786pub unsafe fn vec_any_lt<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5787    !vec_all_ge(a, b)
5788}
5789
5790/// Any Elements Less Than or Equal
5791#[inline]
5792#[target_feature(enable = "vector")]
5793#[unstable(feature = "stdarch_s390x", issue = "135681")]
5794pub unsafe fn vec_any_le<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5795    !vec_all_gt(a, b)
5796}
5797
5798/// Any Elements Greater Than
5799#[inline]
5800#[target_feature(enable = "vector")]
5801#[unstable(feature = "stdarch_s390x", issue = "135681")]
5802pub unsafe fn vec_any_gt<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5803    !vec_all_le(a, b)
5804}
5805
5806/// Any Elements Greater Than or Equal
5807#[inline]
5808#[target_feature(enable = "vector")]
5809#[unstable(feature = "stdarch_s390x", issue = "135681")]
5810pub unsafe fn vec_any_ge<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5811    !vec_all_lt(a, b)
5812}
5813
5814/// Any Elements Not Less Than
5815#[inline]
5816#[target_feature(enable = "vector")]
5817#[unstable(feature = "stdarch_s390x", issue = "135681")]
5818pub unsafe fn vec_any_nlt<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5819    vec_any_ge(a, b)
5820}
5821
5822/// Any Elements Not Less Than or Equal
5823#[inline]
5824#[target_feature(enable = "vector")]
5825#[unstable(feature = "stdarch_s390x", issue = "135681")]
5826pub unsafe fn vec_any_nle<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5827    vec_any_gt(a, b)
5828}
5829
5830/// Any Elements Not Greater Than
5831#[inline]
5832#[target_feature(enable = "vector")]
5833#[unstable(feature = "stdarch_s390x", issue = "135681")]
5834pub unsafe fn vec_any_ngt<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5835    vec_any_le(a, b)
5836}
5837
5838/// Any Elements Not Greater Than or Equal
5839#[inline]
5840#[target_feature(enable = "vector")]
5841#[unstable(feature = "stdarch_s390x", issue = "135681")]
5842pub unsafe fn vec_any_nge<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5843    vec_any_lt(a, b)
5844}
5845
5846/// Vector Extract
5847#[inline]
5848#[target_feature(enable = "vector")]
5849#[unstable(feature = "stdarch_s390x", issue = "135681")]
5850pub unsafe fn vec_extract<T: sealed::VectorExtract>(a: T, b: i32) -> T::ElementType {
5851    T::vec_extract(a, b)
5852}
5853
5854/// Vector Insert
5855#[inline]
5856#[target_feature(enable = "vector")]
5857#[unstable(feature = "stdarch_s390x", issue = "135681")]
5858pub unsafe fn vec_insert<T: sealed::VectorInsert>(a: T::ElementType, b: T, c: i32) -> T {
5859    T::vec_insert(a, b, c)
5860}
5861
5862/// Vector Insert and Zero
5863#[inline]
5864#[target_feature(enable = "vector")]
5865#[unstable(feature = "stdarch_s390x", issue = "135681")]
5866pub unsafe fn vec_insert_and_zero<T: sealed::VectorInsertAndZero>(a: *const T::ElementType) -> T {
5867    T::vec_insert_and_zero(a)
5868}
5869
5870/// Vector Promote
5871#[inline]
5872#[target_feature(enable = "vector")]
5873#[unstable(feature = "stdarch_s390x", issue = "135681")]
5874pub unsafe fn vec_promote<T: sealed::VectorPromote>(a: T::ElementType, b: i32) -> MaybeUninit<T> {
5875    T::vec_promote(a, b)
5876}
5877
5878#[cfg(test)]
5879mod tests {
5880    use super::*;
5881
5882    use std::mem::transmute;
5883
5884    use crate::core_arch::simd::*;
5885    use stdarch_test::simd_test;
5886
5887    impl<const N: usize> ShuffleMask<N> {
5888        fn as_array(&self) -> &[u32; N] {
5889            unsafe { std::mem::transmute(self) }
5890        }
5891    }
5892
5893    #[test]
5894    fn reverse_mask() {
5895        assert_eq!(ShuffleMask::<4>::reverse().as_array(), &[3, 2, 1, 0]);
5896    }
5897
5898    #[test]
5899    fn mergel_mask() {
5900        assert_eq!(ShuffleMask::<4>::merge_low().as_array(), &[2, 6, 3, 7]);
5901    }
5902
5903    #[test]
5904    fn mergeh_mask() {
5905        assert_eq!(ShuffleMask::<4>::merge_high().as_array(), &[0, 4, 1, 5]);
5906    }
5907
5908    #[test]
5909    fn pack_mask() {
5910        assert_eq!(ShuffleMask::<4>::pack().as_array(), &[1, 3, 5, 7]);
5911    }
5912
5913    #[test]
5914    fn test_vec_mask() {
5915        assert_eq!(
5916            genmask::<0x00FF>(),
5917            [
5918                0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
5919            ]
5920        );
5921    }
5922
5923    #[test]
5924    fn test_genmasks() {
5925        assert_eq!(genmasks(u8::BITS, 3, 5), 28);
5926        assert_eq!(genmasks(u8::BITS, 3, 7), 31);
5927
5928        // If a or b is greater than 8, the operation is performed as if the value gets modulo by 8.
5929        assert_eq!(genmasks(u8::BITS, 3 + 8, 7 + 8), 31);
5930        // If a is greater than b, the operation is perform as if b equals 7.
5931        assert_eq!(genmasks(u8::BITS, 5, 4), genmasks(u8::BITS, 5, 7));
5932
5933        assert_eq!(
5934            genmasks(u16::BITS, 4, 12) as u16,
5935            u16::from_be_bytes([15, -8i8 as u8])
5936        );
5937        assert_eq!(
5938            genmasks(u32::BITS, 4, 29) as u32,
5939            u32::from_be_bytes([15, 0xFF, 0xFF, -4i8 as u8])
5940        );
5941    }
5942
5943    macro_rules! test_vec_1 {
5944        { $name: ident, $fn:ident, f32x4, [$($a:expr),+], ~[$($d:expr),+] } => {
5945            #[simd_test(enable = "vector")]
5946            unsafe fn $name() {
5947                let a: vector_float = transmute(f32x4::new($($a),+));
5948
5949                let d: vector_float = transmute(f32x4::new($($d),+));
5950                let r = transmute(vec_cmple(vec_abs(vec_sub($fn(a), d)), vec_splats(f32::EPSILON)));
5951                let e = m32x4::new(true, true, true, true);
5952                assert_eq!(e, r);
5953            }
5954        };
5955        { $name: ident, $fn:ident, $ty: ident, [$($a:expr),+], [$($d:expr),+] } => {
5956            test_vec_1! { $name, $fn, $ty -> $ty, [$($a),+], [$($d),+] }
5957        };
5958        { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($d:expr),+] } => {
5959            #[simd_test(enable = "vector")]
5960            unsafe fn $name() {
5961                let a: s_t_l!($ty) = transmute($ty::new($($a),+));
5962
5963                let d = $ty_out::new($($d),+);
5964                let r : $ty_out = transmute($fn(a));
5965                assert_eq!(d, r);
5966            }
5967        }
5968    }
5969
5970    macro_rules! test_vec_2 {
5971        { $name: ident, $fn:ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
5972            test_vec_2! { $name, $fn, $ty -> $ty, [$($a),+], [$($b),+], [$($d),+] }
5973        };
5974        { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
5975            test_vec_2! { $name, $fn, $ty, $ty -> $ty, [$($a),+], [$($b),+], [$($d),+] }
5976         };
5977        { $name: ident, $fn:ident, $ty1: ident, $ty2: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
5978            #[simd_test(enable = "vector")]
5979            unsafe fn $name() {
5980                let a: s_t_l!($ty1) = transmute($ty1::new($($a),+));
5981                let b: s_t_l!($ty2) = transmute($ty2::new($($b),+));
5982
5983                let d = $ty_out::new($($d),+);
5984                let r : $ty_out = transmute($fn(a, b));
5985                assert_eq!(d, r);
5986            }
5987         };
5988         { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], $d:expr } => {
5989            #[simd_test(enable = "vector")]
5990            unsafe fn $name() {
5991                let a: s_t_l!($ty) = transmute($ty::new($($a),+));
5992                let b: s_t_l!($ty) = transmute($ty::new($($b),+));
5993
5994                let r : $ty_out = transmute($fn(a, b));
5995                assert_eq!($d, r);
5996            }
5997         }
5998   }
5999
6000    #[simd_test(enable = "vector")]
6001    unsafe fn vec_add_i32x4_i32x4() {
6002        let x = i32x4::new(1, 2, 3, 4);
6003        let y = i32x4::new(4, 3, 2, 1);
6004        let x: vector_signed_int = transmute(x);
6005        let y: vector_signed_int = transmute(y);
6006        let z = vec_add(x, y);
6007        assert_eq!(i32x4::splat(5), transmute(z));
6008    }
6009
6010    macro_rules! test_vec_sub {
6011        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
6012            test_vec_2! {$name, vec_sub, $ty, [$($a),+], [$($b),+], [$($d),+] }
6013        }
6014    }
6015
6016    test_vec_sub! { test_vec_sub_f32x4, f32x4,
6017    [-1.0, 0.0, 1.0, 2.0],
6018    [2.0, 1.0, -1.0, -2.0],
6019    [-3.0, -1.0, 2.0, 4.0] }
6020
6021    test_vec_sub! { test_vec_sub_f64x2, f64x2,
6022    [-1.0, 0.0],
6023    [2.0, 1.0],
6024    [-3.0, -1.0] }
6025
6026    test_vec_sub! { test_vec_sub_i64x2, i64x2,
6027    [-1, 0],
6028    [2, 1],
6029    [-3, -1] }
6030
6031    test_vec_sub! { test_vec_sub_u64x2, u64x2,
6032    [0, 1],
6033    [1, 0],
6034    [u64::MAX, 1] }
6035
6036    test_vec_sub! { test_vec_sub_i32x4, i32x4,
6037    [-1, 0, 1, 2],
6038    [2, 1, -1, -2],
6039    [-3, -1, 2, 4] }
6040
6041    test_vec_sub! { test_vec_sub_u32x4, u32x4,
6042    [0, 0, 1, 2],
6043    [2, 1, 0, 0],
6044    [4294967294, 4294967295, 1, 2] }
6045
6046    test_vec_sub! { test_vec_sub_i16x8, i16x8,
6047    [-1, 0, 1, 2, -1, 0, 1, 2],
6048    [2, 1, -1, -2, 2, 1, -1, -2],
6049    [-3, -1, 2, 4, -3, -1, 2, 4] }
6050
6051    test_vec_sub! { test_vec_sub_u16x8, u16x8,
6052    [0, 0, 1, 2, 0, 0, 1, 2],
6053    [2, 1, 0, 0, 2, 1, 0, 0],
6054    [65534, 65535, 1, 2, 65534, 65535, 1, 2] }
6055
6056    test_vec_sub! { test_vec_sub_i8x16, i8x16,
6057    [-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
6058    [2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
6059    [-3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4] }
6060
6061    test_vec_sub! { test_vec_sub_u8x16, u8x16,
6062    [0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2],
6063    [2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
6064    [254, 255, 1, 2, 254, 255, 1, 2, 254, 255, 1, 2, 254, 255, 1, 2] }
6065
6066    macro_rules! test_vec_mul {
6067        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
6068            test_vec_2! {$name, vec_mul, $ty, [$($a),+], [$($b),+], [$($d),+] }
6069        }
6070    }
6071
6072    test_vec_mul! { test_vec_mul_f32x4, f32x4,
6073    [-1.0, 0.0, 1.0, 2.0],
6074    [2.0, 1.0, -1.0, -2.0],
6075    [-2.0, 0.0, -1.0, -4.0] }
6076
6077    test_vec_mul! { test_vec_mul_f64x2, f64x2,
6078    [-1.0, 0.0],
6079    [2.0, 1.0],
6080    [-2.0, 0.0] }
6081
6082    test_vec_mul! { test_vec_mul_i64x2, i64x2,
6083    [i64::MAX, -4],
6084    [2, 3],
6085    [i64::MAX.wrapping_mul(2), -12] }
6086
6087    test_vec_mul! { test_vec_mul_u64x2, u64x2,
6088    [u64::MAX, 4],
6089    [2, 3],
6090    [u64::MAX.wrapping_mul(2), 12] }
6091
6092    test_vec_mul! { test_vec_mul_i32x4, i32x4,
6093    [-1, 0, 1, 2],
6094    [2, 1, -1, -2],
6095    [-2, 0, -1, -4] }
6096
6097    test_vec_mul! { test_vec_mul_u32x4, u32x4,
6098    [0, u32::MAX - 1, 1, 2],
6099    [5, 6, 7, 8],
6100    [0, 4294967284, 7, 16] }
6101
6102    test_vec_mul! { test_vec_mul_i16x8, i16x8,
6103    [-1, 0, 1, 2, -1, 0, 1, 2],
6104    [2, 1, -1, -2, 2, 1, -1, -2],
6105    [-2, 0, -1, -4, -2, 0, -1, -4] }
6106
6107    test_vec_mul! { test_vec_mul_u16x8, u16x8,
6108    [0, u16::MAX - 1, 1, 2, 3, 4, 5, 6],
6109    [5, 6, 7, 8, 9, 8, 7, 6],
6110    [0, 65524, 7, 16, 27, 32, 35, 36] }
6111
6112    test_vec_mul! { test_vec_mul_i8x16, i8x16,
6113    [-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
6114    [2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
6115    [-2, 0, -1, -4, -2, 0, -1, -4, -2, 0, -1, -4, -2, 0, -1, -4] }
6116
6117    test_vec_mul! { test_vec_mul_u8x16, u8x16,
6118    [0, u8::MAX - 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4],
6119    [5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 0, u8::MAX, 1, 2, 3, 4],
6120    [0, 244, 7, 16, 27, 32, 35, 36, 35, 32, 0, 248, 7, 12, 15, 16] }
6121
6122    macro_rules! test_vec_abs {
6123        { $name: ident, $ty: ident, $a: expr, $d: expr } => {
6124            #[simd_test(enable = "vector")]
6125            unsafe fn $name() {
6126                let a: s_t_l!($ty) = vec_splats($a);
6127                let a: s_t_l!($ty) = vec_abs(a);
6128                let d = $ty::splat($d);
6129                assert_eq!(d, transmute(a));
6130            }
6131        }
6132    }
6133
6134    test_vec_abs! { test_vec_abs_i8, i8x16, -42i8, 42i8 }
6135    test_vec_abs! { test_vec_abs_i16, i16x8, -42i16, 42i16 }
6136    test_vec_abs! { test_vec_abs_i32, i32x4, -42i32, 42i32 }
6137    test_vec_abs! { test_vec_abs_i64, i64x2, -42i64, 42i64 }
6138    test_vec_abs! { test_vec_abs_f32, f32x4, -42f32, 42f32 }
6139    test_vec_abs! { test_vec_abs_f64, f64x2, -42f64, 42f64 }
6140
6141    test_vec_1! { test_vec_nabs, vec_nabs, f32x4,
6142    [core::f32::consts::PI, 1.0, 0.0, -1.0],
6143    [-core::f32::consts::PI, -1.0, 0.0, -1.0] }
6144
6145    test_vec_2! { test_vec_andc, vec_andc, i32x4,
6146    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
6147    [0b00110011, 0b11110011, 0b00001100, 0b10000000],
6148    [0b11001100, 0b00001100, 0b11000000, 0b01001100] }
6149
6150    test_vec_2! { test_vec_and, vec_and, i32x4,
6151    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
6152    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
6153    [0b00000000, 0b11000000, 0b00001100, 0b00000000] }
6154
6155    test_vec_2! { test_vec_nand, vec_nand, i32x4,
6156    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
6157    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
6158    [!0b00000000, !0b11000000, !0b00001100, !0b00000000] }
6159
6160    test_vec_2! { test_vec_orc, vec_orc, u32x4,
6161    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
6162    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
6163    [0b11001100 | !0b00110011, 0b11001100 | !0b11110011, 0b11001100 | !0b00001100, 0b11001100 | !0b00000000] }
6164
6165    test_vec_2! { test_vec_or, vec_or, i32x4,
6166    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
6167    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
6168    [0b11111111, 0b11111111, 0b11001100, 0b11001100] }
6169
6170    test_vec_2! { test_vec_nor, vec_nor, i32x4,
6171    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
6172    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
6173    [!0b11111111, !0b11111111, !0b11001100, !0b11001100] }
6174
6175    test_vec_2! { test_vec_xor, vec_xor, i32x4,
6176    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
6177    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
6178    [0b11111111, 0b00111111, 0b11000000, 0b11001100] }
6179
6180    test_vec_2! { test_vec_eqv, vec_eqv, i32x4,
6181    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
6182    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
6183    [!0b11111111, !0b00111111, !0b11000000, !0b11001100] }
6184
6185    test_vec_1! { test_vec_floor_f32, vec_floor, f32x4,
6186        [1.1, 1.9, -0.5, -0.9],
6187        [1.0, 1.0, -1.0, -1.0]
6188    }
6189
6190    test_vec_1! { test_vec_floor_f64_1, vec_floor, f64x2,
6191        [1.1, 1.9],
6192        [1.0, 1.0]
6193    }
6194    test_vec_1! { test_vec_floor_f64_2, vec_floor, f64x2,
6195        [-0.5, -0.9],
6196        [-1.0, -1.0]
6197    }
6198
6199    test_vec_1! { test_vec_ceil_f32, vec_ceil, f32x4,
6200        [0.1, 0.5, 0.6, 0.9],
6201        [1.0, 1.0, 1.0, 1.0]
6202    }
6203    test_vec_1! { test_vec_ceil_f64_1, vec_ceil, f64x2,
6204        [0.1, 0.5],
6205        [1.0, 1.0]
6206    }
6207    test_vec_1! { test_vec_ceil_f64_2, vec_ceil, f64x2,
6208        [0.6, 0.9],
6209        [1.0, 1.0]
6210    }
6211
6212    test_vec_1! { test_vec_round_f32, vec_round, f32x4,
6213        [0.1, 0.5, 0.6, 0.9],
6214        [0.0, 0.0, 1.0, 1.0]
6215    }
6216
6217    test_vec_1! { test_vec_round_f32_even_odd, vec_round, f32x4,
6218        [0.5, 1.5, 2.5, 3.5],
6219        [0.0, 2.0, 2.0, 4.0]
6220    }
6221
6222    test_vec_1! { test_vec_round_f64_1, vec_round, f64x2,
6223        [0.1, 0.5],
6224        [0.0, 0.0]
6225    }
6226    test_vec_1! { test_vec_round_f64_2, vec_round, f64x2,
6227        [0.6, 0.9],
6228        [1.0, 1.0]
6229    }
6230
6231    test_vec_1! { test_vec_roundc_f32, vec_roundc, f32x4,
6232        [0.1, 0.5, 0.6, 0.9],
6233        [0.0, 0.0, 1.0, 1.0]
6234    }
6235
6236    test_vec_1! { test_vec_roundc_f32_even_odd, vec_roundc, f32x4,
6237        [0.5, 1.5, 2.5, 3.5],
6238        [0.0, 2.0, 2.0, 4.0]
6239    }
6240
6241    test_vec_1! { test_vec_roundc_f64_1, vec_roundc, f64x2,
6242        [0.1, 0.5],
6243        [0.0, 0.0]
6244    }
6245    test_vec_1! { test_vec_roundc_f64_2, vec_roundc, f64x2,
6246        [0.6, 0.9],
6247        [1.0, 1.0]
6248    }
6249
6250    test_vec_1! { test_vec_rint_f32, vec_rint, f32x4,
6251        [0.1, 0.5, 0.6, 0.9],
6252        [0.0, 0.0, 1.0, 1.0]
6253    }
6254
6255    test_vec_1! { test_vec_rint_f32_even_odd, vec_rint, f32x4,
6256        [0.5, 1.5, 2.5, 3.5],
6257        [0.0, 2.0, 2.0, 4.0]
6258    }
6259
6260    test_vec_1! { test_vec_rint_f64_1, vec_rint, f64x2,
6261        [0.1, 0.5],
6262        [0.0, 0.0]
6263    }
6264    test_vec_1! { test_vec_rint_f64_2, vec_rint, f64x2,
6265        [0.6, 0.9],
6266        [1.0, 1.0]
6267    }
6268
6269    test_vec_2! { test_vec_sll, vec_sll, i32x4, u8x16 -> i32x4,
6270    [1, 1, 1, 1],
6271    [0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 8],
6272    [1 << 2, 1 << 3, 1 << 4, 1] }
6273
6274    test_vec_2! { test_vec_srl, vec_srl, i32x4, u8x16 -> i32x4,
6275    [0b1000, 0b1000, 0b1000, 0b1000],
6276    [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16],
6277    [4, 2, 1, 8] }
6278
6279    test_vec_2! { test_vec_sral_pos, vec_sral, u32x4, u8x16 -> i32x4,
6280    [0b1000, 0b1000, 0b1000, 0b1000],
6281    [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16],
6282    [4, 2, 1, 8] }
6283
6284    test_vec_2! { test_vec_sral_neg, vec_sral, i32x4, u8x16 -> i32x4,
6285    [-8, -8, -8, -8],
6286    [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16],
6287    [-4, -2, -1, -8] }
6288
6289    test_vec_1! { test_vec_reve_f32, vec_reve, f32x4,
6290        [0.1, 0.5, 0.6, 0.9],
6291        [0.9, 0.6, 0.5, 0.1]
6292    }
6293
6294    test_vec_1! { test_vec_revb_u32, vec_revb, u32x4,
6295        [0xAABBCCDD, 0xEEFF0011, 0x22334455, 0x66778899],
6296        [0xDDCCBBAA, 0x1100FFEE, 0x55443322, 0x99887766]
6297    }
6298
6299    test_vec_2! { test_vec_mergeh_u32, vec_mergeh, u32x4,
6300        [0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD],
6301        [0x00000000, 0x11111111, 0x22222222, 0x33333333],
6302        [0xAAAAAAAA, 0x00000000, 0xBBBBBBBB, 0x11111111]
6303    }
6304
6305    test_vec_2! { test_vec_mergel_u32, vec_mergel, u32x4,
6306        [0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD],
6307        [0x00000000, 0x11111111, 0x22222222, 0x33333333],
6308        [0xCCCCCCCC, 0x22222222, 0xDDDDDDDD, 0x33333333]
6309    }
6310
6311    macro_rules! test_vec_perm {
6312        {$name:ident,
6313         $shorttype:ident, $longtype:ident,
6314         [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => {
6315            #[simd_test(enable = "vector")]
6316            unsafe fn $name() {
6317                let a: $longtype = transmute($shorttype::new($($a),+));
6318                let b: $longtype = transmute($shorttype::new($($b),+));
6319                let c: vector_unsigned_char = transmute(u8x16::new($($c),+));
6320                let d = $shorttype::new($($d),+);
6321
6322                let r: $shorttype = transmute(vec_perm(a, b, c));
6323                assert_eq!(d, r);
6324            }
6325        }
6326    }
6327
6328    test_vec_perm! {test_vec_perm_u8x16,
6329    u8x16, vector_unsigned_char,
6330    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
6331    [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115],
6332    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6333     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6334    [0, 1, 100, 101, 2, 3, 102, 103, 4, 5, 104, 105, 6, 7, 106, 107]}
6335    test_vec_perm! {test_vec_perm_i8x16,
6336    i8x16, vector_signed_char,
6337    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
6338    [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115],
6339    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6340     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6341    [0, 1, 100, 101, 2, 3, 102, 103, 4, 5, 104, 105, 6, 7, 106, 107]}
6342
6343    test_vec_perm! {test_vec_perm_m8x16,
6344    m8x16, vector_bool_char,
6345    [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false],
6346    [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true],
6347    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6348     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6349    [false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true]}
6350    test_vec_perm! {test_vec_perm_u16x8,
6351    u16x8, vector_unsigned_short,
6352    [0, 1, 2, 3, 4, 5, 6, 7],
6353    [10, 11, 12, 13, 14, 15, 16, 17],
6354    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6355     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6356    [0, 10, 1, 11, 2, 12, 3, 13]}
6357    test_vec_perm! {test_vec_perm_i16x8,
6358    i16x8, vector_signed_short,
6359    [0, 1, 2, 3, 4, 5, 6, 7],
6360    [10, 11, 12, 13, 14, 15, 16, 17],
6361    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6362     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6363    [0, 10, 1, 11, 2, 12, 3, 13]}
6364    test_vec_perm! {test_vec_perm_m16x8,
6365    m16x8, vector_bool_short,
6366    [false, false, false, false, false, false, false, false],
6367    [true, true, true, true, true, true, true, true],
6368    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6369     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6370    [false, true, false, true, false, true, false, true]}
6371
6372    test_vec_perm! {test_vec_perm_u32x4,
6373    u32x4, vector_unsigned_int,
6374    [0, 1, 2, 3],
6375    [10, 11, 12, 13],
6376    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
6377     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
6378    [0, 10, 1, 11]}
6379    test_vec_perm! {test_vec_perm_i32x4,
6380    i32x4, vector_signed_int,
6381    [0, 1, 2, 3],
6382    [10, 11, 12, 13],
6383    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
6384     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
6385    [0, 10, 1, 11]}
6386    test_vec_perm! {test_vec_perm_m32x4,
6387    m32x4, vector_bool_int,
6388    [false, false, false, false],
6389    [true, true, true, true],
6390    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
6391     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
6392    [false, true, false, true]}
6393    test_vec_perm! {test_vec_perm_f32x4,
6394    f32x4, vector_float,
6395    [0.0, 1.0, 2.0, 3.0],
6396    [1.0, 1.1, 1.2, 1.3],
6397    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
6398     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
6399    [0.0, 1.0, 1.0, 1.1]}
6400
6401    test_vec_1! { test_vec_sqrt, vec_sqrt, f32x4,
6402    [core::f32::consts::PI, 1.0, 25.0, 2.0],
6403    [core::f32::consts::PI.sqrt(), 1.0, 5.0, core::f32::consts::SQRT_2] }
6404
6405    test_vec_2! { test_vec_find_any_eq, vec_find_any_eq, i32x4, i32x4 -> u32x4,
6406        [1, -2, 3, -4],
6407        [-5, 3, -7, 8],
6408        [0, 0, 0xFFFFFFFF, 0]
6409    }
6410
6411    test_vec_2! { test_vec_find_any_ne, vec_find_any_ne, i32x4, i32x4 -> u32x4,
6412        [1, -2, 3, -4],
6413        [-5, 3, -7, 8],
6414        [0xFFFFFFFF, 0xFFFFFFFF, 0, 0xFFFFFFFF]
6415    }
6416
6417    test_vec_2! { test_vec_find_any_eq_idx_1, vec_find_any_eq_idx, i32x4, i32x4 -> u32x4,
6418        [1, 2, 3, 4],
6419        [5, 3, 7, 8],
6420        [0, 8, 0, 0]
6421    }
6422    test_vec_2! { test_vec_find_any_eq_idx_2, vec_find_any_eq_idx, i32x4, i32x4 -> u32x4,
6423        [1, 2, 3, 4],
6424        [5, 6, 7, 8],
6425        [0, 16, 0, 0]
6426    }
6427
6428    test_vec_2! { test_vec_find_any_ne_idx_1, vec_find_any_ne_idx, i32x4, i32x4 -> u32x4,
6429        [1, 2, 3, 4],
6430        [1, 5, 3, 4],
6431        [0, 4, 0, 0]
6432    }
6433    test_vec_2! { test_vec_find_any_ne_idx_2, vec_find_any_ne_idx, i32x4, i32x4 -> u32x4,
6434        [1, 2, 3, 4],
6435        [1, 2, 3, 4],
6436        [0, 16, 0, 0]
6437    }
6438
6439    test_vec_2! { test_vec_find_any_eq_or_0_idx_1, vec_find_any_eq_or_0_idx, i32x4, i32x4 -> u32x4,
6440        [1, 2, 0, 4],
6441        [5, 6, 7, 8],
6442        [0, 8, 0, 0]
6443    }
6444    test_vec_2! { test_vec_find_any_ne_or_0_idx_1, vec_find_any_ne_or_0_idx, i32x4, i32x4 -> u32x4,
6445        [1, 2, 0, 4],
6446        [1, 2, 3, 4],
6447        [0, 8, 0, 0]
6448    }
6449
6450    #[simd_test(enable = "vector")]
6451    fn test_vec_find_any_eq_cc() {
6452        let a = vector_unsigned_int([1, 2, 3, 4]);
6453        let b = vector_unsigned_int([5, 3, 7, 8]);
6454
6455        let (d, c) = unsafe { vec_find_any_eq_cc(a, b) };
6456        assert_eq!(c, 1);
6457        assert_eq!(d.as_array(), &[0, 0, -1, 0]);
6458
6459        let a = vector_unsigned_int([1, 2, 3, 4]);
6460        let b = vector_unsigned_int([5, 6, 7, 8]);
6461        let (d, c) = unsafe { vec_find_any_eq_cc(a, b) };
6462        assert_eq!(c, 3);
6463        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
6464    }
6465
6466    #[simd_test(enable = "vector")]
6467    fn test_vec_find_any_ne_cc() {
6468        let a = vector_unsigned_int([1, 2, 3, 4]);
6469        let b = vector_unsigned_int([5, 3, 7, 8]);
6470
6471        let (d, c) = unsafe { vec_find_any_ne_cc(a, b) };
6472        assert_eq!(c, 1);
6473        assert_eq!(d.as_array(), &[-1, -1, 0, -1]);
6474
6475        let a = vector_unsigned_int([1, 2, 3, 4]);
6476        let b = vector_unsigned_int([1, 2, 3, 4]);
6477        let (d, c) = unsafe { vec_find_any_ne_cc(a, b) };
6478        assert_eq!(c, 3);
6479        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
6480    }
6481
6482    #[simd_test(enable = "vector")]
6483    fn test_vec_find_any_eq_idx_cc() {
6484        let a = vector_unsigned_int([1, 2, 3, 4]);
6485        let b = vector_unsigned_int([5, 3, 7, 8]);
6486
6487        let (d, c) = unsafe { vec_find_any_eq_idx_cc(a, b) };
6488        assert_eq!(c, 1);
6489        assert_eq!(d.as_array(), &[0, 8, 0, 0]);
6490
6491        let a = vector_unsigned_int([1, 2, 3, 4]);
6492        let b = vector_unsigned_int([5, 6, 7, 8]);
6493        let (d, c) = unsafe { vec_find_any_eq_idx_cc(a, b) };
6494        assert_eq!(c, 3);
6495        assert_eq!(d.as_array(), &[0, 16, 0, 0]);
6496    }
6497
6498    #[simd_test(enable = "vector")]
6499    fn test_vec_find_any_ne_idx_cc() {
6500        let a = vector_unsigned_int([5, 2, 3, 4]);
6501        let b = vector_unsigned_int([5, 3, 7, 8]);
6502
6503        let (d, c) = unsafe { vec_find_any_ne_idx_cc(a, b) };
6504        assert_eq!(c, 1);
6505        assert_eq!(d.as_array(), &[0, 4, 0, 0]);
6506
6507        let a = vector_unsigned_int([1, 2, 3, 4]);
6508        let b = vector_unsigned_int([1, 2, 3, 4]);
6509        let (d, c) = unsafe { vec_find_any_ne_idx_cc(a, b) };
6510        assert_eq!(c, 3);
6511        assert_eq!(d.as_array(), &[0, 16, 0, 0]);
6512    }
6513
6514    #[simd_test(enable = "vector")]
6515    fn test_vec_find_any_eq_or_0_idx_cc() {
6516        // if no element of a matches any element of b with an equal value, and there is at least one element from a with a value of 0
6517        let a = vector_unsigned_int([0, 1, 2, 3]);
6518        let b = vector_unsigned_int([4, 5, 6, 7]);
6519        let (d, c) = unsafe { vec_find_any_eq_or_0_idx_cc(a, b) };
6520        assert_eq!(c, 0);
6521        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
6522
6523        // if at least one element of a matches any element of b with an equal value, and no elements of a with a value of 0
6524        let a = vector_unsigned_int([1, 2, 3, 4]);
6525        let b = vector_unsigned_int([5, 2, 3, 4]);
6526        let (d, c) = unsafe { vec_find_any_eq_or_0_idx_cc(a, b) };
6527        assert_eq!(c, 1);
6528        assert_eq!(d.as_array(), &[0, 4, 0, 0]);
6529
6530        // if at least one element of a matches any element of b with an equal value, and there is at least one element from a has a value of 0
6531        let a = vector_unsigned_int([1, 2, 3, 0]);
6532        let b = vector_unsigned_int([1, 2, 3, 4]);
6533        let (d, c) = unsafe { vec_find_any_eq_or_0_idx_cc(a, b) };
6534        assert_eq!(c, 2);
6535        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
6536
6537        // if no element of a matches any element of b with an equal value, and there is no element from a with a value of 0.
6538        let a = vector_unsigned_int([1, 2, 3, 4]);
6539        let b = vector_unsigned_int([5, 6, 7, 8]);
6540        let (d, c) = unsafe { vec_find_any_eq_or_0_idx_cc(a, b) };
6541        assert_eq!(c, 3);
6542        assert_eq!(d.as_array(), &[0, 16, 0, 0]);
6543    }
6544
6545    #[simd_test(enable = "vector")]
6546    fn test_vec_find_any_ne_or_0_idx_cc() {
6547        // if no element of a matches any element of b with a not equal value, and there is at least one element from a with a value of 0.
6548        let a = vector_unsigned_int([0, 1, 2, 3]);
6549        let b = vector_unsigned_int([4, 1, 2, 3]);
6550        let (d, c) = unsafe { vec_find_any_ne_or_0_idx_cc(a, b) };
6551        assert_eq!(c, 0);
6552        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
6553
6554        // if at least one element of a matches any element of b with a not equal value, and no elements of a with a value of 0.
6555        let a = vector_unsigned_int([4, 2, 3, 4]);
6556        let b = vector_unsigned_int([4, 5, 6, 7]);
6557        let (d, c) = unsafe { vec_find_any_ne_or_0_idx_cc(a, b) };
6558        assert_eq!(c, 1);
6559        assert_eq!(d.as_array(), &[0, 4, 0, 0]);
6560
6561        // if at least one element of a matches any element of b with a not equal value, and there is at least one element from a has a value of 0.
6562        let a = vector_unsigned_int([1, 0, 1, 1]);
6563        let b = vector_unsigned_int([4, 5, 6, 7]);
6564        let (d, c) = unsafe { vec_find_any_ne_or_0_idx_cc(a, b) };
6565        assert_eq!(c, 2);
6566        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
6567
6568        // if no element of a matches any element of b with a not equal value, and there is no element from a with a value of 0.
6569        let a = vector_unsigned_int([4, 4, 4, 4]);
6570        let b = vector_unsigned_int([4, 5, 6, 7]);
6571        let (d, c) = unsafe { vec_find_any_ne_or_0_idx_cc(a, b) };
6572        assert_eq!(c, 3);
6573        assert_eq!(d.as_array(), &[0, 16, 0, 0]);
6574    }
6575
6576    #[simd_test(enable = "vector")]
6577    fn test_vector_load() {
6578        let expected = [0xAAAA_AAAA, 0xBBBB_BBBB, 0xCCCC_CCCC, 0xDDDD_DDDD];
6579
6580        let source: [u32; 8] = [
6581            0xAAAA_AAAA,
6582            0xBBBB_BBBB,
6583            0xCCCC_CCCC,
6584            0xDDDD_DDDD,
6585            0,
6586            0,
6587            0,
6588            0,
6589        ];
6590        assert_eq!(
6591            unsafe { vec_xl::<vector_unsigned_int>(0, source.as_ptr()) }.as_array(),
6592            &expected
6593        );
6594
6595        // offset is in bytes
6596        let source: [u32; 8] = [
6597            0x0000_AAAA,
6598            0xAAAA_BBBB,
6599            0xBBBB_CCCC,
6600            0xCCCC_DDDD,
6601            0xDDDD_0000,
6602            0,
6603            0,
6604            0,
6605        ];
6606        assert_eq!(
6607            unsafe { vec_xl::<vector_unsigned_int>(2, source.as_ptr()) }.as_array(),
6608            &expected
6609        );
6610    }
6611
6612    #[simd_test(enable = "vector")]
6613    fn test_vector_store() {
6614        let vec = vector_unsigned_int([0xAAAA_AAAA, 0xBBBB_BBBB, 0xCCCC_CCCC, 0xDDDD_DDDD]);
6615
6616        let mut dest = [0u32; 8];
6617        unsafe { vec_xst(vec, 0, dest.as_mut_ptr()) };
6618        assert_eq!(
6619            dest,
6620            [
6621                0xAAAA_AAAA,
6622                0xBBBB_BBBB,
6623                0xCCCC_CCCC,
6624                0xDDDD_DDDD,
6625                0,
6626                0,
6627                0,
6628                0
6629            ]
6630        );
6631
6632        // offset is in bytes
6633        let mut dest = [0u32; 8];
6634        unsafe { vec_xst(vec, 2, dest.as_mut_ptr()) };
6635        assert_eq!(
6636            dest,
6637            [
6638                0x0000_AAAA,
6639                0xAAAA_BBBB,
6640                0xBBBB_CCCC,
6641                0xCCCC_DDDD,
6642                0xDDDD_0000,
6643                0,
6644                0,
6645                0,
6646            ]
6647        );
6648    }
6649
6650    #[simd_test(enable = "vector")]
6651    fn test_vector_lcbb() {
6652        #[repr(align(64))]
6653        struct Align64<T>(T);
6654
6655        static ARRAY: Align64<[u8; 128]> = Align64([0; 128]);
6656
6657        assert_eq!(unsafe { __lcbb::<64>(ARRAY.0[64..].as_ptr()) }, 16);
6658        assert_eq!(unsafe { __lcbb::<64>(ARRAY.0[63..].as_ptr()) }, 1);
6659        assert_eq!(unsafe { __lcbb::<64>(ARRAY.0[56..].as_ptr()) }, 8);
6660        assert_eq!(unsafe { __lcbb::<64>(ARRAY.0[48..].as_ptr()) }, 16);
6661    }
6662
6663    test_vec_2! { test_vec_pack, vec_pack, i16x8, i16x8 -> i8x16,
6664        [0, 1, -1, 42, 32767, -32768, 30000, -30000],
6665        [32767, -32768, 12345, -12345, 0, 1, -1, 42],
6666        [0, 1, -1, 42, -1, 0, 48, -48, -1, 0, 57, -57, 0, 1, -1, 42]
6667    }
6668
6669    test_vec_2! { test_vec_packs, vec_packs, i16x8, i16x8 -> i8x16,
6670        [0, 1, -1, 42, 32767, -32768, 30000, -30000],
6671        [32767, -32768, 12345, -12345, 0, 1, -1, 42],
6672        [0, 1, -1, 42, 127, -128, 127, -128, 127, -128, 127, -128, 0, 1, -1, 42]
6673    }
6674
6675    test_vec_2! { test_vec_packsu_signed, vec_packsu, i16x8, i16x8 -> u8x16,
6676        [0, 1, -1, 42, 32767, -32768, 30000, -30000],
6677        [32767, -32768, 12345, -12345, 0, 1, -1, 42],
6678        [0, 1, 0, 42, 255, 0, 255, 0, 255, 0, 255, 0, 0, 1, 0, 42]
6679    }
6680
6681    test_vec_2! { test_vec_packsu_unsigned, vec_packsu, u16x8, u16x8 -> u8x16,
6682        [65535, 32768, 1234, 5678, 16, 8, 4, 2],
6683        [30000, 25000, 20000, 15000, 31, 63, 127, 255],
6684        [255, 255, 255, 255, 16, 8, 4, 2, 255, 255, 255, 255, 31, 63, 127, 255]
6685    }
6686
6687    test_vec_2! { test_vec_rl, vec_rl, u32x4,
6688        [0x12345678, 0x9ABCDEF0, 0x0F0F0F0F, 0x12345678],
6689        [4, 8, 12, 68],
6690        [0x23456781, 0xBCDEF09A, 0xF0F0F0F0, 0x23456781]
6691    }
6692
6693    test_vec_1! { test_vec_unpackh_i, vec_unpackh, i16x8 -> i32x4,
6694        [0x1234, -2, 0x0F0F, -32768, 0, 0, 0, 0],
6695        [0x1234, -2, 0x0F0F, -32768]
6696    }
6697
6698    test_vec_1! { test_vec_unpackh_u, vec_unpackh, u16x8 -> u32x4,
6699        [0x1234, 0xFFFF, 0x0F0F, 0x8000, 0, 0, 0, 0],
6700        [0x1234, 0xFFFF, 0x0F0F, 0x8000]
6701    }
6702
6703    test_vec_1! { test_vec_unpackl_i, vec_unpackl, i16x8 -> i32x4,
6704        [0, 0, 0, 0, 0x1234, -2, 0x0F0F, -32768],
6705        [0x1234, -2, 0x0F0F, -32768]
6706    }
6707
6708    test_vec_1! { test_vec_unpackl_u, vec_unpackl, u16x8 -> u32x4,
6709        [0, 0, 0, 0, 0x1234, 0xFFFF, 0x0F0F, 0x8000],
6710        [0x1234, 0xFFFF, 0x0F0F, 0x8000]
6711    }
6712
6713    test_vec_2! { test_vec_avg, vec_avg, u32x4,
6714        [2, 1, u32::MAX, 0],
6715        [4, 2, 2, 0],
6716        [3, (1u32 + 2).div_ceil(2), (u32::MAX as u64 + 2u64).div_ceil(2) as u32, 0]
6717    }
6718
6719    test_vec_2! { test_vec_checksum, vec_checksum, u32x4,
6720        [1, 2, 3, u32::MAX],
6721        [5, 6, 7, 8],
6722        [0, 12, 0, 0]
6723    }
6724
6725    test_vec_2! { test_vec_add_u128, vec_add_u128, u8x16,
6726        [0x01, 0x05, 0x0F, 0x1A, 0x2F, 0x3F, 0x50, 0x65,
6727                              0x7A, 0x8F, 0x9A, 0xAD, 0xB0, 0xC3, 0xD5, 0xE8],
6728        [0xF0, 0xEF, 0xC3, 0xB1, 0x92, 0x71, 0x5A, 0x43,
6729                              0x3B, 0x29, 0x13, 0x04, 0xD7, 0xA1, 0x8C, 0x76],
6730        [0xF1, 0xF4, 0xD2, 0xCB, 0xC1, 0xB0, 0xAA, 0xA8, 0xB5, 0xB8, 0xAD, 0xB2, 0x88, 0x65, 0x62, 0x5E]
6731    }
6732
6733    #[simd_test(enable = "vector")]
6734    fn test_vec_addc_u128() {
6735        unsafe {
6736            let a = u128::MAX;
6737            let b = 1u128;
6738
6739            let d: u128 = transmute(vec_addc_u128(transmute(a), transmute(b)));
6740            assert!(a.checked_add(b).is_none());
6741            assert_eq!(d, 1);
6742
6743            let a = 1u128;
6744            let b = 1u128;
6745
6746            let d: u128 = transmute(vec_addc_u128(transmute(a), transmute(b)));
6747            assert!(a.checked_add(b).is_some());
6748            assert_eq!(d, 0);
6749        }
6750    }
6751
6752    #[simd_test(enable = "vector")]
6753    fn test_vec_subc_u128() {
6754        unsafe {
6755            let a = 0u128;
6756            let b = 1u128;
6757
6758            let d: u128 = transmute(vec_subc_u128(transmute(a), transmute(b)));
6759            assert!(a.checked_sub(b).is_none());
6760            assert_eq!(d, 0);
6761
6762            let a = 1u128;
6763            let b = 1u128;
6764
6765            let d: u128 = transmute(vec_subc_u128(transmute(a), transmute(b)));
6766            assert!(a.checked_sub(b).is_some());
6767            assert_eq!(d, 1);
6768        }
6769    }
6770
6771    test_vec_2! { test_vec_mule_u, vec_mule, u16x8, u16x8 -> u32x4,
6772        [0xFFFF, 0, 2, 0, 2, 0, 1, 0],
6773        [0xFFFF, 0, 4, 0, 0xFFFF, 0, 2, 0],
6774        [0xFFFE_0001, 8, 0x0001_FFFE, 2]
6775    }
6776
6777    test_vec_2! { test_vec_mule_i, vec_mule, i16x8, i16x8 -> i32x4,
6778        [i16::MIN, 0, -2, 0, 2, 0, 1, 0],
6779        [i16::MIN, 0, 4, 0, i16::MAX, 0, 2, 0],
6780        [0x4000_0000, -8, 0xFFFE, 2]
6781    }
6782
6783    test_vec_2! { test_vec_mulo_u, vec_mulo, u16x8, u16x8 -> u32x4,
6784        [0, 0xFFFF, 0, 2, 0, 2, 0, 1],
6785        [0, 0xFFFF, 0, 4, 0, 0xFFFF, 0, 2],
6786        [0xFFFE_0001, 8, 0x0001_FFFE, 2]
6787    }
6788
6789    test_vec_2! { test_vec_mulo_i, vec_mulo, i16x8, i16x8 -> i32x4,
6790        [0, i16::MIN, 0, -2, 0, 2, 0, 1],
6791        [0, i16::MIN, 0, 4, 0, i16::MAX, 0, 2],
6792        [0x4000_0000, -8, 0xFFFE, 2]
6793    }
6794
6795    test_vec_2! { test_vec_mulh_u, vec_mulh, u32x4, u32x4 -> u32x4,
6796        [u32::MAX, 2, 2, 1],
6797        [u32::MAX, 4, u32::MAX, 2],
6798        [u32::MAX - 1, 0, 1, 0]
6799    }
6800
6801    test_vec_2! { test_vec_mulh_i, vec_mulh, i32x4, i32x4 -> i32x4,
6802        [i32::MIN, -2, 2, 1],
6803        [i32::MIN, 4, i32::MAX, 2],
6804        [0x4000_0000, -1, 0, 0]
6805    }
6806
6807    test_vec_2! { test_vec_gfmsum_1, vec_gfmsum, u16x8, u16x8 -> u32x4,
6808        [0x1234, 0x5678, 0x9ABC, 0xDEF0, 0x1357, 0x2468, 0xACE0, 0xBDF0],
6809        [0xFFFF, 0x0001, 0x8000, 0x7FFF, 0xAAAA, 0x5555, 0x1234, 0x5678],
6810        [0xE13A794, 0x68764A50, 0x94AA3E, 0x2C93F300]
6811    }
6812
6813    test_vec_2! { test_vec_gfmsum_2, vec_gfmsum, u16x8, u16x8 -> u32x4,
6814        [0x0000, 0xFFFF, 0xAAAA, 0x5555, 0x1234, 0x5678, 0x9ABC, 0xDEF0],
6815        [0xFFFF, 0x0000, 0x5555, 0xAAAA, 0x0001, 0x8000, 0x7FFF, 0x1357],
6816        [0, 0, 0x2B3C1234, 0x3781D244]
6817    }
6818
6819    #[simd_test(enable = "vector")]
6820    fn test_vec_gfmsum_128() {
6821        let a = vector_unsigned_long_long([1, 2]);
6822        let b = vector_unsigned_long_long([3, 4]);
6823
6824        let d: u128 = unsafe { transmute(vec_gfmsum_128(a, b)) };
6825        assert_eq!(d, 11);
6826
6827        let a = vector_unsigned_long_long([0x0101010101010101, 0x0202020202020202]);
6828        let b = vector_unsigned_long_long([0x0404040404040404, 0x0505050505050505]);
6829
6830        let d: u128 = unsafe { transmute(vec_gfmsum_128(a, b)) };
6831        assert_eq!(d, 0xE000E000E000E000E000E000E000E);
6832    }
6833
6834    #[simd_test(enable = "vector-enhancements-1")]
6835    fn test_vec_bperm_u128() {
6836        let a = vector_unsigned_char([65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
6837        let b = vector_unsigned_char([
6838            0, 0, 0, 0, 1, 1, 1, 1, 128, 128, 128, 128, 255, 255, 255, 255,
6839        ]);
6840        let d = unsafe { vec_bperm_u128(a, b) };
6841        assert_eq!(d.as_array(), &[0xF00, 0]);
6842    }
6843
6844    #[simd_test(enable = "vector")]
6845    fn test_vec_sel() {
6846        let a = vector_signed_int([1, 2, 3, 4]);
6847        let b = vector_signed_int([5, 6, 7, 8]);
6848
6849        let e = vector_unsigned_int([9, 10, 11, 12]);
6850        let f = vector_unsigned_int([9, 9, 11, 11]);
6851
6852        let c: vector_bool_int = unsafe { simd_eq(e, f) };
6853        assert_eq!(c.as_array(), &[!0, 0, !0, 0]);
6854        let d: vector_signed_int = unsafe { vec_sel(a, b, c) };
6855        assert_eq!(d.as_array(), &[5, 2, 7, 4]);
6856    }
6857
6858    #[simd_test(enable = "vector")]
6859    fn test_vec_gather_element() {
6860        let a1: [u32; 10] = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
6861        let a2: [u32; 10] = [20, 21, 22, 23, 24, 25, 26, 27, 28, 29];
6862
6863        let v1 = vector_unsigned_int([1, 2, 3, 4]);
6864        let v2 = vector_unsigned_int([1, 2, 3, 4]);
6865
6866        let sizeof_int = core::mem::size_of::<u32>() as u32;
6867        let v3 = vector_unsigned_int([
6868            5 * sizeof_int,
6869            8 * sizeof_int,
6870            9 * sizeof_int,
6871            6 * sizeof_int,
6872        ]);
6873
6874        unsafe {
6875            let d1 = vec_gather_element::<_, 0>(v1, v3, a1.as_ptr());
6876            assert_eq!(d1.as_array(), &[15, 2, 3, 4]);
6877            let d2 = vec_gather_element::<_, 0>(v2, v3, a2.as_ptr());
6878            assert_eq!(d2.as_array(), &[25, 2, 3, 4]);
6879        }
6880    }
6881
6882    #[simd_test(enable = "vector")]
6883    fn test_vec_fp_test_data_class() {
6884        let mut cc = 42;
6885
6886        let v1 = vector_double([0.0, f64::NAN]);
6887        let v2 = vector_double([f64::INFINITY, 1.0]);
6888        let v3 = vector_double([1.0, 2.0]);
6889
6890        unsafe {
6891            let d = vec_fp_test_data_class::<_, __VEC_CLASS_FP_ZERO>(v1, &mut cc);
6892            assert_eq!(cc, 1);
6893            assert_eq!(d.as_array(), &[!0, 0]);
6894
6895            let d = vec_fp_test_data_class::<_, __VEC_CLASS_FP_NAN>(v1, &mut cc);
6896            assert_eq!(cc, 1);
6897            assert_eq!(d.as_array(), &[0, !0]);
6898
6899            let d = vec_fp_test_data_class::<_, __VEC_CLASS_FP_INFINITY>(v2, &mut cc);
6900            assert_eq!(cc, 1);
6901            assert_eq!(d.as_array(), &[!0, 0]);
6902
6903            let d = vec_fp_test_data_class::<_, __VEC_CLASS_FP_INFINITY_N>(v2, &mut cc);
6904            assert_eq!(cc, 3);
6905            assert_eq!(d.as_array(), &[0, 0]);
6906
6907            let d = vec_fp_test_data_class::<_, __VEC_CLASS_FP_NORMAL>(v2, &mut cc);
6908            assert_eq!(cc, 1);
6909            assert_eq!(d.as_array(), &[0, !0]);
6910
6911            let d = vec_fp_test_data_class::<_, __VEC_CLASS_FP_NORMAL>(v3, &mut cc);
6912            assert_eq!(cc, 0);
6913            assert_eq!(d.as_array(), &[!0, !0]);
6914        }
6915    }
6916
6917    #[simd_test(enable = "vector")]
6918    fn test_vec_fp_any_all_nan_numeric() {
6919        unsafe {
6920            assert_eq!(
6921                vec_all_nan(vector_double([f64::NAN, f64::NAN])),
6922                i32::from(true)
6923            );
6924            assert_eq!(
6925                vec_all_nan(vector_double([f64::NAN, 1.0])),
6926                i32::from(false)
6927            );
6928            assert_eq!(vec_all_nan(vector_double([0.0, 1.0])), i32::from(false));
6929
6930            assert_eq!(
6931                vec_any_nan(vector_double([f64::NAN, f64::NAN])),
6932                i32::from(true)
6933            );
6934            assert_eq!(vec_any_nan(vector_double([f64::NAN, 1.0])), i32::from(true));
6935            assert_eq!(vec_any_nan(vector_double([0.0, 1.0])), i32::from(false));
6936
6937            assert_eq!(
6938                vec_all_numeric(vector_double([f64::NAN, f64::NAN])),
6939                i32::from(false)
6940            );
6941            assert_eq!(
6942                vec_all_numeric(vector_double([f64::NAN, 1.0])),
6943                i32::from(false)
6944            );
6945            assert_eq!(vec_all_numeric(vector_double([0.0, 1.0])), i32::from(true));
6946
6947            assert_eq!(
6948                vec_any_numeric(vector_double([f64::NAN, f64::NAN])),
6949                i32::from(false)
6950            );
6951            assert_eq!(
6952                vec_any_numeric(vector_double([f64::NAN, 1.0])),
6953                i32::from(true)
6954            );
6955            assert_eq!(vec_any_numeric(vector_double([0.0, 1.0])), i32::from(true));
6956
6957            // "numeric" means "not NaN". infinities are numeric
6958            assert_eq!(
6959                vec_all_numeric(vector_double([f64::INFINITY, f64::NEG_INFINITY])),
6960                i32::from(true)
6961            );
6962            assert_eq!(
6963                vec_any_numeric(vector_double([f64::INFINITY, f64::NEG_INFINITY])),
6964                i32::from(true)
6965            );
6966        }
6967    }
6968
6969    #[simd_test(enable = "vector")]
6970    fn test_vec_test_mask() {
6971        unsafe {
6972            let v = vector_unsigned_long_long([0xFF00FF00FF00FF00; 2]);
6973            let m = vector_unsigned_long_long([0x0000FF000000FF00; 2]);
6974            assert_eq!(vec_test_mask(v, m), 3);
6975
6976            let v = vector_unsigned_long_long([u64::MAX; 2]);
6977            let m = vector_unsigned_long_long([0; 2]);
6978            assert_eq!(vec_test_mask(v, m), 0);
6979
6980            let v = vector_unsigned_long_long([0; 2]);
6981            let m = vector_unsigned_long_long([u64::MAX; 2]);
6982            assert_eq!(vec_test_mask(v, m), 0);
6983
6984            let v = vector_unsigned_long_long([0xAAAAAAAAAAAAAAAA; 2]);
6985            let m = vector_unsigned_long_long([0xAAAAAAAAAAAAAAAA; 2]);
6986            assert_eq!(vec_test_mask(v, m), 3);
6987        }
6988    }
6989
6990    #[simd_test(enable = "vector-enhancements-2")]
6991    fn test_vec_search_string_cc() {
6992        unsafe {
6993            let b = vector_unsigned_char(*b"ABCD------------");
6994            let c = vector_unsigned_char([4; 16]);
6995
6996            let haystack = vector_unsigned_char(*b"__ABCD__________");
6997            let (result, d) = vec_search_string_cc(haystack, b, c);
6998            assert_eq!(result.as_array()[7], 2);
6999            assert_eq!(d, 2);
7000
7001            let haystack = vector_unsigned_char(*b"___ABCD_________");
7002            let (result, d) = vec_search_string_cc(haystack, b, c);
7003            assert_eq!(result.as_array()[7], 3);
7004            assert_eq!(d, 2);
7005
7006            let haystack = vector_unsigned_char(*b"________________");
7007            let (result, d) = vec_search_string_cc(haystack, b, c);
7008            assert_eq!(result.as_array()[7], 16);
7009            assert_eq!(d, 0);
7010
7011            let haystack = vector_unsigned_char(*b"______\0_________");
7012            let (result, d) = vec_search_string_cc(haystack, b, c);
7013            assert_eq!(result.as_array()[7], 16);
7014            assert_eq!(d, 0);
7015
7016            let haystack = vector_unsigned_char(*b"______\0__ABCD___");
7017            let (result, d) = vec_search_string_cc(haystack, b, c);
7018            assert_eq!(result.as_array()[7], 9);
7019            assert_eq!(d, 2);
7020        }
7021    }
7022
7023    #[simd_test(enable = "vector-enhancements-2")]
7024    fn test_vec_search_string_until_zero_cc() {
7025        unsafe {
7026            let b = vector_unsigned_char(*b"ABCD\0\0\0\0\0\0\0\0\0\0\0\0");
7027            let c = vector_unsigned_char([16; 16]);
7028
7029            let haystack = vector_unsigned_char(*b"__ABCD__________");
7030            let (result, d) = vec_search_string_until_zero_cc(haystack, b, c);
7031            assert_eq!(result.as_array()[7], 2);
7032            assert_eq!(d, 2);
7033
7034            let haystack = vector_unsigned_char(*b"___ABCD_________");
7035            let (result, d) = vec_search_string_until_zero_cc(haystack, b, c);
7036            assert_eq!(result.as_array()[7], 3);
7037            assert_eq!(d, 2);
7038
7039            let haystack = vector_unsigned_char(*b"________________");
7040            let (result, d) = vec_search_string_until_zero_cc(haystack, b, c);
7041            assert_eq!(result.as_array()[7], 16);
7042            assert_eq!(d, 0);
7043
7044            let haystack = vector_unsigned_char(*b"______\0_________");
7045            let (result, d) = vec_search_string_until_zero_cc(haystack, b, c);
7046            assert_eq!(result.as_array()[7], 16);
7047            assert_eq!(d, 1);
7048
7049            let haystack = vector_unsigned_char(*b"______\0__ABCD___");
7050            let (result, d) = vec_search_string_until_zero_cc(haystack, b, c);
7051            assert_eq!(result.as_array()[7], 16);
7052            assert_eq!(d, 1);
7053        }
7054    }
7055
7056    #[simd_test(enable = "vector")]
7057    fn test_vec_doublee() {
7058        unsafe {
7059            let v = vector_float([1.0, 2.0, 3.0, 4.0]);
7060            assert_eq!(vec_doublee(v).as_array(), &[1.0, 3.0]);
7061
7062            let v = vector_float([f32::NAN, 2.0, f32::INFINITY, 4.0]);
7063            let d = vec_doublee(v);
7064            assert!(d.as_array()[0].is_nan());
7065            assert_eq!(d.as_array()[1], f64::INFINITY);
7066        }
7067    }
7068
7069    #[simd_test(enable = "vector")]
7070    fn test_vec_floate() {
7071        // NOTE: indices 1 and 3 can have an arbitrary value. With the C version
7072        // these are poison values, our version initializes the memory but its
7073        // value still should not be relied upon by application code.
7074        unsafe {
7075            let v = vector_double([1.0, 2.0]);
7076            let d = vec_floate(v);
7077            assert_eq!(d.as_array()[0], 1.0);
7078            assert_eq!(d.as_array()[2], 2.0);
7079
7080            let v = vector_double([f64::NAN, f64::INFINITY]);
7081            let d = vec_floate(v);
7082            assert!(d.as_array()[0].is_nan());
7083            assert_eq!(d.as_array()[2], f32::INFINITY);
7084
7085            let v = vector_double([f64::MIN, f64::MAX]);
7086            let d = vec_floate(v);
7087            assert_eq!(d.as_array()[0], f64::MIN as f32);
7088            assert_eq!(d.as_array()[2], f64::MAX as f32);
7089        }
7090    }
7091
7092    #[simd_test(enable = "vector")]
7093    fn test_vec_extend_s64() {
7094        unsafe {
7095            let v = vector_signed_char([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
7096            assert_eq!(vec_extend_s64(v).as_array(), &[7, 15]);
7097
7098            let v = vector_signed_short([0, 1, 2, 3, 4, 5, 6, 7]);
7099            assert_eq!(vec_extend_s64(v).as_array(), &[3, 7]);
7100
7101            let v = vector_signed_int([0, 1, 2, 3]);
7102            assert_eq!(vec_extend_s64(v).as_array(), &[1, 3]);
7103        }
7104    }
7105
7106    #[simd_test(enable = "vector")]
7107    fn test_vec_signed() {
7108        unsafe {
7109            let v = vector_float([1.0, 2.5, -2.5, -0.0]);
7110            assert_eq!(vec_signed(v).as_array(), &[1, 2, -2, 0]);
7111
7112            let v = vector_double([2.5, -2.5]);
7113            assert_eq!(vec_signed(v).as_array(), &[2, -2]);
7114        }
7115    }
7116
7117    #[simd_test(enable = "vector")]
7118    fn test_vec_unsigned() {
7119        // NOTE: converting a negative floating point value is UB!
7120        unsafe {
7121            let v = vector_float([1.0, 2.5, 3.5, 0.0]);
7122            assert_eq!(vec_unsigned(v).as_array(), &[1, 2, 3, 0]);
7123
7124            let v = vector_double([2.5, 3.5]);
7125            assert_eq!(vec_unsigned(v).as_array(), &[2, 3]);
7126        }
7127    }
7128
7129    #[simd_test(enable = "vector")]
7130    fn test_vec_cp_until_zero() {
7131        unsafe {
7132            let v = vector_signed_int([1, 2, 3, 4]);
7133            let d = vec_cp_until_zero(v);
7134            assert_eq!(d.as_array(), &[1, 2, 3, 4]);
7135
7136            let v = vector_signed_int([1, 2, 0, 4]);
7137            let d = vec_cp_until_zero(v);
7138            assert_eq!(d.as_array(), &[1, 2, 0, 0]);
7139        }
7140    }
7141
7142    #[simd_test(enable = "vector")]
7143    fn test_vec_cp_until_zero_cc() {
7144        unsafe {
7145            let v = vector_signed_int([1, 2, 3, 4]);
7146            let (d, cc) = vec_cp_until_zero_cc(v);
7147            assert_eq!(d.as_array(), &[1, 2, 3, 4]);
7148            assert_eq!(cc, 3);
7149
7150            let v = vector_signed_int([1, 2, 0, 4]);
7151            let (d, cc) = vec_cp_until_zero_cc(v);
7152            assert_eq!(d.as_array(), &[1, 2, 0, 0]);
7153            assert_eq!(cc, 0);
7154        }
7155    }
7156
7157    #[simd_test(enable = "vector-enhancements-1")]
7158    fn test_vec_msum_u128() {
7159        let a = vector_unsigned_long_long([1, 2]);
7160        let b = vector_unsigned_long_long([3, 4]);
7161
7162        unsafe {
7163            let c: vector_unsigned_char = transmute(100u128);
7164
7165            let d: u128 = transmute(vec_msum_u128::<0>(a, b, c));
7166            assert_eq!(d, (1 * 3) + (2 * 4) + 100);
7167
7168            let d: u128 = transmute(vec_msum_u128::<4>(a, b, c));
7169            assert_eq!(d, (1 * 3) + (2 * 4) * 2 + 100);
7170
7171            let d: u128 = transmute(vec_msum_u128::<8>(a, b, c));
7172            assert_eq!(d, (1 * 3) * 2 + (2 * 4) + 100);
7173
7174            let d: u128 = transmute(vec_msum_u128::<12>(a, b, c));
7175            assert_eq!(d, (1 * 3) * 2 + (2 * 4) * 2 + 100);
7176        }
7177    }
7178
7179    #[simd_test(enable = "vector")]
7180    fn test_vec_sld() {
7181        let a = vector_unsigned_long_long([0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA]);
7182        let b = vector_unsigned_long_long([0xBBBBBBBBBBBBBBBB, 0xBBBBBBBBBBBBBBBB]);
7183
7184        unsafe {
7185            let d = vec_sld::<_, 4>(a, b);
7186            assert_eq!(d.as_array(), &[0xAAAAAAAAAAAAAAAA, 0xAAAAAAAABBBBBBBB]);
7187        }
7188    }
7189
7190    #[simd_test(enable = "vector")]
7191    fn test_vec_sldw() {
7192        let a = vector_unsigned_long_long([0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA]);
7193        let b = vector_unsigned_long_long([0xBBBBBBBBBBBBBBBB, 0xBBBBBBBBBBBBBBBB]);
7194
7195        unsafe {
7196            let d = vec_sldw::<_, 1>(a, b);
7197            assert_eq!(d.as_array(), &[0xAAAAAAAAAAAAAAAA, 0xAAAAAAAABBBBBBBB]);
7198        }
7199    }
7200
7201    #[simd_test(enable = "vector-enhancements-2")]
7202    fn test_vec_sldb() {
7203        let a = vector_unsigned_long_long([0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA]);
7204        let b = vector_unsigned_long_long([0xBBBBBBBBBBBBBBBB, 0xBBBBBBBBBBBBBBBB]);
7205
7206        unsafe {
7207            let d = vec_sldb::<_, 4>(a, b);
7208            assert_eq!(d.as_array(), &[0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAB]);
7209        }
7210    }
7211
7212    #[simd_test(enable = "vector-enhancements-2")]
7213    fn test_vec_srdb() {
7214        let a = vector_unsigned_long_long([0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA]);
7215        let b = vector_unsigned_long_long([0xBBBBBBBBBBBBBBBB, 0xBBBBBBBBBBBBBBBB]);
7216
7217        unsafe {
7218            let d = vec_srdb::<_, 4>(a, b);
7219            assert_eq!(d.as_array(), &[0xABBBBBBBBBBBBBBB, 0xBBBBBBBBBBBBBBBB]);
7220        }
7221    }
7222
7223    const GT: u32 = 0x20000000;
7224    const LT: u32 = 0x40000000;
7225    const EQ: u32 = 0x80000000;
7226
7227    #[simd_test(enable = "vector")]
7228    fn test_vec_cmprg() {
7229        let a = vector_unsigned_int([11, 22, 33, 44]);
7230        let b = vector_unsigned_int([10, 20, 30, 40]);
7231
7232        let c = vector_unsigned_int([GT, LT, GT, LT]);
7233        let d = unsafe { vec_cmprg(a, b, c) };
7234        assert_eq!(d.as_array(), &[!0, 0, !0, 0]);
7235
7236        let c = vector_unsigned_int([GT, LT, 0, 0]);
7237        let d = unsafe { vec_cmprg(a, b, c) };
7238        assert_eq!(d.as_array(), &[!0, 0, 0, 0]);
7239
7240        let a = vector_unsigned_int([11, 22, 33, 30]);
7241        let b = vector_unsigned_int([10, 20, 30, 30]);
7242
7243        let c = vector_unsigned_int([GT, LT, EQ, EQ]);
7244        let d = unsafe { vec_cmprg(a, b, c) };
7245        assert_eq!(d.as_array(), &[!0, 0, 0, !0]);
7246    }
7247
7248    #[simd_test(enable = "vector")]
7249    fn test_vec_cmpnrg() {
7250        let a = vector_unsigned_int([11, 22, 33, 44]);
7251        let b = vector_unsigned_int([10, 20, 30, 40]);
7252
7253        let c = vector_unsigned_int([GT, LT, GT, LT]);
7254        let d = unsafe { vec_cmpnrg(a, b, c) };
7255        assert_eq!(d.as_array(), &[0, !0, 0, !0]);
7256
7257        let c = vector_unsigned_int([GT, LT, 0, 0]);
7258        let d = unsafe { vec_cmpnrg(a, b, c) };
7259        assert_eq!(d.as_array(), &[0, !0, !0, !0]);
7260
7261        let a = vector_unsigned_int([11, 22, 33, 30]);
7262        let b = vector_unsigned_int([10, 20, 30, 30]);
7263
7264        let c = vector_unsigned_int([GT, LT, EQ, EQ]);
7265        let d = unsafe { vec_cmpnrg(a, b, c) };
7266        assert_eq!(d.as_array(), &[0, !0, !0, 0]);
7267    }
7268
7269    #[simd_test(enable = "vector")]
7270    fn test_vec_cmprg_idx() {
7271        let a = vector_unsigned_int([1, 11, 22, 33]);
7272        let b = vector_unsigned_int([10, 20, 30, 40]);
7273
7274        let c = vector_unsigned_int([GT, LT, GT, LT]);
7275        let d = unsafe { vec_cmprg_idx(a, b, c) };
7276        assert_eq!(d.as_array(), &[0, 4, 0, 0]);
7277    }
7278
7279    #[simd_test(enable = "vector")]
7280    fn test_vec_cmpnrg_idx() {
7281        let a = vector_unsigned_int([1, 11, 22, 33]);
7282        let b = vector_unsigned_int([10, 20, 30, 40]);
7283
7284        let c = vector_unsigned_int([GT, LT, GT, LT]);
7285        let d = unsafe { vec_cmpnrg_idx(a, b, c) };
7286        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
7287    }
7288
7289    #[simd_test(enable = "vector")]
7290    fn test_vec_cmprg_or_0_idx() {
7291        let a = vector_unsigned_int([1, 0, 22, 33]);
7292        let b = vector_unsigned_int([10, 20, 30, 40]);
7293
7294        let c = vector_unsigned_int([GT, LT, GT, LT]);
7295        let d = unsafe { vec_cmprg_or_0_idx(a, b, c) };
7296        assert_eq!(d.as_array(), &[0, 4, 0, 0]);
7297    }
7298
7299    #[simd_test(enable = "vector")]
7300    fn test_vec_cmpnrg_or_0_idx() {
7301        let a = vector_unsigned_int([11, 33, 0, 22]);
7302        let b = vector_unsigned_int([10, 20, 30, 40]);
7303
7304        let c = vector_unsigned_int([GT, LT, GT, LT]);
7305        let d = unsafe { vec_cmpnrg_or_0_idx(a, b, c) };
7306        assert_eq!(d.as_array(), &[0, 8, 0, 0]);
7307    }
7308
7309    test_vec_2! { test_vec_cmpgt, vec_cmpgt, f32x4, f32x4 -> i32x4,
7310        [1.0, f32::NAN, f32::NAN, 3.14],
7311        [2.0, f32::NAN, 5.0, 2.0],
7312        [0, 0, 0, !0]
7313    }
7314
7315    test_vec_2! { test_vec_cmpge, vec_cmpge, f32x4, f32x4 -> i32x4,
7316        [1.0, f32::NAN, f32::NAN, 3.14],
7317        [1.0, f32::NAN, 5.0, 2.0],
7318        [!0, 0, 0, !0]
7319    }
7320
7321    test_vec_2! { test_vec_cmplt, vec_cmplt, f32x4, f32x4 -> i32x4,
7322        [1.0, f32::NAN, f32::NAN, 2.0],
7323        [2.0, f32::NAN, 5.0, 2.0],
7324        [!0, 0, 0, 0]
7325    }
7326
7327    test_vec_2! { test_vec_cmple, vec_cmple, f32x4, f32x4 -> i32x4,
7328        [1.0, f32::NAN, f32::NAN, 2.0],
7329        [1.0, f32::NAN, 5.0, 3.14],
7330        [!0, 0, 0, !0]
7331    }
7332
7333    test_vec_2! { test_vec_cmpeq, vec_cmpeq, f32x4, f32x4 -> i32x4,
7334        [1.0, f32::NAN, f32::NAN, 2.0],
7335        [1.0, f32::NAN, 5.0, 3.14],
7336        [!0, 0, 0, 0]
7337    }
7338
7339    test_vec_2! { test_vec_cmpne, vec_cmpne, f32x4, f32x4 -> i32x4,
7340        [1.0, f32::NAN, f32::NAN, 2.0],
7341        [1.0, f32::NAN, 5.0, 3.14],
7342        [0, !0, !0, !0]
7343    }
7344
7345    #[simd_test(enable = "vector")]
7346    fn test_vec_meadd() {
7347        let a = vector_unsigned_short([1, 0, 2, 0, 3, 0, 4, 0]);
7348        let b = vector_unsigned_short([5, 0, 6, 0, 7, 0, 8, 0]);
7349        let c = vector_unsigned_int([2, 2, 2, 2]);
7350
7351        let d = unsafe { vec_meadd(a, b, c) };
7352        assert_eq!(d.as_array(), &[7, 14, 23, 34]);
7353
7354        let a = vector_signed_short([1, 0, 2, 0, 3, 0, 4, 0]);
7355        let b = vector_signed_short([5, 0, 6, 0, 7, 0, 8, 0]);
7356        let c = vector_signed_int([2, -2, 2, -2]);
7357
7358        let d = unsafe { vec_meadd(a, b, c) };
7359        assert_eq!(d.as_array(), &[7, 10, 23, 30]);
7360    }
7361
7362    #[simd_test(enable = "vector")]
7363    fn test_vec_moadd() {
7364        let a = vector_unsigned_short([0, 1, 0, 2, 0, 3, 0, 4]);
7365        let b = vector_unsigned_short([0, 5, 0, 6, 0, 7, 0, 8]);
7366        let c = vector_unsigned_int([2, 2, 2, 2]);
7367
7368        let d = unsafe { vec_moadd(a, b, c) };
7369        assert_eq!(d.as_array(), &[7, 14, 23, 34]);
7370
7371        let a = vector_signed_short([0, 1, 0, 2, 0, 3, 0, 4]);
7372        let b = vector_signed_short([0, 5, 0, 6, 0, 7, 0, 8]);
7373        let c = vector_signed_int([2, -2, 2, -2]);
7374
7375        let d = unsafe { vec_moadd(a, b, c) };
7376        assert_eq!(d.as_array(), &[7, 10, 23, 30]);
7377    }
7378
7379    #[simd_test(enable = "vector")]
7380    fn test_vec_mhadd() {
7381        let a = vector_unsigned_int([1, 2, 3, 4]);
7382        let b = vector_unsigned_int([5, 6, 7, 8]);
7383        let c = vector_unsigned_int([u32::MAX; 4]);
7384
7385        let d = unsafe { vec_mhadd(a, b, c) };
7386        assert_eq!(d.as_array(), &[1, 1, 1, 1]);
7387
7388        let a = vector_signed_int([-1, -2, -3, -4]);
7389        let b = vector_signed_int([5, 6, 7, 8]);
7390        let c = vector_signed_int([i32::MIN; 4]);
7391
7392        let d = unsafe { vec_mhadd(a, b, c) };
7393        assert_eq!(d.as_array(), &[-1, -1, -1, -1]);
7394    }
7395
7396    #[simd_test(enable = "vector")]
7397    fn test_vec_mladd() {
7398        let a = vector_unsigned_int([1, 2, 3, 4]);
7399        let b = vector_unsigned_int([5, 6, 7, 8]);
7400        let c = vector_unsigned_int([2, 2, 2, 2]);
7401
7402        let d = unsafe { vec_mladd(a, b, c) };
7403        assert_eq!(d.as_array(), &[7, 14, 23, 34]);
7404
7405        let a = vector_signed_int([-1, -2, -3, -4]);
7406        let b = vector_signed_int([5, 6, 7, 8]);
7407        let c = vector_signed_int([2, 2, 2, 2]);
7408
7409        let d = unsafe { vec_mladd(a, b, c) };
7410        assert_eq!(d.as_array(), &[-3, -10, -19, -30]);
7411    }
7412
7413    #[simd_test(enable = "vector")]
7414    fn test_vec_extract() {
7415        let v = vector_unsigned_int([1, 2, 3, 4]);
7416
7417        assert_eq!(unsafe { vec_extract(v, 1) }, 2);
7418        assert_eq!(unsafe { vec_extract(v, 4 + 2) }, 3);
7419    }
7420
7421    #[simd_test(enable = "vector")]
7422    fn test_vec_insert() {
7423        let mut v = vector_unsigned_int([1, 2, 3, 4]);
7424
7425        v = unsafe { vec_insert(42, v, 1) };
7426        assert_eq!(v.as_array(), &[1, 42, 3, 4]);
7427
7428        v = unsafe { vec_insert(64, v, 6) };
7429        assert_eq!(v.as_array(), &[1, 42, 64, 4]);
7430    }
7431
7432    #[simd_test(enable = "vector")]
7433    fn test_vec_promote() {
7434        let v: vector_unsigned_int = unsafe { vec_promote(42, 1).assume_init() };
7435        assert_eq!(v.as_array(), &[0, 42, 0, 0]);
7436    }
7437
7438    #[simd_test(enable = "vector")]
7439    fn test_vec_insert_and_zero() {
7440        let v = unsafe { vec_insert_and_zero::<vector_unsigned_int>(&42u32) };
7441        assert_eq!(v.as_array(), vector_unsigned_int([0, 42, 0, 0]).as_array());
7442    }
7443}