Thanks to visit codestin.com
Credit goes to doc.rust-lang.org

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

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