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