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