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