Skip to main content

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