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::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.fshl.v16i8"] fn fshlb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> vector_unsigned_char;
101    #[link_name = "llvm.fshl.v8i16"] fn fshlh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short;
102    #[link_name = "llvm.fshl.v4i32"] fn fshlf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int;
103    #[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;
104
105    #[link_name = "llvm.s390.verimb"] fn verimb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char, d: i32) -> vector_signed_char;
106    #[link_name = "llvm.s390.verimh"] fn verimh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short, d: i32) -> vector_signed_short;
107    #[link_name = "llvm.s390.verimf"] fn verimf(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int, d: i32) -> vector_signed_int;
108    #[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;
109
110    #[link_name = "llvm.s390.vperm"] fn vperm(a: vector_signed_char, b: vector_signed_char, c: vector_unsigned_char) -> vector_signed_char;
111
112    #[link_name = "llvm.s390.vsumb"] fn vsumb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_int;
113    #[link_name = "llvm.s390.vsumh"] fn vsumh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int;
114
115    #[link_name = "llvm.s390.vsumgh"] fn vsumgh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_long_long;
116    #[link_name = "llvm.s390.vsumgf"] fn vsumgf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long;
117
118    #[link_name = "llvm.s390.vsumqf"] fn vsumqf(a: vector_unsigned_int, b: vector_unsigned_int) -> u128;
119    #[link_name = "llvm.s390.vsumqg"] fn vsumqg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> u128;
120
121    #[link_name = "llvm.s390.vscbiq"] fn vscbiq(a: u128, b: u128) -> u128;
122    #[link_name = "llvm.s390.vsbiq"] fn vsbiq(a: u128, b: u128, c: u128) -> u128;
123    #[link_name = "llvm.s390.vsbcbiq"] fn vsbcbiq(a: u128, b: u128, c: u128) -> u128;
124
125    #[link_name = "llvm.s390.vscbib"] fn vscbib(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
126    #[link_name = "llvm.s390.vscbih"] fn vscbih(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
127    #[link_name = "llvm.s390.vscbif"] fn vscbif(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
128    #[link_name = "llvm.s390.vscbig"] fn vscbig(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long;
129
130    #[link_name = "llvm.s390.vfaeb"] fn vfaeb(a: vector_signed_char, b: vector_signed_char, c: i32) -> vector_signed_char;
131    #[link_name = "llvm.s390.vfaeh"] fn vfaeh(a: vector_signed_short, b: vector_signed_short, c: i32) -> vector_signed_short;
132    #[link_name = "llvm.s390.vfaef"] fn vfaef(a: vector_signed_int, b: vector_signed_int, c: i32) -> vector_signed_int;
133
134    #[link_name = "llvm.s390.vfaezb"] fn vfaezb(a: vector_signed_char, b: vector_signed_char, c: i32) -> vector_signed_char;
135    #[link_name = "llvm.s390.vfaezh"] fn vfaezh(a: vector_signed_short, b: vector_signed_short, c: i32) -> vector_signed_short;
136    #[link_name = "llvm.s390.vfaezf"] fn vfaezf(a: vector_signed_int, b: vector_signed_int, c: i32) -> vector_signed_int;
137
138    #[link_name = "llvm.s390.vfaebs"] fn vfaebs(a: vector_signed_char, b: vector_signed_char, c: i32) -> PackedTuple<vector_signed_char, i32>;
139    #[link_name = "llvm.s390.vfaehs"] fn vfaehs(a: vector_signed_short, b: vector_signed_short, c: i32) -> PackedTuple<vector_signed_short, i32>;
140    #[link_name = "llvm.s390.vfaefs"] fn vfaefs(a: vector_signed_int, b: vector_signed_int, c: i32) -> PackedTuple<vector_signed_int, i32>;
141
142    #[link_name = "llvm.s390.vfaezbs"] fn vfaezbs(a: vector_signed_char, b: vector_signed_char, c: i32) -> PackedTuple<vector_signed_char, i32>;
143    #[link_name = "llvm.s390.vfaezhs"] fn vfaezhs(a: vector_signed_short, b: vector_signed_short, c: i32) -> PackedTuple<vector_signed_short, i32>;
144    #[link_name = "llvm.s390.vfaezfs"] fn vfaezfs(a: vector_signed_int, b: vector_signed_int, c: i32) -> PackedTuple<vector_signed_int, i32>;
145}
146
147impl_from! { i8x16, u8x16,  i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 }
148
149impl_neg! { i8x16 : 0 }
150impl_neg! { i16x8 : 0 }
151impl_neg! { i32x4 : 0 }
152impl_neg! { i64x2 : 0 }
153impl_neg! { f32x4 : 0f32 }
154impl_neg! { f64x2 : 0f64 }
155
156#[repr(simd)]
157struct ShuffleMask<const N: usize>([u32; N]);
158
159impl<const N: usize> ShuffleMask<N> {
160    const fn reverse() -> Self {
161        let mut index = [0; N];
162        let mut i = 0;
163        while i < N {
164            index[i] = (N - i - 1) as u32;
165            i += 1;
166        }
167        ShuffleMask(index)
168    }
169
170    const fn merge_low() -> Self {
171        let mut mask = [0; N];
172        let mut i = N / 2;
173        let mut index = 0;
174        while index < N {
175            mask[index] = i as u32;
176            mask[index + 1] = (i + N) as u32;
177
178            i += 1;
179            index += 2;
180        }
181        ShuffleMask(mask)
182    }
183
184    const fn merge_high() -> Self {
185        let mut mask = [0; N];
186        let mut i = 0;
187        let mut index = 0;
188        while index < N {
189            mask[index] = i as u32;
190            mask[index + 1] = (i + N) as u32;
191
192            i += 1;
193            index += 2;
194        }
195        ShuffleMask(mask)
196    }
197}
198
199const fn genmask<const MASK: u16>() -> [u8; 16] {
200    let mut bits = MASK;
201    let mut elements = [0u8; 16];
202
203    let mut i = 0;
204    while i < 16 {
205        elements[i] = match bits & (1u16 << 15) {
206            0 => 0,
207            _ => 0xFF,
208        };
209
210        bits <<= 1;
211        i += 1;
212    }
213
214    elements
215}
216
217const fn genmasks(bit_width: u32, a: u8, b: u8) -> u64 {
218    let bit_width = bit_width as u8;
219    let a = a % bit_width;
220    let mut b = b % bit_width;
221    if a > b {
222        b = bit_width - 1;
223    }
224
225    // of course these indices start from the left
226    let a = (bit_width - 1) - a;
227    let b = (bit_width - 1) - b;
228
229    ((1u64.wrapping_shl(a as u32 + 1)) - 1) & !((1u64.wrapping_shl(b as u32)) - 1)
230}
231
232#[macro_use]
233mod sealed {
234    use super::*;
235
236    #[unstable(feature = "stdarch_s390x", issue = "135681")]
237    pub trait VectorAdd<Other> {
238        type Result;
239        unsafe fn vec_add(self, other: Other) -> Self::Result;
240    }
241
242    macro_rules! impl_add {
243        ($name:ident, $a:ty, $instr:ident) => {
244            impl_add!($name, $a, $a, $a, $instr);
245        };
246        ($name:ident, $a:ty, $b:ty, $c:ty, $instr:ident) => {
247            #[inline]
248            #[target_feature(enable = "vector")]
249            #[cfg_attr(test, assert_instr($instr))]
250            pub unsafe fn $name(a: $a, b: $b) -> $c {
251                transmute(simd_add(transmute(a), b))
252            }
253
254            #[unstable(feature = "stdarch_s390x", issue = "135681")]
255            impl VectorAdd<$b> for $a {
256                type Result = $c;
257
258                #[inline]
259                #[target_feature(enable = "vector")]
260                unsafe fn vec_add(self, other: $b) -> Self::Result {
261                    $name(self, other)
262                }
263            }
264        };
265    }
266
267    #[rustfmt::skip]
268    mod impl_add {
269        use super::*;
270
271        impl_add!(va_sc, vector_signed_char, vab);
272        impl_add!(va_uc, vector_unsigned_char, vab);
273        impl_add!(va_sh, vector_signed_short, vah);
274        impl_add!(va_uh, vector_unsigned_short, vah);
275        impl_add!(va_sf, vector_signed_int, vaf);
276        impl_add!(va_uf, vector_unsigned_int, vaf);
277        impl_add!(va_sg, vector_signed_long_long, vag);
278        impl_add!(va_ug, vector_unsigned_long_long, vag);
279
280        impl_add!(va_sc_bc, vector_signed_char, vector_bool_char, vector_signed_char, vab);
281        impl_add!(va_uc_bc, vector_unsigned_char, vector_bool_char, vector_unsigned_char, vab);
282        impl_add!(va_sh_bh, vector_signed_short, vector_bool_short, vector_signed_short, vah);
283        impl_add!(va_uh_bh, vector_unsigned_short, vector_bool_short, vector_unsigned_short, vah);
284        impl_add!(va_sf_bf, vector_signed_int, vector_bool_int, vector_signed_int, vaf);
285        impl_add!(va_uf_bf, vector_unsigned_int, vector_bool_int, vector_unsigned_int, vaf);
286        impl_add!(va_sg_bg, vector_signed_long_long, vector_bool_long_long, vector_signed_long_long, vag);
287        impl_add!(va_ug_bg, vector_unsigned_long_long, vector_bool_long_long, vector_unsigned_long_long, vag);
288
289        impl_add!(va_bc_sc, vector_bool_char, vector_signed_char, vector_signed_char, vab);
290        impl_add!(va_bc_uc, vector_bool_char, vector_unsigned_char, vector_unsigned_char, vab);
291        impl_add!(va_bh_sh, vector_bool_short, vector_signed_short, vector_signed_short, vah);
292        impl_add!(va_bh_uh, vector_bool_short, vector_unsigned_short, vector_unsigned_short, vah);
293        impl_add!(va_bf_sf, vector_bool_int, vector_signed_int, vector_signed_int, vaf);
294        impl_add!(va_bf_uf, vector_bool_int, vector_unsigned_int, vector_unsigned_int, vaf);
295        impl_add!(va_bg_sg, vector_bool_long_long, vector_signed_long_long, vector_signed_long_long, vag);
296        impl_add!(va_bg_ug, vector_bool_long_long, vector_unsigned_long_long, vector_unsigned_long_long, vag);
297
298        impl_add!(va_double, vector_double, vfadb);
299
300        #[inline]
301        #[target_feature(enable = "vector")]
302        #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vfasb))]
303        pub unsafe fn va_float(a: vector_float, b: vector_float) -> vector_float {
304            transmute(simd_add(a, b))
305        }
306
307        #[unstable(feature = "stdarch_s390x", issue = "135681")]
308        impl VectorAdd<Self> for vector_float {
309            type Result = Self;
310
311            #[inline]
312            #[target_feature(enable = "vector")]
313            unsafe fn vec_add(self, other: Self) -> Self::Result {
314                va_float(self, other)
315            }
316        }
317    }
318
319    #[unstable(feature = "stdarch_s390x", issue = "135681")]
320    pub trait VectorSub<Other> {
321        type Result;
322        unsafe fn vec_sub(self, other: Other) -> Self::Result;
323    }
324
325    macro_rules! impl_sub {
326        ($name:ident, $a:ty, $instr:ident) => {
327            impl_sub!($name, $a, $a, $a, $instr);
328        };
329        ($name:ident, $a:ty, $b:ty, $c:ty, $instr:ident) => {
330            #[inline]
331            #[target_feature(enable = "vector")]
332            #[cfg_attr(test, assert_instr($instr))]
333            pub unsafe fn $name(a: $a, b: $b) -> $c {
334                transmute(simd_sub(transmute(a), b))
335            }
336
337            #[unstable(feature = "stdarch_s390x", issue = "135681")]
338            impl VectorSub<$b> for $a {
339                type Result = $c;
340
341                #[inline]
342                #[target_feature(enable = "vector")]
343                unsafe fn vec_sub(self, other: $b) -> Self::Result {
344                    $name(self, other)
345                }
346            }
347        };
348    }
349
350    #[rustfmt::skip]
351    mod impl_sub {
352        use super::*;
353
354        impl_sub!(vs_sc, vector_signed_char, vsb);
355        impl_sub!(vs_uc, vector_unsigned_char, vsb);
356        impl_sub!(vs_sh, vector_signed_short, vsh);
357        impl_sub!(vs_uh, vector_unsigned_short, vsh);
358        impl_sub!(vs_sf, vector_signed_int, vsf);
359        impl_sub!(vs_uf, vector_unsigned_int, vsf);
360        impl_sub!(vs_sg, vector_signed_long_long, vsg);
361        impl_sub!(vs_ug, vector_unsigned_long_long, vsg);
362
363        impl_sub!(vs_sc_bc, vector_signed_char, vector_bool_char, vector_signed_char, vsb);
364        impl_sub!(vs_uc_bc, vector_unsigned_char, vector_bool_char, vector_unsigned_char, vsb);
365        impl_sub!(vs_sh_bh, vector_signed_short, vector_bool_short, vector_signed_short, vsh);
366        impl_sub!(vs_uh_bh, vector_unsigned_short, vector_bool_short, vector_unsigned_short, vsh);
367        impl_sub!(vs_sf_bf, vector_signed_int, vector_bool_int, vector_signed_int, vsf);
368        impl_sub!(vs_uf_bf, vector_unsigned_int, vector_bool_int, vector_unsigned_int, vsf);
369        impl_sub!(vs_sg_bg, vector_signed_long_long, vector_bool_long_long, vector_signed_long_long, vsg);
370        impl_sub!(vs_ug_bg, vector_unsigned_long_long, vector_bool_long_long, vector_unsigned_long_long, vsg);
371
372        impl_sub!(vs_bc_sc, vector_bool_char, vector_signed_char, vector_signed_char, vsb);
373        impl_sub!(vs_bc_uc, vector_bool_char, vector_unsigned_char, vector_unsigned_char, vsb);
374        impl_sub!(vs_bh_sh, vector_bool_short, vector_signed_short, vector_signed_short, vsh);
375        impl_sub!(vs_bh_uh, vector_bool_short, vector_unsigned_short, vector_unsigned_short, vsh);
376        impl_sub!(vs_bf_sf, vector_bool_int, vector_signed_int, vector_signed_int, vsf);
377        impl_sub!(vs_bf_uf, vector_bool_int, vector_unsigned_int, vector_unsigned_int, vsf);
378        impl_sub!(vs_bg_sg, vector_bool_long_long, vector_signed_long_long, vector_signed_long_long, vsg);
379        impl_sub!(vs_bg_ug, vector_bool_long_long, vector_unsigned_long_long, vector_unsigned_long_long, vsg);
380
381        impl_sub!(vs_double, vector_double, vfsdb);
382
383        #[inline]
384        #[target_feature(enable = "vector")]
385        #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vfssb))]
386        pub unsafe fn vs_float(a: vector_float, b: vector_float) -> vector_float {
387            transmute(simd_sub(a, b))
388        }
389
390        #[unstable(feature = "stdarch_s390x", issue = "135681")]
391        impl VectorSub<Self> for vector_float {
392            type Result = Self;
393
394            #[inline]
395            #[target_feature(enable = "vector")]
396            unsafe fn vec_sub(self, other: Self) -> Self::Result {
397                vs_float(self, other)
398            }
399        }
400    }
401
402    #[unstable(feature = "stdarch_s390x", issue = "135681")]
403    pub trait VectorMul {
404        unsafe fn vec_mul(self, b: Self) -> Self;
405    }
406
407    macro_rules! impl_mul {
408        ($name:ident, $a:ty, std_simd) => {
409            #[unstable(feature = "stdarch_s390x", issue = "135681")]
410            impl VectorMul for $a {
411                #[inline]
412                #[target_feature(enable = "vector")]
413                unsafe fn vec_mul(self, other: Self) -> Self {
414                    transmute(simd_mul(transmute(self), other))
415                }
416            }
417        };
418        ($name:ident, $a:ty, $instr:ident) => {
419            #[inline]
420            #[target_feature(enable = "vector")]
421            #[cfg_attr(test, assert_instr($instr))]
422            pub unsafe fn $name(a: $a, b: $a) -> $a {
423                transmute(simd_mul(transmute(a), b))
424            }
425
426            #[unstable(feature = "stdarch_s390x", issue = "135681")]
427            impl VectorMul for $a {
428                #[inline]
429                #[target_feature(enable = "vector")]
430                unsafe fn vec_mul(self, other: Self) -> Self {
431                    $name(self, other)
432                }
433            }
434        };
435    }
436
437    #[rustfmt::skip]
438    mod impl_mul {
439        use super::*;
440
441        impl_mul!(vml_sc, vector_signed_char, vmlb);
442        impl_mul!(vml_uc, vector_unsigned_char, vmlb);
443        impl_mul!(vml_sh, vector_signed_short, vmlhw);
444        impl_mul!(vml_uh, vector_unsigned_short, vmlhw);
445        impl_mul!(vml_sf, vector_signed_int, vmlf);
446        impl_mul!(vml_uf, vector_unsigned_int, vmlf);
447        impl_mul!(vml_sg, vector_signed_long_long, std_simd);
448        impl_mul!(vml_ug, vector_unsigned_long_long, std_simd);
449
450        impl_mul!(vml_float, vector_float, std_simd);
451        impl_mul!(vml_double, vector_double, vfmdb);
452    }
453
454    #[unstable(feature = "stdarch_s390x", issue = "135681")]
455    pub trait VectorMax<Other> {
456        type Result;
457        unsafe fn vec_max(self, b: Other) -> Self::Result;
458    }
459
460    test_impl! { vec_vmxsb (a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [vmxb, vmxb] }
461    test_impl! { vec_vmxsh (a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [vmxh, vmxh] }
462    test_impl! { vec_vmxsf (a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [vmxf, vmxf] }
463    test_impl! { vec_vmxsg (a: vector_signed_long_long, b: vector_signed_long_long) -> vector_signed_long_long [vmxg, vmxg] }
464
465    test_impl! { vec_vmxslb (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [vmxlb, vmxlb] }
466    test_impl! { vec_vmxslh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [vmxlh, vmxlh] }
467    test_impl! { vec_vmxslf (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vmxlf, vmxlf] }
468    test_impl! { vec_vmxslg (a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long [vmxlg, vmxlg] }
469
470    impl_vec_trait! { [VectorMax vec_max] ~(vmxlb, vmxb, vmxlh, vmxh, vmxlf, vmxf, vmxlg, vmxg) }
471
472    test_impl! { vec_vfmaxsb (a: vector_float, b: vector_float) -> vector_float [simd_fmax, "vector-enhancements-1" vfmaxsb ] }
473    test_impl! { vec_vfmaxdb (a: vector_double, b: vector_double) -> vector_double [simd_fmax, "vector-enhancements-1" vfmaxdb] }
474
475    impl_vec_trait!([VectorMax vec_max] vec_vfmaxsb (vector_float, vector_float) -> vector_float);
476    impl_vec_trait!([VectorMax vec_max] vec_vfmaxdb (vector_double, vector_double) -> vector_double);
477
478    #[unstable(feature = "stdarch_s390x", issue = "135681")]
479    pub trait VectorMin<Other> {
480        type Result;
481        unsafe fn vec_min(self, b: Other) -> Self::Result;
482    }
483
484    test_impl! { vec_vmnsb (a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [vmnb, vmnb] }
485    test_impl! { vec_vmnsh (a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [vmnh, vmnh] }
486    test_impl! { vec_vmnsf (a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [vmnf, vmnf] }
487    test_impl! { vec_vmnsg (a: vector_signed_long_long, b: vector_signed_long_long) -> vector_signed_long_long [vmng, vmng] }
488
489    test_impl! { vec_vmnslb (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [vmnlb, vmnlb] }
490    test_impl! { vec_vmnslh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [vmnlh, vmnlh] }
491    test_impl! { vec_vmnslf (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vmnlf, vmnlf] }
492    test_impl! { vec_vmnslg (a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long [vmnlg, vmnlg] }
493
494    impl_vec_trait! { [VectorMin vec_min] ~(vmxlb, vmxb, vmxlh, vmxh, vmxlf, vmxf, vmxlg, vmxg) }
495
496    test_impl! { vec_vfminsb (a: vector_float, b: vector_float) -> vector_float [simd_fmin, "vector-enhancements-1" vfminsb]  }
497    test_impl! { vec_vfmindb (a: vector_double, b: vector_double) -> vector_double [simd_fmin, "vector-enhancements-1" vfmindb]  }
498
499    impl_vec_trait!([VectorMin vec_min] vec_vfminsb (vector_float, vector_float) -> vector_float);
500    impl_vec_trait!([VectorMin vec_min] vec_vfmindb (vector_double, vector_double) -> vector_double);
501
502    #[unstable(feature = "stdarch_s390x", issue = "135681")]
503    pub trait VectorAbs {
504        unsafe fn vec_abs(self) -> Self;
505    }
506
507    macro_rules! impl_abs {
508        ($name:ident, $ty:ident) => {
509            #[inline]
510            #[target_feature(enable = "vector")]
511            unsafe fn $name(v: s_t_l!($ty)) -> s_t_l!($ty) {
512                v.vec_max(-v)
513            }
514
515            impl_vec_trait! { [VectorAbs vec_abs] $name (s_t_l!($ty)) }
516        };
517    }
518
519    impl_abs! { vec_abs_i8, i8x16 }
520    impl_abs! { vec_abs_i16, i16x8 }
521    impl_abs! { vec_abs_i32, i32x4 }
522    impl_abs! { vec_abs_i64, i64x2 }
523
524    test_impl! { vec_abs_f32 (v: vector_float) -> vector_float [ simd_fabs, "vector-enhancements-1" vflpsb ] }
525    test_impl! { vec_abs_f64 (v: vector_double) -> vector_double [ simd_fabs, vflpdb ] }
526
527    impl_vec_trait! { [VectorAbs vec_abs] vec_abs_f32 (vector_float) }
528    impl_vec_trait! { [VectorAbs vec_abs] vec_abs_f64 (vector_double) }
529
530    #[unstable(feature = "stdarch_s390x", issue = "135681")]
531    pub trait VectorNabs {
532        unsafe fn vec_nabs(self) -> Self;
533    }
534
535    #[inline]
536    #[target_feature(enable = "vector")]
537    #[cfg_attr(
538        all(test, target_feature = "vector-enhancements-1"),
539        assert_instr(vflnsb)
540    )]
541    unsafe fn vec_nabs_f32(a: vector_float) -> vector_float {
542        simd_neg(simd_fabs(a))
543    }
544
545    #[inline]
546    #[target_feature(enable = "vector")]
547    #[cfg_attr(test, assert_instr(vflndb))]
548    unsafe fn vec_nabs_f64(a: vector_double) -> vector_double {
549        simd_neg(simd_fabs(a))
550    }
551
552    impl_vec_trait! { [VectorNabs vec_nabs] vec_nabs_f32 (vector_float) }
553    impl_vec_trait! { [VectorNabs vec_nabs] vec_nabs_f64 (vector_double) }
554
555    #[unstable(feature = "stdarch_s390x", issue = "135681")]
556    pub trait VectorSplat {
557        unsafe fn vec_splat<const IMM: u32>(self) -> Self;
558    }
559
560    #[inline]
561    #[target_feature(enable = "vector")]
562    #[cfg_attr(test, assert_instr(vrepb, IMM2 = 1))]
563    unsafe fn vrepb<const IMM2: u32>(a: vector_signed_char) -> vector_signed_char {
564        static_assert_uimm_bits!(IMM2, 4);
565        simd_shuffle(a, a, const { u32x16::from_array([IMM2; 16]) })
566    }
567
568    #[inline]
569    #[target_feature(enable = "vector")]
570    #[cfg_attr(test, assert_instr(vreph, IMM2 = 1))]
571    unsafe fn vreph<const IMM2: u32>(a: vector_signed_short) -> vector_signed_short {
572        static_assert_uimm_bits!(IMM2, 3);
573        simd_shuffle(a, a, const { u32x8::from_array([IMM2; 8]) })
574    }
575
576    #[inline]
577    #[target_feature(enable = "vector")]
578    #[cfg_attr(test, assert_instr(vrepf, IMM2 = 1))]
579    unsafe fn vrepf<const IMM2: u32>(a: vector_signed_int) -> vector_signed_int {
580        static_assert_uimm_bits!(IMM2, 2);
581        simd_shuffle(a, a, const { u32x4::from_array([IMM2; 4]) })
582    }
583
584    #[inline]
585    #[target_feature(enable = "vector")]
586    #[cfg_attr(test, assert_instr(vrepg, IMM2 = 1))]
587    unsafe fn vrepg<const IMM2: u32>(a: vector_signed_long_long) -> vector_signed_long_long {
588        static_assert_uimm_bits!(IMM2, 1);
589        simd_shuffle(a, a, const { u32x2::from_array([IMM2; 2]) })
590    }
591
592    macro_rules! impl_vec_splat {
593        ($ty:ty, $fun:ident) => {
594            #[unstable(feature = "stdarch_s390x", issue = "135681")]
595            impl VectorSplat for $ty {
596                #[inline]
597                #[target_feature(enable = "vector")]
598                unsafe fn vec_splat<const IMM: u32>(self) -> Self {
599                    transmute($fun::<IMM>(transmute(self)))
600                }
601            }
602        };
603    }
604
605    impl_vec_splat! { vector_signed_char, vrepb }
606    impl_vec_splat! { vector_unsigned_char, vrepb }
607    impl_vec_splat! { vector_bool_char, vrepb }
608    impl_vec_splat! { vector_signed_short, vreph }
609    impl_vec_splat! { vector_unsigned_short, vreph }
610    impl_vec_splat! { vector_bool_short, vreph }
611    impl_vec_splat! { vector_signed_int, vrepf }
612    impl_vec_splat! { vector_unsigned_int, vrepf }
613    impl_vec_splat! { vector_bool_int, vrepf }
614    impl_vec_splat! { vector_signed_long_long, vrepg }
615    impl_vec_splat! { vector_unsigned_long_long, vrepg }
616    impl_vec_splat! { vector_bool_long_long, vrepg }
617
618    impl_vec_splat! { vector_float, vrepf }
619    impl_vec_splat! { vector_double, vrepg }
620
621    #[unstable(feature = "stdarch_s390x", issue = "135681")]
622    pub trait VectorSplats<Output> {
623        unsafe fn vec_splats(self) -> Output;
624    }
625
626    macro_rules! impl_vec_splats {
627        ($(($fn:ident ($ty:ty, $shortty:tt) $instr:ident)),*) => {
628            $(
629                #[inline]
630                #[target_feature(enable = "vector")]
631                #[cfg_attr(test, assert_instr($instr))]
632                pub unsafe fn $fn(v: $ty) -> s_t_l!($shortty) {
633                    transmute($shortty::splat(v))
634                }
635
636                #[unstable(feature = "stdarch_s390x", issue = "135681")]
637                impl VectorSplats<s_t_l!($shortty)> for $ty {
638                    #[inline]
639                    #[target_feature(enable = "vector")]
640                    unsafe fn vec_splats(self) -> s_t_l!($shortty) {
641                        $fn (self)
642                    }
643                }
644            )*
645        }
646    }
647
648    impl_vec_splats! {
649        (vec_splats_u8 (u8, u8x16) vrepb),
650        (vec_splats_i8 (i8, i8x16) vrepb),
651        (vec_splats_u16 (u16, u16x8) vreph),
652        (vec_splats_i16 (i16, i16x8) vreph),
653        (vec_splats_u32 (u32, u32x4) vrepf),
654        (vec_splats_i32 (i32, i32x4) vrepf),
655        (vec_splats_u64 (u64, u64x2) vlvgp),
656        (vec_splats_i64 (i64, i64x2) vlvgp),
657        (vec_splats_f32 (f32, f32x4) vrepf),
658        (vec_splats_f64 (f64, f64x2) vrepg)
659    }
660
661    macro_rules! impl_bool_vec_splats {
662        ($(($ty:ty, $shortty:tt, $boolty:ty)),*) => {
663            $(
664                #[unstable(feature = "stdarch_s390x", issue = "135681")]
665                impl VectorSplats<$boolty> for $ty {
666                    #[inline]
667                    #[target_feature(enable = "vector")]
668                    unsafe fn vec_splats(self) -> $boolty {
669                        transmute($shortty::splat(self))
670                    }
671                }
672            )*
673        }
674    }
675
676    impl_bool_vec_splats! {
677        (u8, u8x16, vector_bool_char),
678        (i8, i8x16, vector_bool_char),
679        (u16, u16x8, vector_bool_short),
680        (i16, i16x8, vector_bool_short),
681        (u32, u32x4, vector_bool_int),
682        (i32, i32x4, vector_bool_int),
683        (u64, u64x2, vector_bool_long_long),
684        (i64, i64x2, vector_bool_long_long)
685    }
686
687    #[unstable(feature = "stdarch_s390x", issue = "135681")]
688    pub trait CountBits {
689        type Result;
690
691        unsafe fn vec_cntlz(self) -> Self::Result;
692        unsafe fn vec_cnttz(self) -> Self::Result;
693        unsafe fn vec_popcnt(self) -> Self::Result;
694    }
695
696    macro_rules! impl_count_bits {
697        ($ty:tt) => {
698            #[unstable(feature = "stdarch_s390x", issue = "135681")]
699            impl CountBits for $ty {
700                type Result = t_u!($ty);
701
702                #[inline]
703                #[target_feature(enable = "vector")]
704                unsafe fn vec_cntlz(self) -> Self::Result {
705                    transmute(simd_ctlz(self))
706                }
707
708                #[inline]
709                #[target_feature(enable = "vector")]
710                unsafe fn vec_cnttz(self) -> Self::Result {
711                    transmute(simd_cttz(self))
712                }
713
714                #[inline]
715                #[target_feature(enable = "vector")]
716                unsafe fn vec_popcnt(self) -> Self::Result {
717                    transmute(simd_ctpop(self))
718                }
719            }
720        };
721    }
722
723    impl_count_bits!(vector_signed_char);
724    impl_count_bits!(vector_unsigned_char);
725    impl_count_bits!(vector_signed_short);
726    impl_count_bits!(vector_unsigned_short);
727    impl_count_bits!(vector_signed_int);
728    impl_count_bits!(vector_unsigned_int);
729    impl_count_bits!(vector_signed_long_long);
730    impl_count_bits!(vector_unsigned_long_long);
731
732    test_impl! { vec_clzb_signed +(a: vector_signed_char) -> vector_unsigned_char [simd_ctlz, vclzb] }
733    test_impl! { vec_clzh_signed +(a: vector_signed_short) -> vector_unsigned_short [simd_ctlz, vclzh] }
734    test_impl! { vec_clzf_signed +(a: vector_signed_int) -> vector_unsigned_int [simd_ctlz, vclzf] }
735    test_impl! { vec_clzg_signed +(a: vector_signed_long_long) -> vector_unsigned_long_long [simd_ctlz, vclzg] }
736
737    test_impl! { vec_clzb_unsigned +(a: vector_unsigned_char) -> vector_unsigned_char [simd_ctlz, vclzb] }
738    test_impl! { vec_clzh_unsigned +(a: vector_unsigned_short) -> vector_unsigned_short [simd_ctlz, vclzh] }
739    test_impl! { vec_clzf_unsigned +(a: vector_unsigned_int) -> vector_unsigned_int [simd_ctlz, vclzf] }
740    test_impl! { vec_clzg_unsigned +(a: vector_unsigned_long_long) -> vector_unsigned_long_long [simd_ctlz, vclzg] }
741
742    test_impl! { vec_ctzb_signed +(a: vector_signed_char) -> vector_unsigned_char [simd_cttz, vctzb] }
743    test_impl! { vec_ctzh_signed +(a: vector_signed_short) -> vector_unsigned_short [simd_cttz, vctzh] }
744    test_impl! { vec_ctzf_signed +(a: vector_signed_int) -> vector_unsigned_int [simd_cttz, vctzf] }
745    test_impl! { vec_ctzg_signed +(a: vector_signed_long_long) -> vector_unsigned_long_long [simd_cttz, vctzg] }
746
747    test_impl! { vec_ctzb_unsigned +(a: vector_unsigned_char) -> vector_unsigned_char [simd_cttz, vctzb] }
748    test_impl! { vec_ctzh_unsigned +(a: vector_unsigned_short) -> vector_unsigned_short [simd_cttz, vctzh] }
749    test_impl! { vec_ctzf_unsigned +(a: vector_unsigned_int) -> vector_unsigned_int [simd_cttz, vctzf] }
750    test_impl! { vec_ctzg_unsigned +(a: vector_unsigned_long_long) -> vector_unsigned_long_long [simd_cttz, vctzg] }
751
752    test_impl! { vec_vpopctb_signed +(a: vector_signed_char) -> vector_signed_char [simd_ctpop, vpopctb] }
753    test_impl! { vec_vpopcth_signed +(a: vector_signed_short) -> vector_signed_short [simd_ctpop, "vector-enhancements-1" vpopcth] }
754    test_impl! { vec_vpopctf_signed +(a: vector_signed_int) -> vector_signed_int [simd_ctpop, "vector-enhancements-1" vpopctf] }
755    test_impl! { vec_vpopctg_signed +(a: vector_signed_long_long) -> vector_signed_long_long [simd_ctpop, "vector-enhancements-1" vpopctg] }
756
757    test_impl! { vec_vpopctb_unsigned +(a: vector_unsigned_char) -> vector_unsigned_char [simd_ctpop, vpopctb] }
758    test_impl! { vec_vpopcth_unsigned +(a: vector_unsigned_short) -> vector_unsigned_short [simd_ctpop, "vector-enhancements-1" vpopcth] }
759    test_impl! { vec_vpopctf_unsigned +(a: vector_unsigned_int) -> vector_unsigned_int [simd_ctpop, "vector-enhancements-1" vpopctf] }
760    test_impl! { vec_vpopctg_unsigned +(a: vector_unsigned_long_long) -> vector_unsigned_long_long [simd_ctpop, "vector-enhancements-1" vpopctg] }
761
762    #[unstable(feature = "stdarch_s390x", issue = "135681")]
763    pub trait VectorAnd<Other> {
764        type Result;
765        unsafe fn vec_and(self, b: Other) -> Self::Result;
766    }
767
768    impl_vec_trait! { [VectorAnd vec_and] ~(simd_and) }
769
770    #[unstable(feature = "stdarch_s390x", issue = "135681")]
771    pub trait VectorOr<Other> {
772        type Result;
773        unsafe fn vec_or(self, b: Other) -> Self::Result;
774    }
775
776    impl_vec_trait! { [VectorOr vec_or] ~(simd_or) }
777
778    #[unstable(feature = "stdarch_s390x", issue = "135681")]
779    pub trait VectorXor<Other> {
780        type Result;
781        unsafe fn vec_xor(self, b: Other) -> Self::Result;
782    }
783
784    impl_vec_trait! { [VectorXor vec_xor] ~(simd_xor) }
785
786    #[inline]
787    #[target_feature(enable = "vector")]
788    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vno))]
789    unsafe fn nor(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
790        let a: u8x16 = transmute(a);
791        let b: u8x16 = transmute(b);
792        transmute(simd_xor(simd_or(a, b), u8x16::splat(0xff)))
793    }
794
795    #[unstable(feature = "stdarch_s390x", issue = "135681")]
796    pub trait VectorNor<Other> {
797        type Result;
798        unsafe fn vec_nor(self, b: Other) -> Self::Result;
799    }
800
801    impl_vec_trait! { [VectorNor vec_nor]+ 2c (nor) }
802
803    #[inline]
804    #[target_feature(enable = "vector")]
805    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vnn))]
806    unsafe fn nand(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
807        let a: u8x16 = transmute(a);
808        let b: u8x16 = transmute(b);
809        transmute(simd_xor(simd_and(a, b), u8x16::splat(0xff)))
810    }
811
812    #[unstable(feature = "stdarch_s390x", issue = "135681")]
813    pub trait VectorNand<Other> {
814        type Result;
815        unsafe fn vec_nand(self, b: Other) -> Self::Result;
816    }
817
818    impl_vec_trait! { [VectorNand vec_nand]+ 2c (nand) }
819
820    #[inline]
821    #[target_feature(enable = "vector")]
822    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vnx))]
823    unsafe fn eqv(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
824        let a: u8x16 = transmute(a);
825        let b: u8x16 = transmute(b);
826        transmute(simd_xor(simd_xor(a, b), u8x16::splat(0xff)))
827    }
828
829    #[unstable(feature = "stdarch_s390x", issue = "135681")]
830    pub trait VectorEqv<Other> {
831        type Result;
832        unsafe fn vec_eqv(self, b: Other) -> Self::Result;
833    }
834
835    impl_vec_trait! { [VectorEqv vec_eqv]+ 2c (eqv) }
836
837    #[inline]
838    #[target_feature(enable = "vector")]
839    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(vnc))]
840    unsafe fn andc(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
841        let a = transmute(a);
842        let b = transmute(b);
843        transmute(simd_and(simd_xor(u8x16::splat(0xff), b), a))
844    }
845
846    #[unstable(feature = "stdarch_s390x", issue = "135681")]
847    pub trait VectorAndc<Other> {
848        type Result;
849        unsafe fn vec_andc(self, b: Other) -> Self::Result;
850    }
851
852    impl_vec_trait! { [VectorAndc vec_andc]+ 2c (andc) }
853
854    #[inline]
855    #[target_feature(enable = "vector")]
856    #[cfg_attr(all(test, target_feature = "vector-enhancements-1"), assert_instr(voc))]
857    unsafe fn orc(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
858        let a = transmute(a);
859        let b = transmute(b);
860        transmute(simd_or(simd_xor(u8x16::splat(0xff), b), a))
861    }
862
863    #[unstable(feature = "stdarch_s390x", issue = "135681")]
864    pub trait VectorOrc<Other> {
865        type Result;
866        unsafe fn vec_orc(self, b: Other) -> Self::Result;
867    }
868
869    impl_vec_trait! { [VectorOrc vec_orc]+ 2c (orc) }
870
871    test_impl! { vec_roundc_f32 (a: vector_float) -> vector_float [nearbyint_v4f32,  "vector-enhancements-1" vfisb] }
872    test_impl! { vec_roundc_f64 (a: vector_double) -> vector_double [nearbyint_v2f64, vfidb] }
873
874    // FIXME(llvm) roundeven does not yet lower to vfidb (but should in the future)
875    test_impl! { vec_round_f32 (a: vector_float) -> vector_float [roundeven_v4f32, _] }
876    test_impl! { vec_round_f64 (a: vector_double) -> vector_double [roundeven_v2f64, _] }
877
878    test_impl! { vec_rint_f32 (a: vector_float) -> vector_float [rint_v4f32, "vector-enhancements-1" vfisb] }
879    test_impl! { vec_rint_f64 (a: vector_double) -> vector_double [rint_v2f64, vfidb] }
880
881    #[unstable(feature = "stdarch_s390x", issue = "135681")]
882    pub trait VectorRoundc {
883        unsafe fn vec_roundc(self) -> Self;
884    }
885
886    #[unstable(feature = "stdarch_s390x", issue = "135681")]
887    pub trait VectorRound {
888        unsafe fn vec_round(self) -> Self;
889    }
890
891    #[unstable(feature = "stdarch_s390x", issue = "135681")]
892    pub trait VectorRint {
893        unsafe fn vec_rint(self) -> Self;
894    }
895
896    impl_vec_trait! { [VectorRoundc vec_roundc] vec_roundc_f32 (vector_float) }
897    impl_vec_trait! { [VectorRoundc vec_roundc] vec_roundc_f64 (vector_double) }
898
899    impl_vec_trait! { [VectorRound vec_round] vec_round_f32 (vector_float) }
900    impl_vec_trait! { [VectorRound vec_round] vec_round_f64 (vector_double) }
901
902    impl_vec_trait! { [VectorRint vec_rint] vec_rint_f32 (vector_float) }
903    impl_vec_trait! { [VectorRint vec_rint] vec_rint_f64 (vector_double) }
904
905    #[unstable(feature = "stdarch_s390x", issue = "135681")]
906    pub trait VectorTrunc {
907        // same as vec_roundz
908        unsafe fn vec_trunc(self) -> Self;
909    }
910
911    #[unstable(feature = "stdarch_s390x", issue = "135681")]
912    pub trait VectorCeil {
913        // same as vec_roundp
914        unsafe fn vec_ceil(self) -> Self;
915    }
916
917    #[unstable(feature = "stdarch_s390x", issue = "135681")]
918    pub trait VectorFloor {
919        // same as vec_roundm
920        unsafe fn vec_floor(self) -> Self;
921    }
922
923    impl_vec_trait! { [VectorTrunc vec_trunc] simd_trunc (vector_float) }
924    impl_vec_trait! { [VectorTrunc vec_trunc] simd_trunc (vector_double) }
925
926    impl_vec_trait! { [VectorCeil vec_ceil] simd_ceil (vector_float) }
927    impl_vec_trait! { [VectorCeil vec_ceil] simd_ceil (vector_double) }
928
929    impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_float) }
930    impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_double) }
931
932    macro_rules! impl_vec_shift {
933        ([$Trait:ident $m:ident] ($b:ident, $h:ident, $w:ident, $g:ident)) => {
934            impl_vec_trait!{ [$Trait $m]+ $b (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
935            impl_vec_trait!{ [$Trait $m]+ $b (vector_signed_char, vector_unsigned_char) -> vector_signed_char }
936            impl_vec_trait!{ [$Trait $m]+ $h (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
937            impl_vec_trait!{ [$Trait $m]+ $h (vector_signed_short, vector_unsigned_short) -> vector_signed_short }
938            impl_vec_trait!{ [$Trait $m]+ $w (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
939            impl_vec_trait!{ [$Trait $m]+ $w (vector_signed_int, vector_unsigned_int) -> vector_signed_int }
940            impl_vec_trait!{ [$Trait $m]+ $g (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long }
941            impl_vec_trait!{ [$Trait $m]+ $g (vector_signed_long_long, vector_unsigned_long_long) -> vector_signed_long_long }
942        };
943    }
944
945    macro_rules! impl_shift {
946        ($fun:ident $intr:ident $ty:ident) => {
947            #[inline]
948            #[target_feature(enable = "vector")]
949            #[cfg_attr(test, assert_instr($fun))]
950            unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) {
951                let a = transmute(a);
952                // use the remainder of b by the width of a's elements to prevent UB
953                let b = simd_rem(transmute(b), <t_t_s!($ty)>::splat($ty::BITS as $ty));
954
955                transmute($intr(a, b))
956            }
957        };
958    }
959
960    #[unstable(feature = "stdarch_s390x", issue = "135681")]
961    pub trait VectorSl<Other> {
962        type Result;
963        unsafe fn vec_sl(self, b: Other) -> Self::Result;
964    }
965
966    impl_shift! { veslvb simd_shl u8 }
967    impl_shift! { veslvh simd_shl u16 }
968    impl_shift! { veslvf simd_shl u32 }
969    impl_shift! { veslvg simd_shl u64 }
970
971    impl_vec_shift! { [VectorSl vec_sl] (veslvb, veslvh, veslvf, veslvg) }
972
973    #[unstable(feature = "stdarch_s390x", issue = "135681")]
974    pub trait VectorSr<Other> {
975        type Result;
976        unsafe fn vec_sr(self, b: Other) -> Self::Result;
977    }
978
979    impl_shift! { vesrlvb simd_shr u8 }
980    impl_shift! { vesrlvh simd_shr u16 }
981    impl_shift! { vesrlvf simd_shr u32 }
982    impl_shift! { vesrlvg simd_shr u64 }
983
984    impl_vec_shift! { [VectorSr vec_sr] (vesrlvb, vesrlvh, vesrlvf, vesrlvg) }
985
986    #[unstable(feature = "stdarch_s390x", issue = "135681")]
987    pub trait VectorSra<Other> {
988        type Result;
989        unsafe fn vec_sra(self, b: Other) -> Self::Result;
990    }
991
992    impl_shift! { vesravb simd_shr i8 }
993    impl_shift! { vesravh simd_shr i16 }
994    impl_shift! { vesravf simd_shr i32 }
995    impl_shift! { vesravg simd_shr i64 }
996
997    impl_vec_shift! { [VectorSra vec_sra] (vesravb, vesravh, vesravf, vesravg) }
998
999    macro_rules! impl_vec_shift_byte {
1000        ([$trait:ident $m:ident] ($f:ident)) => {
1001            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_signed_char) -> vector_unsigned_char }
1002            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
1003            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_char, vector_signed_char) -> vector_signed_char }
1004            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_char, vector_unsigned_char) -> vector_signed_char }
1005            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_short, vector_signed_short) -> vector_unsigned_short }
1006            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
1007            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_short, vector_signed_short) -> vector_signed_short }
1008            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_short, vector_unsigned_short) -> vector_signed_short }
1009            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_int, vector_signed_int) -> vector_unsigned_int }
1010            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
1011            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_int, vector_signed_int) -> vector_signed_int }
1012            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_int, vector_unsigned_int) -> vector_signed_int }
1013            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_long_long, vector_signed_long_long) -> vector_unsigned_long_long }
1014            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long }
1015            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_long_long, vector_signed_long_long) -> vector_signed_long_long }
1016            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_long_long, vector_unsigned_long_long) -> vector_signed_long_long }
1017            impl_vec_trait!{ [$trait $m]+ $f (vector_float, vector_signed_int) -> vector_float }
1018            impl_vec_trait!{ [$trait $m]+ $f (vector_float, vector_unsigned_int) -> vector_float }
1019            impl_vec_trait!{ [$trait $m]+ $f (vector_double, vector_signed_long_long) -> vector_double }
1020            impl_vec_trait!{ [$trait $m]+ $f (vector_double, vector_unsigned_long_long) -> vector_double }
1021        };
1022    }
1023
1024    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1025    pub trait VectorSlb<Other> {
1026        type Result;
1027        unsafe fn vec_slb(self, b: Other) -> Self::Result;
1028    }
1029
1030    impl_vec_shift_byte! { [VectorSlb vec_slb] (vslb) }
1031
1032    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1033    pub trait VectorSrab<Other> {
1034        type Result;
1035        unsafe fn vec_srab(self, b: Other) -> Self::Result;
1036    }
1037
1038    impl_vec_shift_byte! { [VectorSrab vec_srab] (vsrab) }
1039
1040    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1041    pub trait VectorSrb<Other> {
1042        type Result;
1043        unsafe fn vec_srb(self, b: Other) -> Self::Result;
1044    }
1045
1046    impl_vec_shift_byte! { [VectorSrb vec_srb] (vsrlb) }
1047
1048    macro_rules! impl_vec_shift_long {
1049        ([$trait:ident $m:ident] ($f:ident)) => {
1050            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
1051            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_char, vector_unsigned_char) -> vector_signed_char }
1052            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_short, vector_unsigned_char) -> vector_unsigned_short }
1053            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_short, vector_unsigned_char) -> vector_signed_short }
1054            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_int, vector_unsigned_char) -> vector_unsigned_int }
1055            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_int, vector_unsigned_char) -> vector_signed_int }
1056            impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_long_long, vector_unsigned_char) -> vector_unsigned_long_long }
1057            impl_vec_trait!{ [$trait $m]+ $f (vector_signed_long_long, vector_unsigned_char) -> vector_signed_long_long }
1058        };
1059    }
1060
1061    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1062    pub trait VectorSrl<Other> {
1063        type Result;
1064        unsafe fn vec_srl(self, b: Other) -> Self::Result;
1065    }
1066
1067    impl_vec_shift_long! { [VectorSrl vec_srl] (vsrl) }
1068
1069    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1070    pub trait VectorSral<Other> {
1071        type Result;
1072        unsafe fn vec_sral(self, b: Other) -> Self::Result;
1073    }
1074
1075    impl_vec_shift_long! { [VectorSral vec_sral] (vsra) }
1076
1077    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1078    pub trait VectorSll<Other> {
1079        type Result;
1080        unsafe fn vec_sll(self, b: Other) -> Self::Result;
1081    }
1082
1083    impl_vec_shift_long! { [VectorSll vec_sll] (vsl) }
1084
1085    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1086    pub trait VectorRl<Other> {
1087        type Result;
1088        unsafe fn vec_rl(self, b: Other) -> Self::Result;
1089    }
1090
1091    macro_rules! impl_rot {
1092        ($fun:ident $intr:ident $ty:ident) => {
1093            #[inline]
1094            #[target_feature(enable = "vector")]
1095            #[cfg_attr(test, assert_instr($fun))]
1096            unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) {
1097                transmute($intr(transmute(a), transmute(a), transmute(b)))
1098            }
1099        };
1100    }
1101
1102    impl_rot! { verllvb fshlb u8 }
1103    impl_rot! { verllvh fshlh u16 }
1104    impl_rot! { verllvf fshlf u32 }
1105    impl_rot! { verllvg fshlg u64 }
1106
1107    impl_vec_shift! { [VectorRl vec_rl] (verllvb, verllvh, verllvf, verllvg) }
1108
1109    macro_rules! test_rot_imm {
1110        ($fun:ident $instr:ident $intr:ident $ty:ident) => {
1111            #[inline]
1112            #[target_feature(enable = "vector")]
1113            #[cfg_attr(test, assert_instr($instr))]
1114            unsafe fn $fun(a: t_t_l!($ty), bits: core::ffi::c_ulong) -> t_t_l!($ty) {
1115                // mod by the number of bits in a's element type to prevent UB
1116                let bits = (bits % $ty::BITS as core::ffi::c_ulong) as $ty;
1117                let a = transmute(a);
1118                let b = <t_t_s!($ty)>::splat(bits);
1119
1120                transmute($intr(a, a, transmute(b)))
1121            }
1122        };
1123    }
1124
1125    test_rot_imm! { verllvb_imm verllb fshlb u8 }
1126    test_rot_imm! { verllvh_imm verllh fshlh u16 }
1127    test_rot_imm! { verllvf_imm verllf fshlf u32 }
1128    test_rot_imm! { verllvg_imm verllg fshlg u64 }
1129
1130    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1131    pub trait VectorRli {
1132        unsafe fn vec_rli(self, bits: core::ffi::c_ulong) -> Self;
1133    }
1134
1135    macro_rules! impl_rot_imm {
1136        ($($ty:ident, $intr:ident),*) => {
1137            $(
1138                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1139                impl VectorRli for $ty {
1140                    #[inline]
1141                    #[target_feature(enable = "vector")]
1142                    unsafe fn vec_rli(self, bits: core::ffi::c_ulong) -> Self {
1143                        transmute($intr(transmute(self), bits))
1144                    }
1145                }
1146
1147                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1148                impl VectorRli for t_u!($ty) {
1149                    #[inline]
1150                    #[target_feature(enable = "vector")]
1151                    unsafe fn vec_rli(self, bits: core::ffi::c_ulong) -> Self {
1152                        $intr(self, bits)
1153                    }
1154                }
1155            )*
1156        }
1157    }
1158
1159    impl_rot_imm! {
1160        vector_signed_char, verllvb_imm,
1161        vector_signed_short, verllvh_imm,
1162        vector_signed_int, verllvf_imm,
1163        vector_signed_long_long, verllvg_imm
1164    }
1165
1166    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1167    pub trait VectorRlMask<Other> {
1168        unsafe fn vec_rl_mask<const IMM8: u8>(self, other: Other) -> Self;
1169    }
1170
1171    macro_rules! impl_rl_mask {
1172        ($($ty:ident, $intr:ident, $fun:ident),*) => {
1173            $(
1174                #[inline]
1175                #[target_feature(enable = "vector")]
1176                #[cfg_attr(test, assert_instr($intr, IMM8 = 6))]
1177                unsafe fn $fun<const IMM8: u8>(a: $ty, b: t_u!($ty)) -> $ty {
1178                    // mod by the number of bits in a's element type to prevent UB
1179                    $intr(a, a, transmute(b), const { (IMM8 % <l_t_t!($ty)>::BITS as u8) as i32 })
1180                }
1181
1182                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1183                impl VectorRlMask<t_u!($ty)> for $ty {
1184                    #[inline]
1185                    #[target_feature(enable = "vector")]
1186                    unsafe fn vec_rl_mask<const IMM8: u8>(self, other: t_u!($ty)) -> Self {
1187                        $fun::<IMM8>(self, other)
1188                    }
1189                }
1190
1191                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1192                impl VectorRlMask<t_u!($ty)> for t_u!($ty) {
1193                    #[inline]
1194                    #[target_feature(enable = "vector")]
1195                    unsafe fn vec_rl_mask<const IMM8: u8>(self, other: t_u!($ty)) -> Self {
1196                        transmute($fun::<IMM8>(transmute(self), transmute(other)))
1197                    }
1198                }
1199            )*
1200        }
1201    }
1202
1203    impl_rl_mask! {
1204        vector_signed_char, verimb, test_verimb,
1205        vector_signed_short, verimh, test_verimh,
1206        vector_signed_int, verimf, test_verimf,
1207        vector_signed_long_long, verimg, test_verimg
1208    }
1209
1210    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1211    pub trait VectorReve {
1212        unsafe fn vec_reve(self) -> Self;
1213    }
1214
1215    macro_rules! impl_reve {
1216        ($($ty:ident, $fun:ident, $instr:ident),*) => {
1217            $(
1218                #[inline]
1219                #[target_feature(enable = "vector")]
1220                #[cfg_attr(test, assert_instr($instr))]
1221                unsafe fn $fun(a: $ty) -> $ty {
1222                    const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::<l_t_t!($ty)>();
1223                    simd_shuffle(a, a, const { ShuffleMask::<N>::reverse() })
1224                }
1225
1226                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1227                impl VectorReve for $ty {
1228                    #[inline]
1229                    #[target_feature(enable = "vector")]
1230                    unsafe fn vec_reve(self) -> Self {
1231                        $fun(self)
1232                    }
1233                }
1234
1235                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1236                impl VectorReve for t_u!($ty) {
1237                    #[inline]
1238                    #[target_feature(enable = "vector")]
1239                    unsafe fn vec_reve(self) -> Self {
1240                        transmute($fun(transmute(self)))
1241                    }
1242                }
1243
1244                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1245                impl VectorReve for t_b!($ty) {
1246                    #[inline]
1247                    #[target_feature(enable = "vector")]
1248                    unsafe fn vec_reve(self) -> Self {
1249                        transmute($fun(transmute(self)))
1250                    }
1251                }
1252            )*
1253        }
1254    }
1255
1256    impl_reve! {
1257        vector_signed_char, reveb, vperm,
1258        vector_signed_short, reveh, vperm,
1259        vector_signed_int, revef, vperm,
1260        vector_signed_long_long, reveg, vpdi
1261    }
1262
1263    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1264    impl VectorReve for vector_float {
1265        #[inline]
1266        #[target_feature(enable = "vector")]
1267        unsafe fn vec_reve(self) -> Self {
1268            transmute(transmute::<_, vector_signed_int>(self).vec_reve())
1269        }
1270    }
1271
1272    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1273    impl VectorReve for vector_double {
1274        #[inline]
1275        #[target_feature(enable = "vector")]
1276        unsafe fn vec_reve(self) -> Self {
1277            transmute(transmute::<_, vector_signed_long_long>(self).vec_reve())
1278        }
1279    }
1280
1281    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1282    pub trait VectorRevb {
1283        unsafe fn vec_revb(self) -> Self;
1284    }
1285
1286    test_impl! { bswapb (a: vector_signed_char) -> vector_signed_char [simd_bswap, _] }
1287    test_impl! { bswaph (a: vector_signed_short) -> vector_signed_short [simd_bswap, vperm] }
1288    test_impl! { bswapf (a: vector_signed_int) -> vector_signed_int [simd_bswap, vperm] }
1289    test_impl! { bswapg (a: vector_signed_long_long) -> vector_signed_long_long [simd_bswap, vperm] }
1290
1291    impl_vec_trait! { [VectorRevb vec_revb]+ bswapb (vector_unsigned_char) }
1292    impl_vec_trait! { [VectorRevb vec_revb]+ bswapb (vector_signed_char) }
1293    impl_vec_trait! { [VectorRevb vec_revb]+ bswaph (vector_unsigned_short) }
1294    impl_vec_trait! { [VectorRevb vec_revb]+ bswaph (vector_signed_short) }
1295    impl_vec_trait! { [VectorRevb vec_revb]+ bswapf (vector_unsigned_int) }
1296    impl_vec_trait! { [VectorRevb vec_revb]+ bswapf (vector_signed_int) }
1297    impl_vec_trait! { [VectorRevb vec_revb]+ bswapg (vector_unsigned_long_long) }
1298    impl_vec_trait! { [VectorRevb vec_revb]+ bswapg (vector_signed_long_long) }
1299
1300    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1301    impl VectorRevb for vector_float {
1302        #[inline]
1303        #[target_feature(enable = "vector")]
1304        unsafe fn vec_revb(self) -> Self {
1305            transmute(transmute::<_, vector_signed_int>(self).vec_revb())
1306        }
1307    }
1308
1309    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1310    impl VectorRevb for vector_double {
1311        #[inline]
1312        #[target_feature(enable = "vector")]
1313        unsafe fn vec_revb(self) -> Self {
1314            transmute(transmute::<_, vector_signed_long_long>(self).vec_revb())
1315        }
1316    }
1317
1318    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1319    pub trait VectorMergel {
1320        unsafe fn vec_mergel(self, other: Self) -> Self;
1321    }
1322
1323    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1324    pub trait VectorMergeh {
1325        unsafe fn vec_mergeh(self, other: Self) -> Self;
1326    }
1327
1328    macro_rules! impl_merge {
1329        ($($ty:ident, $mergel:ident, $mergeh:ident),*) => {
1330            $(
1331                #[inline]
1332                #[target_feature(enable = "vector")]
1333                #[cfg_attr(test, assert_instr($mergel))]
1334                unsafe fn $mergel(a: $ty, b: $ty) -> $ty {
1335                    const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::<l_t_t!($ty)>();
1336                    simd_shuffle(a, b, const { ShuffleMask::<N>::merge_low() })
1337                }
1338
1339                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1340                impl VectorMergel for $ty {
1341                    #[inline]
1342                    #[target_feature(enable = "vector")]
1343                    unsafe fn vec_mergel(self, other: Self) -> Self {
1344                        $mergel(self, other)
1345                    }
1346                }
1347
1348                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1349                impl VectorMergel for t_u!($ty) {
1350                    #[inline]
1351                    #[target_feature(enable = "vector")]
1352                    unsafe fn vec_mergel(self, other: Self) -> Self {
1353                        transmute($mergel(transmute(self), transmute(other)))
1354                    }
1355                }
1356
1357                #[inline]
1358                #[target_feature(enable = "vector")]
1359                #[cfg_attr(test, assert_instr($mergeh))]
1360                unsafe fn $mergeh(a: $ty, b: $ty) -> $ty {
1361                    const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::<l_t_t!($ty)>();
1362                    simd_shuffle(a, b, const { ShuffleMask::<N>::merge_high() })
1363                }
1364
1365                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1366                impl VectorMergeh for $ty {
1367                    #[inline]
1368                    #[target_feature(enable = "vector")]
1369                    unsafe fn vec_mergeh(self, other: Self) -> Self {
1370                        $mergeh(self, other)
1371                    }
1372                }
1373
1374                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1375                impl VectorMergeh for t_u!($ty) {
1376                    #[inline]
1377                    #[target_feature(enable = "vector")]
1378                    unsafe fn vec_mergeh(self, other: Self) -> Self {
1379                        transmute($mergeh(transmute(self), transmute(other)))
1380                    }
1381                }
1382            )*
1383        }
1384    }
1385
1386    impl_merge! {
1387        vector_signed_char, vmrlb, vmrhb,
1388        vector_signed_short, vmrlh, vmrhh,
1389        vector_signed_int, vmrlf, vmrhf,
1390        vector_signed_long_long, vmrlg, vmrhg
1391    }
1392
1393    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1394    pub trait VectorPerm {
1395        unsafe fn vec_perm(self, other: Self, c: vector_unsigned_char) -> Self;
1396    }
1397
1398    macro_rules! impl_merge {
1399        ($($ty:ident),*) => {
1400            $(
1401                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1402                impl VectorPerm for $ty {
1403                    #[inline]
1404                    #[target_feature(enable = "vector")]
1405                    unsafe fn vec_perm(self, other: Self, c: vector_unsigned_char) -> Self {
1406                        transmute(vperm(transmute(self), transmute(other), c))
1407                    }
1408                }
1409            )*
1410        }
1411    }
1412
1413    impl_merge! {
1414        vector_signed_char,
1415        vector_signed_short,
1416        vector_signed_int,
1417        vector_signed_long_long,
1418        vector_unsigned_char,
1419        vector_unsigned_short,
1420        vector_unsigned_int,
1421        vector_unsigned_long_long,
1422        vector_bool_char,
1423        vector_bool_short,
1424        vector_bool_int,
1425        vector_bool_long_long,
1426        vector_float,
1427        vector_double
1428    }
1429
1430    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1431    pub trait VectorSumU128 {
1432        unsafe fn vec_sum_u128(self, other: Self) -> vector_unsigned_char;
1433    }
1434
1435    #[inline]
1436    #[target_feature(enable = "vector")]
1437    #[cfg_attr(test, assert_instr(vsumqf))]
1438    pub unsafe fn vec_vsumqf(a: vector_unsigned_int, b: vector_unsigned_int) -> u128 {
1439        transmute(vsumqf(a, b))
1440    }
1441
1442    #[inline]
1443    #[target_feature(enable = "vector")]
1444    #[cfg_attr(test, assert_instr(vsumqg))]
1445    pub unsafe fn vec_vsumqg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> u128 {
1446        transmute(vsumqg(a, b))
1447    }
1448
1449    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1450    impl VectorSumU128 for vector_unsigned_int {
1451        #[inline]
1452        #[target_feature(enable = "vector")]
1453        unsafe fn vec_sum_u128(self, other: Self) -> vector_unsigned_char {
1454            transmute(vec_vsumqf(self, other))
1455        }
1456    }
1457
1458    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1459    impl VectorSumU128 for vector_unsigned_long_long {
1460        #[inline]
1461        #[target_feature(enable = "vector")]
1462        unsafe fn vec_sum_u128(self, other: Self) -> vector_unsigned_char {
1463            transmute(vec_vsumqg(self, other))
1464        }
1465    }
1466
1467    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1468    pub trait VectorSum2 {
1469        unsafe fn vec_sum2(self, other: Self) -> vector_unsigned_long_long;
1470    }
1471
1472    test_impl! { vec_vsumgh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_long_long [vsumgh, vsumgh] }
1473    test_impl! { vec_vsumgf (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long [vsumgf, vsumgf] }
1474
1475    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1476    impl VectorSum2 for vector_unsigned_short {
1477        #[inline]
1478        #[target_feature(enable = "vector")]
1479        unsafe fn vec_sum2(self, other: Self) -> vector_unsigned_long_long {
1480            vec_vsumgh(self, other)
1481        }
1482    }
1483
1484    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1485    impl VectorSum2 for vector_unsigned_int {
1486        #[inline]
1487        #[target_feature(enable = "vector")]
1488        unsafe fn vec_sum2(self, other: Self) -> vector_unsigned_long_long {
1489            vec_vsumgf(self, other)
1490        }
1491    }
1492
1493    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1494    pub trait VectorSum4 {
1495        unsafe fn vec_sum4(self, other: Self) -> vector_unsigned_int;
1496    }
1497
1498    test_impl! { vec_vsumb (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_int [vsumb, vsumb] }
1499    test_impl! { vec_vsumh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int [vsumh, vsumh] }
1500
1501    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1502    impl VectorSum4 for vector_unsigned_char {
1503        #[inline]
1504        #[target_feature(enable = "vector")]
1505        unsafe fn vec_sum4(self, other: Self) -> vector_unsigned_int {
1506            vec_vsumb(self, other)
1507        }
1508    }
1509
1510    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1511    impl VectorSum4 for vector_unsigned_short {
1512        #[inline]
1513        #[target_feature(enable = "vector")]
1514        unsafe fn vec_sum4(self, other: Self) -> vector_unsigned_int {
1515            vec_vsumh(self, other)
1516        }
1517    }
1518
1519    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1520    pub trait VectorSubc<Other> {
1521        type Result;
1522        unsafe fn vec_subc(self, b: Other) -> Self::Result;
1523    }
1524
1525    test_impl! { vec_vscbib (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [vscbib, vscbib] }
1526    test_impl! { vec_vscbih (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [vscbih, vscbih] }
1527    test_impl! { vec_vscbif (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vscbif, vscbif] }
1528    test_impl! { vec_vscbig (a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long [vscbig, vscbig] }
1529
1530    impl_vec_trait! {[VectorSubc vec_subc] vec_vscbib (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
1531    impl_vec_trait! {[VectorSubc vec_subc] vec_vscbih (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
1532    impl_vec_trait! {[VectorSubc vec_subc] vec_vscbif (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
1533    impl_vec_trait! {[VectorSubc vec_subc] vec_vscbig (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long }
1534
1535    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1536    pub trait VectorSqrt {
1537        unsafe fn vec_sqrt(self) -> Self;
1538    }
1539
1540    test_impl! { vec_sqrt_f32 (v: vector_float) -> vector_float [ simd_fsqrt, "vector-enhancements-1" vfsqsb ] }
1541    test_impl! { vec_sqrt_f64 (v: vector_double) -> vector_double [ simd_fsqrt, vfsqdb ] }
1542
1543    impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f32 (vector_float) }
1544    impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f64 (vector_double) }
1545
1546    macro_rules! vfae_wrapper {
1547        ($($name:ident $ty:ident)*) => {
1548            $(
1549                #[inline]
1550                #[target_feature(enable = "vector")]
1551                #[cfg_attr(test, assert_instr($name, IMM = 0))]
1552                unsafe fn $name<const IMM: i32>(
1553                    a: $ty,
1554                    b: $ty,
1555                ) -> $ty {
1556                    super::$name(a, b, IMM)
1557                }
1558            )*
1559        }
1560     }
1561
1562    vfae_wrapper! {
1563       vfaeb vector_signed_char
1564       vfaeh vector_signed_short
1565       vfaef vector_signed_int
1566
1567       vfaezb vector_signed_char
1568       vfaezh vector_signed_short
1569       vfaezf vector_signed_int
1570    }
1571
1572    macro_rules! impl_vfae {
1573        ([idx_cc $Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => {
1574            impl_vfae! { [idx_cc $Trait $m] $imm
1575                $b vector_signed_char vector_signed_char
1576                $b vector_unsigned_char vector_unsigned_char
1577                $b vector_bool_char vector_unsigned_char
1578
1579                $h vector_signed_short vector_signed_short
1580                $h vector_unsigned_short vector_unsigned_short
1581                $h vector_bool_short vector_unsigned_short
1582
1583                $f vector_signed_int vector_signed_int
1584                $f vector_unsigned_int vector_unsigned_int
1585                $f vector_bool_int vector_unsigned_int
1586            }
1587        };
1588        ([idx_cc $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident $r:ident)*) => {
1589            $(
1590                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1591                impl $Trait<Self> for $ty {
1592                    type Result = $r;
1593                    #[inline]
1594                    #[target_feature(enable = "vector")]
1595                    unsafe fn $m(self, b: Self, c: *mut i32) -> Self::Result {
1596                        let PackedTuple { x, y } = $fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b));
1597                        c.write(y);
1598                        transmute(x)
1599                    }
1600                }
1601            )*
1602        };
1603        ([cc $Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => {
1604            impl_vfae! { [cc $Trait $m] $imm
1605                $b vector_signed_char
1606                $b vector_unsigned_char
1607                $b vector_bool_char
1608
1609                $h vector_signed_short
1610                $h vector_unsigned_short
1611                $h vector_bool_short
1612
1613                $f vector_signed_int
1614                $f vector_unsigned_int
1615                $f vector_bool_int
1616            }
1617        };
1618        ([cc $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident)*) => {
1619            $(
1620                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1621                impl $Trait<Self> for $ty {
1622                    type Result = t_b!($ty);
1623                    #[inline]
1624                    #[target_feature(enable = "vector")]
1625                    unsafe fn $m(self, b: Self, c: *mut i32) -> Self::Result {
1626                        let PackedTuple { x, y } = $fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b));
1627                        c.write(y);
1628                        transmute(x)
1629                    }
1630                }
1631            )*
1632        };
1633        ([idx $Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => {
1634            impl_vfae! { [idx $Trait $m] $imm
1635                $b vector_signed_char vector_signed_char
1636                $b vector_unsigned_char vector_unsigned_char
1637                $b vector_bool_char vector_unsigned_char
1638
1639                $h vector_signed_short vector_signed_short
1640                $h vector_unsigned_short vector_unsigned_short
1641                $h vector_bool_short vector_unsigned_short
1642
1643                $f vector_signed_int vector_signed_int
1644                $f vector_unsigned_int vector_unsigned_int
1645                $f vector_bool_int vector_unsigned_int
1646            }
1647        };
1648        ([idx $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident $r:ident)*) => {
1649            $(
1650                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1651                impl $Trait<Self> for $ty {
1652                    type Result = $r;
1653                    #[inline]
1654                    #[target_feature(enable = "vector")]
1655                    unsafe fn $m(self, b: Self) -> Self::Result {
1656                        transmute($fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b)))
1657                    }
1658                }
1659            )*
1660        };
1661        ([$Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => {
1662            impl_vfae! { [$Trait $m] $imm
1663                $b vector_signed_char
1664                $b vector_unsigned_char
1665                $b vector_bool_char
1666
1667                $h vector_signed_short
1668                $h vector_unsigned_short
1669                $h vector_bool_short
1670
1671                $f vector_signed_int
1672                $f vector_unsigned_int
1673                $f vector_bool_int
1674            }
1675        };
1676        ([$Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident)*) => {
1677            $(
1678                #[unstable(feature = "stdarch_s390x", issue = "135681")]
1679                impl $Trait<Self> for $ty {
1680                    type Result = t_b!($ty);
1681                    #[inline]
1682                    #[target_feature(enable = "vector")]
1683                    unsafe fn $m(self, b: Self) -> Self::Result {
1684                        transmute($fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b)))
1685                    }
1686                }
1687            )*
1688        };
1689    }
1690
1691    enum FindImm {
1692        Eq = 4,
1693        Ne = 12,
1694        EqIdx = 0,
1695        NeIdx = 8,
1696    }
1697
1698    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1699    pub trait VectorFindAnyEq<Other> {
1700        type Result;
1701        unsafe fn vec_find_any_eq(self, other: Other) -> Self::Result;
1702    }
1703
1704    impl_vfae! { [VectorFindAnyEq vec_find_any_eq] Eq vfaeb vfaeh vfaef }
1705
1706    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1707    pub trait VectorFindAnyNe<Other> {
1708        type Result;
1709        unsafe fn vec_find_any_ne(self, other: Other) -> Self::Result;
1710    }
1711
1712    impl_vfae! { [VectorFindAnyNe vec_find_any_ne] Ne vfaeb vfaeh vfaef }
1713
1714    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1715    pub trait VectorFindAnyEqOrZeroIdx<Other> {
1716        type Result;
1717        unsafe fn vec_find_any_eq_or_0_idx(self, other: Other) -> Self::Result;
1718    }
1719
1720    impl_vfae! { [idx VectorFindAnyEqOrZeroIdx vec_find_any_eq_or_0_idx] EqIdx
1721        vfaezb vector_signed_char vector_signed_char
1722        vfaezb vector_unsigned_char vector_unsigned_char
1723        vfaezb vector_bool_char vector_unsigned_char
1724
1725        vfaezh vector_signed_short vector_signed_short
1726        vfaezh vector_unsigned_short vector_unsigned_short
1727        vfaezh vector_bool_short vector_unsigned_short
1728
1729        vfaezf vector_signed_int vector_signed_int
1730        vfaezf vector_unsigned_int vector_unsigned_int
1731        vfaezf vector_bool_int vector_unsigned_int
1732    }
1733
1734    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1735    pub trait VectorFindAnyNeOrZeroIdx<Other> {
1736        type Result;
1737        unsafe fn vec_find_any_ne_or_0_idx(self, other: Other) -> Self::Result;
1738    }
1739
1740    impl_vfae! { [idx VectorFindAnyNeOrZeroIdx vec_find_any_ne_or_0_idx] NeIdx
1741        vfaezb vector_signed_char vector_signed_char
1742        vfaezb vector_unsigned_char vector_unsigned_char
1743        vfaezb vector_bool_char vector_unsigned_char
1744
1745        vfaezh vector_signed_short vector_signed_short
1746        vfaezh vector_unsigned_short vector_unsigned_short
1747        vfaezh vector_bool_short vector_unsigned_short
1748
1749        vfaezf vector_signed_int vector_signed_int
1750        vfaezf vector_unsigned_int vector_unsigned_int
1751        vfaezf vector_bool_int vector_unsigned_int
1752    }
1753
1754    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1755    pub trait VectorFindAnyEqIdx<Other> {
1756        type Result;
1757        unsafe fn vec_find_any_eq_idx(self, other: Other) -> Self::Result;
1758    }
1759
1760    impl_vfae! { [idx VectorFindAnyEqIdx vec_find_any_eq_idx] EqIdx vfaeb vfaeh vfaef }
1761
1762    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1763    pub trait VectorFindAnyNeIdx<Other> {
1764        type Result;
1765        unsafe fn vec_find_any_ne_idx(self, other: Other) -> Self::Result;
1766    }
1767
1768    impl_vfae! { [idx VectorFindAnyNeIdx vec_find_any_ne_idx] NeIdx vfaeb vfaeh vfaef }
1769
1770    macro_rules! vfaes_wrapper {
1771        ($($name:ident $ty:ident)*) => {
1772            $(
1773                #[inline]
1774                #[target_feature(enable = "vector")]
1775                #[cfg_attr(test, assert_instr($name, IMM = 0))]
1776                unsafe fn $name<const IMM: i32>(
1777                    a: $ty,
1778                    b: $ty,
1779                ) -> PackedTuple<$ty, i32> {
1780                    super::$name(a, b, IMM)
1781                }
1782            )*
1783        }
1784     }
1785
1786    vfaes_wrapper! {
1787       vfaebs vector_signed_char
1788       vfaehs vector_signed_short
1789       vfaefs vector_signed_int
1790
1791       vfaezbs vector_signed_char
1792       vfaezhs vector_signed_short
1793       vfaezfs vector_signed_int
1794    }
1795
1796    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1797    pub trait VectorFindAnyEqCC<Other> {
1798        type Result;
1799        unsafe fn vec_find_any_eq_cc(self, other: Other, c: *mut i32) -> Self::Result;
1800    }
1801
1802    impl_vfae! { [cc VectorFindAnyEqCC vec_find_any_eq_cc] Eq vfaebs vfaehs vfaefs }
1803
1804    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1805    pub trait VectorFindAnyNeCC<Other> {
1806        type Result;
1807        unsafe fn vec_find_any_ne_cc(self, other: Other, c: *mut i32) -> Self::Result;
1808    }
1809
1810    impl_vfae! { [cc VectorFindAnyNeCC vec_find_any_ne_cc] Ne vfaebs vfaehs vfaefs }
1811
1812    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1813    pub trait VectorFindAnyEqIdxCC<Other> {
1814        type Result;
1815        unsafe fn vec_find_any_eq_idx_cc(self, other: Other, c: *mut i32) -> Self::Result;
1816    }
1817
1818    impl_vfae! { [idx_cc VectorFindAnyEqIdxCC vec_find_any_eq_idx_cc] EqIdx vfaebs vfaehs vfaefs }
1819
1820    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1821    pub trait VectorFindAnyNeIdxCC<Other> {
1822        type Result;
1823        unsafe fn vec_find_any_ne_idx_cc(self, other: Other, c: *mut i32) -> Self::Result;
1824    }
1825
1826    impl_vfae! { [idx_cc VectorFindAnyNeIdxCC vec_find_any_ne_idx_cc] NeIdx vfaebs vfaehs vfaefs }
1827
1828    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1829    pub trait VectorFindAnyEqOrZeroIdxCC<Other> {
1830        type Result;
1831        unsafe fn vec_find_any_eq_or_0_idx_cc(self, other: Other, c: *mut i32) -> Self::Result;
1832    }
1833
1834    impl_vfae! { [idx_cc VectorFindAnyEqOrZeroIdxCC vec_find_any_eq_or_0_idx_cc] EqIdx vfaezbs vfaezhs vfaezfs }
1835
1836    #[unstable(feature = "stdarch_s390x", issue = "135681")]
1837    pub trait VectorFindAnyNeOrZeroIdxCC<Other> {
1838        type Result;
1839        unsafe fn vec_find_any_ne_or_0_idx_cc(self, other: Other, c: *mut i32) -> Self::Result;
1840    }
1841
1842    impl_vfae! { [idx_cc VectorFindAnyNeOrZeroIdxCC vec_find_any_ne_or_0_idx_cc] NeIdx vfaezbs vfaezhs vfaezfs }
1843}
1844
1845/// Vector element-wise addition.
1846#[inline]
1847#[target_feature(enable = "vector")]
1848#[unstable(feature = "stdarch_s390x", issue = "135681")]
1849pub unsafe fn vec_add<T, U>(a: T, b: U) -> <T as sealed::VectorAdd<U>>::Result
1850where
1851    T: sealed::VectorAdd<U>,
1852{
1853    a.vec_add(b)
1854}
1855
1856/// Vector element-wise subtraction.
1857#[inline]
1858#[target_feature(enable = "vector")]
1859#[unstable(feature = "stdarch_s390x", issue = "135681")]
1860pub unsafe fn vec_sub<T, U>(a: T, b: U) -> <T as sealed::VectorSub<U>>::Result
1861where
1862    T: sealed::VectorSub<U>,
1863{
1864    a.vec_sub(b)
1865}
1866
1867/// Vector element-wise multiplication.
1868///
1869/// ## Purpose
1870/// Compute the products of corresponding elements of two vectors.
1871///
1872/// ## Result value
1873/// Each element of r receives the product of the corresponding elements of a and b.
1874#[inline]
1875#[target_feature(enable = "vector")]
1876#[unstable(feature = "stdarch_s390x", issue = "135681")]
1877pub unsafe fn vec_mul<T>(a: T, b: T) -> T
1878where
1879    T: sealed::VectorMul,
1880{
1881    a.vec_mul(b)
1882}
1883
1884/// Vector Count Leading Zeros
1885#[inline]
1886#[target_feature(enable = "vector")]
1887#[unstable(feature = "stdarch_s390x", issue = "135681")]
1888pub unsafe fn vec_cntlz<T>(a: T) -> <T as sealed::CountBits>::Result
1889where
1890    T: sealed::CountBits,
1891{
1892    a.vec_cntlz()
1893}
1894
1895/// Vector Count Trailing Zeros
1896#[inline]
1897#[target_feature(enable = "vector")]
1898#[unstable(feature = "stdarch_s390x", issue = "135681")]
1899pub unsafe fn vec_cnttz<T>(a: T) -> <T as sealed::CountBits>::Result
1900where
1901    T: sealed::CountBits,
1902{
1903    a.vec_cnttz()
1904}
1905
1906/// Vector Population Count
1907///
1908/// Computes the population count (number of set bits) in each element of the input.
1909#[inline]
1910#[target_feature(enable = "vector")]
1911#[unstable(feature = "stdarch_s390x", issue = "135681")]
1912pub unsafe fn vec_popcnt<T>(a: T) -> <T as sealed::CountBits>::Result
1913where
1914    T: sealed::CountBits,
1915{
1916    a.vec_popcnt()
1917}
1918
1919/// Vector element-wise maximum.
1920#[inline]
1921#[target_feature(enable = "vector")]
1922#[unstable(feature = "stdarch_s390x", issue = "135681")]
1923pub unsafe fn vec_max<T, U>(a: T, b: U) -> <T as sealed::VectorMax<U>>::Result
1924where
1925    T: sealed::VectorMax<U>,
1926{
1927    a.vec_max(b)
1928}
1929
1930/// Vector element-wise minimum.
1931#[inline]
1932#[target_feature(enable = "vector")]
1933#[unstable(feature = "stdarch_s390x", issue = "135681")]
1934pub unsafe fn vec_min<T, U>(a: T, b: U) -> <T as sealed::VectorMin<U>>::Result
1935where
1936    T: sealed::VectorMin<U>,
1937{
1938    a.vec_min(b)
1939}
1940
1941/// Vector abs.
1942#[inline]
1943#[target_feature(enable = "vector")]
1944#[unstable(feature = "stdarch_s390x", issue = "135681")]
1945pub unsafe fn vec_abs<T>(a: T) -> T
1946where
1947    T: sealed::VectorAbs,
1948{
1949    a.vec_abs()
1950}
1951
1952/// Vector negative abs.
1953#[inline]
1954#[target_feature(enable = "vector")]
1955#[unstable(feature = "stdarch_s390x", issue = "135681")]
1956pub unsafe fn vec_nabs<T>(a: T) -> T
1957where
1958    T: sealed::VectorNabs,
1959{
1960    a.vec_nabs()
1961}
1962
1963/// Vector square root.
1964#[inline]
1965#[target_feature(enable = "vector")]
1966#[unstable(feature = "stdarch_s390x", issue = "135681")]
1967pub unsafe fn vec_sqrt<T>(a: T) -> T
1968where
1969    T: sealed::VectorSqrt,
1970{
1971    a.vec_sqrt()
1972}
1973
1974/// Vector Splat
1975#[inline]
1976#[target_feature(enable = "vector")]
1977#[unstable(feature = "stdarch_s390x", issue = "135681")]
1978pub unsafe fn vec_splat<T, const IMM: u32>(a: T) -> T
1979where
1980    T: sealed::VectorSplat,
1981{
1982    a.vec_splat::<IMM>()
1983}
1984
1985/// Vector splats.
1986#[inline]
1987#[target_feature(enable = "vector")]
1988#[unstable(feature = "stdarch_s390x", issue = "135681")]
1989pub unsafe fn vec_splats<T, U>(a: T) -> U
1990where
1991    T: sealed::VectorSplats<U>,
1992{
1993    a.vec_splats()
1994}
1995
1996/// Vector and
1997#[inline]
1998#[target_feature(enable = "vector")]
1999#[unstable(feature = "stdarch_s390x", issue = "135681")]
2000pub unsafe fn vec_and<T, U>(a: T, b: U) -> <T as sealed::VectorAnd<U>>::Result
2001where
2002    T: sealed::VectorAnd<U>,
2003{
2004    a.vec_and(b)
2005}
2006
2007/// Vector or
2008#[inline]
2009#[target_feature(enable = "vector")]
2010#[unstable(feature = "stdarch_s390x", issue = "135681")]
2011pub unsafe fn vec_or<T, U>(a: T, b: U) -> <T as sealed::VectorOr<U>>::Result
2012where
2013    T: sealed::VectorOr<U>,
2014{
2015    a.vec_or(b)
2016}
2017
2018/// Vector xor
2019#[inline]
2020#[target_feature(enable = "vector")]
2021#[unstable(feature = "stdarch_s390x", issue = "135681")]
2022pub unsafe fn vec_xor<T, U>(a: T, b: U) -> <T as sealed::VectorXor<U>>::Result
2023where
2024    T: sealed::VectorXor<U>,
2025{
2026    a.vec_xor(b)
2027}
2028
2029/// Vector nor
2030#[inline]
2031#[target_feature(enable = "vector")]
2032#[unstable(feature = "stdarch_s390x", issue = "135681")]
2033pub unsafe fn vec_nor<T, U>(a: T, b: U) -> <T as sealed::VectorNor<U>>::Result
2034where
2035    T: sealed::VectorNor<U>,
2036{
2037    a.vec_nor(b)
2038}
2039
2040/// Vector nand
2041#[inline]
2042#[target_feature(enable = "vector")]
2043#[unstable(feature = "stdarch_s390x", issue = "135681")]
2044pub unsafe fn vec_nand<T, U>(a: T, b: U) -> <T as sealed::VectorNand<U>>::Result
2045where
2046    T: sealed::VectorNand<U>,
2047{
2048    a.vec_nand(b)
2049}
2050
2051/// Vector xnor
2052#[inline]
2053#[target_feature(enable = "vector")]
2054#[unstable(feature = "stdarch_s390x", issue = "135681")]
2055pub unsafe fn vec_eqv<T, U>(a: T, b: U) -> <T as sealed::VectorEqv<U>>::Result
2056where
2057    T: sealed::VectorEqv<U>,
2058{
2059    a.vec_eqv(b)
2060}
2061
2062/// Vector andc.
2063#[inline]
2064#[target_feature(enable = "vector")]
2065#[unstable(feature = "stdarch_s390x", issue = "135681")]
2066pub unsafe fn vec_andc<T, U>(a: T, b: U) -> <T as sealed::VectorAndc<U>>::Result
2067where
2068    T: sealed::VectorAndc<U>,
2069{
2070    a.vec_andc(b)
2071}
2072
2073/// Vector OR with Complement
2074///
2075/// ## Purpose
2076/// Performs a bitwise OR of the first vector with the bitwise-complemented second vector.
2077///
2078/// ## Result value
2079/// r is the bitwise OR of a and the bitwise complement of b.
2080#[inline]
2081#[target_feature(enable = "vector")]
2082#[unstable(feature = "stdarch_s390x", issue = "135681")]
2083pub unsafe fn vec_orc<T, U>(a: T, b: U) -> <T as sealed::VectorOrc<U>>::Result
2084where
2085    T: sealed::VectorOrc<U>,
2086{
2087    a.vec_orc(b)
2088}
2089
2090/// Vector floor.
2091#[inline]
2092#[target_feature(enable = "vector")]
2093#[unstable(feature = "stdarch_s390x", issue = "135681")]
2094pub unsafe fn vec_floor<T>(a: T) -> T
2095where
2096    T: sealed::VectorFloor,
2097{
2098    a.vec_floor()
2099}
2100
2101/// Vector ceil.
2102#[inline]
2103#[target_feature(enable = "vector")]
2104#[unstable(feature = "stdarch_s390x", issue = "135681")]
2105pub unsafe fn vec_ceil<T>(a: T) -> T
2106where
2107    T: sealed::VectorCeil,
2108{
2109    a.vec_ceil()
2110}
2111
2112/// Returns a vector containing the truncated values of the corresponding elements of the given vector.
2113/// Each element of the result contains the value of the corresponding element of a, truncated to an integral value.
2114#[inline]
2115#[target_feature(enable = "vector")]
2116#[unstable(feature = "stdarch_s390x", issue = "135681")]
2117pub unsafe fn vec_trunc<T>(a: T) -> T
2118where
2119    T: sealed::VectorTrunc,
2120{
2121    a.vec_trunc()
2122}
2123
2124/// Returns a vector containing the rounded values to the nearest representable floating-point integer,
2125/// using IEEE round-to-nearest rounding, of the corresponding elements of the given vector
2126#[inline]
2127#[target_feature(enable = "vector")]
2128#[unstable(feature = "stdarch_s390x", issue = "135681")]
2129pub unsafe fn vec_round<T>(a: T) -> T
2130where
2131    T: sealed::VectorRound,
2132{
2133    a.vec_round()
2134}
2135
2136/// Returns a vector by using the current rounding mode to round every
2137/// floating-point element in the given vector to integer.
2138#[inline]
2139#[target_feature(enable = "vector")]
2140#[unstable(feature = "stdarch_s390x", issue = "135681")]
2141pub unsafe fn vec_roundc<T>(a: T) -> T
2142where
2143    T: sealed::VectorRoundc,
2144{
2145    a.vec_roundc()
2146}
2147
2148/// Returns a vector containing the largest representable floating-point integral values less
2149/// than or equal to the values of the corresponding elements of the given vector.
2150#[inline]
2151#[target_feature(enable = "vector")]
2152#[unstable(feature = "stdarch_s390x", issue = "135681")]
2153pub unsafe fn vec_roundm<T>(a: T) -> T
2154where
2155    T: sealed::VectorFloor,
2156{
2157    // the IBM docs note
2158    //
2159    // > vec_roundm provides the same functionality as vec_floor, except that vec_roundz would not trigger the IEEE-inexact exception.
2160    //
2161    // but in practice `vec_floor` also does not trigger that exception, so both are equivalent
2162    a.vec_floor()
2163}
2164
2165/// Returns a vector containing the smallest representable floating-point integral values greater
2166/// than or equal to the values of the corresponding elements of the given vector.
2167#[inline]
2168#[target_feature(enable = "vector")]
2169#[unstable(feature = "stdarch_s390x", issue = "135681")]
2170pub unsafe fn vec_roundp<T>(a: T) -> T
2171where
2172    T: sealed::VectorCeil,
2173{
2174    // the IBM docs note
2175    //
2176    // > vec_roundp provides the same functionality as vec_ceil, except that vec_roundz would not trigger the IEEE-inexact exception.
2177    //
2178    // but in practice `vec_ceil` also does not trigger that exception, so both are equivalent
2179    a.vec_ceil()
2180}
2181
2182/// Returns a vector containing the truncated values of the corresponding elements of the given vector.
2183/// Each element of the result contains the value of the corresponding element of a, truncated to an integral value.
2184#[inline]
2185#[target_feature(enable = "vector")]
2186#[unstable(feature = "stdarch_s390x", issue = "135681")]
2187pub unsafe fn vec_roundz<T>(a: T) -> T
2188where
2189    T: sealed::VectorTrunc,
2190{
2191    // the IBM docs note
2192    //
2193    // > vec_roundz provides the same functionality as vec_trunc, except that vec_roundz would not trigger the IEEE-inexact exception.
2194    //
2195    // but in practice `vec_trunc` also does not trigger that exception, so both are equivalent
2196    a.vec_trunc()
2197}
2198
2199/// Returns a vector by using the current rounding mode to round every floating-point element in the given vector to integer.
2200#[inline]
2201#[target_feature(enable = "vector")]
2202#[unstable(feature = "stdarch_s390x", issue = "135681")]
2203pub unsafe fn vec_rint<T>(a: T) -> T
2204where
2205    T: sealed::VectorRint,
2206{
2207    a.vec_rint()
2208}
2209
2210/// Vector Shift Left
2211#[inline]
2212#[target_feature(enable = "vector")]
2213#[unstable(feature = "stdarch_s390x", issue = "135681")]
2214pub unsafe fn vec_sl<T, U>(a: T, b: U) -> <T as sealed::VectorSl<U>>::Result
2215where
2216    T: sealed::VectorSl<U>,
2217{
2218    a.vec_sl(b)
2219}
2220
2221/// Vector Shift Right
2222#[inline]
2223#[target_feature(enable = "vector")]
2224#[unstable(feature = "stdarch_s390x", issue = "135681")]
2225pub unsafe fn vec_sr<T, U>(a: T, b: U) -> <T as sealed::VectorSr<U>>::Result
2226where
2227    T: sealed::VectorSr<U>,
2228{
2229    a.vec_sr(b)
2230}
2231
2232/// Vector Shift Right Algebraic
2233#[inline]
2234#[target_feature(enable = "vector")]
2235#[unstable(feature = "stdarch_s390x", issue = "135681")]
2236pub unsafe fn vec_sra<T, U>(a: T, b: U) -> <T as sealed::VectorSra<U>>::Result
2237where
2238    T: sealed::VectorSra<U>,
2239{
2240    a.vec_sra(b)
2241}
2242
2243/// Vector Shift Left by Byte
2244#[inline]
2245#[target_feature(enable = "vector")]
2246#[unstable(feature = "stdarch_s390x", issue = "135681")]
2247pub unsafe fn vec_slb<T, U>(a: T, b: U) -> <T as sealed::VectorSlb<U>>::Result
2248where
2249    T: sealed::VectorSlb<U>,
2250{
2251    a.vec_slb(b)
2252}
2253
2254/// Vector Shift Right by Byte
2255#[inline]
2256#[target_feature(enable = "vector")]
2257#[unstable(feature = "stdarch_s390x", issue = "135681")]
2258pub unsafe fn vec_srb<T, U>(a: T, b: U) -> <T as sealed::VectorSrb<U>>::Result
2259where
2260    T: sealed::VectorSrb<U>,
2261{
2262    a.vec_srb(b)
2263}
2264
2265/// Vector Shift Right Algebraic by Byte
2266#[inline]
2267#[target_feature(enable = "vector")]
2268#[unstable(feature = "stdarch_s390x", issue = "135681")]
2269pub unsafe fn vec_srab<T, U>(a: T, b: U) -> <T as sealed::VectorSrab<U>>::Result
2270where
2271    T: sealed::VectorSrab<U>,
2272{
2273    a.vec_srab(b)
2274}
2275
2276/// Vector Element Rotate Left
2277#[inline]
2278#[target_feature(enable = "vector")]
2279#[unstable(feature = "stdarch_s390x", issue = "135681")]
2280pub unsafe fn vec_rl<T, U>(a: T, b: U) -> <T as sealed::VectorRl<U>>::Result
2281where
2282    T: sealed::VectorRl<U>,
2283{
2284    a.vec_rl(b)
2285}
2286
2287/// Performs a left shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding
2288/// 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.
2289#[inline]
2290#[target_feature(enable = "vector")]
2291#[unstable(feature = "stdarch_s390x", issue = "135681")]
2292pub unsafe fn vec_sll<T>(a: T, b: vector_unsigned_char) -> T
2293where
2294    T: sealed::VectorSll<vector_unsigned_char, Result = T>,
2295{
2296    a.vec_sll(b)
2297}
2298
2299/// Performs a right shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding
2300/// 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.
2301#[inline]
2302#[target_feature(enable = "vector")]
2303#[unstable(feature = "stdarch_s390x", issue = "135681")]
2304pub unsafe fn vec_srl<T>(a: T, b: vector_unsigned_char) -> T
2305where
2306    T: sealed::VectorSrl<vector_unsigned_char, Result = T>,
2307{
2308    a.vec_srl(b)
2309}
2310
2311/// 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
2312/// 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
2313/// the most significant bit of the element of a.
2314#[inline]
2315#[target_feature(enable = "vector")]
2316#[unstable(feature = "stdarch_s390x", issue = "135681")]
2317pub unsafe fn vec_sral<T>(a: T, b: vector_unsigned_char) -> T
2318where
2319    T: sealed::VectorSral<vector_unsigned_char, Result = T>,
2320{
2321    a.vec_sral(b)
2322}
2323
2324/// 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
2325/// of a left by the number of bits specified by b, modulo the number of bits in the element.
2326#[inline]
2327#[target_feature(enable = "vector")]
2328#[unstable(feature = "stdarch_s390x", issue = "135681")]
2329pub unsafe fn vec_rli<T>(a: T, bits: core::ffi::c_ulong) -> T
2330where
2331    T: sealed::VectorRli,
2332{
2333    a.vec_rli(bits)
2334}
2335
2336/// Returns a vector with the elements of the input vector in reversed order.
2337#[inline]
2338#[target_feature(enable = "vector")]
2339#[unstable(feature = "stdarch_s390x", issue = "135681")]
2340pub unsafe fn vec_reve<T>(a: T) -> T
2341where
2342    T: sealed::VectorReve,
2343{
2344    a.vec_reve()
2345}
2346
2347/// Returns a vector where each vector element contains the corresponding byte-reversed vector element of the input vector.
2348#[inline]
2349#[target_feature(enable = "vector")]
2350#[unstable(feature = "stdarch_s390x", issue = "135681")]
2351pub unsafe fn vec_revb<T>(a: T) -> T
2352where
2353    T: sealed::VectorRevb,
2354{
2355    a.vec_revb()
2356}
2357
2358/// Merges the most significant ("high") halves of two vectors.
2359#[inline]
2360#[target_feature(enable = "vector")]
2361#[unstable(feature = "stdarch_s390x", issue = "135681")]
2362pub unsafe fn vec_mergeh<T>(a: T, b: T) -> T
2363where
2364    T: sealed::VectorMergeh,
2365{
2366    a.vec_mergeh(b)
2367}
2368
2369/// Merges the least significant ("low") halves of two vectors.
2370#[inline]
2371#[target_feature(enable = "vector")]
2372#[unstable(feature = "stdarch_s390x", issue = "135681")]
2373pub unsafe fn vec_mergel<T>(a: T, b: T) -> T
2374where
2375    T: sealed::VectorMergel,
2376{
2377    a.vec_mergel(b)
2378}
2379
2380/// Generates byte masks for elements in the return vector. For each bit in a, if the bit is one, all bit positions
2381/// 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.
2382#[inline]
2383#[target_feature(enable = "vector")]
2384#[unstable(feature = "stdarch_s390x", issue = "135681")]
2385#[cfg_attr(test, assert_instr(vgbm, MASK = 0x00FF))]
2386pub unsafe fn vec_genmask<const MASK: u16>() -> vector_unsigned_char {
2387    vector_unsigned_char(const { genmask::<MASK>() })
2388}
2389
2390/// Vector Generate Mask (Byte)
2391#[inline]
2392#[target_feature(enable = "vector")]
2393#[unstable(feature = "stdarch_s390x", issue = "135681")]
2394#[cfg_attr(test, assert_instr(vrepib, L = 3, H = 5))]
2395pub unsafe fn vec_genmasks_8<const L: u8, const H: u8>() -> vector_unsigned_char {
2396    vector_unsigned_char(const { [genmasks(u8::BITS, L, H) as u8; 16] })
2397}
2398
2399/// Vector Generate Mask (Halfword)
2400#[inline]
2401#[target_feature(enable = "vector")]
2402#[unstable(feature = "stdarch_s390x", issue = "135681")]
2403#[cfg_attr(test, assert_instr(vrepih, L = 3, H = 5))]
2404pub unsafe fn vec_genmasks_16<const L: u8, const H: u8>() -> vector_unsigned_short {
2405    vector_unsigned_short(const { [genmasks(u16::BITS, L, H) as u16; 8] })
2406}
2407
2408/// Vector Generate Mask (Word)
2409#[inline]
2410#[target_feature(enable = "vector")]
2411#[unstable(feature = "stdarch_s390x", issue = "135681")]
2412#[cfg_attr(test, assert_instr(vgmf, L = 3, H = 5))]
2413pub unsafe fn vec_genmasks_32<const L: u8, const H: u8>() -> vector_unsigned_int {
2414    vector_unsigned_int(const { [genmasks(u32::BITS, L, H) as u32; 4] })
2415}
2416
2417/// Vector Generate Mask (Doubleword)
2418#[inline]
2419#[target_feature(enable = "vector")]
2420#[unstable(feature = "stdarch_s390x", issue = "135681")]
2421#[cfg_attr(test, assert_instr(vgmg, L = 3, H = 5))]
2422pub unsafe fn vec_genmasks_64<const L: u8, const H: u8>() -> vector_unsigned_long_long {
2423    vector_unsigned_long_long(const { [genmasks(u64::BITS, L, H); 2] })
2424}
2425
2426/// Returns a vector that contains some elements of two vectors, in the order specified by a third vector.
2427/// 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.
2428/// Note: The vector generate mask built-in function [`vec_genmask`] could help generate the mask c.
2429#[inline]
2430#[target_feature(enable = "vector")]
2431#[unstable(feature = "stdarch_s390x", issue = "135681")]
2432pub unsafe fn vec_perm<T: sealed::VectorPerm>(a: T, b: T, c: vector_unsigned_char) -> T {
2433    a.vec_perm(b, c)
2434}
2435
2436/// Vector Sum Across Quadword
2437///
2438/// Returns a vector containing the results of performing a sum across all the elements in each of the quadword of vector a,
2439/// and the rightmost word or doubleword element of the b. The result is an unsigned 128-bit integer.
2440#[inline]
2441#[target_feature(enable = "vector")]
2442#[unstable(feature = "stdarch_s390x", issue = "135681")]
2443pub unsafe fn vec_sum_u128<T: sealed::VectorSumU128>(a: T, b: T) -> vector_unsigned_char {
2444    a.vec_sum_u128(b)
2445}
2446
2447/// Vector Sum Across Doubleword
2448///
2449/// Returns a vector containing the results of performing a sum across all the elements in each of the doubleword of vector a,
2450/// and the rightmost sub-element of the corresponding doubleword of b.
2451#[inline]
2452#[target_feature(enable = "vector")]
2453#[unstable(feature = "stdarch_s390x", issue = "135681")]
2454pub unsafe fn vec_sum2<T: sealed::VectorSum2>(a: T, b: T) -> vector_unsigned_long_long {
2455    a.vec_sum2(b)
2456}
2457
2458/// Vector Sum Across Word
2459///
2460/// Returns a vector containing the results of performing a sum across all the elements in each of the word of vector a,
2461/// and the rightmost sub-element of the corresponding word of b.
2462#[inline]
2463#[target_feature(enable = "vector")]
2464#[unstable(feature = "stdarch_s390x", issue = "135681")]
2465pub unsafe fn vec_sum4<T: sealed::VectorSum4>(a: T, b: T) -> vector_unsigned_int {
2466    a.vec_sum4(b)
2467}
2468
2469/// Vector Subtract unsigned 128-bits
2470///
2471/// Subtracts unsigned quadword values.
2472///
2473/// This function operates on the vectors as 128-bit unsigned integers. It returns low 128 bits of a - b.
2474#[inline]
2475#[target_feature(enable = "vector")]
2476#[unstable(feature = "stdarch_s390x", issue = "135681")]
2477#[cfg_attr(test, assert_instr(vsq))]
2478pub unsafe fn vec_sub_u128(
2479    a: vector_unsigned_char,
2480    b: vector_unsigned_char,
2481) -> vector_unsigned_char {
2482    let a: u128 = transmute(a);
2483    let b: u128 = transmute(b);
2484
2485    transmute(a.wrapping_sub(b))
2486}
2487
2488/// Vector Subtract Carryout
2489///
2490/// Returns a vector containing the borrow produced by subtracting each of corresponding elements of b from a.
2491///
2492/// On each resulting element, the value is 0 if a borrow occurred, or 1 if no borrow occurred.
2493#[inline]
2494#[target_feature(enable = "vector")]
2495#[unstable(feature = "stdarch_s390x", issue = "135681")]
2496pub unsafe fn vec_subc<T, U>(a: T, b: U) -> <T as sealed::VectorSubc<U>>::Result
2497where
2498    T: sealed::VectorSubc<U>,
2499{
2500    a.vec_subc(b)
2501}
2502
2503/// Gets the carry bit of the 128-bit subtraction of two quadword values.
2504/// 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.
2505/// If no borrow occurred, the bit 127 of d is 1; otherwise it is set to 0. All other bits of d are 0.
2506#[inline]
2507#[target_feature(enable = "vector")]
2508#[unstable(feature = "stdarch_s390x", issue = "135681")]
2509#[cfg_attr(test, assert_instr(vscbiq))]
2510pub unsafe fn vec_subc_u128(
2511    a: vector_unsigned_char,
2512    b: vector_unsigned_char,
2513) -> vector_unsigned_char {
2514    transmute(vscbiq(transmute(a), transmute(b)))
2515}
2516
2517/// Subtracts unsigned quadword values with carry bit from a previous operation.
2518///
2519/// This function operates on the vectors as 128-bit unsigned integers. It returns a vector containing the result of subtracting of b from a,
2520/// and the carryout bit from a previous operation.
2521///
2522/// Note: Only the borrow indication bit (127-bit) of c is used, and the other bits are ignored.
2523#[inline]
2524#[target_feature(enable = "vector")]
2525#[unstable(feature = "stdarch_s390x", issue = "135681")]
2526#[cfg_attr(test, assert_instr(vsbiq))]
2527pub unsafe fn vec_sube_u128(
2528    a: vector_unsigned_char,
2529    b: vector_unsigned_char,
2530    c: vector_unsigned_char,
2531) -> vector_unsigned_char {
2532    transmute(vsbiq(transmute(a), transmute(b), transmute(c)))
2533}
2534
2535/// Vector Subtract with Carryout, Carryout
2536///
2537/// Gets the carry bit of the 128-bit subtraction of two quadword values with carry bit from the previous operation.
2538///
2539/// It returns a vector containing the carryout produced from the result of subtracting of b from a,
2540/// and the carryout bit from a previous operation. If no borrow occurred, the 127-bit of d is 1, otherwise 0.
2541/// All other bits of d are 0.
2542///
2543/// Note: Only the borrow indication bit (127-bit) of c is used, and the other bits are ignored.
2544#[inline]
2545#[target_feature(enable = "vector")]
2546#[unstable(feature = "stdarch_s390x", issue = "135681")]
2547#[cfg_attr(test, assert_instr(vsbcbiq))]
2548pub unsafe fn vec_subec_u128(
2549    a: vector_unsigned_char,
2550    b: vector_unsigned_char,
2551    c: vector_unsigned_char,
2552) -> vector_unsigned_char {
2553    transmute(vsbcbiq(transmute(a), transmute(b), transmute(c)))
2554}
2555
2556/// Vector Splat Signed Byte
2557#[inline]
2558#[target_feature(enable = "vector")]
2559#[unstable(feature = "stdarch_s390x", issue = "135681")]
2560#[cfg_attr(test, assert_instr(vrepib, IMM = 42))]
2561pub unsafe fn vec_splat_i8<const IMM: i8>() -> vector_signed_char {
2562    vector_signed_char([IMM; 16])
2563}
2564
2565/// Vector Splat Signed Halfword
2566#[inline]
2567#[target_feature(enable = "vector")]
2568#[unstable(feature = "stdarch_s390x", issue = "135681")]
2569#[cfg_attr(test, assert_instr(vrepih, IMM = 42))]
2570pub unsafe fn vec_splat_i16<const IMM: i16>() -> vector_signed_short {
2571    vector_signed_short([IMM as i16; 8])
2572}
2573
2574/// Vector Splat Signed Word
2575#[inline]
2576#[target_feature(enable = "vector")]
2577#[unstable(feature = "stdarch_s390x", issue = "135681")]
2578#[cfg_attr(test, assert_instr(vrepif, IMM = 42))]
2579pub unsafe fn vec_splat_i32<const IMM: i16>() -> vector_signed_int {
2580    vector_signed_int([IMM as i32; 4])
2581}
2582
2583/// Vector Splat Signed Doubleword
2584#[inline]
2585#[target_feature(enable = "vector")]
2586#[unstable(feature = "stdarch_s390x", issue = "135681")]
2587#[cfg_attr(test, assert_instr(vrepig, IMM = 42))]
2588pub unsafe fn vec_splat_i64<const IMM: i16>() -> vector_signed_long_long {
2589    vector_signed_long_long([IMM as i64; 2])
2590}
2591
2592/// Vector Splat Unsigned Byte
2593#[inline]
2594#[target_feature(enable = "vector")]
2595#[unstable(feature = "stdarch_s390x", issue = "135681")]
2596#[cfg_attr(test, assert_instr(vrepib, IMM = 42))]
2597pub unsafe fn vec_splat_u8<const IMM: u8>() -> vector_unsigned_char {
2598    vector_unsigned_char([IMM; 16])
2599}
2600
2601/// Vector Splat Unsigned Halfword
2602#[inline]
2603#[target_feature(enable = "vector")]
2604#[unstable(feature = "stdarch_s390x", issue = "135681")]
2605#[cfg_attr(test, assert_instr(vrepih, IMM = 42))]
2606pub unsafe fn vec_splat_u16<const IMM: i16>() -> vector_unsigned_short {
2607    vector_unsigned_short([IMM as u16; 8])
2608}
2609
2610/// Vector Splat Unsigned Word
2611#[inline]
2612#[target_feature(enable = "vector")]
2613#[unstable(feature = "stdarch_s390x", issue = "135681")]
2614#[cfg_attr(test, assert_instr(vrepif, IMM = 42))]
2615pub unsafe fn vec_splat_u32<const IMM: i16>() -> vector_unsigned_int {
2616    vector_unsigned_int([IMM as u32; 4])
2617}
2618
2619/// Vector Splat Unsigned Doubleword
2620#[inline]
2621#[target_feature(enable = "vector")]
2622#[unstable(feature = "stdarch_s390x", issue = "135681")]
2623#[cfg_attr(test, assert_instr(vrepig, IMM = 42))]
2624pub unsafe fn vec_splat_u64<const IMM: i16>() -> vector_unsigned_long_long {
2625    vector_unsigned_long_long([IMM as u64; 2])
2626}
2627
2628macro_rules! vec_find_any {
2629    ($($Trait:ident $fun:ident)*) => {
2630        $(
2631            #[inline]
2632            #[target_feature(enable = "vector")]
2633            #[unstable(feature = "stdarch_s390x", issue = "135681")]
2634            pub unsafe fn $fun<T, U>(a: T, b: U) -> <T as sealed::$Trait<U>>::Result
2635            where
2636                T: sealed::$Trait<U>,
2637            {
2638                a.$fun(b)
2639            }
2640        )*
2641    }
2642}
2643
2644vec_find_any! {
2645    VectorFindAnyEq vec_find_any_eq
2646    VectorFindAnyNe vec_find_any_ne
2647    VectorFindAnyEqIdx vec_find_any_eq_idx
2648    VectorFindAnyNeIdx vec_find_any_ne_idx
2649    VectorFindAnyEqOrZeroIdx vec_find_any_eq_or_0_idx
2650    VectorFindAnyNeOrZeroIdx vec_find_any_ne_or_0_idx
2651}
2652
2653macro_rules! vec_find_any_cc {
2654    ($($Trait:ident $fun:ident)*) => {
2655        $(
2656            #[inline]
2657            #[target_feature(enable = "vector")]
2658            #[unstable(feature = "stdarch_s390x", issue = "135681")]
2659            pub unsafe fn $fun<T, U>(a: T, b: U, c: *mut i32) -> <T as sealed::$Trait<U>>::Result
2660            where
2661                T: sealed::$Trait<U>,
2662            {
2663                a.$fun(b, c)
2664            }
2665        )*
2666    }
2667}
2668
2669vec_find_any_cc! {
2670    VectorFindAnyEqCC vec_find_any_eq_cc
2671    VectorFindAnyNeCC vec_find_any_ne_cc
2672    VectorFindAnyEqIdxCC vec_find_any_eq_idx_cc
2673    VectorFindAnyNeIdxCC vec_find_any_ne_idx_cc
2674    VectorFindAnyEqOrZeroIdxCC vec_find_any_eq_or_0_idx_cc
2675    VectorFindAnyNeOrZeroIdxCC vec_find_any_ne_or_0_idx_cc
2676}
2677
2678#[cfg(test)]
2679mod tests {
2680    use super::*;
2681
2682    use std::mem::transmute;
2683
2684    use crate::core_arch::simd::*;
2685    use stdarch_test::simd_test;
2686
2687    #[test]
2688    fn reverse_mask() {
2689        assert_eq!(ShuffleMask::<4>::reverse().0, [3, 2, 1, 0]);
2690    }
2691
2692    #[test]
2693    fn mergel_mask() {
2694        assert_eq!(ShuffleMask::<4>::merge_low().0, [2, 6, 3, 7]);
2695    }
2696
2697    #[test]
2698    fn mergeh_mask() {
2699        assert_eq!(ShuffleMask::<4>::merge_high().0, [0, 4, 1, 5]);
2700    }
2701
2702    #[test]
2703    fn test_vec_mask() {
2704        assert_eq!(
2705            genmask::<0x00FF>(),
2706            [
2707                0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
2708            ]
2709        );
2710    }
2711
2712    #[test]
2713    fn test_genmasks() {
2714        assert_eq!(genmasks(u8::BITS, 3, 5), 28);
2715        assert_eq!(genmasks(u8::BITS, 3, 7), 31);
2716
2717        // If a or b is greater than 8, the operation is performed as if the value gets modulo by 8.
2718        assert_eq!(genmasks(u8::BITS, 3 + 8, 7 + 8), 31);
2719        // If a is greater than b, the operation is perform as if b equals 7.
2720        assert_eq!(genmasks(u8::BITS, 5, 4), genmasks(u8::BITS, 5, 7));
2721
2722        assert_eq!(
2723            genmasks(u16::BITS, 4, 12) as u16,
2724            u16::from_be_bytes([15, -8i8 as u8])
2725        );
2726        assert_eq!(
2727            genmasks(u32::BITS, 4, 29) as u32,
2728            u32::from_be_bytes([15, 0xFF, 0xFF, -4i8 as u8])
2729        );
2730    }
2731
2732    macro_rules! test_vec_1 {
2733        { $name: ident, $fn:ident, f32x4, [$($a:expr),+], ~[$($d:expr),+] } => {
2734            #[simd_test(enable = "vector")]
2735            unsafe fn $name() {
2736                let a: vector_float = transmute(f32x4::new($($a),+));
2737
2738                let d: vector_float = transmute(f32x4::new($($d),+));
2739                let r = transmute(vec_cmple(vec_abs(vec_sub($fn(a), d)), vec_splats(f32::EPSILON)));
2740                let e = m32x4::new(true, true, true, true);
2741                assert_eq!(e, r);
2742            }
2743        };
2744        { $name: ident, $fn:ident, $ty: ident, [$($a:expr),+], [$($d:expr),+] } => {
2745            test_vec_1! { $name, $fn, $ty -> $ty, [$($a),+], [$($d),+] }
2746        };
2747        { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($d:expr),+] } => {
2748            #[simd_test(enable = "vector")]
2749            unsafe fn $name() {
2750                let a: s_t_l!($ty) = transmute($ty::new($($a),+));
2751
2752                let d = $ty_out::new($($d),+);
2753                let r : $ty_out = transmute($fn(a));
2754                assert_eq!(d, r);
2755            }
2756        }
2757    }
2758
2759    macro_rules! test_vec_2 {
2760        { $name: ident, $fn:ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
2761            test_vec_2! { $name, $fn, $ty -> $ty, [$($a),+], [$($b),+], [$($d),+] }
2762        };
2763        { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
2764            test_vec_2! { $name, $fn, $ty, $ty -> $ty, [$($a),+], [$($b),+], [$($d),+] }
2765         };
2766        { $name: ident, $fn:ident, $ty1: ident, $ty2: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
2767            #[simd_test(enable = "vector")]
2768            unsafe fn $name() {
2769                let a: s_t_l!($ty1) = transmute($ty1::new($($a),+));
2770                let b: s_t_l!($ty2) = transmute($ty2::new($($b),+));
2771
2772                let d = $ty_out::new($($d),+);
2773                let r : $ty_out = transmute($fn(a, b));
2774                assert_eq!(d, r);
2775            }
2776         };
2777         { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], $d:expr } => {
2778            #[simd_test(enable = "vector")]
2779            unsafe fn $name() {
2780                let a: s_t_l!($ty) = transmute($ty::new($($a),+));
2781                let b: s_t_l!($ty) = transmute($ty::new($($b),+));
2782
2783                let r : $ty_out = transmute($fn(a, b));
2784                assert_eq!($d, r);
2785            }
2786         }
2787   }
2788
2789    #[simd_test(enable = "vector")]
2790    unsafe fn vec_add_i32x4_i32x4() {
2791        let x = i32x4::new(1, 2, 3, 4);
2792        let y = i32x4::new(4, 3, 2, 1);
2793        let x: vector_signed_int = transmute(x);
2794        let y: vector_signed_int = transmute(y);
2795        let z = vec_add(x, y);
2796        assert_eq!(i32x4::splat(5), transmute(z));
2797    }
2798
2799    macro_rules! test_vec_sub {
2800        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
2801            test_vec_2! {$name, vec_sub, $ty, [$($a),+], [$($b),+], [$($d),+] }
2802        }
2803    }
2804
2805    test_vec_sub! { test_vec_sub_f32x4, f32x4,
2806    [-1.0, 0.0, 1.0, 2.0],
2807    [2.0, 1.0, -1.0, -2.0],
2808    [-3.0, -1.0, 2.0, 4.0] }
2809
2810    test_vec_sub! { test_vec_sub_f64x2, f64x2,
2811    [-1.0, 0.0],
2812    [2.0, 1.0],
2813    [-3.0, -1.0] }
2814
2815    test_vec_sub! { test_vec_sub_i64x2, i64x2,
2816    [-1, 0],
2817    [2, 1],
2818    [-3, -1] }
2819
2820    test_vec_sub! { test_vec_sub_u64x2, u64x2,
2821    [0, 1],
2822    [1, 0],
2823    [u64::MAX, 1] }
2824
2825    test_vec_sub! { test_vec_sub_i32x4, i32x4,
2826    [-1, 0, 1, 2],
2827    [2, 1, -1, -2],
2828    [-3, -1, 2, 4] }
2829
2830    test_vec_sub! { test_vec_sub_u32x4, u32x4,
2831    [0, 0, 1, 2],
2832    [2, 1, 0, 0],
2833    [4294967294, 4294967295, 1, 2] }
2834
2835    test_vec_sub! { test_vec_sub_i16x8, i16x8,
2836    [-1, 0, 1, 2, -1, 0, 1, 2],
2837    [2, 1, -1, -2, 2, 1, -1, -2],
2838    [-3, -1, 2, 4, -3, -1, 2, 4] }
2839
2840    test_vec_sub! { test_vec_sub_u16x8, u16x8,
2841    [0, 0, 1, 2, 0, 0, 1, 2],
2842    [2, 1, 0, 0, 2, 1, 0, 0],
2843    [65534, 65535, 1, 2, 65534, 65535, 1, 2] }
2844
2845    test_vec_sub! { test_vec_sub_i8x16, i8x16,
2846    [-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
2847    [2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
2848    [-3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4] }
2849
2850    test_vec_sub! { test_vec_sub_u8x16, u8x16,
2851    [0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2],
2852    [2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
2853    [254, 255, 1, 2, 254, 255, 1, 2, 254, 255, 1, 2, 254, 255, 1, 2] }
2854
2855    macro_rules! test_vec_mul {
2856        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
2857            test_vec_2! {$name, vec_mul, $ty, [$($a),+], [$($b),+], [$($d),+] }
2858        }
2859    }
2860
2861    test_vec_mul! { test_vec_mul_f32x4, f32x4,
2862    [-1.0, 0.0, 1.0, 2.0],
2863    [2.0, 1.0, -1.0, -2.0],
2864    [-2.0, 0.0, -1.0, -4.0] }
2865
2866    test_vec_mul! { test_vec_mul_f64x2, f64x2,
2867    [-1.0, 0.0],
2868    [2.0, 1.0],
2869    [-2.0, 0.0] }
2870
2871    test_vec_mul! { test_vec_mul_i64x2, i64x2,
2872    [i64::MAX, -4],
2873    [2, 3],
2874    [i64::MAX.wrapping_mul(2), -12] }
2875
2876    test_vec_mul! { test_vec_mul_u64x2, u64x2,
2877    [u64::MAX, 4],
2878    [2, 3],
2879    [u64::MAX.wrapping_mul(2), 12] }
2880
2881    test_vec_mul! { test_vec_mul_i32x4, i32x4,
2882    [-1, 0, 1, 2],
2883    [2, 1, -1, -2],
2884    [-2, 0, -1, -4] }
2885
2886    test_vec_mul! { test_vec_mul_u32x4, u32x4,
2887    [0, u32::MAX - 1, 1, 2],
2888    [5, 6, 7, 8],
2889    [0, 4294967284, 7, 16] }
2890
2891    test_vec_mul! { test_vec_mul_i16x8, i16x8,
2892    [-1, 0, 1, 2, -1, 0, 1, 2],
2893    [2, 1, -1, -2, 2, 1, -1, -2],
2894    [-2, 0, -1, -4, -2, 0, -1, -4] }
2895
2896    test_vec_mul! { test_vec_mul_u16x8, u16x8,
2897    [0, u16::MAX - 1, 1, 2, 3, 4, 5, 6],
2898    [5, 6, 7, 8, 9, 8, 7, 6],
2899    [0, 65524, 7, 16, 27, 32, 35, 36] }
2900
2901    test_vec_mul! { test_vec_mul_i8x16, i8x16,
2902    [-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
2903    [2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
2904    [-2, 0, -1, -4, -2, 0, -1, -4, -2, 0, -1, -4, -2, 0, -1, -4] }
2905
2906    test_vec_mul! { test_vec_mul_u8x16, u8x16,
2907    [0, u8::MAX - 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4],
2908    [5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 0, u8::MAX, 1, 2, 3, 4],
2909    [0, 244, 7, 16, 27, 32, 35, 36, 35, 32, 0, 248, 7, 12, 15, 16] }
2910
2911    macro_rules! test_vec_abs {
2912        { $name: ident, $ty: ident, $a: expr, $d: expr } => {
2913            #[simd_test(enable = "vector")]
2914            unsafe fn $name() {
2915                let a: s_t_l!($ty) = vec_splats($a);
2916                let a: s_t_l!($ty) = vec_abs(a);
2917                let d = $ty::splat($d);
2918                assert_eq!(d, transmute(a));
2919            }
2920        }
2921    }
2922
2923    test_vec_abs! { test_vec_abs_i8, i8x16, -42i8, 42i8 }
2924    test_vec_abs! { test_vec_abs_i16, i16x8, -42i16, 42i16 }
2925    test_vec_abs! { test_vec_abs_i32, i32x4, -42i32, 42i32 }
2926    test_vec_abs! { test_vec_abs_i64, i64x2, -42i64, 42i64 }
2927    test_vec_abs! { test_vec_abs_f32, f32x4, -42f32, 42f32 }
2928    test_vec_abs! { test_vec_abs_f64, f64x2, -42f64, 42f64 }
2929
2930    test_vec_1! { test_vec_nabs, vec_nabs, f32x4,
2931    [core::f32::consts::PI, 1.0, 0.0, -1.0],
2932    [-core::f32::consts::PI, -1.0, 0.0, -1.0] }
2933
2934    test_vec_2! { test_vec_andc, vec_andc, i32x4,
2935    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
2936    [0b00110011, 0b11110011, 0b00001100, 0b10000000],
2937    [0b11001100, 0b00001100, 0b11000000, 0b01001100] }
2938
2939    test_vec_2! { test_vec_and, vec_and, i32x4,
2940    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
2941    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
2942    [0b00000000, 0b11000000, 0b00001100, 0b00000000] }
2943
2944    test_vec_2! { test_vec_nand, vec_nand, i32x4,
2945    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
2946    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
2947    [!0b00000000, !0b11000000, !0b00001100, !0b00000000] }
2948
2949    test_vec_2! { test_vec_orc, vec_orc, u32x4,
2950    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
2951    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
2952    [0b11001100 | !0b00110011, 0b11001100 | !0b11110011, 0b11001100 | !0b00001100, 0b11001100 | !0b00000000] }
2953
2954    test_vec_2! { test_vec_or, vec_or, i32x4,
2955    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
2956    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
2957    [0b11111111, 0b11111111, 0b11001100, 0b11001100] }
2958
2959    test_vec_2! { test_vec_nor, vec_nor, i32x4,
2960    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
2961    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
2962    [!0b11111111, !0b11111111, !0b11001100, !0b11001100] }
2963
2964    test_vec_2! { test_vec_xor, vec_xor, i32x4,
2965    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
2966    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
2967    [0b11111111, 0b00111111, 0b11000000, 0b11001100] }
2968
2969    test_vec_2! { test_vec_eqv, vec_eqv, i32x4,
2970    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
2971    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
2972    [!0b11111111, !0b00111111, !0b11000000, !0b11001100] }
2973
2974    test_vec_1! { test_vec_floor_f32, vec_floor, f32x4,
2975        [1.1, 1.9, -0.5, -0.9],
2976        [1.0, 1.0, -1.0, -1.0]
2977    }
2978
2979    test_vec_1! { test_vec_floor_f64_1, vec_floor, f64x2,
2980        [1.1, 1.9],
2981        [1.0, 1.0]
2982    }
2983    test_vec_1! { test_vec_floor_f64_2, vec_floor, f64x2,
2984        [-0.5, -0.9],
2985        [-1.0, -1.0]
2986    }
2987
2988    test_vec_1! { test_vec_ceil_f32, vec_ceil, f32x4,
2989        [0.1, 0.5, 0.6, 0.9],
2990        [1.0, 1.0, 1.0, 1.0]
2991    }
2992    test_vec_1! { test_vec_ceil_f64_1, vec_ceil, f64x2,
2993        [0.1, 0.5],
2994        [1.0, 1.0]
2995    }
2996    test_vec_1! { test_vec_ceil_f64_2, vec_ceil, f64x2,
2997        [0.6, 0.9],
2998        [1.0, 1.0]
2999    }
3000
3001    test_vec_1! { test_vec_round_f32, vec_round, f32x4,
3002        [0.1, 0.5, 0.6, 0.9],
3003        [0.0, 0.0, 1.0, 1.0]
3004    }
3005
3006    test_vec_1! { test_vec_round_f32_even_odd, vec_round, f32x4,
3007        [0.5, 1.5, 2.5, 3.5],
3008        [0.0, 2.0, 2.0, 4.0]
3009    }
3010
3011    test_vec_1! { test_vec_round_f64_1, vec_round, f64x2,
3012        [0.1, 0.5],
3013        [0.0, 0.0]
3014    }
3015    test_vec_1! { test_vec_round_f64_2, vec_round, f64x2,
3016        [0.6, 0.9],
3017        [1.0, 1.0]
3018    }
3019
3020    test_vec_1! { test_vec_roundc_f32, vec_roundc, f32x4,
3021        [0.1, 0.5, 0.6, 0.9],
3022        [0.0, 0.0, 1.0, 1.0]
3023    }
3024
3025    test_vec_1! { test_vec_roundc_f32_even_odd, vec_roundc, f32x4,
3026        [0.5, 1.5, 2.5, 3.5],
3027        [0.0, 2.0, 2.0, 4.0]
3028    }
3029
3030    test_vec_1! { test_vec_roundc_f64_1, vec_roundc, f64x2,
3031        [0.1, 0.5],
3032        [0.0, 0.0]
3033    }
3034    test_vec_1! { test_vec_roundc_f64_2, vec_roundc, f64x2,
3035        [0.6, 0.9],
3036        [1.0, 1.0]
3037    }
3038
3039    test_vec_1! { test_vec_rint_f32, vec_rint, f32x4,
3040        [0.1, 0.5, 0.6, 0.9],
3041        [0.0, 0.0, 1.0, 1.0]
3042    }
3043
3044    test_vec_1! { test_vec_rint_f32_even_odd, vec_rint, f32x4,
3045        [0.5, 1.5, 2.5, 3.5],
3046        [0.0, 2.0, 2.0, 4.0]
3047    }
3048
3049    test_vec_1! { test_vec_rint_f64_1, vec_rint, f64x2,
3050        [0.1, 0.5],
3051        [0.0, 0.0]
3052    }
3053    test_vec_1! { test_vec_rint_f64_2, vec_rint, f64x2,
3054        [0.6, 0.9],
3055        [1.0, 1.0]
3056    }
3057
3058    test_vec_2! { test_vec_sll, vec_sll, i32x4, u8x16 -> i32x4,
3059    [1, 1, 1, 1],
3060    [0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 8],
3061    [1 << 2, 1 << 3, 1 << 4, 1] }
3062
3063    test_vec_2! { test_vec_srl, vec_srl, i32x4, u8x16 -> i32x4,
3064    [0b1000, 0b1000, 0b1000, 0b1000],
3065    [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16],
3066    [4, 2, 1, 8] }
3067
3068    test_vec_2! { test_vec_sral_pos, vec_sral, u32x4, u8x16 -> i32x4,
3069    [0b1000, 0b1000, 0b1000, 0b1000],
3070    [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16],
3071    [4, 2, 1, 8] }
3072
3073    test_vec_2! { test_vec_sral_neg, vec_sral, i32x4, u8x16 -> i32x4,
3074    [-8, -8, -8, -8],
3075    [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16],
3076    [-4, -2, -1, -8] }
3077
3078    test_vec_2! { test_vec_rl, vec_rl, u32x4,
3079    [0x12345678, 0x9ABCDEF0, 0x0F0F0F0F, 0x12345678],
3080    [4, 8, 12, 68],
3081    [0x23456781, 0xBCDEF09A, 0xF0F0F0F0, 0x23456781] }
3082
3083    test_vec_1! { test_vec_reve_f32, vec_reve, f32x4,
3084        [0.1, 0.5, 0.6, 0.9],
3085        [0.9, 0.6, 0.5, 0.1]
3086    }
3087
3088    test_vec_1! { test_vec_revb_u32, vec_revb, u32x4,
3089        [0xAABBCCDD, 0xEEFF0011, 0x22334455, 0x66778899],
3090        [0xDDCCBBAA, 0x1100FFEE, 0x55443322, 0x99887766]
3091    }
3092
3093    test_vec_2! { test_vec_mergeh_u32, vec_mergeh, u32x4,
3094        [0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD],
3095        [0x00000000, 0x11111111, 0x22222222, 0x33333333],
3096        [0xAAAAAAAA, 0x00000000, 0xBBBBBBBB, 0x11111111]
3097    }
3098
3099    test_vec_2! { test_vec_mergel_u32, vec_mergel, u32x4,
3100        [0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD],
3101        [0x00000000, 0x11111111, 0x22222222, 0x33333333],
3102        [0xCCCCCCCC, 0x22222222, 0xDDDDDDDD, 0x33333333]
3103    }
3104
3105    macro_rules! test_vec_perm {
3106        {$name:ident,
3107         $shorttype:ident, $longtype:ident,
3108         [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => {
3109            #[simd_test(enable = "vector")]
3110            unsafe fn $name() {
3111                let a: $longtype = transmute($shorttype::new($($a),+));
3112                let b: $longtype = transmute($shorttype::new($($b),+));
3113                let c: vector_unsigned_char = transmute(u8x16::new($($c),+));
3114                let d = $shorttype::new($($d),+);
3115
3116                let r: $shorttype = transmute(vec_perm(a, b, c));
3117                assert_eq!(d, r);
3118            }
3119        }
3120    }
3121
3122    test_vec_perm! {test_vec_perm_u8x16,
3123    u8x16, vector_unsigned_char,
3124    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
3125    [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115],
3126    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
3127     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
3128    [0, 1, 100, 101, 2, 3, 102, 103, 4, 5, 104, 105, 6, 7, 106, 107]}
3129    test_vec_perm! {test_vec_perm_i8x16,
3130    i8x16, vector_signed_char,
3131    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
3132    [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115],
3133    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
3134     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
3135    [0, 1, 100, 101, 2, 3, 102, 103, 4, 5, 104, 105, 6, 7, 106, 107]}
3136
3137    test_vec_perm! {test_vec_perm_m8x16,
3138    m8x16, vector_bool_char,
3139    [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false],
3140    [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true],
3141    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
3142     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
3143    [false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true]}
3144    test_vec_perm! {test_vec_perm_u16x8,
3145    u16x8, vector_unsigned_short,
3146    [0, 1, 2, 3, 4, 5, 6, 7],
3147    [10, 11, 12, 13, 14, 15, 16, 17],
3148    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
3149     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
3150    [0, 10, 1, 11, 2, 12, 3, 13]}
3151    test_vec_perm! {test_vec_perm_i16x8,
3152    i16x8, vector_signed_short,
3153    [0, 1, 2, 3, 4, 5, 6, 7],
3154    [10, 11, 12, 13, 14, 15, 16, 17],
3155    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
3156     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
3157    [0, 10, 1, 11, 2, 12, 3, 13]}
3158    test_vec_perm! {test_vec_perm_m16x8,
3159    m16x8, vector_bool_short,
3160    [false, false, false, false, false, false, false, false],
3161    [true, true, true, true, true, true, true, true],
3162    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
3163     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
3164    [false, true, false, true, false, true, false, true]}
3165
3166    test_vec_perm! {test_vec_perm_u32x4,
3167    u32x4, vector_unsigned_int,
3168    [0, 1, 2, 3],
3169    [10, 11, 12, 13],
3170    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
3171     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
3172    [0, 10, 1, 11]}
3173    test_vec_perm! {test_vec_perm_i32x4,
3174    i32x4, vector_signed_int,
3175    [0, 1, 2, 3],
3176    [10, 11, 12, 13],
3177    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
3178     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
3179    [0, 10, 1, 11]}
3180    test_vec_perm! {test_vec_perm_m32x4,
3181    m32x4, vector_bool_int,
3182    [false, false, false, false],
3183    [true, true, true, true],
3184    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
3185     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
3186    [false, true, false, true]}
3187    test_vec_perm! {test_vec_perm_f32x4,
3188    f32x4, vector_float,
3189    [0.0, 1.0, 2.0, 3.0],
3190    [1.0, 1.1, 1.2, 1.3],
3191    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
3192     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
3193    [0.0, 1.0, 1.0, 1.1]}
3194
3195    test_vec_1! { test_vec_sqrt, vec_sqrt, f32x4,
3196    [core::f32::consts::PI, 1.0, 25.0, 2.0],
3197    [core::f32::consts::PI.sqrt(), 1.0, 5.0, core::f32::consts::SQRT_2] }
3198
3199    test_vec_2! { test_vec_find_any_eq, vec_find_any_eq, i32x4, i32x4 -> u32x4,
3200        [1, -2, 3, -4],
3201        [-5, 3, -7, 8],
3202        [0, 0, 0xFFFFFFFF, 0]
3203    }
3204
3205    test_vec_2! { test_vec_find_any_ne, vec_find_any_ne, i32x4, i32x4 -> u32x4,
3206        [1, -2, 3, -4],
3207        [-5, 3, -7, 8],
3208        [0xFFFFFFFF, 0xFFFFFFFF, 0, 0xFFFFFFFF]
3209    }
3210
3211    test_vec_2! { test_vec_find_any_eq_idx_1, vec_find_any_eq_idx, i32x4, i32x4 -> u32x4,
3212        [1, 2, 3, 4],
3213        [5, 3, 7, 8],
3214        [0, 8, 0, 0]
3215    }
3216    test_vec_2! { test_vec_find_any_eq_idx_2, vec_find_any_eq_idx, i32x4, i32x4 -> u32x4,
3217        [1, 2, 3, 4],
3218        [5, 6, 7, 8],
3219        [0, 16, 0, 0]
3220    }
3221
3222    test_vec_2! { test_vec_find_any_ne_idx_1, vec_find_any_ne_idx, i32x4, i32x4 -> u32x4,
3223        [1, 2, 3, 4],
3224        [1, 5, 3, 4],
3225        [0, 4, 0, 0]
3226    }
3227    test_vec_2! { test_vec_find_any_ne_idx_2, vec_find_any_ne_idx, i32x4, i32x4 -> u32x4,
3228        [1, 2, 3, 4],
3229        [1, 2, 3, 4],
3230        [0, 16, 0, 0]
3231    }
3232
3233    test_vec_2! { test_vec_find_any_eq_or_0_idx_1, vec_find_any_eq_or_0_idx, i32x4, i32x4 -> u32x4,
3234        [1, 2, 0, 4],
3235        [5, 6, 7, 8],
3236        [0, 8, 0, 0]
3237    }
3238    test_vec_2! { test_vec_find_any_ne_or_0_idx_1, vec_find_any_ne_or_0_idx, i32x4, i32x4 -> u32x4,
3239        [1, 2, 0, 4],
3240        [1, 2, 3, 4],
3241        [0, 8, 0, 0]
3242    }
3243
3244    #[simd_test(enable = "vector")]
3245    fn test_vec_find_any_eq_cc() {
3246        let mut c = 0i32;
3247
3248        let a = vector_unsigned_int([1, 2, 3, 4]);
3249        let b = vector_unsigned_int([5, 3, 7, 8]);
3250
3251        let d = unsafe { vec_find_any_eq_cc(a, b, &mut c) };
3252        assert_eq!(c, 1);
3253        assert_eq!(d.as_array(), &[0, 0, -1, 0]);
3254
3255        let a = vector_unsigned_int([1, 2, 3, 4]);
3256        let b = vector_unsigned_int([5, 6, 7, 8]);
3257        let d = unsafe { vec_find_any_eq_cc(a, b, &mut c) };
3258        assert_eq!(c, 3);
3259        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
3260    }
3261
3262    #[simd_test(enable = "vector")]
3263    fn test_vec_find_any_ne_cc() {
3264        let mut c = 0i32;
3265
3266        let a = vector_unsigned_int([1, 2, 3, 4]);
3267        let b = vector_unsigned_int([5, 3, 7, 8]);
3268
3269        let d = unsafe { vec_find_any_ne_cc(a, b, &mut c) };
3270        assert_eq!(c, 1);
3271        assert_eq!(d.as_array(), &[-1, -1, 0, -1]);
3272
3273        let a = vector_unsigned_int([1, 2, 3, 4]);
3274        let b = vector_unsigned_int([1, 2, 3, 4]);
3275        let d = unsafe { vec_find_any_ne_cc(a, b, &mut c) };
3276        assert_eq!(c, 3);
3277        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
3278    }
3279
3280    #[simd_test(enable = "vector")]
3281    fn test_vec_find_any_eq_idx_cc() {
3282        let mut c = 0i32;
3283
3284        let a = vector_unsigned_int([1, 2, 3, 4]);
3285        let b = vector_unsigned_int([5, 3, 7, 8]);
3286
3287        let d = unsafe { vec_find_any_eq_idx_cc(a, b, &mut c) };
3288        assert_eq!(c, 1);
3289        assert_eq!(d.as_array(), &[0, 8, 0, 0]);
3290
3291        let a = vector_unsigned_int([1, 2, 3, 4]);
3292        let b = vector_unsigned_int([5, 6, 7, 8]);
3293        let d = unsafe { vec_find_any_eq_idx_cc(a, b, &mut c) };
3294        assert_eq!(c, 3);
3295        assert_eq!(d.as_array(), &[0, 16, 0, 0]);
3296    }
3297
3298    #[simd_test(enable = "vector")]
3299    fn test_vec_find_any_ne_idx_cc() {
3300        let mut c = 0i32;
3301
3302        let a = vector_unsigned_int([5, 2, 3, 4]);
3303        let b = vector_unsigned_int([5, 3, 7, 8]);
3304
3305        let d = unsafe { vec_find_any_ne_idx_cc(a, b, &mut c) };
3306        assert_eq!(c, 1);
3307        assert_eq!(d.as_array(), &[0, 4, 0, 0]);
3308
3309        let a = vector_unsigned_int([1, 2, 3, 4]);
3310        let b = vector_unsigned_int([1, 2, 3, 4]);
3311        let d = unsafe { vec_find_any_ne_idx_cc(a, b, &mut c) };
3312        assert_eq!(c, 3);
3313        assert_eq!(d.as_array(), &[0, 16, 0, 0]);
3314    }
3315
3316    #[simd_test(enable = "vector")]
3317    fn test_vec_find_any_eq_or_0_idx_cc() {
3318        let mut c = 0i32;
3319
3320        // 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
3321        let a = vector_unsigned_int([0, 1, 2, 3]);
3322        let b = vector_unsigned_int([4, 5, 6, 7]);
3323        let d = unsafe { vec_find_any_eq_or_0_idx_cc(a, b, &mut c) };
3324        assert_eq!(c, 0);
3325        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
3326
3327        // 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
3328        let a = vector_unsigned_int([1, 2, 3, 4]);
3329        let b = vector_unsigned_int([5, 2, 3, 4]);
3330        let d = unsafe { vec_find_any_eq_or_0_idx_cc(a, b, &mut c) };
3331        assert_eq!(c, 1);
3332        assert_eq!(d.as_array(), &[0, 4, 0, 0]);
3333
3334        // 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
3335        let a = vector_unsigned_int([1, 2, 3, 0]);
3336        let b = vector_unsigned_int([1, 2, 3, 4]);
3337        let d = unsafe { vec_find_any_eq_or_0_idx_cc(a, b, &mut c) };
3338        assert_eq!(c, 2);
3339        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
3340
3341        // 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.
3342        let a = vector_unsigned_int([1, 2, 3, 4]);
3343        let b = vector_unsigned_int([5, 6, 7, 8]);
3344        let d = unsafe { vec_find_any_eq_or_0_idx_cc(a, b, &mut c) };
3345        assert_eq!(c, 3);
3346        assert_eq!(d.as_array(), &[0, 16, 0, 0]);
3347    }
3348
3349    #[simd_test(enable = "vector")]
3350    fn test_vec_find_any_ne_or_0_idx_cc() {
3351        let mut c = 0i32;
3352
3353        // 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.
3354        let a = vector_unsigned_int([0, 1, 2, 3]);
3355        let b = vector_unsigned_int([4, 1, 2, 3]);
3356        let d = unsafe { vec_find_any_ne_or_0_idx_cc(a, b, &mut c) };
3357        assert_eq!(c, 0);
3358        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
3359
3360        // 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.
3361        let a = vector_unsigned_int([4, 2, 3, 4]);
3362        let b = vector_unsigned_int([4, 5, 6, 7]);
3363        let d = unsafe { vec_find_any_ne_or_0_idx_cc(a, b, &mut c) };
3364        assert_eq!(c, 1);
3365        assert_eq!(d.as_array(), &[0, 4, 0, 0]);
3366
3367        // 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.
3368        let a = vector_unsigned_int([1, 0, 1, 1]);
3369        let b = vector_unsigned_int([4, 5, 6, 7]);
3370        let d = unsafe { vec_find_any_ne_or_0_idx_cc(a, b, &mut c) };
3371        assert_eq!(c, 2);
3372        assert_eq!(d.as_array(), &[0, 0, 0, 0]);
3373
3374        // 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.
3375        let a = vector_unsigned_int([4, 4, 4, 4]);
3376        let b = vector_unsigned_int([4, 5, 6, 7]);
3377        let d = unsafe { vec_find_any_ne_or_0_idx_cc(a, b, &mut c) };
3378        assert_eq!(c, 3);
3379        assert_eq!(d.as_array(), &[0, 16, 0, 0]);
3380    }
3381}