core/stdarch/crates/core_arch/src/powerpc/
altivec.rs

1//! PowerPC AltiVec intrinsics.
2//!
3//! AltiVec is a brandname trademarked by Freescale (previously Motorola) for
4//! the standard `Category:Vector` part of the Power ISA v.2.03 specification.
5//! This Category is also known as VMX (used by IBM), and "Velocity Engine" (a
6//! brand name previously used by Apple).
7//!
8//! The references are: [POWER ISA v2.07B (for POWER8 & POWER8 with NVIDIA
9//! NVlink)] and [POWER ISA v3.0B (for POWER9)].
10//!
11//! [POWER ISA v2.07B (for POWER8 & POWER8 with NVIDIA NVlink)]: https://ibm.box.com/s/jd5w15gz301s5b5dt375mshpq9c3lh4u
12//! [POWER ISA v3.0B (for POWER9)]: https://ibm.box.com/s/1hzcwkwf8rbju5h9iyf44wm94amnlcrv
13
14#![allow(non_camel_case_types)]
15
16use crate::{core_arch::simd::*, intrinsics::simd::*, mem, mem::transmute};
17
18#[cfg(test)]
19use stdarch_test::assert_instr;
20
21use super::macros::*;
22
23types! {
24    #![unstable(feature = "stdarch_powerpc", issue = "111145")]
25
26    /// PowerPC-specific 128-bit wide vector of sixteen packed `i8`
27    pub struct vector_signed_char(16 x i8);
28    /// PowerPC-specific 128-bit wide vector of sixteen packed `u8`
29    pub struct vector_unsigned_char(16 x u8);
30
31    /// PowerPC-specific 128-bit wide vector mask of sixteen packed elements
32    pub struct vector_bool_char(16 x i8);
33    /// PowerPC-specific 128-bit wide vector of eight packed `i16`
34    pub struct vector_signed_short(8 x i16);
35    /// PowerPC-specific 128-bit wide vector of eight packed `u16`
36    pub struct vector_unsigned_short(8 x u16);
37    /// PowerPC-specific 128-bit wide vector mask of eight packed elements
38    pub struct vector_bool_short(8 x i16);
39    // pub struct vector_pixel(???);
40    /// PowerPC-specific 128-bit wide vector of four packed `i32`
41    pub struct vector_signed_int(4 x i32);
42    /// PowerPC-specific 128-bit wide vector of four packed `u32`
43    pub struct vector_unsigned_int(4 x u32);
44    /// PowerPC-specific 128-bit wide vector mask of four packed elements
45    pub struct vector_bool_int(4 x i32);
46    /// PowerPC-specific 128-bit wide vector of four packed `f32`
47    pub struct vector_float(4 x f32);
48}
49
50#[allow(improper_ctypes)]
51unsafe extern "C" {
52    #[link_name = "llvm.ppc.altivec.lvx"]
53    fn lvx(p: *const i8) -> vector_unsigned_int;
54
55    #[link_name = "llvm.ppc.altivec.lvebx"]
56    fn lvebx(p: *const i8) -> vector_signed_char;
57    #[link_name = "llvm.ppc.altivec.lvehx"]
58    fn lvehx(p: *const i8) -> vector_signed_short;
59    #[link_name = "llvm.ppc.altivec.lvewx"]
60    fn lvewx(p: *const i8) -> vector_signed_int;
61
62    #[link_name = "llvm.ppc.altivec.lvxl"]
63    fn lvxl(p: *const i8) -> vector_unsigned_int;
64
65    #[link_name = "llvm.ppc.altivec.stvx"]
66    fn stvx(a: vector_signed_int, p: *const i8);
67
68    #[link_name = "llvm.ppc.altivec.stvebx"]
69    fn stvebx(a: vector_signed_char, p: *const i8);
70    #[link_name = "llvm.ppc.altivec.stvehx"]
71    fn stvehx(a: vector_signed_short, p: *const i8);
72    #[link_name = "llvm.ppc.altivec.stvewx"]
73    fn stvewx(a: vector_signed_int, p: *const i8);
74
75    #[link_name = "llvm.ppc.altivec.stvxl"]
76    fn stvxl(a: vector_signed_int, p: *const i8);
77
78    #[link_name = "llvm.ppc.altivec.vperm"]
79    fn vperm(
80        a: vector_signed_int,
81        b: vector_signed_int,
82        c: vector_unsigned_char,
83    ) -> vector_signed_int;
84    #[link_name = "llvm.ppc.altivec.vmhaddshs"]
85    fn vmhaddshs(
86        a: vector_signed_short,
87        b: vector_signed_short,
88        c: vector_signed_short,
89    ) -> vector_signed_short;
90    #[link_name = "llvm.ppc.altivec.vmhraddshs"]
91    fn vmhraddshs(
92        a: vector_signed_short,
93        b: vector_signed_short,
94        c: vector_signed_short,
95    ) -> vector_signed_short;
96    #[link_name = "llvm.ppc.altivec.vmsumuhs"]
97    fn vmsumuhs(
98        a: vector_unsigned_short,
99        b: vector_unsigned_short,
100        c: vector_unsigned_int,
101    ) -> vector_unsigned_int;
102    #[link_name = "llvm.ppc.altivec.vmsumshs"]
103    fn vmsumshs(
104        a: vector_signed_short,
105        b: vector_signed_short,
106        c: vector_signed_int,
107    ) -> vector_signed_int;
108    #[link_name = "llvm.ppc.altivec.vmsumubm"]
109    fn vmsumubm(
110        a: vector_unsigned_char,
111        b: vector_unsigned_char,
112        c: vector_unsigned_int,
113    ) -> vector_unsigned_int;
114    #[link_name = "llvm.ppc.altivec.vmsummbm"]
115    fn vmsummbm(
116        a: vector_signed_char,
117        b: vector_unsigned_char,
118        c: vector_signed_int,
119    ) -> vector_signed_int;
120    #[link_name = "llvm.ppc.altivec.vmsumuhm"]
121    fn vmsumuhm(
122        a: vector_unsigned_short,
123        b: vector_unsigned_short,
124        c: vector_unsigned_int,
125    ) -> vector_unsigned_int;
126    #[link_name = "llvm.ppc.altivec.vmsumshm"]
127    fn vmsumshm(
128        a: vector_signed_short,
129        b: vector_signed_short,
130        c: vector_signed_int,
131    ) -> vector_signed_int;
132    #[link_name = "llvm.ppc.altivec.vnmsubfp"]
133    fn vnmsubfp(a: vector_float, b: vector_float, c: vector_float) -> vector_float;
134    #[link_name = "llvm.ppc.altivec.vsum2sws"]
135    fn vsum2sws(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
136    #[link_name = "llvm.ppc.altivec.vsum4ubs"]
137    fn vsum4ubs(a: vector_unsigned_char, b: vector_unsigned_int) -> vector_unsigned_int;
138    #[link_name = "llvm.ppc.altivec.vsum4sbs"]
139    fn vsum4sbs(a: vector_signed_char, b: vector_signed_int) -> vector_signed_int;
140    #[link_name = "llvm.ppc.altivec.vsum4shs"]
141    fn vsum4shs(a: vector_signed_short, b: vector_signed_int) -> vector_signed_int;
142    #[link_name = "llvm.ppc.altivec.vmuleub"]
143    fn vmuleub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_short;
144    #[link_name = "llvm.ppc.altivec.vmulesb"]
145    fn vmulesb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_short;
146    #[link_name = "llvm.ppc.altivec.vmuleuh"]
147    fn vmuleuh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int;
148    #[link_name = "llvm.ppc.altivec.vmulesh"]
149    fn vmulesh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_int;
150    #[link_name = "llvm.ppc.altivec.vmuloub"]
151    fn vmuloub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_short;
152    #[link_name = "llvm.ppc.altivec.vmulosb"]
153    fn vmulosb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_short;
154    #[link_name = "llvm.ppc.altivec.vmulouh"]
155    fn vmulouh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int;
156    #[link_name = "llvm.ppc.altivec.vmulosh"]
157    fn vmulosh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_int;
158
159    #[link_name = "llvm.smax.v16i8"]
160    fn vmaxsb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
161    #[link_name = "llvm.smax.v8i16"]
162    fn vmaxsh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short;
163    #[link_name = "llvm.smax.v4i32"]
164    fn vmaxsw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
165
166    #[link_name = "llvm.umax.v16i8"]
167    fn vmaxub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
168    #[link_name = "llvm.umax.v8i16"]
169    fn vmaxuh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
170    #[link_name = "llvm.umax.v4i32"]
171    fn vmaxuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
172
173    #[link_name = "llvm.smin.v16i8"]
174    fn vminsb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
175    #[link_name = "llvm.smin.v8i16"]
176    fn vminsh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short;
177    #[link_name = "llvm.smin.v4i32"]
178    fn vminsw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
179
180    #[link_name = "llvm.umin.v16i8"]
181    fn vminub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
182    #[link_name = "llvm.umin.v8i16"]
183    fn vminuh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
184    #[link_name = "llvm.umin.v4i32"]
185    fn vminuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
186
187    #[link_name = "llvm.ppc.altivec.vsubsbs"]
188    fn vsubsbs(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
189    #[link_name = "llvm.ppc.altivec.vsubshs"]
190    fn vsubshs(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short;
191    #[link_name = "llvm.ppc.altivec.vsubsws"]
192    fn vsubsws(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
193
194    #[link_name = "llvm.ppc.altivec.vsububs"]
195    fn vsububs(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
196    #[link_name = "llvm.ppc.altivec.vsubuhs"]
197    fn vsubuhs(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
198    #[link_name = "llvm.ppc.altivec.vsubuws"]
199    fn vsubuws(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
200
201    #[link_name = "llvm.ppc.altivec.vsubcuw"]
202    fn vsubcuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
203
204    #[link_name = "llvm.ppc.altivec.vaddcuw"]
205    fn vaddcuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
206
207    #[link_name = "llvm.ppc.altivec.vaddsbs"]
208    fn vaddsbs(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
209    #[link_name = "llvm.ppc.altivec.vaddshs"]
210    fn vaddshs(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short;
211    #[link_name = "llvm.ppc.altivec.vaddsws"]
212    fn vaddsws(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
213
214    #[link_name = "llvm.ppc.altivec.vaddubs"]
215    fn vaddubs(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
216    #[link_name = "llvm.ppc.altivec.vadduhs"]
217    fn vadduhs(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
218    #[link_name = "llvm.ppc.altivec.vadduws"]
219    fn vadduws(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
220
221    #[link_name = "llvm.ppc.altivec.vavgsb"]
222    fn vavgsb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
223    #[link_name = "llvm.ppc.altivec.vavgsh"]
224    fn vavgsh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short;
225    #[link_name = "llvm.ppc.altivec.vavgsw"]
226    fn vavgsw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
227
228    #[link_name = "llvm.ppc.altivec.vavgub"]
229    fn vavgub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
230    #[link_name = "llvm.ppc.altivec.vavguh"]
231    fn vavguh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short;
232    #[link_name = "llvm.ppc.altivec.vavguw"]
233    fn vavguw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
234
235    #[link_name = "llvm.ppc.altivec.vcmpbfp"]
236    fn vcmpbfp(a: vector_float, b: vector_float) -> vector_signed_int;
237
238    #[link_name = "llvm.ppc.altivec.vcmpequb"]
239    fn vcmpequb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_bool_char;
240    #[link_name = "llvm.ppc.altivec.vcmpequh"]
241    fn vcmpequh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_bool_short;
242    #[link_name = "llvm.ppc.altivec.vcmpequw"]
243    fn vcmpequw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_bool_int;
244
245    #[link_name = "llvm.ppc.altivec.vcmpneb"]
246    fn vcmpneb(a: vector_signed_char, b: vector_signed_char) -> vector_bool_char;
247    #[link_name = "llvm.ppc.altivec.vcmpneh"]
248    fn vcmpneh(a: vector_signed_short, b: vector_signed_short) -> vector_bool_short;
249    #[link_name = "llvm.ppc.altivec.vcmpnew"]
250    fn vcmpnew(a: vector_signed_int, b: vector_signed_int) -> vector_bool_int;
251
252    #[link_name = "llvm.ppc.altivec.vcmpgefp"]
253    fn vcmpgefp(a: vector_float, b: vector_float) -> vector_bool_int;
254
255    #[link_name = "llvm.ppc.altivec.vcmpgtub"]
256    fn vcmpgtub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_bool_char;
257    #[link_name = "llvm.ppc.altivec.vcmpgtuh"]
258    fn vcmpgtuh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_bool_short;
259    #[link_name = "llvm.ppc.altivec.vcmpgtuw"]
260    fn vcmpgtuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_bool_int;
261
262    #[link_name = "llvm.ppc.altivec.vcmpgtsb"]
263    fn vcmpgtsb(a: vector_signed_char, b: vector_signed_char) -> vector_bool_char;
264    #[link_name = "llvm.ppc.altivec.vcmpgtsh"]
265    fn vcmpgtsh(a: vector_signed_short, b: vector_signed_short) -> vector_bool_short;
266    #[link_name = "llvm.ppc.altivec.vcmpgtsw"]
267    fn vcmpgtsw(a: vector_signed_int, b: vector_signed_int) -> vector_bool_int;
268
269    #[link_name = "llvm.ppc.altivec.vexptefp"]
270    fn vexptefp(a: vector_float) -> vector_float;
271
272    #[link_name = "llvm.ppc.altivec.vcmpequb.p"]
273    fn vcmpequb_p(cr: i32, a: vector_unsigned_char, b: vector_unsigned_char) -> i32;
274    #[link_name = "llvm.ppc.altivec.vcmpequh.p"]
275    fn vcmpequh_p(cr: i32, a: vector_unsigned_short, b: vector_unsigned_short) -> i32;
276    #[link_name = "llvm.ppc.altivec.vcmpequw.p"]
277    fn vcmpequw_p(cr: i32, a: vector_unsigned_int, b: vector_unsigned_int) -> i32;
278
279    #[link_name = "llvm.ppc.altivec.vcmpeqfp.p"]
280    fn vcmpeqfp_p(cr: i32, a: vector_float, b: vector_float) -> i32;
281
282    #[link_name = "llvm.ppc.altivec.vcmpgtub.p"]
283    fn vcmpgtub_p(cr: i32, a: vector_unsigned_char, b: vector_unsigned_char) -> i32;
284    #[link_name = "llvm.ppc.altivec.vcmpgtuh.p"]
285    fn vcmpgtuh_p(cr: i32, a: vector_unsigned_short, b: vector_unsigned_short) -> i32;
286    #[link_name = "llvm.ppc.altivec.vcmpgtuw.p"]
287    fn vcmpgtuw_p(cr: i32, a: vector_unsigned_int, b: vector_unsigned_int) -> i32;
288    #[link_name = "llvm.ppc.altivec.vcmpgtsb.p"]
289    fn vcmpgtsb_p(cr: i32, a: vector_signed_char, b: vector_signed_char) -> i32;
290    #[link_name = "llvm.ppc.altivec.vcmpgtsh.p"]
291    fn vcmpgtsh_p(cr: i32, a: vector_signed_short, b: vector_signed_short) -> i32;
292    #[link_name = "llvm.ppc.altivec.vcmpgtsw.p"]
293    fn vcmpgtsw_p(cr: i32, a: vector_signed_int, b: vector_signed_int) -> i32;
294
295    #[link_name = "llvm.ppc.altivec.vcmpgefp.p"]
296    fn vcmpgefp_p(cr: i32, a: vector_float, b: vector_float) -> i32;
297    #[link_name = "llvm.ppc.altivec.vcmpgtfp.p"]
298    fn vcmpgtfp_p(cr: i32, a: vector_float, b: vector_float) -> i32;
299    #[link_name = "llvm.ppc.altivec.vcmpbfp.p"]
300    fn vcmpbfp_p(cr: i32, a: vector_float, b: vector_float) -> i32;
301
302    #[link_name = "llvm.ppc.altivec.vcfsx"]
303    fn vcfsx(a: vector_signed_int, b: i32) -> vector_float;
304    #[link_name = "llvm.ppc.altivec.vcfux"]
305    fn vcfux(a: vector_unsigned_int, b: i32) -> vector_float;
306
307    #[link_name = "llvm.ppc.altivec.vctsxs"]
308    fn vctsxs(a: vector_float, b: i32) -> vector_signed_int;
309    #[link_name = "llvm.ppc.altivec.vctuxs"]
310    fn vctuxs(a: vector_float, b: i32) -> vector_unsigned_int;
311
312    #[link_name = "llvm.ppc.altivec.vpkshss"]
313    fn vpkshss(a: vector_signed_short, b: vector_signed_short) -> vector_signed_char;
314    #[link_name = "llvm.ppc.altivec.vpkshus"]
315    fn vpkshus(a: vector_signed_short, b: vector_signed_short) -> vector_unsigned_char;
316    #[link_name = "llvm.ppc.altivec.vpkuhus"]
317    fn vpkuhus(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_char;
318    #[link_name = "llvm.ppc.altivec.vpkswss"]
319    fn vpkswss(a: vector_signed_int, b: vector_signed_int) -> vector_signed_short;
320    #[link_name = "llvm.ppc.altivec.vpkswus"]
321    fn vpkswus(a: vector_signed_int, b: vector_signed_int) -> vector_unsigned_short;
322    #[link_name = "llvm.ppc.altivec.vpkuwus"]
323    fn vpkuwus(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_short;
324
325    #[link_name = "llvm.ppc.altivec.vupkhsb"]
326    fn vupkhsb(a: vector_signed_char) -> vector_signed_short;
327    #[link_name = "llvm.ppc.altivec.vupklsb"]
328    fn vupklsb(a: vector_signed_char) -> vector_signed_short;
329
330    #[link_name = "llvm.ppc.altivec.vupkhsh"]
331    fn vupkhsh(a: vector_signed_short) -> vector_signed_int;
332    #[link_name = "llvm.ppc.altivec.vupklsh"]
333    fn vupklsh(a: vector_signed_short) -> vector_signed_int;
334
335    #[link_name = "llvm.ppc.altivec.mfvscr"]
336    fn mfvscr() -> vector_unsigned_short;
337
338    #[link_name = "llvm.ppc.altivec.vlogefp"]
339    fn vlogefp(a: vector_float) -> vector_float;
340
341    #[link_name = "llvm.ppc.altivec.vsl"]
342    fn vsl(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
343    #[link_name = "llvm.ppc.altivec.vslo"]
344    fn vslo(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
345
346    #[link_name = "llvm.ppc.altivec.vsrab"]
347    fn vsrab(a: vector_signed_char, b: vector_unsigned_char) -> vector_signed_char;
348    #[link_name = "llvm.ppc.altivec.vsrah"]
349    fn vsrah(a: vector_signed_short, b: vector_unsigned_short) -> vector_signed_short;
350    #[link_name = "llvm.ppc.altivec.vsraw"]
351    fn vsraw(a: vector_signed_int, b: vector_unsigned_int) -> vector_signed_int;
352
353    #[link_name = "llvm.ppc.altivec.vsr"]
354    fn vsr(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
355    #[link_name = "llvm.ppc.altivec.vsro"]
356    fn vsro(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int;
357
358    #[link_name = "llvm.ppc.altivec.vslv"]
359    fn vslv(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
360    #[link_name = "llvm.ppc.altivec.vsrv"]
361    fn vsrv(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char;
362
363    #[link_name = "llvm.nearbyint.v4f32"]
364    fn vrfin(a: vector_float) -> vector_float;
365}
366
367impl_from! { i8x16, u8x16,  i16x8, u16x8, i32x4, u32x4, f32x4 }
368
369impl_neg! { i8x16 : 0 }
370impl_neg! { i16x8 : 0 }
371impl_neg! { i32x4 : 0 }
372impl_neg! { f32x4 : 0f32 }
373
374#[macro_use]
375mod sealed {
376    use super::*;
377
378    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
379    pub trait VectorInsert {
380        type Scalar;
381        unsafe fn vec_insert<const IDX: u32>(self, s: Self::Scalar) -> Self;
382    }
383
384    const fn idx_in_vec<T, const IDX: u32>() -> u32 {
385        IDX & (16 / crate::mem::size_of::<T>() as u32)
386    }
387
388    macro_rules! impl_vec_insert {
389        ($ty:ident) => {
390            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
391            impl VectorInsert for t_t_l!($ty) {
392                type Scalar = $ty;
393                #[inline]
394                #[target_feature(enable = "altivec")]
395                unsafe fn vec_insert<const IDX: u32>(self, s: Self::Scalar) -> Self {
396                    simd_insert(self, const { idx_in_vec::<Self::Scalar, IDX>() }, s)
397                }
398            }
399        };
400    }
401
402    impl_vec_insert! { i8 }
403    impl_vec_insert! { u8 }
404    impl_vec_insert! { i16 }
405    impl_vec_insert! { u16 }
406    impl_vec_insert! { i32 }
407    impl_vec_insert! { u32 }
408    impl_vec_insert! { f32 }
409
410    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
411    pub trait VectorExtract {
412        type Scalar;
413        unsafe fn vec_extract<const IDX: u32>(self) -> Self::Scalar;
414    }
415
416    macro_rules! impl_vec_extract {
417        ($ty:ident) => {
418            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
419            impl VectorExtract for t_t_l!($ty) {
420                type Scalar = $ty;
421                #[inline]
422                #[target_feature(enable = "altivec")]
423                unsafe fn vec_extract<const IDX: u32>(self) -> Self::Scalar {
424                    simd_extract(self, const { idx_in_vec::<Self::Scalar, IDX>() })
425                }
426            }
427        };
428    }
429
430    impl_vec_extract! { i8 }
431    impl_vec_extract! { u8 }
432    impl_vec_extract! { i16 }
433    impl_vec_extract! { u16 }
434    impl_vec_extract! { i32 }
435    impl_vec_extract! { u32 }
436    impl_vec_extract! { f32 }
437
438    macro_rules! impl_vec_cmp {
439        ([$Trait:ident $m:ident] ($b:ident, $h:ident, $w:ident)) => {
440            impl_vec_cmp! { [$Trait $m] ($b, $b, $h, $h, $w, $w) }
441        };
442        ([$Trait:ident $m:ident] ($ub:ident, $sb:ident, $uh:ident, $sh:ident, $uw:ident, $sw:ident)) => {
443            impl_vec_trait!{ [$Trait $m] $ub (vector_unsigned_char, vector_unsigned_char) -> vector_bool_char }
444            impl_vec_trait!{ [$Trait $m] $sb (vector_signed_char, vector_signed_char) -> vector_bool_char }
445            impl_vec_trait!{ [$Trait $m] $uh (vector_unsigned_short, vector_unsigned_short) -> vector_bool_short }
446            impl_vec_trait!{ [$Trait $m] $sh (vector_signed_short, vector_signed_short) -> vector_bool_short }
447            impl_vec_trait!{ [$Trait $m] $uw (vector_unsigned_int, vector_unsigned_int) -> vector_bool_int }
448            impl_vec_trait!{ [$Trait $m] $sw (vector_signed_int, vector_signed_int) -> vector_bool_int }
449        }
450    }
451
452    macro_rules! impl_vec_any_all {
453        ([$Trait:ident $m:ident] ($b:ident, $h:ident, $w:ident)) => {
454            impl_vec_any_all! { [$Trait $m] ($b, $b, $h, $h, $w, $w) }
455        };
456        ([$Trait:ident $m:ident] ($ub:ident, $sb:ident, $uh:ident, $sh:ident, $uw:ident, $sw:ident)) => {
457            impl_vec_trait!{ [$Trait $m] $ub (vector_unsigned_char, vector_unsigned_char) -> bool }
458            impl_vec_trait!{ [$Trait $m] $sb (vector_signed_char, vector_signed_char) -> bool }
459            impl_vec_trait!{ [$Trait $m] $uh (vector_unsigned_short, vector_unsigned_short) -> bool }
460            impl_vec_trait!{ [$Trait $m] $sh (vector_signed_short, vector_signed_short) -> bool }
461            impl_vec_trait!{ [$Trait $m] $uw (vector_unsigned_int, vector_unsigned_int) -> bool }
462            impl_vec_trait!{ [$Trait $m] $sw (vector_signed_int, vector_signed_int) -> bool }
463        }
464    }
465
466    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
467    pub trait VectorLd {
468        type Result;
469        unsafe fn vec_ld(self, off: isize) -> Self::Result;
470        unsafe fn vec_ldl(self, off: isize) -> Self::Result;
471    }
472
473    macro_rules! impl_vec_ld {
474        ($fun:ident $fun_lru:ident $ty:ident) => {
475            #[inline]
476            #[target_feature(enable = "altivec")]
477            #[cfg_attr(test, assert_instr(lvx))]
478            pub unsafe fn $fun(off: isize, p: *const $ty) -> t_t_l!($ty) {
479                let addr = (p as *const i8).offset(off);
480                transmute(lvx(addr))
481            }
482
483            #[inline]
484            #[target_feature(enable = "altivec")]
485            #[cfg_attr(test, assert_instr(lvxl))]
486            pub unsafe fn $fun_lru(off: isize, p: *const $ty) -> t_t_l!($ty) {
487                let addr = (p as *const i8).offset(off);
488                transmute(lvxl(addr))
489            }
490
491            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
492            impl VectorLd for *const $ty {
493                type Result = t_t_l!($ty);
494                #[inline]
495                #[target_feature(enable = "altivec")]
496                unsafe fn vec_ld(self, off: isize) -> Self::Result {
497                    $fun(off, self)
498                }
499                #[inline]
500                #[target_feature(enable = "altivec")]
501                unsafe fn vec_ldl(self, off: isize) -> Self::Result {
502                    $fun_lru(off, self)
503                }
504            }
505        };
506    }
507
508    impl_vec_ld! { vec_ld_u8 vec_ldl_u8 u8 }
509    impl_vec_ld! { vec_ld_i8 vec_ldl_i8 i8 }
510
511    impl_vec_ld! { vec_ld_u16 vec_ldl_u16 u16 }
512    impl_vec_ld! { vec_ld_i16 vec_ldl_i16 i16 }
513
514    impl_vec_ld! { vec_ld_u32 vec_ldl_u32 u32 }
515    impl_vec_ld! { vec_ld_i32 vec_ldl_i32 i32 }
516
517    impl_vec_ld! { vec_ld_f32 vec_ldl_f32 f32 }
518
519    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
520    pub trait VectorLde {
521        type Result;
522        unsafe fn vec_lde(self, a: isize) -> Self::Result;
523    }
524
525    macro_rules! impl_vec_lde {
526        ($fun:ident $instr:ident $ty:ident) => {
527            #[inline]
528            #[target_feature(enable = "altivec")]
529            #[cfg_attr(test, assert_instr($instr))]
530            pub unsafe fn $fun(a: isize, b: *const $ty) -> t_t_l!($ty) {
531                let addr = b.byte_offset(a).cast::<i8>();
532                transmute($instr(addr))
533            }
534
535            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
536            impl VectorLde for *const $ty {
537                type Result = t_t_l!($ty);
538                #[inline]
539                #[target_feature(enable = "altivec")]
540                unsafe fn vec_lde(self, a: isize) -> Self::Result {
541                    $fun(a, self)
542                }
543            }
544        };
545    }
546
547    impl_vec_lde! { vec_lde_u8 lvebx u8 }
548    impl_vec_lde! { vec_lde_i8 lvebx i8 }
549
550    impl_vec_lde! { vec_lde_u16 lvehx u16 }
551    impl_vec_lde! { vec_lde_i16 lvehx i16 }
552
553    impl_vec_lde! { vec_lde_u32 lvewx u32 }
554    impl_vec_lde! { vec_lde_i32 lvewx i32 }
555
556    impl_vec_lde! { vec_lde_f32 lvewx f32 }
557
558    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
559    pub trait VectorSt {
560        type Target;
561        unsafe fn vec_st(self, off: isize, p: Self::Target);
562        unsafe fn vec_stl(self, off: isize, p: Self::Target);
563    }
564
565    macro_rules! impl_vec_st {
566        ($fun:ident $fun_lru:ident $ty:ident) => {
567            #[inline]
568            #[target_feature(enable = "altivec")]
569            #[cfg_attr(test, assert_instr(stvx))]
570            pub unsafe fn $fun(a: t_t_l!($ty), off: isize, p: *const $ty) {
571                let addr = (p as *const i8).offset(off);
572                stvx(transmute(a), addr)
573            }
574
575            #[inline]
576            #[target_feature(enable = "altivec")]
577            #[cfg_attr(test, assert_instr(stvxl))]
578            pub unsafe fn $fun_lru(a: t_t_l!($ty), off: isize, p: *const $ty) {
579                let addr = (p as *const i8).offset(off as isize);
580                stvxl(transmute(a), addr)
581            }
582
583            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
584            impl VectorSt for t_t_l!($ty) {
585                type Target = *const $ty;
586                #[inline]
587                #[target_feature(enable = "altivec")]
588                unsafe fn vec_st(self, off: isize, p: Self::Target) {
589                    $fun(self, off, p)
590                }
591                #[inline]
592                #[target_feature(enable = "altivec")]
593                unsafe fn vec_stl(self, off: isize, p: Self::Target) {
594                    $fun(self, off, p)
595                }
596            }
597        };
598    }
599
600    impl_vec_st! { vec_st_u8 vec_stl_u8 u8 }
601    impl_vec_st! { vec_st_i8 vec_stl_i8 i8 }
602
603    impl_vec_st! { vec_st_u16 vec_stl_u16 u16 }
604    impl_vec_st! { vec_st_i16 vec_stl_i16 i16 }
605
606    impl_vec_st! { vec_st_u32 vec_stl_u32 u32 }
607    impl_vec_st! { vec_st_i32 vec_stl_i32 i32 }
608
609    impl_vec_st! { vec_st_f32 vec_stl_f32 f32 }
610
611    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
612    pub trait VectorSte {
613        type Target;
614        unsafe fn vec_ste(self, off: isize, p: Self::Target);
615    }
616
617    macro_rules! impl_vec_ste {
618        ($fun:ident $instr:ident $ty:ident) => {
619            #[inline]
620            #[target_feature(enable = "altivec")]
621            #[cfg_attr(test, assert_instr($instr))]
622            pub unsafe fn $fun(a: t_t_l!($ty), off: isize, p: *const $ty) {
623                let addr = (p as *const i8).offset(off);
624                $instr(transmute(a), addr)
625            }
626
627            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
628            impl VectorSte for t_t_l!($ty) {
629                type Target = *const $ty;
630                #[inline]
631                #[target_feature(enable = "altivec")]
632                unsafe fn vec_ste(self, off: isize, p: Self::Target) {
633                    $fun(self, off, p)
634                }
635            }
636        };
637    }
638
639    impl_vec_ste! { vec_ste_u8 stvebx u8 }
640    impl_vec_ste! { vec_ste_i8 stvebx i8 }
641
642    impl_vec_ste! { vec_ste_u16 stvehx u16 }
643    impl_vec_ste! { vec_ste_i16 stvehx i16 }
644
645    impl_vec_ste! { vec_ste_u32 stvewx u32 }
646    impl_vec_ste! { vec_ste_i32 stvewx i32 }
647
648    impl_vec_ste! { vec_ste_f32 stvewx f32 }
649
650    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
651    pub trait VectorXl {
652        type Result;
653        unsafe fn vec_xl(self, a: isize) -> Self::Result;
654    }
655
656    macro_rules! impl_vec_xl {
657        ($fun:ident $notpwr9:ident / $pwr9:ident $ty:ident) => {
658            #[inline]
659            #[target_feature(enable = "altivec")]
660            #[cfg_attr(
661                all(test, not(target_feature = "power9-altivec")),
662                assert_instr($notpwr9)
663            )]
664            #[cfg_attr(all(test, target_feature = "power9-altivec"), assert_instr($pwr9))]
665            pub unsafe fn $fun(a: isize, b: *const $ty) -> t_t_l!($ty) {
666                let addr = (b as *const u8).offset(a);
667
668                let mut r = mem::MaybeUninit::uninit();
669
670                crate::ptr::copy_nonoverlapping(
671                    addr,
672                    r.as_mut_ptr() as *mut u8,
673                    mem::size_of::<t_t_l!($ty)>(),
674                );
675
676                r.assume_init()
677            }
678
679            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
680            impl VectorXl for *const $ty {
681                type Result = t_t_l!($ty);
682                #[inline]
683                #[target_feature(enable = "altivec")]
684                unsafe fn vec_xl(self, a: isize) -> Self::Result {
685                    $fun(a, self)
686                }
687            }
688        };
689    }
690
691    impl_vec_xl! { vec_xl_i8 lxvd2x / lxv i8 }
692    impl_vec_xl! { vec_xl_u8 lxvd2x / lxv u8 }
693    impl_vec_xl! { vec_xl_i16 lxvd2x / lxv i16 }
694    impl_vec_xl! { vec_xl_u16 lxvd2x / lxv u16 }
695    impl_vec_xl! { vec_xl_i32 lxvd2x / lxv i32 }
696    impl_vec_xl! { vec_xl_u32 lxvd2x / lxv u32 }
697    impl_vec_xl! { vec_xl_f32 lxvd2x / lxv f32 }
698
699    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
700    pub trait VectorXst {
701        type Out;
702        unsafe fn vec_xst(self, a: isize, p: Self::Out);
703    }
704
705    macro_rules! impl_vec_xst {
706        ($fun:ident $notpwr9:ident / $pwr9:ident $ty:ident) => {
707            #[inline]
708            #[target_feature(enable = "altivec")]
709            #[cfg_attr(
710                all(test, not(target_feature = "power9-altivec")),
711                assert_instr($notpwr9)
712            )]
713            #[cfg_attr(all(test, target_feature = "power9-altivec"), assert_instr($pwr9))]
714            pub unsafe fn $fun(s: t_t_l!($ty), a: isize, b: *mut $ty) {
715                let addr = (b as *mut u8).offset(a);
716
717                crate::ptr::copy_nonoverlapping(
718                    &s as *const _ as *const u8,
719                    addr,
720                    mem::size_of::<t_t_l!($ty)>(),
721                );
722            }
723
724            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
725            impl VectorXst for t_t_l!($ty) {
726                type Out = *mut $ty;
727                #[inline]
728                #[target_feature(enable = "altivec")]
729                unsafe fn vec_xst(self, a: isize, b: Self::Out) {
730                    $fun(self, a, b)
731                }
732            }
733        };
734    }
735
736    impl_vec_xst! { vec_xst_i8 stxvd2x / stxv i8 }
737    impl_vec_xst! { vec_xst_u8 stxvd2x / stxv u8 }
738    impl_vec_xst! { vec_xst_i16 stxvd2x / stxv i16 }
739    impl_vec_xst! { vec_xst_u16 stxvd2x / stxv u16 }
740    impl_vec_xst! { vec_xst_i32 stxvd2x / stxv i32 }
741    impl_vec_xst! { vec_xst_u32 stxvd2x / stxv u32 }
742    impl_vec_xst! { vec_xst_f32 stxvd2x / stxv f32 }
743
744    test_impl! { vec_floor(a: vector_float) -> vector_float [ simd_floor, vrfim / xvrspim ] }
745
746    test_impl! { vec_vexptefp(a: vector_float) -> vector_float [ vexptefp, vexptefp ] }
747
748    test_impl! { vec_vcmpgtub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_bool_char [ vcmpgtub, vcmpgtub ] }
749    test_impl! { vec_vcmpgtuh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_bool_short [ vcmpgtuh, vcmpgtuh ] }
750    test_impl! { vec_vcmpgtuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_bool_int [ vcmpgtuw, vcmpgtuw ] }
751
752    test_impl! { vec_vcmpgtsb(a: vector_signed_char, b: vector_signed_char) -> vector_bool_char [ vcmpgtsb, vcmpgtsb ] }
753    test_impl! { vec_vcmpgtsh(a: vector_signed_short, b: vector_signed_short) -> vector_bool_short [ vcmpgtsh, vcmpgtsh ] }
754    test_impl! { vec_vcmpgtsw(a: vector_signed_int, b: vector_signed_int) -> vector_bool_int [ vcmpgtsw, vcmpgtsw ] }
755
756    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
757    pub trait VectorCmpGt<Other> {
758        type Result;
759        unsafe fn vec_cmpgt(self, b: Other) -> Self::Result;
760    }
761
762    impl_vec_cmp! { [VectorCmpGt vec_cmpgt] ( vec_vcmpgtub, vec_vcmpgtsb, vec_vcmpgtuh, vec_vcmpgtsh, vec_vcmpgtuw, vec_vcmpgtsw ) }
763
764    test_impl! { vec_vcmpgefp(a: vector_float, b: vector_float) -> vector_bool_int [ vcmpgefp, vcmpgefp ] }
765
766    test_impl! { vec_vcmpequb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_bool_char [ vcmpequb, vcmpequb ] }
767    test_impl! { vec_vcmpequh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_bool_short [ vcmpequh, vcmpequh ] }
768    test_impl! { vec_vcmpequw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_bool_int [ vcmpequw, vcmpequw ] }
769
770    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
771    pub trait VectorCmpEq<Other> {
772        type Result;
773        unsafe fn vec_cmpeq(self, b: Other) -> Self::Result;
774    }
775
776    impl_vec_cmp! { [VectorCmpEq vec_cmpeq] (vec_vcmpequb, vec_vcmpequh, vec_vcmpequw) }
777
778    macro_rules! impl_cmpne {
779        ($fun:ident ($ty:ident) -> $r:ident $([ $pwr9:ident ])? ) => {
780            #[inline]
781            #[target_feature(enable = "altivec")]
782            $( #[cfg_attr(all(test, target_feature = "power9-altivec"), assert_instr($pwr9))] )?
783            unsafe fn $fun(a: $ty, b: $ty) -> $r {
784                $( if cfg!(target_feature = "power9-altivec") {
785                    transmute($pwr9(transmute(a), transmute(b)))
786                } else )? {
787                    let zero = transmute(i32x4::new(0, 0, 0, 0));
788                    vec_nor(vec_cmpeq(a, b), zero)
789                }
790            }
791        };
792    }
793
794    impl_cmpne! { vec_vcmpneb(vector_signed_char) -> vector_bool_char [ vcmpneb ] }
795    impl_cmpne! { vec_vcmpneh(vector_signed_short) -> vector_bool_short [ vcmpneh ] }
796    impl_cmpne! { vec_vcmpnew(vector_signed_int) -> vector_bool_int [ vcmpnew ] }
797
798    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
799    pub trait VectorCmpNe<Other> {
800        type Result;
801        unsafe fn vec_cmpne(self, b: Other) -> Self::Result;
802    }
803
804    impl_vec_cmp! { [VectorCmpNe vec_cmpne] (vec_vcmpneb, vec_vcmpneh, vec_vcmpnew) }
805
806    test_impl! { vec_vcmpbfp(a: vector_float, b: vector_float) -> vector_signed_int [vcmpbfp, vcmpbfp] }
807
808    #[inline]
809    #[target_feature(enable = "altivec")]
810    #[cfg_attr(test, assert_instr(vcmpequb.))]
811    unsafe fn vcmpequb_all(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
812        vcmpequb_p(2, a, b) != 0
813    }
814
815    #[inline]
816    #[target_feature(enable = "altivec")]
817    #[cfg_attr(test, assert_instr(vcmpequb.))]
818    unsafe fn vcmpequb_any(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
819        vcmpequb_p(1, a, b) != 0
820    }
821
822    #[inline]
823    #[target_feature(enable = "altivec")]
824    #[cfg_attr(test, assert_instr(vcmpequh.))]
825    unsafe fn vcmpequh_all(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
826        vcmpequh_p(2, a, b) != 0
827    }
828
829    #[inline]
830    #[target_feature(enable = "altivec")]
831    #[cfg_attr(test, assert_instr(vcmpequh.))]
832    unsafe fn vcmpequh_any(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
833        vcmpequh_p(1, a, b) != 0
834    }
835
836    #[inline]
837    #[target_feature(enable = "altivec")]
838    #[cfg_attr(test, assert_instr(vcmpequw.))]
839    unsafe fn vcmpequw_all(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
840        vcmpequw_p(2, a, b) != 0
841    }
842
843    #[inline]
844    #[target_feature(enable = "altivec")]
845    #[cfg_attr(test, assert_instr(vcmpequw.))]
846    unsafe fn vcmpequw_any(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
847        vcmpequw_p(1, a, b) != 0
848    }
849
850    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
851    pub trait VectorAllEq<Other> {
852        type Result;
853        unsafe fn vec_all_eq(self, b: Other) -> Self::Result;
854    }
855
856    impl_vec_any_all! { [VectorAllEq vec_all_eq] (vcmpequb_all, vcmpequh_all, vcmpequw_all) }
857
858    // TODO: vsx encoding
859    #[inline]
860    #[target_feature(enable = "altivec")]
861    #[cfg_attr(test, assert_instr(vcmpeqfp.))]
862    unsafe fn vcmpeqfp_all(a: vector_float, b: vector_float) -> bool {
863        vcmpeqfp_p(2, a, b) != 0
864    }
865
866    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
867    impl VectorAllEq<vector_float> for vector_float {
868        type Result = bool;
869        #[inline]
870        unsafe fn vec_all_eq(self, b: vector_float) -> Self::Result {
871            vcmpeqfp_all(self, b)
872        }
873    }
874
875    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
876    pub trait VectorAnyEq<Other> {
877        type Result;
878        unsafe fn vec_any_eq(self, b: Other) -> Self::Result;
879    }
880
881    impl_vec_any_all! { [VectorAnyEq vec_any_eq] (vcmpequb_any, vcmpequh_any, vcmpequw_any) }
882
883    #[inline]
884    #[target_feature(enable = "altivec")]
885    #[cfg_attr(test, assert_instr(vcmpeqfp.))]
886    unsafe fn vcmpeqfp_any(a: vector_float, b: vector_float) -> bool {
887        vcmpeqfp_p(1, a, b) != 0
888    }
889
890    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
891    impl VectorAnyEq<vector_float> for vector_float {
892        type Result = bool;
893        #[inline]
894        unsafe fn vec_any_eq(self, b: vector_float) -> Self::Result {
895            vcmpeqfp_any(self, b)
896        }
897    }
898
899    // All/Any GreaterEqual
900
901    #[inline]
902    #[target_feature(enable = "altivec")]
903    #[cfg_attr(test, assert_instr(vcmpgtsb.))]
904    unsafe fn vcmpgesb_all(a: vector_signed_char, b: vector_signed_char) -> bool {
905        vcmpgtsb_p(0, b, a) != 0
906    }
907
908    #[inline]
909    #[target_feature(enable = "altivec")]
910    #[cfg_attr(test, assert_instr(vcmpgtsb.))]
911    unsafe fn vcmpgesb_any(a: vector_signed_char, b: vector_signed_char) -> bool {
912        vcmpgtsb_p(3, b, a) != 0
913    }
914
915    #[inline]
916    #[target_feature(enable = "altivec")]
917    #[cfg_attr(test, assert_instr(vcmpgtsh.))]
918    unsafe fn vcmpgesh_all(a: vector_signed_short, b: vector_signed_short) -> bool {
919        vcmpgtsh_p(0, b, a) != 0
920    }
921
922    #[inline]
923    #[target_feature(enable = "altivec")]
924    #[cfg_attr(test, assert_instr(vcmpgtsh.))]
925    unsafe fn vcmpgesh_any(a: vector_signed_short, b: vector_signed_short) -> bool {
926        vcmpgtsh_p(3, b, a) != 0
927    }
928
929    #[inline]
930    #[target_feature(enable = "altivec")]
931    #[cfg_attr(test, assert_instr(vcmpgtsw.))]
932    unsafe fn vcmpgesw_all(a: vector_signed_int, b: vector_signed_int) -> bool {
933        vcmpgtsw_p(0, b, a) != 0
934    }
935
936    #[inline]
937    #[target_feature(enable = "altivec")]
938    #[cfg_attr(test, assert_instr(vcmpgtsw.))]
939    unsafe fn vcmpgesw_any(a: vector_signed_int, b: vector_signed_int) -> bool {
940        vcmpgtsw_p(3, b, a) != 0
941    }
942
943    #[inline]
944    #[target_feature(enable = "altivec")]
945    #[cfg_attr(test, assert_instr(vcmpgtub.))]
946    unsafe fn vcmpgeub_all(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
947        vcmpgtub_p(0, b, a) != 0
948    }
949
950    #[inline]
951    #[target_feature(enable = "altivec")]
952    #[cfg_attr(test, assert_instr(vcmpgtub.))]
953    unsafe fn vcmpgeub_any(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
954        vcmpgtub_p(3, b, a) != 0
955    }
956
957    #[inline]
958    #[target_feature(enable = "altivec")]
959    #[cfg_attr(test, assert_instr(vcmpgtuh.))]
960    unsafe fn vcmpgeuh_all(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
961        vcmpgtuh_p(0, b, a) != 0
962    }
963
964    #[inline]
965    #[target_feature(enable = "altivec")]
966    #[cfg_attr(test, assert_instr(vcmpgtuh.))]
967    unsafe fn vcmpgeuh_any(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
968        vcmpgtuh_p(3, b, a) != 0
969    }
970
971    #[inline]
972    #[target_feature(enable = "altivec")]
973    #[cfg_attr(test, assert_instr(vcmpgtuw.))]
974    unsafe fn vcmpgeuw_all(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
975        vcmpgtuw_p(0, b, a) != 0
976    }
977
978    #[inline]
979    #[target_feature(enable = "altivec")]
980    #[cfg_attr(test, assert_instr(vcmpgtuw.))]
981    unsafe fn vcmpgeuw_any(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
982        vcmpgtuw_p(3, b, a) != 0
983    }
984
985    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
986    pub trait VectorAllGe<Other> {
987        type Result;
988        unsafe fn vec_all_ge(self, b: Other) -> Self::Result;
989    }
990
991    impl_vec_any_all! { [VectorAllGe vec_all_ge] (
992        vcmpgeub_all, vcmpgesb_all,
993        vcmpgeuh_all, vcmpgesh_all,
994        vcmpgeuw_all, vcmpgesw_all
995    ) }
996
997    // TODO: vsx encoding
998    #[inline]
999    #[target_feature(enable = "altivec")]
1000    #[cfg_attr(test, assert_instr(vcmpgefp.))]
1001    unsafe fn vcmpgefp_all(a: vector_float, b: vector_float) -> bool {
1002        vcmpgefp_p(2, a, b) != 0
1003    }
1004
1005    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1006    impl VectorAllGe<vector_float> for vector_float {
1007        type Result = bool;
1008        #[inline]
1009        unsafe fn vec_all_ge(self, b: vector_float) -> Self::Result {
1010            vcmpgefp_all(self, b)
1011        }
1012    }
1013
1014    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1015    pub trait VectorAnyGe<Other> {
1016        type Result;
1017        unsafe fn vec_any_ge(self, b: Other) -> Self::Result;
1018    }
1019
1020    impl_vec_any_all! { [VectorAnyGe vec_any_ge] (
1021        vcmpgeub_any, vcmpgesb_any,
1022        vcmpgeuh_any, vcmpgesh_any,
1023        vcmpgeuw_any, vcmpgesw_any
1024    ) }
1025
1026    #[inline]
1027    #[target_feature(enable = "altivec")]
1028    #[cfg_attr(test, assert_instr(vcmpgefp.))]
1029    unsafe fn vcmpgefp_any(a: vector_float, b: vector_float) -> bool {
1030        vcmpgefp_p(1, a, b) != 0
1031    }
1032
1033    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1034    impl VectorAnyGe<vector_float> for vector_float {
1035        type Result = bool;
1036        #[inline]
1037        unsafe fn vec_any_ge(self, b: vector_float) -> Self::Result {
1038            vcmpgefp_any(self, b)
1039        }
1040    }
1041
1042    // All/Any Greater Than
1043
1044    #[inline]
1045    #[target_feature(enable = "altivec")]
1046    #[cfg_attr(test, assert_instr(vcmpgtsb.))]
1047    unsafe fn vcmpgtsb_all(a: vector_signed_char, b: vector_signed_char) -> bool {
1048        vcmpgtsb_p(2, a, b) != 0
1049    }
1050
1051    #[inline]
1052    #[target_feature(enable = "altivec")]
1053    #[cfg_attr(test, assert_instr(vcmpgtsb.))]
1054    unsafe fn vcmpgtsb_any(a: vector_signed_char, b: vector_signed_char) -> bool {
1055        vcmpgtsb_p(1, a, b) != 0
1056    }
1057
1058    #[inline]
1059    #[target_feature(enable = "altivec")]
1060    #[cfg_attr(test, assert_instr(vcmpgtsh.))]
1061    unsafe fn vcmpgtsh_all(a: vector_signed_short, b: vector_signed_short) -> bool {
1062        vcmpgtsh_p(2, a, b) != 0
1063    }
1064
1065    #[inline]
1066    #[target_feature(enable = "altivec")]
1067    #[cfg_attr(test, assert_instr(vcmpgtsh.))]
1068    unsafe fn vcmpgtsh_any(a: vector_signed_short, b: vector_signed_short) -> bool {
1069        vcmpgtsh_p(1, a, b) != 0
1070    }
1071
1072    #[inline]
1073    #[target_feature(enable = "altivec")]
1074    #[cfg_attr(test, assert_instr(vcmpgtsw.))]
1075    unsafe fn vcmpgtsw_all(a: vector_signed_int, b: vector_signed_int) -> bool {
1076        vcmpgtsw_p(2, a, b) != 0
1077    }
1078
1079    #[inline]
1080    #[target_feature(enable = "altivec")]
1081    #[cfg_attr(test, assert_instr(vcmpgtsw.))]
1082    unsafe fn vcmpgtsw_any(a: vector_signed_int, b: vector_signed_int) -> bool {
1083        vcmpgtsw_p(1, a, b) != 0
1084    }
1085
1086    #[inline]
1087    #[target_feature(enable = "altivec")]
1088    #[cfg_attr(test, assert_instr(vcmpgtub.))]
1089    unsafe fn vcmpgtub_all(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
1090        vcmpgtub_p(2, a, b) != 0
1091    }
1092
1093    #[inline]
1094    #[target_feature(enable = "altivec")]
1095    #[cfg_attr(test, assert_instr(vcmpgtub.))]
1096    unsafe fn vcmpgtub_any(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
1097        vcmpgtub_p(1, a, b) != 0
1098    }
1099
1100    #[inline]
1101    #[target_feature(enable = "altivec")]
1102    #[cfg_attr(test, assert_instr(vcmpgtuh.))]
1103    unsafe fn vcmpgtuh_all(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
1104        vcmpgtuh_p(2, a, b) != 0
1105    }
1106
1107    #[inline]
1108    #[target_feature(enable = "altivec")]
1109    #[cfg_attr(test, assert_instr(vcmpgtuh.))]
1110    unsafe fn vcmpgtuh_any(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
1111        vcmpgtuh_p(1, a, b) != 0
1112    }
1113
1114    #[inline]
1115    #[target_feature(enable = "altivec")]
1116    #[cfg_attr(test, assert_instr(vcmpgtuw.))]
1117    unsafe fn vcmpgtuw_all(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
1118        vcmpgtuw_p(2, a, b) != 0
1119    }
1120
1121    #[inline]
1122    #[target_feature(enable = "altivec")]
1123    #[cfg_attr(test, assert_instr(vcmpgtuw.))]
1124    unsafe fn vcmpgtuw_any(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
1125        vcmpgtuw_p(1, a, b) != 0
1126    }
1127
1128    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1129    pub trait VectorAllGt<Other> {
1130        type Result;
1131        unsafe fn vec_all_gt(self, b: Other) -> Self::Result;
1132    }
1133
1134    impl_vec_any_all! { [VectorAllGt vec_all_gt] (
1135        vcmpgtub_all, vcmpgtsb_all,
1136        vcmpgtuh_all, vcmpgtsh_all,
1137        vcmpgtuw_all, vcmpgtsw_all
1138    ) }
1139
1140    // TODO: vsx encoding
1141    #[inline]
1142    #[target_feature(enable = "altivec")]
1143    #[cfg_attr(test, assert_instr(vcmpgtfp.))]
1144    unsafe fn vcmpgtfp_all(a: vector_float, b: vector_float) -> bool {
1145        vcmpgtfp_p(2, a, b) != 0
1146    }
1147
1148    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1149    impl VectorAllGt<vector_float> for vector_float {
1150        type Result = bool;
1151        #[inline]
1152        unsafe fn vec_all_gt(self, b: vector_float) -> Self::Result {
1153            vcmpgtfp_all(self, b)
1154        }
1155    }
1156
1157    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1158    pub trait VectorAnyGt<Other> {
1159        type Result;
1160        unsafe fn vec_any_gt(self, b: Other) -> Self::Result;
1161    }
1162
1163    impl_vec_any_all! { [VectorAnyGt vec_any_gt] (
1164        vcmpgtub_any, vcmpgtsb_any,
1165        vcmpgtuh_any, vcmpgtsh_any,
1166        vcmpgtuw_any, vcmpgtsw_any
1167    ) }
1168
1169    #[inline]
1170    #[target_feature(enable = "altivec")]
1171    #[cfg_attr(test, assert_instr(vcmpgtfp.))]
1172    unsafe fn vcmpgtfp_any(a: vector_float, b: vector_float) -> bool {
1173        vcmpgtfp_p(1, a, b) != 0
1174    }
1175
1176    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1177    impl VectorAnyGt<vector_float> for vector_float {
1178        type Result = bool;
1179        #[inline]
1180        unsafe fn vec_any_gt(self, b: vector_float) -> Self::Result {
1181            vcmpgtfp_any(self, b)
1182        }
1183    }
1184
1185    // All/Any Elements Not Equal
1186
1187    #[inline]
1188    #[target_feature(enable = "altivec")]
1189    #[cfg_attr(test, assert_instr(vcmpequb.))]
1190    unsafe fn vcmpneub_all(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
1191        vcmpequb_p(0, a, b) != 0
1192    }
1193
1194    #[inline]
1195    #[target_feature(enable = "altivec")]
1196    #[cfg_attr(test, assert_instr(vcmpequb.))]
1197    unsafe fn vcmpneub_any(a: vector_unsigned_char, b: vector_unsigned_char) -> bool {
1198        vcmpequb_p(3, a, b) != 0
1199    }
1200
1201    #[inline]
1202    #[target_feature(enable = "altivec")]
1203    #[cfg_attr(test, assert_instr(vcmpequh.))]
1204    unsafe fn vcmpneuh_all(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
1205        vcmpequh_p(0, a, b) != 0
1206    }
1207
1208    #[inline]
1209    #[target_feature(enable = "altivec")]
1210    #[cfg_attr(test, assert_instr(vcmpequh.))]
1211    unsafe fn vcmpneuh_any(a: vector_unsigned_short, b: vector_unsigned_short) -> bool {
1212        vcmpequh_p(3, a, b) != 0
1213    }
1214
1215    #[inline]
1216    #[target_feature(enable = "altivec")]
1217    #[cfg_attr(test, assert_instr(vcmpequw.))]
1218    unsafe fn vcmpneuw_all(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
1219        vcmpequw_p(0, a, b) != 0
1220    }
1221
1222    #[inline]
1223    #[target_feature(enable = "altivec")]
1224    #[cfg_attr(test, assert_instr(vcmpequw.))]
1225    unsafe fn vcmpneuw_any(a: vector_unsigned_int, b: vector_unsigned_int) -> bool {
1226        vcmpequw_p(3, a, b) != 0
1227    }
1228
1229    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1230    pub trait VectorAllNe<Other> {
1231        type Result;
1232        unsafe fn vec_all_ne(self, b: Other) -> Self::Result;
1233    }
1234
1235    impl_vec_any_all! { [VectorAllNe vec_all_ne] (vcmpneub_all, vcmpneuh_all, vcmpneuw_all) }
1236
1237    // TODO: vsx encoding
1238    #[inline]
1239    #[target_feature(enable = "altivec")]
1240    #[cfg_attr(test, assert_instr(vcmpeqfp.))]
1241    unsafe fn vcmpnefp_all(a: vector_float, b: vector_float) -> bool {
1242        vcmpeqfp_p(0, a, b) != 0
1243    }
1244
1245    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1246    impl VectorAllNe<vector_float> for vector_float {
1247        type Result = bool;
1248        #[inline]
1249        unsafe fn vec_all_ne(self, b: vector_float) -> Self::Result {
1250            vcmpnefp_all(self, b)
1251        }
1252    }
1253
1254    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1255    pub trait VectorAnyNe<Other> {
1256        type Result;
1257        unsafe fn vec_any_ne(self, b: Other) -> Self::Result;
1258    }
1259
1260    impl_vec_any_all! { [VectorAnyNe vec_any_ne] (vcmpneub_any, vcmpneuh_any, vcmpneuw_any) }
1261
1262    #[inline]
1263    #[target_feature(enable = "altivec")]
1264    #[cfg_attr(test, assert_instr(vcmpeqfp.))]
1265    unsafe fn vcmpnefp_any(a: vector_float, b: vector_float) -> bool {
1266        vcmpeqfp_p(3, a, b) != 0
1267    }
1268
1269    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1270    impl VectorAnyNe<vector_float> for vector_float {
1271        type Result = bool;
1272        #[inline]
1273        unsafe fn vec_any_ne(self, b: vector_float) -> Self::Result {
1274            vcmpnefp_any(self, b)
1275        }
1276    }
1277
1278    test_impl! { vec_vceil(a: vector_float) -> vector_float [simd_ceil, vrfip / xvrspip ] }
1279
1280    test_impl! { vec_vavgsb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [ vavgsb, vavgsb ] }
1281    test_impl! { vec_vavgsh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [ vavgsh, vavgsh ] }
1282    test_impl! { vec_vavgsw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [ vavgsw, vavgsw ] }
1283    test_impl! { vec_vavgub(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [ vavgub, vavgub ] }
1284    test_impl! { vec_vavguh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [ vavguh, vavguh ] }
1285    test_impl! { vec_vavguw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [ vavguw, vavguw ] }
1286
1287    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1288    pub trait VectorAvg<Other> {
1289        type Result;
1290        unsafe fn vec_avg(self, b: Other) -> Self::Result;
1291    }
1292
1293    impl_vec_trait! { [VectorAvg vec_avg] 2 (vec_vavgub, vec_vavgsb, vec_vavguh, vec_vavgsh, vec_vavguw, vec_vavgsw) }
1294
1295    #[inline]
1296    #[target_feature(enable = "altivec")]
1297    #[cfg_attr(all(test, not(target_feature = "vsx")), assert_instr(vandc))]
1298    #[cfg_attr(all(test, target_feature = "vsx"), assert_instr(xxlandc))]
1299    unsafe fn andc(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
1300        let a = transmute(a);
1301        let b = transmute(b);
1302        transmute(simd_and(simd_xor(u8x16::splat(0xff), b), a))
1303    }
1304
1305    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1306    pub trait VectorAndc<Other> {
1307        type Result;
1308        unsafe fn vec_andc(self, b: Other) -> Self::Result;
1309    }
1310
1311    impl_vec_trait! { [VectorAndc vec_andc]+ 2b (andc) }
1312
1313    #[inline]
1314    #[target_feature(enable = "altivec")]
1315    #[cfg_attr(all(test, not(target_feature = "vsx")), assert_instr(vorc))]
1316    #[cfg_attr(all(test, target_feature = "vsx"), assert_instr(xxlorc))]
1317    unsafe fn orc(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
1318        let a = transmute(a);
1319        let b = transmute(b);
1320        transmute(simd_or(simd_xor(u8x16::splat(0xff), b), a))
1321    }
1322
1323    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1324    pub trait VectorOrc<Other> {
1325        type Result;
1326        unsafe fn vec_orc(self, b: Other) -> Self::Result;
1327    }
1328
1329    impl_vec_trait! { [VectorOrc vec_orc]+ 2b (orc) }
1330
1331    test_impl! { vec_vand(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [ simd_and, vand / xxland ] }
1332
1333    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1334    pub trait VectorAnd<Other> {
1335        type Result;
1336        unsafe fn vec_and(self, b: Other) -> Self::Result;
1337    }
1338
1339    impl_vec_trait! { [VectorAnd vec_and] ~(simd_and) }
1340
1341    test_impl! { vec_vaddsbs(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [ vaddsbs, vaddsbs ] }
1342    test_impl! { vec_vaddshs(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [ vaddshs, vaddshs ] }
1343    test_impl! { vec_vaddsws(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [ vaddsws, vaddsws ] }
1344    test_impl! { vec_vaddubs(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [ vaddubs, vaddubs ] }
1345    test_impl! { vec_vadduhs(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [ vadduhs, vadduhs ] }
1346    test_impl! { vec_vadduws(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [ vadduws, vadduws ] }
1347
1348    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1349    pub trait VectorAdds<Other> {
1350        type Result;
1351        unsafe fn vec_adds(self, b: Other) -> Self::Result;
1352    }
1353
1354    impl_vec_trait! { [VectorAdds vec_adds] ~(vaddubs, vaddsbs, vadduhs, vaddshs, vadduws, vaddsws) }
1355
1356    test_impl! { vec_vaddcuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vaddcuw, vaddcuw] }
1357
1358    test_impl! { vec_vsubsbs(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [ vsubsbs, vsubsbs ] }
1359    test_impl! { vec_vsubshs(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [ vsubshs, vsubshs ] }
1360    test_impl! { vec_vsubsws(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [ vsubsws, vsubsws ] }
1361    test_impl! { vec_vsububs(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [ vsububs, vsububs ] }
1362    test_impl! { vec_vsubuhs(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [ vsubuhs, vsubuhs ] }
1363    test_impl! { vec_vsubuws(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [ vsubuws, vsubuws ] }
1364
1365    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1366    pub trait VectorSubs<Other> {
1367        type Result;
1368        unsafe fn vec_subs(self, b: Other) -> Self::Result;
1369    }
1370
1371    impl_vec_trait! { [VectorSubs vec_subs] ~(vsububs, vsubsbs, vsubuhs, vsubshs, vsubuws, vsubsws) }
1372
1373    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1374    pub trait VectorAbs {
1375        unsafe fn vec_abs(self) -> Self;
1376    }
1377
1378    macro_rules! impl_abs {
1379        ($name:ident,  $ty: ident) => {
1380            #[inline]
1381            #[target_feature(enable = "altivec")]
1382            unsafe fn $name(v: s_t_l!($ty)) -> s_t_l!($ty) {
1383                v.vec_max(-v)
1384            }
1385
1386            impl_vec_trait! { [VectorAbs vec_abs] $name (s_t_l!($ty)) }
1387        };
1388    }
1389
1390    impl_abs! { vec_abs_i8, i8x16 }
1391    impl_abs! { vec_abs_i16, i16x8 }
1392    impl_abs! { vec_abs_i32, i32x4 }
1393
1394    #[inline]
1395    #[target_feature(enable = "altivec")]
1396    unsafe fn vec_abs_f32(v: vector_float) -> vector_float {
1397        let v: u32x4 = transmute(v);
1398
1399        transmute(simd_and(v, u32x4::splat(0x7FFFFFFF)))
1400    }
1401
1402    impl_vec_trait! { [VectorAbs vec_abs] vec_abs_f32 (vector_float) }
1403
1404    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1405    pub trait VectorAbss {
1406        unsafe fn vec_abss(self) -> Self;
1407    }
1408
1409    macro_rules! impl_abss {
1410        ($name:ident,  $ty: ident) => {
1411            #[inline]
1412            #[target_feature(enable = "altivec")]
1413            unsafe fn $name(v: s_t_l!($ty)) -> s_t_l!($ty) {
1414                let zero: s_t_l!($ty) = transmute(0u8.vec_splats());
1415                v.vec_max(zero.vec_subs(v))
1416            }
1417
1418            impl_vec_trait! { [VectorAbss vec_abss] $name (s_t_l!($ty)) }
1419        };
1420    }
1421
1422    impl_abss! { vec_abss_i8, i8x16 }
1423    impl_abss! { vec_abss_i16, i16x8 }
1424    impl_abss! { vec_abss_i32, i32x4 }
1425
1426    #[inline]
1427    #[target_feature(enable = "altivec")]
1428    #[cfg_attr(test, assert_instr(vspltb, IMM4 = 15))]
1429    unsafe fn vspltb<const IMM4: u32>(a: vector_signed_char) -> vector_signed_char {
1430        static_assert_uimm_bits!(IMM4, 4);
1431        simd_shuffle(a, a, const { u32x16::from_array([IMM4; 16]) })
1432    }
1433
1434    #[inline]
1435    #[target_feature(enable = "altivec")]
1436    #[cfg_attr(test, assert_instr(vsplth, IMM3 = 7))]
1437    unsafe fn vsplth<const IMM3: u32>(a: vector_signed_short) -> vector_signed_short {
1438        static_assert_uimm_bits!(IMM3, 3);
1439        simd_shuffle(a, a, const { u32x8::from_array([IMM3; 8]) })
1440    }
1441
1442    #[inline]
1443    #[target_feature(enable = "altivec")]
1444    #[cfg_attr(all(test, not(target_feature = "vsx")), assert_instr(vspltw, IMM2 = 3))]
1445    #[cfg_attr(all(test, target_feature = "vsx"), assert_instr(xxspltw, IMM2 = 3))]
1446    unsafe fn vspltw<const IMM2: u32>(a: vector_signed_int) -> vector_signed_int {
1447        static_assert_uimm_bits!(IMM2, 2);
1448        simd_shuffle(a, a, const { u32x4::from_array([IMM2; 4]) })
1449    }
1450
1451    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1452    pub trait VectorSplat {
1453        unsafe fn vec_splat<const IMM: u32>(self) -> Self;
1454    }
1455
1456    macro_rules! impl_vec_splat {
1457        ($ty:ty, $fun:ident) => {
1458            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1459            impl VectorSplat for $ty {
1460                #[inline]
1461                #[target_feature(enable = "altivec")]
1462                unsafe fn vec_splat<const IMM: u32>(self) -> Self {
1463                    transmute($fun::<IMM>(transmute(self)))
1464                }
1465            }
1466        };
1467    }
1468
1469    impl_vec_splat! { vector_signed_char, vspltb }
1470    impl_vec_splat! { vector_unsigned_char, vspltb }
1471    impl_vec_splat! { vector_bool_char, vspltb }
1472    impl_vec_splat! { vector_signed_short, vsplth }
1473    impl_vec_splat! { vector_unsigned_short, vsplth }
1474    impl_vec_splat! { vector_bool_short, vsplth }
1475    impl_vec_splat! { vector_signed_int, vspltw }
1476    impl_vec_splat! { vector_unsigned_int, vspltw }
1477    impl_vec_splat! { vector_bool_int, vspltw }
1478
1479    macro_rules! splat {
1480        ($name:ident, $v:ident, $r:ident [$instr_altivec:ident / $instr_pwr9:ident, $doc:literal]) => {
1481            #[doc = $doc]
1482            #[inline]
1483            #[target_feature(enable = "altivec")]
1484            #[cfg_attr(
1485                all(test, not(target_feature = "vsx")),
1486                assert_instr($instr_altivec, IMM5 = 1)
1487            )]
1488            #[cfg_attr(
1489                all(test, target_feature = "power9-vector"),
1490                assert_instr($instr_pwr9, IMM5 = 1)
1491            )]
1492            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1493            pub unsafe fn $name<const IMM5: i8>() -> s_t_l!($r) {
1494                static_assert_simm_bits!(IMM5, 5);
1495                transmute($r::splat(IMM5 as $v))
1496            }
1497        };
1498        ($name:ident, $v:ident, $r:ident [$instr:ident, $doc:literal]) => {
1499            splat! { $name, $v, $r [$instr / $instr, $doc] }
1500        };
1501    }
1502
1503    macro_rules! splats {
1504        ($name:ident, $v:ident, $r:ident) => {
1505            #[inline]
1506            #[target_feature(enable = "altivec")]
1507            unsafe fn $name(v: $v) -> s_t_l!($r) {
1508                transmute($r::splat(v))
1509            }
1510        };
1511    }
1512
1513    splats! { splats_u8, u8, u8x16 }
1514    splats! { splats_u16, u16, u16x8 }
1515    splats! { splats_u32, u32, u32x4 }
1516    splats! { splats_i8, i8, i8x16 }
1517    splats! { splats_i16, i16, i16x8 }
1518    splats! { splats_i32, i32, i32x4 }
1519    splats! { splats_f32, f32, f32x4 }
1520
1521    test_impl! { vec_splats_u8 (v: u8) -> vector_unsigned_char [splats_u8, vspltb] }
1522    test_impl! { vec_splats_u16 (v: u16) -> vector_unsigned_short [splats_u16, vsplth] }
1523    test_impl! { vec_splats_u32 (v: u32) -> vector_unsigned_int [splats_u32, vspltw / xxspltw / mtvsrws] }
1524    test_impl! { vec_splats_i8 (v: i8) -> vector_signed_char [splats_i8, vspltb] }
1525    test_impl! { vec_splats_i16 (v: i16) -> vector_signed_short [splats_i16, vsplth] }
1526    test_impl! { vec_splats_i32 (v: i32) -> vector_signed_int [splats_i32, vspltw / xxspltw / mtvsrws] }
1527    test_impl! { vec_splats_f32 (v: f32) -> vector_float [splats_f32, vspltw / xxspltw / mtvsrws] }
1528
1529    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1530    pub trait VectorSplats {
1531        type Result;
1532        unsafe fn vec_splats(self) -> Self::Result;
1533    }
1534
1535    macro_rules! impl_vec_splats {
1536        ($(($fn:ident ($ty:ty) -> $r:ty)),*) => {
1537            $(
1538                impl_vec_trait!{ [VectorSplats vec_splats] $fn ($ty) -> $r }
1539            )*
1540        }
1541    }
1542
1543    impl_vec_splats! {
1544        (vec_splats_u8 (u8) -> vector_unsigned_char),
1545        (vec_splats_i8 (i8) -> vector_signed_char),
1546        (vec_splats_u16 (u16) -> vector_unsigned_short),
1547        (vec_splats_i16 (i16) -> vector_signed_short),
1548        (vec_splats_u32 (u32) -> vector_unsigned_int),
1549        (vec_splats_i32 (i32) -> vector_signed_int),
1550        (vec_splats_f32 (f32) -> vector_float)
1551    }
1552
1553    test_impl! { vec_vsububm (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [simd_sub, vsububm] }
1554    test_impl! { vec_vsubuhm (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [simd_sub, vsubuhm] }
1555    test_impl! { vec_vsubuwm (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [simd_sub, vsubuwm] }
1556
1557    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1558    pub trait VectorSub<Other> {
1559        type Result;
1560        unsafe fn vec_sub(self, b: Other) -> Self::Result;
1561    }
1562
1563    impl_vec_trait! { [VectorSub vec_sub] ~(simd_sub, simd_sub, simd_sub, simd_sub, simd_sub, simd_sub) }
1564    impl_vec_trait! { [VectorSub vec_sub] simd_sub(vector_float, vector_float) -> vector_float }
1565
1566    test_impl! { vec_vsubcuw (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vsubcuw, vsubcuw] }
1567
1568    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1569    pub trait VectorSubc<Other> {
1570        type Result;
1571        unsafe fn vec_subc(self, b: Other) -> Self::Result;
1572    }
1573
1574    impl_vec_trait! {[VectorSubc vec_subc]+ vec_vsubcuw(vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
1575    impl_vec_trait! {[VectorSubc vec_subc]+ vec_vsubcuw(vector_signed_int, vector_signed_int) -> vector_signed_int }
1576
1577    test_impl! { vec_vminsb (a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [vminsb, vminsb] }
1578    test_impl! { vec_vminsh (a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [vminsh, vminsh] }
1579    test_impl! { vec_vminsw (a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [vminsw, vminsw] }
1580
1581    test_impl! { vec_vminub (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [vminub, vminub] }
1582    test_impl! { vec_vminuh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [vminuh, vminuh] }
1583    test_impl! { vec_vminuw (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vminuw, vminuw] }
1584
1585    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1586    pub trait VectorMin<Other> {
1587        type Result;
1588        unsafe fn vec_min(self, b: Other) -> Self::Result;
1589    }
1590
1591    impl_vec_trait! { [VectorMin vec_min] ~(vminub, vminsb, vminuh, vminsh, vminuw, vminsw) }
1592
1593    test_impl! { vec_vmaxsb (a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [vmaxsb, vmaxsb] }
1594    test_impl! { vec_vmaxsh (a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [vmaxsh, vmaxsh] }
1595    test_impl! { vec_vmaxsw (a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [vmaxsw, vmaxsw] }
1596
1597    test_impl! { vec_vmaxub (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [vmaxub, vmaxub] }
1598    test_impl! { vec_vmaxuh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [vmaxuh, vmaxuh] }
1599    test_impl! { vec_vmaxuw (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vmaxuw, vmaxuw] }
1600
1601    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1602    pub trait VectorMax<Other> {
1603        type Result;
1604        unsafe fn vec_max(self, b: Other) -> Self::Result;
1605    }
1606
1607    impl_vec_trait! { [VectorMax vec_max] ~(vmaxub, vmaxsb, vmaxuh, vmaxsh, vmaxuw, vmaxsw) }
1608
1609    #[inline]
1610    #[target_feature(enable = "altivec")]
1611    #[cfg_attr(test, assert_instr(vmuleub))]
1612    unsafe fn vec_vmuleub(
1613        a: vector_unsigned_char,
1614        b: vector_unsigned_char,
1615    ) -> vector_unsigned_short {
1616        vmuleub(a, b)
1617    }
1618    #[inline]
1619    #[target_feature(enable = "altivec")]
1620    #[cfg_attr(test, assert_instr(vmulesb))]
1621    unsafe fn vec_vmulesb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_short {
1622        vmulesb(a, b)
1623    }
1624    #[inline]
1625    #[target_feature(enable = "altivec")]
1626    #[cfg_attr(test, assert_instr(vmuleuh))]
1627    unsafe fn vec_vmuleuh(
1628        a: vector_unsigned_short,
1629        b: vector_unsigned_short,
1630    ) -> vector_unsigned_int {
1631        vmuleuh(a, b)
1632    }
1633    #[inline]
1634    #[target_feature(enable = "altivec")]
1635    #[cfg_attr(test, assert_instr(vmulesh))]
1636    unsafe fn vec_vmulesh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_int {
1637        vmulesh(a, b)
1638    }
1639
1640    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1641    pub trait VectorMul {
1642        unsafe fn vec_mul(self, b: Self) -> Self;
1643    }
1644
1645    #[inline]
1646    #[target_feature(enable = "altivec")]
1647    #[cfg_attr(test, assert_instr(vmuluwm))]
1648    unsafe fn vec_vmuluwm(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
1649        transmute(simd_mul::<i32x4>(transmute(a), transmute(b)))
1650    }
1651
1652    #[inline]
1653    #[target_feature(enable = "altivec")]
1654    #[cfg_attr(test, assert_instr(xvmulsp))]
1655    unsafe fn vec_xvmulsp(a: vector_float, b: vector_float) -> vector_float {
1656        transmute(simd_mul::<f32x4>(transmute(a), transmute(b)))
1657    }
1658
1659    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1660    impl VectorMul for vector_signed_int {
1661        #[inline]
1662        #[target_feature(enable = "altivec")]
1663        unsafe fn vec_mul(self, b: Self) -> Self {
1664            vec_vmuluwm(self, b)
1665        }
1666    }
1667
1668    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1669    impl VectorMul for vector_unsigned_int {
1670        #[inline]
1671        #[target_feature(enable = "altivec")]
1672        unsafe fn vec_mul(self, b: Self) -> Self {
1673            transmute(simd_mul::<u32x4>(transmute(self), transmute(b)))
1674        }
1675    }
1676
1677    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1678    impl VectorMul for vector_float {
1679        #[inline]
1680        #[target_feature(enable = "altivec")]
1681        unsafe fn vec_mul(self, b: Self) -> Self {
1682            vec_xvmulsp(self, b)
1683        }
1684    }
1685
1686    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1687    pub trait VectorMule<Result> {
1688        unsafe fn vec_mule(self, b: Self) -> Result;
1689    }
1690
1691    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1692    impl VectorMule<vector_unsigned_short> for vector_unsigned_char {
1693        #[inline]
1694        #[target_feature(enable = "altivec")]
1695        unsafe fn vec_mule(self, b: Self) -> vector_unsigned_short {
1696            vmuleub(self, b)
1697        }
1698    }
1699    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1700    impl VectorMule<vector_signed_short> for vector_signed_char {
1701        #[inline]
1702        #[target_feature(enable = "altivec")]
1703        unsafe fn vec_mule(self, b: Self) -> vector_signed_short {
1704            vmulesb(self, b)
1705        }
1706    }
1707    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1708    impl VectorMule<vector_unsigned_int> for vector_unsigned_short {
1709        #[inline]
1710        #[target_feature(enable = "altivec")]
1711        unsafe fn vec_mule(self, b: Self) -> vector_unsigned_int {
1712            vmuleuh(self, b)
1713        }
1714    }
1715    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1716    impl VectorMule<vector_signed_int> for vector_signed_short {
1717        #[inline]
1718        #[target_feature(enable = "altivec")]
1719        unsafe fn vec_mule(self, b: Self) -> vector_signed_int {
1720            vmulesh(self, b)
1721        }
1722    }
1723
1724    #[inline]
1725    #[target_feature(enable = "altivec")]
1726    #[cfg_attr(test, assert_instr(vmuloub))]
1727    unsafe fn vec_vmuloub(
1728        a: vector_unsigned_char,
1729        b: vector_unsigned_char,
1730    ) -> vector_unsigned_short {
1731        vmuloub(a, b)
1732    }
1733    #[inline]
1734    #[target_feature(enable = "altivec")]
1735    #[cfg_attr(test, assert_instr(vmulosb))]
1736    unsafe fn vec_vmulosb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_short {
1737        vmulosb(a, b)
1738    }
1739    #[inline]
1740    #[target_feature(enable = "altivec")]
1741    #[cfg_attr(test, assert_instr(vmulouh))]
1742    unsafe fn vec_vmulouh(
1743        a: vector_unsigned_short,
1744        b: vector_unsigned_short,
1745    ) -> vector_unsigned_int {
1746        vmulouh(a, b)
1747    }
1748    #[inline]
1749    #[target_feature(enable = "altivec")]
1750    #[cfg_attr(test, assert_instr(vmulosh))]
1751    unsafe fn vec_vmulosh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_int {
1752        vmulosh(a, b)
1753    }
1754
1755    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1756    pub trait VectorMulo<Result> {
1757        unsafe fn vec_mulo(self, b: Self) -> Result;
1758    }
1759
1760    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1761    impl VectorMulo<vector_unsigned_short> for vector_unsigned_char {
1762        #[inline]
1763        #[target_feature(enable = "altivec")]
1764        unsafe fn vec_mulo(self, b: Self) -> vector_unsigned_short {
1765            vmuloub(self, b)
1766        }
1767    }
1768    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1769    impl VectorMulo<vector_signed_short> for vector_signed_char {
1770        #[inline]
1771        #[target_feature(enable = "altivec")]
1772        unsafe fn vec_mulo(self, b: Self) -> vector_signed_short {
1773            vmulosb(self, b)
1774        }
1775    }
1776    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1777    impl VectorMulo<vector_unsigned_int> for vector_unsigned_short {
1778        #[inline]
1779        #[target_feature(enable = "altivec")]
1780        unsafe fn vec_mulo(self, b: Self) -> vector_unsigned_int {
1781            vmulouh(self, b)
1782        }
1783    }
1784    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1785    impl VectorMulo<vector_signed_int> for vector_signed_short {
1786        #[inline]
1787        #[target_feature(enable = "altivec")]
1788        unsafe fn vec_mulo(self, b: Self) -> vector_signed_int {
1789            vmulosh(self, b)
1790        }
1791    }
1792
1793    #[inline]
1794    #[target_feature(enable = "altivec")]
1795    #[cfg_attr(test, assert_instr(vsum4ubs))]
1796    unsafe fn vec_vsum4ubs(a: vector_unsigned_char, b: vector_unsigned_int) -> vector_unsigned_int {
1797        vsum4ubs(a, b)
1798    }
1799
1800    #[inline]
1801    #[target_feature(enable = "altivec")]
1802    #[cfg_attr(test, assert_instr(vsum4sbs))]
1803    unsafe fn vec_vsum4sbs(a: vector_signed_char, b: vector_signed_int) -> vector_signed_int {
1804        vsum4sbs(a, b)
1805    }
1806
1807    #[inline]
1808    #[target_feature(enable = "altivec")]
1809    #[cfg_attr(test, assert_instr(vsum4shs))]
1810    unsafe fn vec_vsum4shs(a: vector_signed_short, b: vector_signed_int) -> vector_signed_int {
1811        vsum4shs(a, b)
1812    }
1813
1814    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1815    pub trait VectorSum4s<Other> {
1816        unsafe fn vec_sum4s(self, b: Other) -> Other;
1817    }
1818
1819    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1820    impl VectorSum4s<vector_unsigned_int> for vector_unsigned_char {
1821        #[inline]
1822        #[target_feature(enable = "altivec")]
1823        unsafe fn vec_sum4s(self, b: vector_unsigned_int) -> vector_unsigned_int {
1824            vsum4ubs(self, b)
1825        }
1826    }
1827
1828    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1829    impl VectorSum4s<vector_signed_int> for vector_signed_char {
1830        #[inline]
1831        #[target_feature(enable = "altivec")]
1832        unsafe fn vec_sum4s(self, b: vector_signed_int) -> vector_signed_int {
1833            vsum4sbs(self, b)
1834        }
1835    }
1836
1837    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1838    impl VectorSum4s<vector_signed_int> for vector_signed_short {
1839        #[inline]
1840        #[target_feature(enable = "altivec")]
1841        unsafe fn vec_sum4s(self, b: vector_signed_int) -> vector_signed_int {
1842            vsum4shs(self, b)
1843        }
1844    }
1845
1846    #[inline]
1847    #[target_feature(enable = "altivec")]
1848    #[cfg_attr(test, assert_instr(vsum2sws))]
1849    unsafe fn vec_vsum2sws(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
1850        vsum2sws(a, b)
1851    }
1852
1853    #[inline]
1854    #[target_feature(enable = "altivec")]
1855    #[cfg_attr(test, assert_instr(vnmsubfp))]
1856    unsafe fn vec_vnmsubfp(a: vector_float, b: vector_float, c: vector_float) -> vector_float {
1857        vnmsubfp(a, b, c)
1858    }
1859
1860    #[inline]
1861    #[target_feature(enable = "altivec")]
1862    #[cfg_attr(test, assert_instr(xvmaddasp))]
1863    pub unsafe fn vec_vmaddfp(a: vector_float, b: vector_float, c: vector_float) -> vector_float {
1864        simd_fma(a, b, c)
1865    }
1866
1867    #[inline]
1868    #[target_feature(enable = "altivec")]
1869    #[cfg_attr(test, assert_instr(vmsumubm))]
1870    unsafe fn vec_vmsumubm(
1871        a: vector_unsigned_char,
1872        b: vector_unsigned_char,
1873        c: vector_unsigned_int,
1874    ) -> vector_unsigned_int {
1875        vmsumubm(a, b, c)
1876    }
1877
1878    #[inline]
1879    #[target_feature(enable = "altivec")]
1880    #[cfg_attr(test, assert_instr(vmsummbm))]
1881    unsafe fn vec_vmsummbm(
1882        a: vector_signed_char,
1883        b: vector_unsigned_char,
1884        c: vector_signed_int,
1885    ) -> vector_signed_int {
1886        vmsummbm(a, b, c)
1887    }
1888
1889    #[inline]
1890    #[target_feature(enable = "altivec")]
1891    #[cfg_attr(test, assert_instr(vmsumuhm))]
1892    unsafe fn vec_vmsumuhm(
1893        a: vector_unsigned_short,
1894        b: vector_unsigned_short,
1895        c: vector_unsigned_int,
1896    ) -> vector_unsigned_int {
1897        vmsumuhm(a, b, c)
1898    }
1899
1900    #[inline]
1901    #[target_feature(enable = "altivec")]
1902    #[cfg_attr(test, assert_instr(vmsumshm))]
1903    unsafe fn vec_vmsumshm(
1904        a: vector_signed_short,
1905        b: vector_signed_short,
1906        c: vector_signed_int,
1907    ) -> vector_signed_int {
1908        vmsumshm(a, b, c)
1909    }
1910
1911    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1912    pub trait VectorMsum<B, Other> {
1913        unsafe fn vec_msum(self, b: B, c: Other) -> Other;
1914    }
1915
1916    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1917    impl VectorMsum<vector_unsigned_char, vector_unsigned_int> for vector_unsigned_char {
1918        #[inline]
1919        #[target_feature(enable = "altivec")]
1920        unsafe fn vec_msum(
1921            self,
1922            b: vector_unsigned_char,
1923            c: vector_unsigned_int,
1924        ) -> vector_unsigned_int {
1925            vmsumubm(self, b, c)
1926        }
1927    }
1928
1929    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1930    impl VectorMsum<vector_unsigned_char, vector_signed_int> for vector_signed_char {
1931        #[inline]
1932        #[target_feature(enable = "altivec")]
1933        unsafe fn vec_msum(
1934            self,
1935            b: vector_unsigned_char,
1936            c: vector_signed_int,
1937        ) -> vector_signed_int {
1938            vmsummbm(self, b, c)
1939        }
1940    }
1941
1942    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1943    impl VectorMsum<vector_unsigned_short, vector_unsigned_int> for vector_unsigned_short {
1944        #[inline]
1945        #[target_feature(enable = "altivec")]
1946        unsafe fn vec_msum(
1947            self,
1948            b: vector_unsigned_short,
1949            c: vector_unsigned_int,
1950        ) -> vector_unsigned_int {
1951            vmsumuhm(self, b, c)
1952        }
1953    }
1954
1955    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1956    impl VectorMsum<vector_signed_short, vector_signed_int> for vector_signed_short {
1957        #[inline]
1958        #[target_feature(enable = "altivec")]
1959        unsafe fn vec_msum(
1960            self,
1961            b: vector_signed_short,
1962            c: vector_signed_int,
1963        ) -> vector_signed_int {
1964            vmsumshm(self, b, c)
1965        }
1966    }
1967
1968    #[inline]
1969    #[target_feature(enable = "altivec")]
1970    #[cfg_attr(test, assert_instr(vmsumuhs))]
1971    unsafe fn vec_vmsumuhs(
1972        a: vector_unsigned_short,
1973        b: vector_unsigned_short,
1974        c: vector_unsigned_int,
1975    ) -> vector_unsigned_int {
1976        vmsumuhs(a, b, c)
1977    }
1978
1979    #[inline]
1980    #[target_feature(enable = "altivec")]
1981    #[cfg_attr(test, assert_instr(vmsumshs))]
1982    unsafe fn vec_vmsumshs(
1983        a: vector_signed_short,
1984        b: vector_signed_short,
1985        c: vector_signed_int,
1986    ) -> vector_signed_int {
1987        vmsumshs(a, b, c)
1988    }
1989
1990    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1991    pub trait VectorMsums<Other> {
1992        unsafe fn vec_msums(self, b: Self, c: Other) -> Other;
1993    }
1994
1995    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
1996    impl VectorMsums<vector_unsigned_int> for vector_unsigned_short {
1997        #[inline]
1998        #[target_feature(enable = "altivec")]
1999        unsafe fn vec_msums(self, b: Self, c: vector_unsigned_int) -> vector_unsigned_int {
2000            vmsumuhs(self, b, c)
2001        }
2002    }
2003
2004    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2005    impl VectorMsums<vector_signed_int> for vector_signed_short {
2006        #[inline]
2007        #[target_feature(enable = "altivec")]
2008        unsafe fn vec_msums(self, b: Self, c: vector_signed_int) -> vector_signed_int {
2009            vmsumshs(self, b, c)
2010        }
2011    }
2012
2013    #[inline]
2014    #[target_feature(enable = "altivec")]
2015    #[cfg_attr(test, assert_instr(vperm))]
2016    unsafe fn vec_vperm(
2017        a: vector_signed_int,
2018        b: vector_signed_int,
2019        c: vector_unsigned_char,
2020    ) -> vector_signed_int {
2021        vperm(a, b, c)
2022    }
2023
2024    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2025    pub trait VectorPerm {
2026        unsafe fn vec_vperm(self, b: Self, c: vector_unsigned_char) -> Self;
2027    }
2028
2029    macro_rules! vector_perm {
2030        {$impl: ident} => {
2031            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2032            impl VectorPerm for $impl {
2033            #[inline]
2034            #[target_feature(enable = "altivec")]
2035            unsafe fn vec_vperm(self, b: Self, c: vector_unsigned_char) -> Self {
2036                    transmute(vec_vperm(transmute(self), transmute(b), c))
2037                }
2038            }
2039        }
2040    }
2041
2042    vector_perm! { vector_signed_char }
2043    vector_perm! { vector_unsigned_char }
2044    vector_perm! { vector_bool_char }
2045
2046    vector_perm! { vector_signed_short }
2047    vector_perm! { vector_unsigned_short }
2048    vector_perm! { vector_bool_short }
2049
2050    vector_perm! { vector_signed_int }
2051    vector_perm! { vector_unsigned_int }
2052    vector_perm! { vector_bool_int }
2053
2054    vector_perm! { vector_float }
2055
2056    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2057    pub trait VectorAdd<Other> {
2058        type Result;
2059        unsafe fn vec_add(self, other: Other) -> Self::Result;
2060    }
2061
2062    #[inline]
2063    #[target_feature(enable = "altivec")]
2064    #[cfg_attr(test, assert_instr(vaddubm))]
2065    pub unsafe fn vec_add_bc_sc(a: vector_bool_char, b: vector_signed_char) -> vector_signed_char {
2066        simd_add(transmute(a), b)
2067    }
2068    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2069    impl VectorAdd<vector_signed_char> for vector_bool_char {
2070        type Result = vector_signed_char;
2071        #[inline]
2072        #[target_feature(enable = "altivec")]
2073        unsafe fn vec_add(self, other: vector_signed_char) -> Self::Result {
2074            vec_add_bc_sc(self, other)
2075        }
2076    }
2077    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2078    impl VectorAdd<vector_bool_char> for vector_signed_char {
2079        type Result = vector_signed_char;
2080        #[inline]
2081        #[target_feature(enable = "altivec")]
2082        unsafe fn vec_add(self, other: vector_bool_char) -> Self::Result {
2083            other.vec_add(self)
2084        }
2085    }
2086
2087    #[inline]
2088    #[target_feature(enable = "altivec")]
2089    #[cfg_attr(test, assert_instr(vaddubm))]
2090    pub unsafe fn vec_add_sc_sc(
2091        a: vector_signed_char,
2092        b: vector_signed_char,
2093    ) -> vector_signed_char {
2094        simd_add(a, b)
2095    }
2096    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2097    impl VectorAdd<vector_signed_char> for vector_signed_char {
2098        type Result = vector_signed_char;
2099        #[inline]
2100        #[target_feature(enable = "altivec")]
2101        unsafe fn vec_add(self, other: vector_signed_char) -> Self::Result {
2102            vec_add_sc_sc(self, other)
2103        }
2104    }
2105
2106    #[inline]
2107    #[target_feature(enable = "altivec")]
2108    #[cfg_attr(test, assert_instr(vaddubm))]
2109    pub unsafe fn vec_add_bc_uc(
2110        a: vector_bool_char,
2111        b: vector_unsigned_char,
2112    ) -> vector_unsigned_char {
2113        simd_add(transmute(a), b)
2114    }
2115    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2116    impl VectorAdd<vector_unsigned_char> for vector_bool_char {
2117        type Result = vector_unsigned_char;
2118        #[inline]
2119        #[target_feature(enable = "altivec")]
2120        unsafe fn vec_add(self, other: vector_unsigned_char) -> Self::Result {
2121            vec_add_bc_uc(self, other)
2122        }
2123    }
2124    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2125    impl VectorAdd<vector_bool_char> for vector_unsigned_char {
2126        type Result = vector_unsigned_char;
2127        #[inline]
2128        #[target_feature(enable = "altivec")]
2129        unsafe fn vec_add(self, other: vector_bool_char) -> Self::Result {
2130            other.vec_add(self)
2131        }
2132    }
2133
2134    #[inline]
2135    #[target_feature(enable = "altivec")]
2136    #[cfg_attr(test, assert_instr(vaddubm))]
2137    pub unsafe fn vec_add_uc_uc(
2138        a: vector_unsigned_char,
2139        b: vector_unsigned_char,
2140    ) -> vector_unsigned_char {
2141        simd_add(a, b)
2142    }
2143    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2144    impl VectorAdd<vector_unsigned_char> for vector_unsigned_char {
2145        type Result = vector_unsigned_char;
2146        #[inline]
2147        #[target_feature(enable = "altivec")]
2148        unsafe fn vec_add(self, other: vector_unsigned_char) -> Self::Result {
2149            vec_add_uc_uc(self, other)
2150        }
2151    }
2152
2153    #[inline]
2154    #[target_feature(enable = "altivec")]
2155    #[cfg_attr(test, assert_instr(vadduhm))]
2156    pub unsafe fn vec_add_bs_ss(
2157        a: vector_bool_short,
2158        b: vector_signed_short,
2159    ) -> vector_signed_short {
2160        let a: i16x8 = transmute(a);
2161        let a: vector_signed_short = simd_cast(a);
2162        simd_add(a, b)
2163    }
2164
2165    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2166    impl VectorAdd<vector_signed_short> for vector_bool_short {
2167        type Result = vector_signed_short;
2168        #[inline]
2169        #[target_feature(enable = "altivec")]
2170        unsafe fn vec_add(self, other: vector_signed_short) -> Self::Result {
2171            vec_add_bs_ss(self, other)
2172        }
2173    }
2174    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2175    impl VectorAdd<vector_bool_short> for vector_signed_short {
2176        type Result = vector_signed_short;
2177        #[inline]
2178        #[target_feature(enable = "altivec")]
2179        unsafe fn vec_add(self, other: vector_bool_short) -> Self::Result {
2180            other.vec_add(self)
2181        }
2182    }
2183
2184    #[inline]
2185    #[target_feature(enable = "altivec")]
2186    #[cfg_attr(test, assert_instr(vadduhm))]
2187    pub unsafe fn vec_add_ss_ss(
2188        a: vector_signed_short,
2189        b: vector_signed_short,
2190    ) -> vector_signed_short {
2191        simd_add(a, b)
2192    }
2193    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2194    impl VectorAdd<vector_signed_short> for vector_signed_short {
2195        type Result = vector_signed_short;
2196        #[inline]
2197        #[target_feature(enable = "altivec")]
2198        unsafe fn vec_add(self, other: vector_signed_short) -> Self::Result {
2199            vec_add_ss_ss(self, other)
2200        }
2201    }
2202
2203    #[inline]
2204    #[target_feature(enable = "altivec")]
2205    #[cfg_attr(test, assert_instr(vadduhm))]
2206    pub unsafe fn vec_add_bs_us(
2207        a: vector_bool_short,
2208        b: vector_unsigned_short,
2209    ) -> vector_unsigned_short {
2210        let a: i16x8 = transmute(a);
2211        let a: vector_unsigned_short = simd_cast(a);
2212        simd_add(a, b)
2213    }
2214    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2215    impl VectorAdd<vector_unsigned_short> for vector_bool_short {
2216        type Result = vector_unsigned_short;
2217        #[inline]
2218        #[target_feature(enable = "altivec")]
2219        unsafe fn vec_add(self, other: vector_unsigned_short) -> Self::Result {
2220            vec_add_bs_us(self, other)
2221        }
2222    }
2223    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2224    impl VectorAdd<vector_bool_short> for vector_unsigned_short {
2225        type Result = vector_unsigned_short;
2226        #[inline]
2227        #[target_feature(enable = "altivec")]
2228        unsafe fn vec_add(self, other: vector_bool_short) -> Self::Result {
2229            other.vec_add(self)
2230        }
2231    }
2232
2233    #[inline]
2234    #[target_feature(enable = "altivec")]
2235    #[cfg_attr(test, assert_instr(vadduhm))]
2236    pub unsafe fn vec_add_us_us(
2237        a: vector_unsigned_short,
2238        b: vector_unsigned_short,
2239    ) -> vector_unsigned_short {
2240        simd_add(a, b)
2241    }
2242
2243    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2244    impl VectorAdd<vector_unsigned_short> for vector_unsigned_short {
2245        type Result = vector_unsigned_short;
2246        #[inline]
2247        #[target_feature(enable = "altivec")]
2248        unsafe fn vec_add(self, other: vector_unsigned_short) -> Self::Result {
2249            vec_add_us_us(self, other)
2250        }
2251    }
2252
2253    #[inline]
2254    #[target_feature(enable = "altivec")]
2255    #[cfg_attr(test, assert_instr(vadduwm))]
2256    pub unsafe fn vec_add_bi_si(a: vector_bool_int, b: vector_signed_int) -> vector_signed_int {
2257        let a: i32x4 = transmute(a);
2258        let a: vector_signed_int = simd_cast(a);
2259        simd_add(a, b)
2260    }
2261    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2262    impl VectorAdd<vector_signed_int> for vector_bool_int {
2263        type Result = vector_signed_int;
2264        #[inline]
2265        #[target_feature(enable = "altivec")]
2266        unsafe fn vec_add(self, other: vector_signed_int) -> Self::Result {
2267            vec_add_bi_si(self, other)
2268        }
2269    }
2270    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2271    impl VectorAdd<vector_bool_int> for vector_signed_int {
2272        type Result = vector_signed_int;
2273        #[inline]
2274        #[target_feature(enable = "altivec")]
2275        unsafe fn vec_add(self, other: vector_bool_int) -> Self::Result {
2276            other.vec_add(self)
2277        }
2278    }
2279
2280    #[inline]
2281    #[target_feature(enable = "altivec")]
2282    #[cfg_attr(test, assert_instr(vadduwm))]
2283    pub unsafe fn vec_add_si_si(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
2284        simd_add(a, b)
2285    }
2286    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2287    impl VectorAdd<vector_signed_int> for vector_signed_int {
2288        type Result = vector_signed_int;
2289        #[inline]
2290        #[target_feature(enable = "altivec")]
2291        unsafe fn vec_add(self, other: vector_signed_int) -> Self::Result {
2292            vec_add_si_si(self, other)
2293        }
2294    }
2295
2296    #[inline]
2297    #[target_feature(enable = "altivec")]
2298    #[cfg_attr(test, assert_instr(vadduwm))]
2299    pub unsafe fn vec_add_bi_ui(a: vector_bool_int, b: vector_unsigned_int) -> vector_unsigned_int {
2300        let a: i32x4 = transmute(a);
2301        let a: vector_unsigned_int = simd_cast(a);
2302        simd_add(a, b)
2303    }
2304    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2305    impl VectorAdd<vector_unsigned_int> for vector_bool_int {
2306        type Result = vector_unsigned_int;
2307        #[inline]
2308        #[target_feature(enable = "altivec")]
2309        unsafe fn vec_add(self, other: vector_unsigned_int) -> Self::Result {
2310            vec_add_bi_ui(self, other)
2311        }
2312    }
2313    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2314    impl VectorAdd<vector_bool_int> for vector_unsigned_int {
2315        type Result = vector_unsigned_int;
2316        #[inline]
2317        #[target_feature(enable = "altivec")]
2318        unsafe fn vec_add(self, other: vector_bool_int) -> Self::Result {
2319            other.vec_add(self)
2320        }
2321    }
2322
2323    #[inline]
2324    #[target_feature(enable = "altivec")]
2325    #[cfg_attr(test, assert_instr(vadduwm))]
2326    pub unsafe fn vec_add_ui_ui(
2327        a: vector_unsigned_int,
2328        b: vector_unsigned_int,
2329    ) -> vector_unsigned_int {
2330        simd_add(a, b)
2331    }
2332    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2333    impl VectorAdd<vector_unsigned_int> for vector_unsigned_int {
2334        type Result = vector_unsigned_int;
2335        #[inline]
2336        #[target_feature(enable = "altivec")]
2337        unsafe fn vec_add(self, other: vector_unsigned_int) -> Self::Result {
2338            vec_add_ui_ui(self, other)
2339        }
2340    }
2341
2342    #[inline]
2343    #[target_feature(enable = "altivec")]
2344    #[cfg_attr(test, assert_instr(xvaddsp))]
2345    pub unsafe fn vec_add_float_float(a: vector_float, b: vector_float) -> vector_float {
2346        simd_add(a, b)
2347    }
2348
2349    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2350    impl VectorAdd<vector_float> for vector_float {
2351        type Result = vector_float;
2352        #[inline]
2353        #[target_feature(enable = "altivec")]
2354        unsafe fn vec_add(self, other: vector_float) -> Self::Result {
2355            vec_add_float_float(self, other)
2356        }
2357    }
2358
2359    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2360    pub trait VectorAdde {
2361        unsafe fn vec_adde(self, b: Self, c: Self) -> Self;
2362    }
2363
2364    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2365    impl VectorAdde for vector_unsigned_int {
2366        #[inline]
2367        #[target_feature(enable = "altivec")]
2368        unsafe fn vec_adde(self, b: Self, c: Self) -> Self {
2369            let mask: vector_unsigned_int = transmute(u32x4::new(1, 1, 1, 1));
2370            let carry = vec_and(c, mask);
2371            vec_add(vec_add(self, b), carry)
2372        }
2373    }
2374
2375    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2376    impl VectorAdde for vector_signed_int {
2377        #[inline]
2378        #[target_feature(enable = "altivec")]
2379        unsafe fn vec_adde(self, b: Self, c: Self) -> Self {
2380            let mask: vector_signed_int = transmute(i32x4::new(1, 1, 1, 1));
2381            let carry = vec_and(c, mask);
2382            vec_add(vec_add(self, b), carry)
2383        }
2384    }
2385
2386    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2387    pub trait VectorMladd<Other> {
2388        type Result;
2389        unsafe fn vec_mladd(self, b: Other, c: Other) -> Self::Result;
2390    }
2391
2392    #[inline]
2393    #[target_feature(enable = "altivec")]
2394    #[cfg_attr(test, assert_instr(vmladduhm))]
2395    unsafe fn mladd(
2396        a: vector_signed_short,
2397        b: vector_signed_short,
2398        c: vector_signed_short,
2399    ) -> vector_signed_short {
2400        let a: i16x8 = transmute(a);
2401        let b: i16x8 = transmute(b);
2402        let c: i16x8 = transmute(c);
2403        transmute(simd_add(simd_mul(a, b), c))
2404    }
2405
2406    macro_rules! vector_mladd {
2407        ($a: ident, $bc: ident, $d: ident) => {
2408            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2409            impl VectorMladd<$bc> for $a {
2410                type Result = $d;
2411                #[inline]
2412                #[target_feature(enable = "altivec")]
2413                unsafe fn vec_mladd(self, b: $bc, c: $bc) -> Self::Result {
2414                    let a = transmute(self);
2415                    let b = transmute(b);
2416                    let c = transmute(c);
2417
2418                    transmute(mladd(a, b, c))
2419                }
2420            }
2421        };
2422    }
2423
2424    vector_mladd! { vector_unsigned_short, vector_unsigned_short, vector_unsigned_short }
2425    vector_mladd! { vector_unsigned_short, vector_signed_short, vector_signed_short }
2426    vector_mladd! { vector_signed_short, vector_unsigned_short, vector_signed_short }
2427    vector_mladd! { vector_signed_short, vector_signed_short, vector_signed_short }
2428
2429    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2430    pub trait VectorOr<Other> {
2431        type Result;
2432        unsafe fn vec_or(self, b: Other) -> Self::Result;
2433    }
2434
2435    impl_vec_trait! { [VectorOr vec_or] ~(simd_or) }
2436
2437    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2438    pub trait VectorXor<Other> {
2439        type Result;
2440        unsafe fn vec_xor(self, b: Other) -> Self::Result;
2441    }
2442
2443    impl_vec_trait! { [VectorXor vec_xor] ~(simd_xor) }
2444
2445    macro_rules! vector_vnor {
2446        ($fun:ident $ty:ident) => {
2447            #[inline]
2448            #[target_feature(enable = "altivec")]
2449            #[cfg_attr(all(test, not(target_feature = "vsx")), assert_instr(vnor))]
2450            #[cfg_attr(all(test, target_feature = "vsx"), assert_instr(xxlnor))]
2451            pub unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) {
2452                let o = vec_splats(!0 as $ty);
2453                vec_xor(vec_or(a, b), o)
2454            }
2455        };
2456    }
2457
2458    vector_vnor! { vec_vnorsb i8 }
2459    vector_vnor! { vec_vnorsh i16 }
2460    vector_vnor! { vec_vnorsw i32 }
2461
2462    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2463    pub trait VectorNor<Other> {
2464        type Result;
2465        unsafe fn vec_nor(self, b: Other) -> Self::Result;
2466    }
2467
2468    impl_vec_trait! { [VectorNor vec_nor]+ 2b (vec_vnorsb, vec_vnorsh, vec_vnorsw) }
2469
2470    macro_rules! vector_vnand {
2471        ($fun:ident $ty:ident) => {
2472            #[inline]
2473            #[target_feature(enable = "altivec")]
2474            #[cfg_attr(all(test, not(target_feature = "vsx")), assert_instr(vnand))]
2475            #[cfg_attr(all(test, target_feature = "vsx"), assert_instr(xxlnand))]
2476            pub unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) {
2477                let o = vec_splats(!0 as $ty);
2478                vec_xor(vec_and(a, b), o)
2479            }
2480        };
2481    }
2482
2483    vector_vnand! { vec_vnandsb i8 }
2484    vector_vnand! { vec_vnandsh i16 }
2485    vector_vnand! { vec_vnandsw i32 }
2486
2487    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2488    pub trait VectorNand<Other> {
2489        type Result;
2490        unsafe fn vec_nand(self, b: Other) -> Self::Result;
2491    }
2492
2493    impl_vec_trait! { [VectorNand vec_nand]+ 2b (vec_vnandsb, vec_vnandsh, vec_vnandsw) }
2494
2495    #[inline]
2496    #[target_feature(enable = "altivec")]
2497    #[cfg_attr(all(test, not(target_feature = "vsx")), assert_instr(vsel))]
2498    #[cfg_attr(all(test, target_feature = "vsx"), assert_instr(xxsel))]
2499    pub unsafe fn vec_vsel(
2500        a: vector_signed_char,
2501        b: vector_signed_char,
2502        c: vector_signed_char,
2503    ) -> vector_signed_char {
2504        let a: i8x16 = transmute(a);
2505        let b: i8x16 = transmute(b);
2506        let c: i8x16 = transmute(c);
2507        let not_c = simd_xor(c, i8x16::splat(!0));
2508
2509        transmute(simd_or(simd_and(a, not_c), simd_and(b, c)))
2510    }
2511
2512    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2513    pub trait VectorSel<Mask> {
2514        unsafe fn vec_sel(self, b: Self, c: Mask) -> Self;
2515    }
2516
2517    macro_rules! vector_sel {
2518        ($ty: ty, $m: ty) => {
2519            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2520            impl VectorSel<$m> for $ty {
2521                #[inline]
2522                #[target_feature(enable = "altivec")]
2523                unsafe fn vec_sel(self, b: Self, c: $m) -> Self {
2524                    let a = transmute(self);
2525                    let b = transmute(b);
2526                    let c = transmute(c);
2527
2528                    transmute(vec_vsel(a, b, c))
2529                }
2530            }
2531        };
2532        ($ty: ident) => {
2533            vector_sel! { $ty, t_b!{ $ty } }
2534            vector_sel! { $ty, t_u!{ $ty } }
2535            vector_sel! { t_u!{ $ty }, t_b!{ $ty } }
2536            vector_sel! { t_u!{ $ty }, t_u!{ $ty } }
2537            vector_sel! { t_b!{ $ty }, t_b!{ $ty } }
2538            vector_sel! { t_b!{ $ty }, t_u!{ $ty } }
2539        };
2540        (- $ty: ident) => {
2541            vector_sel! { $ty, t_b!{ $ty } }
2542            vector_sel! { $ty, t_u!{ $ty } }
2543        };
2544    }
2545
2546    vector_sel! { vector_signed_char }
2547    vector_sel! { vector_signed_short }
2548    vector_sel! { vector_signed_int }
2549    vector_sel! {- vector_float }
2550
2551    #[inline]
2552    #[target_feature(enable = "altivec")]
2553    #[cfg_attr(test, assert_instr(vcfsx, IMM5 = 1))]
2554    unsafe fn vec_ctf_i32<const IMM5: i32>(a: vector_signed_int) -> vector_float {
2555        static_assert_uimm_bits!(IMM5, 5);
2556        vcfsx(a, IMM5)
2557    }
2558
2559    #[inline]
2560    #[target_feature(enable = "altivec")]
2561    #[cfg_attr(test, assert_instr(vcfux, IMM5 = 1))]
2562    unsafe fn vec_ctf_u32<const IMM5: i32>(a: vector_unsigned_int) -> vector_float {
2563        static_assert_uimm_bits!(IMM5, 5);
2564        vcfux(a, IMM5)
2565    }
2566
2567    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2568    pub trait VectorCtf {
2569        unsafe fn vec_ctf<const IMM5: i32>(self) -> vector_float;
2570    }
2571
2572    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2573    impl VectorCtf for vector_signed_int {
2574        unsafe fn vec_ctf<const IMM5: i32>(self) -> vector_float {
2575            vec_ctf_i32::<IMM5>(self)
2576        }
2577    }
2578
2579    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2580    impl VectorCtf for vector_unsigned_int {
2581        unsafe fn vec_ctf<const IMM5: i32>(self) -> vector_float {
2582            vec_ctf_u32::<IMM5>(self)
2583        }
2584    }
2585
2586    #[inline]
2587    #[target_feature(enable = "altivec")]
2588    #[cfg_attr(all(test, target_endian = "little"), assert_instr(vmrghb))]
2589    #[cfg_attr(all(test, target_endian = "big"), assert_instr(vmrglb))]
2590    unsafe fn vec_vmrglb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
2591        let mergel_perm = transmute(u8x16::new(
2592            0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E,
2593            0x0F, 0x1F,
2594        ));
2595        vec_perm(a, b, mergel_perm)
2596    }
2597
2598    #[inline]
2599    #[target_feature(enable = "altivec")]
2600    #[cfg_attr(all(test, target_endian = "little"), assert_instr(vmrghh))]
2601    #[cfg_attr(all(test, target_endian = "big"), assert_instr(vmrglh))]
2602    unsafe fn vec_vmrglh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short {
2603        let mergel_perm = transmute(u8x16::new(
2604            0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B, 0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F,
2605            0x1E, 0x1F,
2606        ));
2607        vec_perm(a, b, mergel_perm)
2608    }
2609
2610    #[inline]
2611    #[target_feature(enable = "altivec")]
2612    #[cfg_attr(
2613        all(test, target_endian = "little", not(target_feature = "vsx")),
2614        assert_instr(vmrghw)
2615    )]
2616    #[cfg_attr(
2617        all(test, target_endian = "little", target_feature = "vsx"),
2618        assert_instr(xxmrghw)
2619    )]
2620    #[cfg_attr(
2621        all(test, target_endian = "big", not(target_feature = "vsx")),
2622        assert_instr(vmrglw)
2623    )]
2624    #[cfg_attr(
2625        all(test, target_endian = "big", target_feature = "vsx"),
2626        assert_instr(xxmrglw)
2627    )]
2628    unsafe fn vec_vmrglw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
2629        let mergel_perm = transmute(u8x16::new(
2630            0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D,
2631            0x1E, 0x1F,
2632        ));
2633        vec_perm(a, b, mergel_perm)
2634    }
2635
2636    #[inline]
2637    #[target_feature(enable = "altivec")]
2638    #[cfg_attr(all(test, target_endian = "little"), assert_instr(vmrglb))]
2639    #[cfg_attr(all(test, target_endian = "big"), assert_instr(vmrghb))]
2640    unsafe fn vec_vmrghb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
2641        let mergel_perm = transmute(u8x16::new(
2642            0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 0x04, 0x14, 0x05, 0x15, 0x06, 0x16,
2643            0x07, 0x17,
2644        ));
2645        vec_perm(a, b, mergel_perm)
2646    }
2647
2648    #[inline]
2649    #[target_feature(enable = "altivec")]
2650    #[cfg_attr(all(test, target_endian = "little"), assert_instr(vmrglh))]
2651    #[cfg_attr(all(test, target_endian = "big"), assert_instr(vmrghh))]
2652    unsafe fn vec_vmrghh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_short {
2653        let mergel_perm = transmute(u8x16::new(
2654            0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, 0x06, 0x07,
2655            0x16, 0x17,
2656        ));
2657        vec_perm(a, b, mergel_perm)
2658    }
2659
2660    #[inline]
2661    #[target_feature(enable = "altivec")]
2662    #[cfg_attr(
2663        all(test, target_endian = "little", not(target_feature = "vsx")),
2664        assert_instr(vmrglw)
2665    )]
2666    #[cfg_attr(
2667        all(test, target_endian = "little", target_feature = "vsx"),
2668        assert_instr(xxmrglw)
2669    )]
2670    #[cfg_attr(
2671        all(test, target_endian = "big", not(target_feature = "vsx")),
2672        assert_instr(vmrghw)
2673    )]
2674    #[cfg_attr(
2675        all(test, target_endian = "big", target_feature = "vsx"),
2676        assert_instr(xxmrghw)
2677    )]
2678    unsafe fn vec_vmrghw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
2679        let mergel_perm = transmute(u8x16::new(
2680            0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, 0x14, 0x15,
2681            0x16, 0x17,
2682        ));
2683        vec_perm(a, b, mergel_perm)
2684    }
2685
2686    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2687    pub trait VectorMergeh<Other> {
2688        type Result;
2689        unsafe fn vec_mergeh(self, b: Other) -> Self::Result;
2690    }
2691
2692    impl_vec_trait! { [VectorMergeh vec_mergeh]+ 2b (vec_vmrghb, vec_vmrghh, vec_vmrghw) }
2693    impl_vec_trait! { [VectorMergeh vec_mergeh]+ vec_vmrghw (vector_float, vector_float) -> vector_float }
2694
2695    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2696    pub trait VectorMergel<Other> {
2697        type Result;
2698        unsafe fn vec_mergel(self, b: Other) -> Self::Result;
2699    }
2700
2701    impl_vec_trait! { [VectorMergel vec_mergel]+ 2b (vec_vmrglb, vec_vmrglh, vec_vmrglw) }
2702    impl_vec_trait! { [VectorMergel vec_mergel]+ vec_vmrglw (vector_float, vector_float) -> vector_float }
2703
2704    #[inline]
2705    #[target_feature(enable = "altivec")]
2706    #[cfg_attr(test, assert_instr(vpkuhum))]
2707    unsafe fn vec_vpkuhum(a: vector_signed_short, b: vector_signed_short) -> vector_signed_char {
2708        let pack_perm = if cfg!(target_endian = "little") {
2709            transmute(u8x16::new(
2710                0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A,
2711                0x1C, 0x1E,
2712            ))
2713        } else {
2714            transmute(u8x16::new(
2715                0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B,
2716                0x1D, 0x1F,
2717            ))
2718        };
2719
2720        transmute(vec_perm(a, b, pack_perm))
2721    }
2722
2723    #[inline]
2724    #[target_feature(enable = "altivec")]
2725    #[cfg_attr(test, assert_instr(vpkuwum))]
2726    unsafe fn vec_vpkuwum(a: vector_signed_int, b: vector_signed_int) -> vector_signed_short {
2727        let pack_perm = if cfg!(target_endian = "little") {
2728            transmute(u8x16::new(
2729                0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D, 0x10, 0x11, 0x14, 0x15, 0x18, 0x19,
2730                0x1C, 0x1D,
2731            ))
2732        } else {
2733            transmute(u8x16::new(
2734                0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F, 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B,
2735                0x1E, 0x1F,
2736            ))
2737        };
2738
2739        transmute(vec_perm(a, b, pack_perm))
2740    }
2741
2742    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2743    pub trait VectorPack<Other> {
2744        type Result;
2745        unsafe fn vec_pack(self, b: Other) -> Self::Result;
2746    }
2747
2748    impl_vec_trait! { [VectorPack vec_pack]+ vec_vpkuhum (vector_signed_short, vector_signed_short) -> vector_signed_char }
2749    impl_vec_trait! { [VectorPack vec_pack]+ vec_vpkuhum (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_char }
2750    impl_vec_trait! { [VectorPack vec_pack]+ vec_vpkuhum (vector_bool_short, vector_bool_short) -> vector_bool_char }
2751    impl_vec_trait! { [VectorPack vec_pack]+ vec_vpkuwum (vector_signed_int, vector_signed_int) -> vector_signed_short }
2752    impl_vec_trait! { [VectorPack vec_pack]+ vec_vpkuwum (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_short }
2753    impl_vec_trait! { [VectorPack vec_pack]+ vec_vpkuwum (vector_bool_int, vector_bool_int) -> vector_bool_short }
2754
2755    #[inline]
2756    #[target_feature(enable = "altivec")]
2757    #[cfg_attr(test, assert_instr(vpkshss))]
2758    unsafe fn vec_vpkshss(a: vector_signed_short, b: vector_signed_short) -> vector_signed_char {
2759        if cfg!(target_endian = "little") {
2760            vpkshss(b, a)
2761        } else {
2762            vpkshss(a, b)
2763        }
2764    }
2765
2766    #[inline]
2767    #[target_feature(enable = "altivec")]
2768    #[cfg_attr(test, assert_instr(vpkshus))]
2769    unsafe fn vec_vpkshus(a: vector_signed_short, b: vector_signed_short) -> vector_unsigned_char {
2770        if cfg!(target_endian = "little") {
2771            vpkshus(b, a)
2772        } else {
2773            vpkshus(a, b)
2774        }
2775    }
2776
2777    #[inline]
2778    #[target_feature(enable = "altivec")]
2779    #[cfg_attr(test, assert_instr(vpkuhus))]
2780    unsafe fn vec_vpkuhus(
2781        a: vector_unsigned_short,
2782        b: vector_unsigned_short,
2783    ) -> vector_unsigned_char {
2784        if cfg!(target_endian = "little") {
2785            vpkuhus(b, a)
2786        } else {
2787            vpkuhus(a, b)
2788        }
2789    }
2790
2791    #[inline]
2792    #[target_feature(enable = "altivec")]
2793    #[cfg_attr(test, assert_instr(vpkswss))]
2794    unsafe fn vec_vpkswss(a: vector_signed_int, b: vector_signed_int) -> vector_signed_short {
2795        if cfg!(target_endian = "little") {
2796            vpkswss(b, a)
2797        } else {
2798            vpkswss(a, b)
2799        }
2800    }
2801
2802    #[inline]
2803    #[target_feature(enable = "altivec")]
2804    #[cfg_attr(test, assert_instr(vpkswus))]
2805    unsafe fn vec_vpkswus(a: vector_signed_int, b: vector_signed_int) -> vector_unsigned_short {
2806        if cfg!(target_endian = "little") {
2807            vpkswus(b, a)
2808        } else {
2809            vpkswus(a, b)
2810        }
2811    }
2812
2813    #[inline]
2814    #[target_feature(enable = "altivec")]
2815    #[cfg_attr(test, assert_instr(vpkuwus))]
2816    unsafe fn vec_vpkuwus(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_short {
2817        if cfg!(target_endian = "little") {
2818            vpkuwus(b, a)
2819        } else {
2820            vpkuwus(a, b)
2821        }
2822    }
2823
2824    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2825    pub trait VectorPacks<Other> {
2826        type Result;
2827        unsafe fn vec_packs(self, b: Other) -> Self::Result;
2828    }
2829
2830    impl_vec_trait! { [VectorPacks vec_packs] vec_vpkshss (vector_signed_short, vector_signed_short) -> vector_signed_char }
2831    impl_vec_trait! { [VectorPacks vec_packs] vec_vpkuhus (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_char }
2832    impl_vec_trait! { [VectorPacks vec_packs] vec_vpkswss (vector_signed_int, vector_signed_int) -> vector_signed_short }
2833    impl_vec_trait! { [VectorPacks vec_packs] vec_vpkuwus (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_short }
2834
2835    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2836    pub trait VectorPacksu<Other> {
2837        type Result;
2838        unsafe fn vec_packsu(self, b: Other) -> Self::Result;
2839    }
2840
2841    impl_vec_trait! { [VectorPacksu vec_packsu] vec_vpkshus (vector_signed_short, vector_signed_short) -> vector_unsigned_char }
2842    impl_vec_trait! { [VectorPacksu vec_packsu] vec_vpkuhus (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_char }
2843    impl_vec_trait! { [VectorPacksu vec_packsu] vec_vpkswus (vector_signed_int, vector_signed_int) -> vector_unsigned_short }
2844    impl_vec_trait! { [VectorPacksu vec_packsu] vec_vpkuwus (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_short }
2845
2846    macro_rules! impl_vec_unpack {
2847        ($fun:ident ($a:ident) -> $r:ident [$little:ident, $big:ident]) => {
2848            #[inline]
2849            #[target_feature(enable = "altivec")]
2850            #[cfg_attr(all(test, target_endian = "little"), assert_instr($little))]
2851            #[cfg_attr(all(test, target_endian = "big"), assert_instr($big))]
2852            unsafe fn $fun(a: $a) -> $r {
2853                if cfg!(target_endian = "little") {
2854                    $little(a)
2855                } else {
2856                    $big(a)
2857                }
2858            }
2859        };
2860    }
2861
2862    impl_vec_unpack! { vec_vupkhsb (vector_signed_char) -> vector_signed_short [vupklsb, vupkhsb] }
2863    impl_vec_unpack! { vec_vupklsb (vector_signed_char) -> vector_signed_short [vupkhsb, vupklsb] }
2864    impl_vec_unpack! { vec_vupkhsh (vector_signed_short) -> vector_signed_int [vupklsh, vupkhsh] }
2865    impl_vec_unpack! { vec_vupklsh (vector_signed_short) -> vector_signed_int [vupkhsh, vupklsh] }
2866
2867    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2868    pub trait VectorUnpackh {
2869        type Result;
2870        unsafe fn vec_unpackh(self) -> Self::Result;
2871    }
2872
2873    impl_vec_trait! { [VectorUnpackh vec_unpackh] vec_vupkhsb (vector_signed_char) -> vector_signed_short }
2874    impl_vec_trait! { [VectorUnpackh vec_unpackh]+ vec_vupkhsb (vector_bool_char) -> vector_bool_short }
2875    impl_vec_trait! { [VectorUnpackh vec_unpackh] vec_vupkhsh (vector_signed_short) -> vector_signed_int }
2876    impl_vec_trait! { [VectorUnpackh vec_unpackh]+ vec_vupkhsh (vector_bool_short) -> vector_bool_int }
2877
2878    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2879    pub trait VectorUnpackl {
2880        type Result;
2881        unsafe fn vec_unpackl(self) -> Self::Result;
2882    }
2883
2884    impl_vec_trait! { [VectorUnpackl vec_unpackl] vec_vupklsb (vector_signed_char) -> vector_signed_short }
2885    impl_vec_trait! { [VectorUnpackl vec_unpackl]+ vec_vupklsb (vector_bool_char) -> vector_bool_short }
2886    impl_vec_trait! { [VectorUnpackl vec_unpackl] vec_vupklsh (vector_signed_short) -> vector_signed_int }
2887    impl_vec_trait! { [VectorUnpackl vec_unpackl]+ vec_vupklsh (vector_bool_short) -> vector_bool_int }
2888
2889    macro_rules! impl_vec_shift {
2890        ([$Trait:ident $m:ident] ($b:ident, $h:ident, $w:ident)) => {
2891            impl_vec_trait!{ [$Trait $m]+ $b (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
2892            impl_vec_trait!{ [$Trait $m]+ $b (vector_signed_char, vector_unsigned_char) -> vector_signed_char }
2893            impl_vec_trait!{ [$Trait $m]+ $h (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
2894            impl_vec_trait!{ [$Trait $m]+ $h (vector_signed_short, vector_unsigned_short) -> vector_signed_short }
2895            impl_vec_trait!{ [$Trait $m]+ $w (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
2896            impl_vec_trait!{ [$Trait $m]+ $w (vector_signed_int, vector_unsigned_int) -> vector_signed_int }
2897        };
2898    }
2899
2900    macro_rules! impl_shift {
2901        ($fun:ident $intr:ident $ty:ident) => {
2902            #[inline]
2903            #[target_feature(enable = "altivec")]
2904            #[cfg_attr(test, assert_instr($fun))]
2905            unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) {
2906                let a = transmute(a);
2907                let b = simd_rem(
2908                    transmute(b),
2909                    <t_t_s!($ty)>::splat(mem::size_of::<$ty>() as $ty * $ty::BITS as $ty),
2910                );
2911
2912                transmute($intr(a, b))
2913            }
2914        };
2915    }
2916
2917    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2918    pub trait VectorSl<Other> {
2919        type Result;
2920        unsafe fn vec_sl(self, b: Other) -> Self::Result;
2921    }
2922
2923    impl_shift! { vslb simd_shl u8 }
2924    impl_shift! { vslh simd_shl u16 }
2925    impl_shift! { vslw simd_shl u32 }
2926
2927    impl_vec_shift! { [VectorSl vec_sl] (vslb, vslh, vslw) }
2928
2929    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2930    pub trait VectorSr<Other> {
2931        type Result;
2932        unsafe fn vec_sr(self, b: Other) -> Self::Result;
2933    }
2934
2935    impl_shift! { vsrb simd_shr u8 }
2936    impl_shift! { vsrh simd_shr u16 }
2937    impl_shift! { vsrw simd_shr u32 }
2938
2939    impl_vec_shift! { [VectorSr vec_sr] (vsrb, vsrh, vsrw) }
2940
2941    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2942    pub trait VectorSra<Other> {
2943        type Result;
2944        unsafe fn vec_sra(self, b: Other) -> Self::Result;
2945    }
2946
2947    impl_vec_shift! { [VectorSra vec_sra] (vsrab, vsrah, vsraw) }
2948
2949    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
2950    pub trait VectorSld {
2951        unsafe fn vec_sld<const UIMM4: i32>(self, b: Self) -> Self;
2952        unsafe fn vec_sldw<const UIMM2: i32>(self, b: Self) -> Self;
2953    }
2954
2955    #[inline]
2956    #[target_feature(enable = "altivec")]
2957    #[cfg_attr(test, assert_instr(vsldoi, UIMM4 = 1))]
2958    unsafe fn vsldoi<const UIMM4: i32>(
2959        a: vector_unsigned_char,
2960        b: vector_unsigned_char,
2961    ) -> vector_unsigned_char {
2962        static_assert_uimm_bits!(UIMM4, 4);
2963        let d = UIMM4 as u8;
2964        if cfg!(target_endian = "little") {
2965            let perm = u8x16::new(
2966                16 - d,
2967                17 - d,
2968                18 - d,
2969                19 - d,
2970                20 - d,
2971                21 - d,
2972                22 - d,
2973                23 - d,
2974                24 - d,
2975                25 - d,
2976                26 - d,
2977                27 - d,
2978                28 - d,
2979                29 - d,
2980                30 - d,
2981                31 - d,
2982            );
2983
2984            vec_perm(b, a, transmute(perm))
2985        } else {
2986            let perm = u8x16::new(
2987                d,
2988                d + 1,
2989                d + 2,
2990                d + 3,
2991                d + 4,
2992                d + 5,
2993                d + 6,
2994                d + 7,
2995                d + 8,
2996                d + 9,
2997                d + 10,
2998                d + 11,
2999                d + 12,
3000                d + 13,
3001                d + 14,
3002                d + 15,
3003            );
3004            vec_perm(a, b, transmute(perm))
3005        }
3006    }
3007
3008    // TODO: collapse the two once generic_const_exprs are usable.
3009    #[inline]
3010    #[target_feature(enable = "altivec")]
3011    #[cfg_attr(test, assert_instr(xxsldwi, UIMM2 = 1))]
3012    unsafe fn xxsldwi<const UIMM2: i32>(
3013        a: vector_unsigned_char,
3014        b: vector_unsigned_char,
3015    ) -> vector_unsigned_char {
3016        static_assert_uimm_bits!(UIMM2, 2);
3017        let d = (UIMM2 << 2) as u8;
3018        if cfg!(target_endian = "little") {
3019            let perm = u8x16::new(
3020                16 - d,
3021                17 - d,
3022                18 - d,
3023                19 - d,
3024                20 - d,
3025                21 - d,
3026                22 - d,
3027                23 - d,
3028                24 - d,
3029                25 - d,
3030                26 - d,
3031                27 - d,
3032                28 - d,
3033                29 - d,
3034                30 - d,
3035                31 - d,
3036            );
3037
3038            vec_perm(b, a, transmute(perm))
3039        } else {
3040            let perm = u8x16::new(
3041                d,
3042                d + 1,
3043                d + 2,
3044                d + 3,
3045                d + 4,
3046                d + 5,
3047                d + 6,
3048                d + 7,
3049                d + 8,
3050                d + 9,
3051                d + 10,
3052                d + 11,
3053                d + 12,
3054                d + 13,
3055                d + 14,
3056                d + 15,
3057            );
3058            vec_perm(a, b, transmute(perm))
3059        }
3060    }
3061
3062    macro_rules! impl_vec_sld {
3063        ($($ty:ident),+) => { $(
3064            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3065            impl VectorSld for $ty {
3066                #[inline]
3067                #[target_feature(enable = "altivec")]
3068                unsafe fn vec_sld<const UIMM4: i32>(self, b: Self) -> Self {
3069                    transmute(vsldoi::<UIMM4>(transmute(self), transmute(b)))
3070                }
3071                #[inline]
3072                #[target_feature(enable = "altivec")]
3073                unsafe fn vec_sldw<const UIMM2: i32>(self, b: Self) -> Self {
3074                    transmute(xxsldwi::<UIMM2>(transmute(self), transmute(b)))
3075                }
3076           }
3077        )+ };
3078    }
3079
3080    impl_vec_sld! { vector_bool_char, vector_signed_char, vector_unsigned_char }
3081    impl_vec_sld! { vector_bool_short, vector_signed_short, vector_unsigned_short }
3082    impl_vec_sld! { vector_bool_int, vector_signed_int, vector_unsigned_int }
3083    impl_vec_sld! { vector_float }
3084
3085    macro_rules! impl_vec_shift_long {
3086        ([$Trait:ident $m:ident] ($f:ident)) => {
3087            impl_vec_trait!{ [$Trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
3088            impl_vec_trait!{ [$Trait $m]+ $f (vector_signed_char, vector_unsigned_char) -> vector_signed_char }
3089            impl_vec_trait!{ [$Trait $m]+ $f (vector_unsigned_short, vector_unsigned_char) -> vector_unsigned_short }
3090            impl_vec_trait!{ [$Trait $m]+ $f (vector_signed_short, vector_unsigned_char) -> vector_signed_short }
3091            impl_vec_trait!{ [$Trait $m]+ $f (vector_unsigned_int, vector_unsigned_char) -> vector_unsigned_int }
3092            impl_vec_trait!{ [$Trait $m]+ $f (vector_signed_int, vector_unsigned_char) -> vector_signed_int }
3093        };
3094    }
3095
3096    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3097    pub trait VectorSll<Other> {
3098        type Result;
3099        unsafe fn vec_sll(self, b: Other) -> Self::Result;
3100    }
3101
3102    impl_vec_shift_long! { [VectorSll vec_sll] (vsl) }
3103
3104    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3105    pub trait VectorSrl<Other> {
3106        type Result;
3107        unsafe fn vec_srl(self, b: Other) -> Self::Result;
3108    }
3109
3110    impl_vec_shift_long! { [VectorSrl vec_srl] (vsr) }
3111
3112    macro_rules! impl_vec_shift_octect {
3113        ([$Trait:ident $m:ident] ($f:ident)) => {
3114            impl_vec_trait!{ [$Trait $m]+ $f (vector_unsigned_char, vector_signed_char) -> vector_unsigned_char }
3115            impl_vec_trait!{ [$Trait $m]+ $f (vector_signed_char, vector_signed_char) -> vector_signed_char }
3116            impl_vec_trait!{ [$Trait $m]+ $f (vector_unsigned_short, vector_signed_char) -> vector_unsigned_short }
3117            impl_vec_trait!{ [$Trait $m]+ $f (vector_signed_short, vector_signed_char) -> vector_signed_short }
3118            impl_vec_trait!{ [$Trait $m]+ $f (vector_unsigned_int, vector_signed_char) -> vector_unsigned_int }
3119            impl_vec_trait!{ [$Trait $m]+ $f (vector_signed_int, vector_signed_char) -> vector_signed_int }
3120            impl_vec_trait!{ [$Trait $m]+ $f (vector_float, vector_signed_char) -> vector_float }
3121            impl_vec_trait!{ [$Trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
3122            impl_vec_trait!{ [$Trait $m]+ $f (vector_signed_char, vector_unsigned_char) -> vector_signed_char }
3123            impl_vec_trait!{ [$Trait $m]+ $f (vector_unsigned_short, vector_unsigned_char) -> vector_unsigned_short }
3124            impl_vec_trait!{ [$Trait $m]+ $f (vector_signed_short, vector_unsigned_char) -> vector_signed_short }
3125            impl_vec_trait!{ [$Trait $m]+ $f (vector_unsigned_int, vector_unsigned_char) -> vector_unsigned_int }
3126            impl_vec_trait!{ [$Trait $m]+ $f (vector_signed_int, vector_unsigned_char) -> vector_signed_int }
3127            impl_vec_trait!{ [$Trait $m]+ $f (vector_float, vector_unsigned_char) -> vector_float }
3128        };
3129    }
3130
3131    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3132    pub trait VectorSlo<Other> {
3133        type Result;
3134        unsafe fn vec_slo(self, b: Other) -> Self::Result;
3135    }
3136
3137    impl_vec_shift_octect! { [VectorSlo vec_slo] (vslo) }
3138
3139    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3140    pub trait VectorSro<Other> {
3141        type Result;
3142        unsafe fn vec_sro(self, b: Other) -> Self::Result;
3143    }
3144
3145    impl_vec_shift_octect! { [VectorSro vec_sro] (vsro) }
3146
3147    test_impl! { vec_vcntlzb(a: vector_signed_char) -> vector_signed_char [simd_ctlz, vclzb] }
3148    test_impl! { vec_vcntlzh(a: vector_signed_short) -> vector_signed_short [simd_ctlz, vclzh] }
3149    test_impl! { vec_vcntlzw(a: vector_signed_int) -> vector_signed_int [simd_ctlz, vclzw] }
3150
3151    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3152    pub trait VectorCntlz {
3153        unsafe fn vec_cntlz(self) -> Self;
3154    }
3155
3156    macro_rules! impl_vec_cntlz {
3157        ($fun:ident ($a:ty)) => {
3158            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3159            impl VectorCntlz for $a {
3160                #[inline]
3161                #[target_feature(enable = "altivec")]
3162                unsafe fn vec_cntlz(self) -> Self {
3163                    transmute($fun(transmute(self)))
3164                }
3165            }
3166        };
3167    }
3168
3169    impl_vec_cntlz! { vec_vcntlzb(vector_signed_char) }
3170    impl_vec_cntlz! { vec_vcntlzb(vector_unsigned_char) }
3171    impl_vec_cntlz! { vec_vcntlzh(vector_signed_short) }
3172    impl_vec_cntlz! { vec_vcntlzh(vector_unsigned_short) }
3173    impl_vec_cntlz! { vec_vcntlzw(vector_signed_int) }
3174    impl_vec_cntlz! { vec_vcntlzw(vector_unsigned_int) }
3175
3176    macro_rules! impl_vrl {
3177        ($fun:ident $ty:ident) => {
3178            #[inline]
3179            #[target_feature(enable = "altivec")]
3180            #[cfg_attr(test, assert_instr($fun))]
3181            unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) {
3182                simd_funnel_shl(a, a, b)
3183            }
3184        };
3185    }
3186
3187    impl_vrl! { vrlb u8 }
3188    impl_vrl! { vrlh u16 }
3189    impl_vrl! { vrlw u32 }
3190
3191    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3192    pub trait VectorRl {
3193        type Shift;
3194        unsafe fn vec_rl(self, b: Self::Shift) -> Self;
3195    }
3196
3197    macro_rules! impl_vec_rl {
3198        ($fun:ident ($a:ident)) => {
3199            #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3200            impl VectorRl for $a {
3201                type Shift = t_u!($a);
3202                #[inline]
3203                #[target_feature(enable = "altivec")]
3204                unsafe fn vec_rl(self, b: Self::Shift) -> Self {
3205                    transmute($fun(transmute(self), b))
3206                }
3207            }
3208        };
3209    }
3210
3211    impl_vec_rl! { vrlb(vector_signed_char) }
3212    impl_vec_rl! { vrlh(vector_signed_short) }
3213    impl_vec_rl! { vrlw(vector_signed_int) }
3214    impl_vec_rl! { vrlb(vector_unsigned_char) }
3215    impl_vec_rl! { vrlh(vector_unsigned_short) }
3216    impl_vec_rl! { vrlw(vector_unsigned_int) }
3217
3218    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3219    pub trait VectorRound {
3220        unsafe fn vec_round(self) -> Self;
3221    }
3222
3223    test_impl! { vec_vrfin(a: vector_float) -> vector_float [vrfin, xvrspic] }
3224
3225    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
3226    impl VectorRound for vector_float {
3227        #[inline]
3228        #[target_feature(enable = "altivec")]
3229        unsafe fn vec_round(self) -> Self {
3230            vec_vrfin(self)
3231        }
3232    }
3233}
3234
3235/// Vector Insert
3236///
3237/// ## Purpose
3238/// Returns a copy of vector b with element c replaced by the value of a.
3239///
3240/// ## Result value
3241/// r contains a copy of vector b with element c replaced by the value of a.
3242/// This function uses modular arithmetic on c to determine the element number.
3243/// For example, if c is out of range, the compiler uses c modulo the number of
3244/// elements in the vector to determine the element position.
3245#[inline]
3246#[target_feature(enable = "altivec")]
3247#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3248pub unsafe fn vec_insert<T, const IDX: u32>(a: T, b: <T as sealed::VectorInsert>::Scalar) -> T
3249where
3250    T: sealed::VectorInsert,
3251{
3252    a.vec_insert::<IDX>(b)
3253}
3254
3255/// Vector Extract
3256///
3257/// ## Purpose
3258/// Returns the value of the bth element of vector a.
3259///
3260/// ## Result value
3261/// The value of each element of r is the element of a at position b modulo the number of
3262/// elements of a.
3263#[inline]
3264#[target_feature(enable = "altivec")]
3265#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3266pub unsafe fn vec_extract<T, const IDX: u32>(a: T) -> <T as sealed::VectorExtract>::Scalar
3267where
3268    T: sealed::VectorExtract,
3269{
3270    a.vec_extract::<IDX>()
3271}
3272
3273/// Vector Merge Low
3274#[inline]
3275#[target_feature(enable = "altivec")]
3276#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3277pub unsafe fn vec_mergel<T, U>(a: T, b: U) -> <T as sealed::VectorMergel<U>>::Result
3278where
3279    T: sealed::VectorMergel<U>,
3280{
3281    a.vec_mergel(b)
3282}
3283
3284/// Vector Merge High
3285#[inline]
3286#[target_feature(enable = "altivec")]
3287#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3288pub unsafe fn vec_mergeh<T, U>(a: T, b: U) -> <T as sealed::VectorMergeh<U>>::Result
3289where
3290    T: sealed::VectorMergeh<U>,
3291{
3292    a.vec_mergeh(b)
3293}
3294
3295/// Vector Pack
3296#[inline]
3297#[target_feature(enable = "altivec")]
3298#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3299pub unsafe fn vec_pack<T, U>(a: T, b: U) -> <T as sealed::VectorPack<U>>::Result
3300where
3301    T: sealed::VectorPack<U>,
3302{
3303    a.vec_pack(b)
3304}
3305
3306/// Vector Pack Saturated
3307#[inline]
3308#[target_feature(enable = "altivec")]
3309#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3310pub unsafe fn vec_packs<T, U>(a: T, b: U) -> <T as sealed::VectorPacks<U>>::Result
3311where
3312    T: sealed::VectorPacks<U>,
3313{
3314    a.vec_packs(b)
3315}
3316
3317/// Vector Pack Saturated Unsigned
3318#[inline]
3319#[target_feature(enable = "altivec")]
3320#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3321pub unsafe fn vec_packsu<T, U>(a: T, b: U) -> <T as sealed::VectorPacksu<U>>::Result
3322where
3323    T: sealed::VectorPacksu<U>,
3324{
3325    a.vec_packsu(b)
3326}
3327
3328/// Vector Unpack High
3329#[inline]
3330#[target_feature(enable = "altivec")]
3331#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3332pub unsafe fn vec_unpackh<T>(a: T) -> <T as sealed::VectorUnpackh>::Result
3333where
3334    T: sealed::VectorUnpackh,
3335{
3336    a.vec_unpackh()
3337}
3338
3339/// Vector Unpack Low
3340#[inline]
3341#[target_feature(enable = "altivec")]
3342#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3343pub unsafe fn vec_unpackl<T>(a: T) -> <T as sealed::VectorUnpackl>::Result
3344where
3345    T: sealed::VectorUnpackl,
3346{
3347    a.vec_unpackl()
3348}
3349
3350/// Vector Shift Left
3351#[inline]
3352#[target_feature(enable = "altivec")]
3353#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3354pub unsafe fn vec_sl<T, U>(a: T, b: U) -> <T as sealed::VectorSl<U>>::Result
3355where
3356    T: sealed::VectorSl<U>,
3357{
3358    a.vec_sl(b)
3359}
3360
3361/// Vector Shift Right
3362#[inline]
3363#[target_feature(enable = "altivec")]
3364#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3365pub unsafe fn vec_sr<T, U>(a: T, b: U) -> <T as sealed::VectorSr<U>>::Result
3366where
3367    T: sealed::VectorSr<U>,
3368{
3369    a.vec_sr(b)
3370}
3371
3372/// Vector Shift Right Algebraic
3373#[inline]
3374#[target_feature(enable = "altivec")]
3375#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3376pub unsafe fn vec_sra<T, U>(a: T, b: U) -> <T as sealed::VectorSra<U>>::Result
3377where
3378    T: sealed::VectorSra<U>,
3379{
3380    a.vec_sra(b)
3381}
3382
3383/// Vector Shift Left Double
3384///
3385/// ## Endian considerations
3386///
3387/// This intrinsic is not endian-neutral, so uses of vec_sld in
3388/// big-endian code must be rewritten for little-endian targets.
3389///
3390/// Historically, vec_sld could be used to shift by amounts not a multiple of the element size
3391/// for most types, in which case the purpose of the shift is difficult to determine and difficult
3392/// to automatically rewrite efficiently for little endian.
3393///
3394/// So the concatenation of a and b is done in big-endian fashion (left to right), and the shift is
3395/// always to the left. This will generally produce surprising results for little-endian targets.
3396#[inline]
3397#[target_feature(enable = "altivec")]
3398#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3399pub unsafe fn vec_sld<T, const UIMM4: i32>(a: T, b: T) -> T
3400where
3401    T: sealed::VectorSld,
3402{
3403    a.vec_sld::<UIMM4>(b)
3404}
3405
3406/// Vector Shift Left Double by Words
3407///
3408/// ## Endian considerations
3409///
3410/// This intrinsic is not endian-neutral, so uses of vec_sldw in
3411/// big-endian code must be rewritten for little-endian targets.
3412///
3413/// The concatenation of a and b is done in big-endian fashion (left to right), and the shift is
3414/// always to the left. This will generally produce surprising results for little- endian targets.
3415#[inline]
3416#[target_feature(enable = "altivec")]
3417#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3418pub unsafe fn vec_sldw<T, const UIMM2: i32>(a: T, b: T) -> T
3419where
3420    T: sealed::VectorSld,
3421{
3422    a.vec_sldw::<UIMM2>(b)
3423}
3424
3425/// Vector Shift Left Long
3426///
3427/// ## Endian considerations
3428/// This intrinsic is not endian-neutral, so uses of vec_sll in big-endian
3429/// code must be rewritten for little-endian targets.
3430#[inline]
3431#[target_feature(enable = "altivec")]
3432#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3433pub unsafe fn vec_sll<T, U>(a: T, b: U) -> <T as sealed::VectorSll<U>>::Result
3434where
3435    T: sealed::VectorSll<U>,
3436{
3437    a.vec_sll(b)
3438}
3439
3440/// Vector Shift Right Long
3441///
3442/// ## Endian considerations
3443/// This intrinsic is not endian-neutral, so uses of vec_srl in big-endian
3444/// code must be rewritten for little-endian targets.
3445#[inline]
3446#[target_feature(enable = "altivec")]
3447#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3448pub unsafe fn vec_srl<T, U>(a: T, b: U) -> <T as sealed::VectorSrl<U>>::Result
3449where
3450    T: sealed::VectorSrl<U>,
3451{
3452    a.vec_srl(b)
3453}
3454
3455/// Vector Shift Left by Octets
3456///
3457/// ## Endian considerations
3458/// This intrinsic is not endian-neutral, so uses of vec_slo in big-endian code must be rewritten
3459/// for little-endian targets. The shift count is in element 15 of b for big-endian, but in element
3460/// 0 of b for little-endian.
3461#[inline]
3462#[target_feature(enable = "altivec")]
3463#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3464pub unsafe fn vec_slo<T, U>(a: T, b: U) -> <T as sealed::VectorSlo<U>>::Result
3465where
3466    T: sealed::VectorSlo<U>,
3467{
3468    a.vec_slo(b)
3469}
3470
3471/// Vector Shift Right by Octets
3472///
3473/// ## Endian considerations
3474/// This intrinsic is not endian-neutral, so uses of vec_sro in big-endian code must be rewritten
3475/// for little-endian targets. The shift count is in element 15 of b for big-endian, but in element
3476/// 0 of b for little-endian.
3477#[inline]
3478#[target_feature(enable = "altivec")]
3479#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3480pub unsafe fn vec_sro<T, U>(a: T, b: U) -> <T as sealed::VectorSro<U>>::Result
3481where
3482    T: sealed::VectorSro<U>,
3483{
3484    a.vec_sro(b)
3485}
3486
3487/// Vector Shift Left Variable
3488///
3489/// ## Result value
3490/// Let v be a 17-byte vector formed from a in bytes `[0:15]` and a zero byte in element 16.
3491/// Then each byte element i of r is determined as follows. The start bit sb is
3492/// obtained from bits 5:7 of byte element i of b. Then the contents of bits sb:sb+7 of the
3493/// halfword in byte elements i:i+1 of v are placed into byte element i of r.
3494///
3495/// ## Endian considerations
3496/// All bit and byte element numbers are specified in big-endian order. This intrinsic is not
3497/// endian-neutral.
3498#[inline]
3499#[target_feature(enable = "power9-altivec")]
3500#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3501pub unsafe fn vec_slv(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char {
3502    vslv(a, b)
3503}
3504
3505/// Vector Shift Right Variable
3506///
3507/// ## Result value
3508/// Let v be a 17-byte vector formed from a zero byte in element 0 and the elements of
3509/// a in bytes `[1:16]`. Then each byte element i of r is determined as follows. The start bit sb is
3510/// obtained from bits 5:7 of byte element i of b. Then the contents of bits (8 – sb):(15 – sb) of
3511/// the halfword in byte elements i:i+1 of v are placed into byte element i of r.
3512///
3513/// ## Endian considerations
3514/// All bit and byte element numbers are specified in big-endian order. This intrinsic is not
3515/// endian-neutral.
3516#[inline]
3517#[target_feature(enable = "power9-altivec")]
3518#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3519pub unsafe fn vec_srv(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char {
3520    vsrv(a, b)
3521}
3522
3523/// Vector Load Indexed.
3524#[inline]
3525#[target_feature(enable = "altivec")]
3526#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3527pub unsafe fn vec_ld<T>(off: isize, p: T) -> <T as sealed::VectorLd>::Result
3528where
3529    T: sealed::VectorLd,
3530{
3531    p.vec_ld(off)
3532}
3533
3534/// Vector Load Indexed Least Recently Used.
3535#[inline]
3536#[target_feature(enable = "altivec")]
3537#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3538pub unsafe fn vec_ldl<T>(off: isize, p: T) -> <T as sealed::VectorLd>::Result
3539where
3540    T: sealed::VectorLd,
3541{
3542    p.vec_ldl(off)
3543}
3544
3545/// Vector Load Element Indexed.
3546#[inline]
3547#[target_feature(enable = "altivec")]
3548#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3549pub unsafe fn vec_lde<T>(off: isize, p: T) -> <T as sealed::VectorLde>::Result
3550where
3551    T: sealed::VectorLde,
3552{
3553    p.vec_lde(off)
3554}
3555
3556/// Vector Store Indexed
3557///
3558/// ## Purpose
3559/// Stores a 16-byte vector into memory at the address specified by a displacement and a
3560/// pointer, ignoring the four low-order bits of the calculated address.
3561///
3562/// ## Operation
3563/// A memory address is obtained by adding b and c, and masking off the four low-order
3564/// bits of the result. The 16-byte vector in a is stored to the resultant memory address.
3565#[inline]
3566#[target_feature(enable = "altivec")]
3567#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3568pub unsafe fn vec_st<T>(a: T, off: isize, c: <T as sealed::VectorSt>::Target)
3569where
3570    T: sealed::VectorSt,
3571{
3572    a.vec_st(off, c)
3573}
3574
3575/// Vector Store Indexed Least Recently Used
3576///
3577/// ## Purpose
3578/// Stores a 16-byte vector into memory at the address specified by a displacement and
3579/// a pointer, ignoring the four low-order bits of the calculated address, and marking the cache
3580/// line containing the address as least frequently used.
3581///
3582/// ## Operation
3583/// A memory address is obtained by adding b and c, and masking off the four
3584/// low-order bits of the result. The 16-byte vector in a is stored to the resultant memory
3585/// address, and the containing cache line is marked as least frequently used.
3586///
3587/// ## Notes
3588/// This intrinsic can be used to indicate the last access to a portion of memory, as a hint to the
3589/// data cache controller that the associated cache line can be replaced without performance loss.
3590#[inline]
3591#[target_feature(enable = "altivec")]
3592#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3593pub unsafe fn vec_stl<T>(a: T, off: isize, c: <T as sealed::VectorSt>::Target)
3594where
3595    T: sealed::VectorSt,
3596{
3597    a.vec_stl(off, c)
3598}
3599
3600/// Vector Store Element Indexed
3601///
3602/// ## Purpose
3603/// Stores a single element from a 16-byte vector into memory at the address specified by
3604/// a displacement and a pointer, aligned to the element size.
3605///
3606/// ## Operation
3607/// The integer value b is added to the pointer value c. The resulting address is
3608/// rounded down to the nearest address that is a multiple of es, where es is 1 for char pointers,
3609/// 2 for short pointers, and 4 for float or int pointers. An element offset eo is calculated by
3610/// taking the resultant address modulo 16. The vector element of a at offset eo is stored to the
3611/// resultant address.
3612///
3613/// ## Notes
3614/// Be careful to note that the address (b+c) is aligned to an element boundary. Do not attempt
3615/// to store unaligned data with this intrinsic.
3616#[inline]
3617#[target_feature(enable = "altivec")]
3618#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3619pub unsafe fn vec_ste<T>(a: T, off: isize, c: <T as sealed::VectorSte>::Target)
3620where
3621    T: sealed::VectorSte,
3622{
3623    a.vec_ste(off, c)
3624}
3625
3626/// VSX Unaligned Load
3627#[inline]
3628#[target_feature(enable = "altivec")]
3629#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3630pub unsafe fn vec_xl<T>(off: isize, p: T) -> <T as sealed::VectorXl>::Result
3631where
3632    T: sealed::VectorXl,
3633{
3634    p.vec_xl(off)
3635}
3636
3637/// VSX Unaligned Store
3638#[inline]
3639#[target_feature(enable = "altivec")]
3640#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3641pub unsafe fn vec_xst<T>(v: T, off: isize, p: <T as sealed::VectorXst>::Out)
3642where
3643    T: sealed::VectorXst,
3644{
3645    v.vec_xst(off, p)
3646}
3647
3648/// Vector Base-2 Logarithm Estimate
3649#[inline]
3650#[target_feature(enable = "altivec")]
3651#[cfg_attr(test, assert_instr(vlogefp))]
3652#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3653pub unsafe fn vec_loge(a: vector_float) -> vector_float {
3654    vlogefp(a)
3655}
3656
3657/// Vector floor.
3658#[inline]
3659#[target_feature(enable = "altivec")]
3660#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3661pub unsafe fn vec_floor(a: vector_float) -> vector_float {
3662    sealed::vec_floor(a)
3663}
3664
3665/// Vector expte.
3666#[inline]
3667#[target_feature(enable = "altivec")]
3668#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3669pub unsafe fn vec_expte(a: vector_float) -> vector_float {
3670    sealed::vec_vexptefp(a)
3671}
3672
3673/// Vector cmplt.
3674#[inline]
3675#[target_feature(enable = "altivec")]
3676#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3677pub unsafe fn vec_cmplt<T, U>(a: U, b: T) -> <T as sealed::VectorCmpGt<U>>::Result
3678where
3679    T: sealed::VectorCmpGt<U>,
3680{
3681    vec_cmpgt(b, a)
3682}
3683
3684/// Vector cmple.
3685#[inline]
3686#[target_feature(enable = "altivec")]
3687#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3688pub unsafe fn vec_cmple(a: vector_float, b: vector_float) -> vector_bool_int {
3689    vec_cmpge(b, a)
3690}
3691
3692/// Vector cmpgt.
3693#[inline]
3694#[target_feature(enable = "altivec")]
3695#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3696pub unsafe fn vec_cmpgt<T, U>(a: T, b: U) -> <T as sealed::VectorCmpGt<U>>::Result
3697where
3698    T: sealed::VectorCmpGt<U>,
3699{
3700    a.vec_cmpgt(b)
3701}
3702
3703/// Vector cmpge.
3704#[inline]
3705#[target_feature(enable = "altivec")]
3706#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3707pub unsafe fn vec_cmpge(a: vector_float, b: vector_float) -> vector_bool_int {
3708    sealed::vec_vcmpgefp(a, b)
3709}
3710
3711/// Vector cmpeq.
3712#[inline]
3713#[target_feature(enable = "altivec")]
3714#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3715pub unsafe fn vec_cmpeq<T, U>(a: T, b: U) -> <T as sealed::VectorCmpEq<U>>::Result
3716where
3717    T: sealed::VectorCmpEq<U>,
3718{
3719    a.vec_cmpeq(b)
3720}
3721
3722/// Vector Compare Not Equal
3723///
3724/// ## Result value
3725/// For each element of r, the value of each bit is 1 if the corresponding elements
3726/// of a and b are not equal. Otherwise, the value of each bit is 0.
3727#[inline]
3728#[target_feature(enable = "altivec")]
3729#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3730pub unsafe fn vec_cmpne<T, U>(a: T, b: U) -> <T as sealed::VectorCmpNe<U>>::Result
3731where
3732    T: sealed::VectorCmpNe<U>,
3733{
3734    a.vec_cmpne(b)
3735}
3736
3737/// Vector cmpb.
3738#[inline]
3739#[target_feature(enable = "altivec")]
3740#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3741pub unsafe fn vec_cmpb(a: vector_float, b: vector_float) -> vector_signed_int {
3742    sealed::vec_vcmpbfp(a, b)
3743}
3744
3745/// Vector ceil.
3746#[inline]
3747#[target_feature(enable = "altivec")]
3748#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3749pub unsafe fn vec_ceil(a: vector_float) -> vector_float {
3750    sealed::vec_vceil(a)
3751}
3752
3753/// Vector avg.
3754#[inline]
3755#[target_feature(enable = "altivec")]
3756#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3757pub unsafe fn vec_avg<T, U>(a: T, b: U) -> <T as sealed::VectorAvg<U>>::Result
3758where
3759    T: sealed::VectorAvg<U>,
3760{
3761    a.vec_avg(b)
3762}
3763
3764/// Vector andc.
3765#[inline]
3766#[target_feature(enable = "altivec")]
3767#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3768pub unsafe fn vec_andc<T, U>(a: T, b: U) -> <T as sealed::VectorAndc<U>>::Result
3769where
3770    T: sealed::VectorAndc<U>,
3771{
3772    a.vec_andc(b)
3773}
3774
3775/// Vector OR with Complement
3776///
3777/// ## Purpose
3778/// Performs a bitwise OR of the first vector with the bitwise-complemented second vector.
3779///
3780/// ## Result value
3781/// r is the bitwise OR of a and the bitwise complement of b.
3782#[inline]
3783#[target_feature(enable = "altivec")]
3784#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3785pub unsafe fn vec_orc<T, U>(a: T, b: U) -> <T as sealed::VectorOrc<U>>::Result
3786where
3787    T: sealed::VectorOrc<U>,
3788{
3789    a.vec_orc(b)
3790}
3791
3792/// Vector and.
3793#[inline]
3794#[target_feature(enable = "altivec")]
3795#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3796pub unsafe fn vec_and<T, U>(a: T, b: U) -> <T as sealed::VectorAnd<U>>::Result
3797where
3798    T: sealed::VectorAnd<U>,
3799{
3800    a.vec_and(b)
3801}
3802
3803/// Vector or.
3804#[inline]
3805#[target_feature(enable = "altivec")]
3806#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3807pub unsafe fn vec_or<T, U>(a: T, b: U) -> <T as sealed::VectorOr<U>>::Result
3808where
3809    T: sealed::VectorOr<U>,
3810{
3811    a.vec_or(b)
3812}
3813
3814/// Vector NAND
3815///
3816/// ## Purpose
3817/// Performs a bitwise NAND of two vectors.
3818///
3819/// ## Result value
3820/// r is the bitwise NAND of a and b.
3821#[inline]
3822#[target_feature(enable = "altivec")]
3823#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3824pub unsafe fn vec_nand<T, U>(a: T, b: U) -> <T as sealed::VectorNand<U>>::Result
3825where
3826    T: sealed::VectorNand<U>,
3827{
3828    a.vec_nand(b)
3829}
3830
3831/// Vector nor.
3832#[inline]
3833#[target_feature(enable = "altivec")]
3834#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3835pub unsafe fn vec_nor<T, U>(a: T, b: U) -> <T as sealed::VectorNor<U>>::Result
3836where
3837    T: sealed::VectorNor<U>,
3838{
3839    a.vec_nor(b)
3840}
3841
3842/// Vector xor.
3843#[inline]
3844#[target_feature(enable = "altivec")]
3845#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3846pub unsafe fn vec_xor<T, U>(a: T, b: U) -> <T as sealed::VectorXor<U>>::Result
3847where
3848    T: sealed::VectorXor<U>,
3849{
3850    a.vec_xor(b)
3851}
3852
3853/// Vector adds.
3854#[inline]
3855#[target_feature(enable = "altivec")]
3856#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3857pub unsafe fn vec_adds<T, U>(a: T, b: U) -> <T as sealed::VectorAdds<U>>::Result
3858where
3859    T: sealed::VectorAdds<U>,
3860{
3861    a.vec_adds(b)
3862}
3863
3864/// Vector addc.
3865#[inline]
3866#[target_feature(enable = "altivec")]
3867#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3868pub unsafe fn vec_addc(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int {
3869    sealed::vec_vaddcuw(a, b)
3870}
3871
3872/// Vector abs.
3873#[inline]
3874#[target_feature(enable = "altivec")]
3875#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3876pub unsafe fn vec_abs<T>(a: T) -> T
3877where
3878    T: sealed::VectorAbs,
3879{
3880    a.vec_abs()
3881}
3882
3883/// Vector abss.
3884#[inline]
3885#[target_feature(enable = "altivec")]
3886#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3887pub unsafe fn vec_abss<T>(a: T) -> T
3888where
3889    T: sealed::VectorAbss,
3890{
3891    a.vec_abss()
3892}
3893
3894/// Vector Rotate Left
3895///
3896/// ## Purpose
3897/// Rotates each element of a vector left by a given number of bits.
3898///
3899/// ## Result value
3900/// Each element of r is obtained by rotating the corresponding element of a left by
3901/// the number of bits specified by the corresponding element of b.
3902#[inline]
3903#[target_feature(enable = "altivec")]
3904#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3905pub unsafe fn vec_rl<T>(a: T, b: <T as sealed::VectorRl>::Shift) -> T
3906where
3907    T: sealed::VectorRl,
3908{
3909    a.vec_rl(b)
3910}
3911
3912/// Vector Round
3913///
3914/// ## Purpose
3915/// Returns a vector containing the rounded values of the corresponding elements of the
3916/// source vector.
3917///
3918/// ## Result value
3919/// Each element of r contains the value of the corresponding element of a, rounded
3920/// to the nearest representable floating-point integer, using IEEE round-to-nearest
3921/// rounding.
3922/// The current floating-point rounding mode is ignored.
3923#[inline]
3924#[target_feature(enable = "altivec")]
3925#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3926pub unsafe fn vec_round<T>(a: T) -> T
3927where
3928    T: sealed::VectorRound,
3929{
3930    a.vec_round()
3931}
3932
3933/// Vector Splat
3934#[inline]
3935#[target_feature(enable = "altivec")]
3936#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3937pub unsafe fn vec_splat<T, const IMM: u32>(a: T) -> T
3938where
3939    T: sealed::VectorSplat,
3940{
3941    a.vec_splat::<IMM>()
3942}
3943
3944splat! { vec_splat_u8, u8, u8x16 [vspltisb / xxspltib, "Vector Splat to Unsigned Byte"] }
3945splat! { vec_splat_s8, i8, i8x16 [vspltisb / xxspltib, "Vector Splat to Signed Byte"] }
3946splat! { vec_splat_u16, u16, u16x8 [vspltish, "Vector Splat to Unsigned Halfword"] }
3947splat! { vec_splat_s16, i16, i16x8 [vspltish, "Vector Splat to Signed Halfword"] }
3948splat! { vec_splat_u32, u32, u32x4 [vspltisw, "Vector Splat to Unsigned Word"] }
3949splat! { vec_splat_s32, i32, i32x4 [vspltisw, "Vector Splat to Signed Word"] }
3950
3951/// Vector splats.
3952#[inline]
3953#[target_feature(enable = "altivec")]
3954#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3955pub unsafe fn vec_splats<T>(a: T) -> <T as sealed::VectorSplats>::Result
3956where
3957    T: sealed::VectorSplats,
3958{
3959    a.vec_splats()
3960}
3961
3962/// Vector sub.
3963#[inline]
3964#[target_feature(enable = "altivec")]
3965#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3966pub unsafe fn vec_sub<T, U>(a: T, b: U) -> <T as sealed::VectorSub<U>>::Result
3967where
3968    T: sealed::VectorSub<U>,
3969{
3970    a.vec_sub(b)
3971}
3972
3973/// Vector Subtract Carryout
3974///
3975/// ## Purpose
3976/// Returns a vector wherein each element contains the carry produced by subtracting the
3977/// corresponding elements of the two source vectors.
3978///
3979/// ## Result value
3980/// The value of each element of r is the complement of the carry produced by subtract- ing the
3981/// value of the corresponding element of b from the value of the corresponding element of a. The
3982/// value is 0 if a borrow occurred, or 1 if no borrow occurred.
3983#[inline]
3984#[target_feature(enable = "altivec")]
3985#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3986pub unsafe fn vec_subc<T, U>(a: T, b: U) -> <T as sealed::VectorSubc<U>>::Result
3987where
3988    T: sealed::VectorSubc<U>,
3989{
3990    a.vec_subc(b)
3991}
3992
3993/// Vector subs.
3994#[inline]
3995#[target_feature(enable = "altivec")]
3996#[unstable(feature = "stdarch_powerpc", issue = "111145")]
3997pub unsafe fn vec_subs<T, U>(a: T, b: U) -> <T as sealed::VectorSubs<U>>::Result
3998where
3999    T: sealed::VectorSubs<U>,
4000{
4001    a.vec_subs(b)
4002}
4003
4004/// Vector min.
4005#[inline]
4006#[target_feature(enable = "altivec")]
4007#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4008pub unsafe fn vec_min<T, U>(a: T, b: U) -> <T as sealed::VectorMin<U>>::Result
4009where
4010    T: sealed::VectorMin<U>,
4011{
4012    a.vec_min(b)
4013}
4014
4015/// Vector max.
4016#[inline]
4017#[target_feature(enable = "altivec")]
4018#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4019pub unsafe fn vec_max<T, U>(a: T, b: U) -> <T as sealed::VectorMax<U>>::Result
4020where
4021    T: sealed::VectorMax<U>,
4022{
4023    a.vec_max(b)
4024}
4025
4026/// Move From Vector Status and Control Register.
4027#[inline]
4028#[target_feature(enable = "altivec")]
4029#[cfg_attr(test, assert_instr(mfvscr))]
4030#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4031pub unsafe fn vec_mfvscr() -> vector_unsigned_short {
4032    mfvscr()
4033}
4034
4035/// Vector add.
4036#[inline]
4037#[target_feature(enable = "altivec")]
4038#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4039pub unsafe fn vec_add<T, U>(a: T, b: U) -> <T as sealed::VectorAdd<U>>::Result
4040where
4041    T: sealed::VectorAdd<U>,
4042{
4043    a.vec_add(b)
4044}
4045
4046/// Vector Add Extended
4047///
4048/// ## Result value
4049/// The value of each element of r is produced by adding the corresponding elements of
4050/// a and b with a carry specified in the corresponding element of c (1 if there is a carry, 0
4051/// otherwise).
4052#[inline]
4053#[target_feature(enable = "altivec")]
4054#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4055pub unsafe fn vec_adde<T>(a: T, b: T, c: T) -> T
4056where
4057    T: sealed::VectorAdde,
4058{
4059    a.vec_adde(b, c)
4060}
4061
4062/// Vector Convert to Floating-Point
4063#[inline]
4064#[target_feature(enable = "altivec")]
4065#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4066pub unsafe fn vec_ctf<const IMM5: i32, T>(a: T) -> vector_float
4067where
4068    T: sealed::VectorCtf,
4069{
4070    a.vec_ctf::<IMM5>()
4071}
4072
4073/// Vector Convert to Signed Integer
4074#[inline]
4075#[target_feature(enable = "altivec")]
4076#[cfg_attr(test, assert_instr(vctsxs, IMM5 = 1))]
4077#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4078pub unsafe fn vec_cts<const IMM5: i32>(a: vector_float) -> vector_signed_int {
4079    static_assert_uimm_bits!(IMM5, 5);
4080
4081    vctsxs(a, IMM5)
4082}
4083
4084/// Vector Convert to Unsigned Integer
4085#[inline]
4086#[target_feature(enable = "altivec")]
4087#[cfg_attr(test, assert_instr(vctuxs, IMM5 = 1))]
4088#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4089pub unsafe fn vec_ctu<const IMM5: i32>(a: vector_float) -> vector_unsigned_int {
4090    static_assert_uimm_bits!(IMM5, 5);
4091
4092    vctuxs(a, IMM5)
4093}
4094
4095/// Endian-biased intrinsics
4096#[cfg(target_endian = "little")]
4097mod endian {
4098    use super::*;
4099    /// Vector permute.
4100    #[inline]
4101    #[target_feature(enable = "altivec")]
4102    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
4103    pub unsafe fn vec_perm<T>(a: T, b: T, c: vector_unsigned_char) -> T
4104    where
4105        T: sealed::VectorPerm,
4106    {
4107        // vperm has big-endian bias
4108        //
4109        // Xor the mask and flip the arguments
4110        let d = transmute(u8x16::new(
4111            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
4112        ));
4113        let c = simd_xor(c, d);
4114
4115        b.vec_vperm(a, c)
4116    }
4117
4118    /// Vector Sum Across Partial (1/2) Saturated
4119    #[inline]
4120    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
4121    #[target_feature(enable = "altivec")]
4122    pub unsafe fn vec_sum2s(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
4123        // vsum2sws has big-endian bias
4124        //
4125        // swap the even b elements with the odd ones
4126        let flip = transmute(u8x16::new(
4127            4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11,
4128        ));
4129        let b = vec_perm(b, b, flip);
4130        let c = vsum2sws(a, b);
4131
4132        vec_perm(c, c, flip)
4133    }
4134
4135    // Even and Odd are swapped in little-endian
4136    /// Vector Multiply Even
4137    #[inline]
4138    #[target_feature(enable = "altivec")]
4139    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
4140    pub unsafe fn vec_mule<T, U>(a: T, b: T) -> U
4141    where
4142        T: sealed::VectorMulo<U>,
4143    {
4144        a.vec_mulo(b)
4145    }
4146    /// Vector Multiply Odd
4147    #[inline]
4148    #[target_feature(enable = "altivec")]
4149    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
4150    pub unsafe fn vec_mulo<T, U>(a: T, b: T) -> U
4151    where
4152        T: sealed::VectorMule<U>,
4153    {
4154        a.vec_mule(b)
4155    }
4156}
4157
4158/// Vector Multiply
4159///
4160/// ## Purpose
4161/// Compute the products of corresponding elements of two vectors.
4162///
4163/// ## Result value
4164/// Each element of r receives the product of the corresponding elements of a and b.
4165#[inline]
4166#[target_feature(enable = "altivec")]
4167#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4168pub unsafe fn vec_mul<T>(a: T, b: T) -> T
4169where
4170    T: sealed::VectorMul,
4171{
4172    a.vec_mul(b)
4173}
4174
4175/// Vector Multiply Add Saturated
4176#[inline]
4177#[target_feature(enable = "altivec")]
4178#[cfg_attr(test, assert_instr(vmhaddshs))]
4179#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4180pub unsafe fn vec_madds(
4181    a: vector_signed_short,
4182    b: vector_signed_short,
4183    c: vector_signed_short,
4184) -> vector_signed_short {
4185    vmhaddshs(a, b, c)
4186}
4187
4188/// Vector Multiply Low and Add Unsigned Half Word
4189#[inline]
4190#[target_feature(enable = "altivec")]
4191#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4192pub unsafe fn vec_mladd<T, U>(a: T, b: U, c: U) -> <T as sealed::VectorMladd<U>>::Result
4193where
4194    T: sealed::VectorMladd<U>,
4195{
4196    a.vec_mladd(b, c)
4197}
4198
4199/// Vector Multiply Round and Add Saturated
4200#[inline]
4201#[target_feature(enable = "altivec")]
4202#[cfg_attr(test, assert_instr(vmhraddshs))]
4203#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4204pub unsafe fn vec_mradds(
4205    a: vector_signed_short,
4206    b: vector_signed_short,
4207    c: vector_signed_short,
4208) -> vector_signed_short {
4209    vmhraddshs(a, b, c)
4210}
4211
4212/// Vector Multiply Sum
4213#[inline]
4214#[target_feature(enable = "altivec")]
4215#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4216pub unsafe fn vec_msum<T, B, U>(a: T, b: B, c: U) -> U
4217where
4218    T: sealed::VectorMsum<B, U>,
4219{
4220    a.vec_msum(b, c)
4221}
4222
4223/// Vector Multiply Sum Saturated
4224#[inline]
4225#[target_feature(enable = "altivec")]
4226#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4227pub unsafe fn vec_msums<T, U>(a: T, b: T, c: U) -> U
4228where
4229    T: sealed::VectorMsums<U>,
4230{
4231    a.vec_msums(b, c)
4232}
4233
4234/// Vector Multiply Add
4235#[inline]
4236#[target_feature(enable = "altivec")]
4237#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4238pub unsafe fn vec_madd(a: vector_float, b: vector_float, c: vector_float) -> vector_float {
4239    sealed::vec_vmaddfp(a, b, c)
4240}
4241
4242/// Vector Negative Multiply Subtract
4243#[inline]
4244#[target_feature(enable = "altivec")]
4245#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4246pub unsafe fn vec_nmsub(a: vector_float, b: vector_float, c: vector_float) -> vector_float {
4247    vnmsubfp(a, b, c)
4248}
4249
4250/// Vector Select
4251///
4252/// ## Purpose
4253/// Returns a vector selecting bits from two source vectors depending on the corresponding
4254/// bit values of a third source vector.
4255///
4256/// ## Result value
4257/// Each bit of r has the value of the corresponding bit of a if the corresponding
4258/// bit of c is 0. Otherwise, the bit of r has the value of the corresponding bit of b.
4259#[inline]
4260#[target_feature(enable = "altivec")]
4261#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4262pub unsafe fn vec_sel<T, U>(a: T, b: T, c: U) -> T
4263where
4264    T: sealed::VectorSel<U>,
4265{
4266    a.vec_sel(b, c)
4267}
4268
4269/// Vector Sum Across Partial (1/4) Saturated
4270#[inline]
4271#[target_feature(enable = "altivec")]
4272#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4273pub unsafe fn vec_sum4s<T, U>(a: T, b: U) -> U
4274where
4275    T: sealed::VectorSum4s<U>,
4276{
4277    a.vec_sum4s(b)
4278}
4279
4280/// Vector All Elements Equal
4281#[inline]
4282#[target_feature(enable = "altivec")]
4283#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4284pub unsafe fn vec_all_eq<T, U>(a: T, b: U) -> <T as sealed::VectorAllEq<U>>::Result
4285where
4286    T: sealed::VectorAllEq<U>,
4287{
4288    a.vec_all_eq(b)
4289}
4290
4291/// Vector All Elements Equal
4292#[inline]
4293#[target_feature(enable = "altivec")]
4294#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4295pub unsafe fn vec_any_eq<T, U>(a: T, b: U) -> <T as sealed::VectorAnyEq<U>>::Result
4296where
4297    T: sealed::VectorAnyEq<U>,
4298{
4299    a.vec_any_eq(b)
4300}
4301
4302/// Vector All Elements Greater or Equal
4303#[inline]
4304#[target_feature(enable = "altivec")]
4305#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4306pub unsafe fn vec_all_ge<T, U>(a: T, b: U) -> <T as sealed::VectorAllGe<U>>::Result
4307where
4308    T: sealed::VectorAllGe<U>,
4309{
4310    a.vec_all_ge(b)
4311}
4312
4313/// Vector Any Element Greater or Equal
4314#[inline]
4315#[target_feature(enable = "altivec")]
4316#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4317pub unsafe fn vec_any_ge<T, U>(a: T, b: U) -> <T as sealed::VectorAnyGe<U>>::Result
4318where
4319    T: sealed::VectorAnyGe<U>,
4320{
4321    a.vec_any_ge(b)
4322}
4323
4324/// Vector All Elements Greater Than
4325#[inline]
4326#[target_feature(enable = "altivec")]
4327#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4328pub unsafe fn vec_all_gt<T, U>(a: T, b: U) -> <T as sealed::VectorAllGt<U>>::Result
4329where
4330    T: sealed::VectorAllGt<U>,
4331{
4332    a.vec_all_gt(b)
4333}
4334
4335/// Vector Any Element Greater Than
4336#[inline]
4337#[target_feature(enable = "altivec")]
4338#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4339pub unsafe fn vec_any_gt<T, U>(a: T, b: U) -> <T as sealed::VectorAnyGt<U>>::Result
4340where
4341    T: sealed::VectorAnyGt<U>,
4342{
4343    a.vec_any_gt(b)
4344}
4345
4346/// Vector All In
4347#[inline]
4348#[target_feature(enable = "altivec")]
4349#[cfg_attr(test, assert_instr("vcmpbfp."))]
4350#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4351pub unsafe fn vec_all_in(a: vector_float, b: vector_float) -> bool {
4352    vcmpbfp_p(0, a, b) != 0
4353}
4354
4355/// Vector All Elements Less Than or Equal
4356#[inline]
4357#[target_feature(enable = "altivec")]
4358#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4359pub unsafe fn vec_all_le<T, U>(a: U, b: T) -> <T as sealed::VectorAllGe<U>>::Result
4360where
4361    T: sealed::VectorAllGe<U>,
4362{
4363    b.vec_all_ge(a)
4364}
4365
4366/// Vector Any Element Less Than or Equal
4367#[inline]
4368#[target_feature(enable = "altivec")]
4369#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4370pub unsafe fn vec_any_le<T, U>(a: U, b: T) -> <T as sealed::VectorAnyGe<U>>::Result
4371where
4372    T: sealed::VectorAnyGe<U>,
4373{
4374    b.vec_any_ge(a)
4375}
4376
4377/// Vector All Elements Less Than
4378#[inline]
4379#[target_feature(enable = "altivec")]
4380#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4381pub unsafe fn vec_all_lt<T, U>(a: U, b: T) -> <T as sealed::VectorAllGt<U>>::Result
4382where
4383    T: sealed::VectorAllGt<U>,
4384{
4385    b.vec_all_gt(a)
4386}
4387
4388/// Vector Any Element Less Than
4389#[inline]
4390#[target_feature(enable = "altivec")]
4391#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4392pub unsafe fn vec_any_lt<T, U>(a: U, b: T) -> <T as sealed::VectorAnyGt<U>>::Result
4393where
4394    T: sealed::VectorAnyGt<U>,
4395{
4396    b.vec_any_gt(a)
4397}
4398
4399/// All Elements Not a Number
4400#[inline]
4401#[target_feature(enable = "altivec")]
4402#[cfg_attr(test, assert_instr("vcmpeqfp."))]
4403#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4404pub unsafe fn vec_all_nan(a: vector_float) -> bool {
4405    vcmpeqfp_p(0, a, a) != 0
4406}
4407
4408/// Any Elements Not a Number
4409#[inline]
4410#[target_feature(enable = "altivec")]
4411#[cfg_attr(test, assert_instr("vcmpeqfp."))]
4412#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4413pub unsafe fn vec_any_nan(a: vector_float) -> bool {
4414    vcmpeqfp_p(3, a, a) != 0
4415}
4416
4417/// Vector All Elements Not Equal
4418#[inline]
4419#[target_feature(enable = "altivec")]
4420#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4421pub unsafe fn vec_all_ne<T, U>(a: T, b: U) -> <T as sealed::VectorAllNe<U>>::Result
4422where
4423    T: sealed::VectorAllNe<U>,
4424{
4425    a.vec_all_ne(b)
4426}
4427
4428/// Vector Any Elements Not Equal
4429#[inline]
4430#[target_feature(enable = "altivec")]
4431#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4432pub unsafe fn vec_any_ne<T, U>(a: T, b: U) -> <T as sealed::VectorAnyNe<U>>::Result
4433where
4434    T: sealed::VectorAnyNe<U>,
4435{
4436    a.vec_any_ne(b)
4437}
4438
4439/// All Elements Not Greater Than or Equal
4440#[inline]
4441#[target_feature(enable = "altivec")]
4442#[cfg_attr(test, assert_instr("vcmpgefp."))]
4443#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4444pub unsafe fn vec_all_nge(a: vector_float, b: vector_float) -> bool {
4445    vcmpgefp_p(0, a, b) != 0
4446}
4447
4448/// All Elements Not Greater Than
4449#[inline]
4450#[target_feature(enable = "altivec")]
4451#[cfg_attr(test, assert_instr("vcmpgtfp."))]
4452#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4453pub unsafe fn vec_all_ngt(a: vector_float, b: vector_float) -> bool {
4454    vcmpgtfp_p(0, a, b) != 0
4455}
4456
4457/// All Elements Not Less Than or Equal
4458#[inline]
4459#[target_feature(enable = "altivec")]
4460#[cfg_attr(test, assert_instr("vcmpgefp."))]
4461#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4462pub unsafe fn vec_all_nle(a: vector_float, b: vector_float) -> bool {
4463    vcmpgefp_p(0, b, a) != 0
4464}
4465
4466/// All Elements Not Less Than
4467#[inline]
4468#[target_feature(enable = "altivec")]
4469#[cfg_attr(test, assert_instr("vcmpgtfp."))]
4470#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4471pub unsafe fn vec_all_nlt(a: vector_float, b: vector_float) -> bool {
4472    vcmpgtfp_p(0, b, a) != 0
4473}
4474
4475/// All Elements Numeric
4476#[inline]
4477#[target_feature(enable = "altivec")]
4478#[cfg_attr(test, assert_instr("vcmpgefp."))]
4479#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4480pub unsafe fn vec_all_numeric(a: vector_float) -> bool {
4481    vcmpgefp_p(2, a, a) != 0
4482}
4483
4484/// Any Elements Not Greater Than or Equal
4485#[inline]
4486#[target_feature(enable = "altivec")]
4487#[cfg_attr(test, assert_instr("vcmpgefp."))]
4488#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4489pub unsafe fn vec_any_nge(a: vector_float, b: vector_float) -> bool {
4490    vcmpgefp_p(3, a, b) != 0
4491}
4492
4493/// Any Elements Not Greater Than
4494#[inline]
4495#[target_feature(enable = "altivec")]
4496#[cfg_attr(test, assert_instr("vcmpgtfp."))]
4497#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4498pub unsafe fn vec_any_ngt(a: vector_float, b: vector_float) -> bool {
4499    vcmpgtfp_p(3, a, b) != 0
4500}
4501
4502/// Any Elements Not Less Than or Equal
4503#[inline]
4504#[target_feature(enable = "altivec")]
4505#[cfg_attr(test, assert_instr("vcmpgefp."))]
4506#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4507pub unsafe fn vec_any_nle(a: vector_float, b: vector_float) -> bool {
4508    vcmpgefp_p(3, b, a) != 0
4509}
4510
4511/// Any Elements Not Less Than
4512#[inline]
4513#[target_feature(enable = "altivec")]
4514#[cfg_attr(test, assert_instr("vcmpgtfp."))]
4515#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4516pub unsafe fn vec_any_nlt(a: vector_float, b: vector_float) -> bool {
4517    vcmpgtfp_p(3, b, a) != 0
4518}
4519
4520/// Any Elements Numeric
4521#[inline]
4522#[target_feature(enable = "altivec")]
4523#[cfg_attr(test, assert_instr("vcmpgefp."))]
4524#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4525pub unsafe fn vec_any_numeric(a: vector_float) -> bool {
4526    vcmpgefp_p(1, a, a) != 0
4527}
4528
4529/// Vector Count Leading Zeros
4530///
4531/// ## Purpose
4532/// Returns a vector containing the number of most-significant bits equal to zero of each
4533/// corresponding element of the source vector.
4534///
4535/// ## Result value
4536/// The value of each element of r is set to the number of leading zeros of the
4537/// corresponding element of a.
4538#[inline]
4539#[target_feature(enable = "altivec")]
4540#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4541pub unsafe fn vec_cntlz<T>(a: T) -> T
4542where
4543    T: sealed::VectorCntlz,
4544{
4545    a.vec_cntlz()
4546}
4547
4548/// Any Element Out of Bounds
4549#[inline]
4550#[target_feature(enable = "altivec")]
4551#[cfg_attr(test, assert_instr("vcmpeqfp."))]
4552#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4553pub unsafe fn vec_any_out(a: vector_float) -> bool {
4554    vcmpeqfp_p(1, a, a) != 0
4555}
4556
4557#[cfg(target_endian = "big")]
4558mod endian {
4559    use super::*;
4560    /// Vector permute.
4561    #[inline]
4562    #[target_feature(enable = "altivec")]
4563    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
4564    pub unsafe fn vec_perm<T>(a: T, b: T, c: vector_unsigned_char) -> T
4565    where
4566        T: sealed::VectorPerm,
4567    {
4568        a.vec_vperm(b, c)
4569    }
4570
4571    /// Vector Sum Across Partial (1/2) Saturated
4572    #[inline]
4573    #[target_feature(enable = "altivec")]
4574    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
4575    pub unsafe fn vec_sum2s(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
4576        vsum2sws(a, b)
4577    }
4578
4579    /// Vector Multiply Even
4580    #[inline]
4581    #[target_feature(enable = "altivec")]
4582    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
4583    pub unsafe fn vec_mule<T, U>(a: T, b: T) -> U
4584    where
4585        T: sealed::VectorMule<U>,
4586    {
4587        a.vec_mule(b)
4588    }
4589    /// Vector Multiply Odd
4590    #[inline]
4591    #[target_feature(enable = "altivec")]
4592    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
4593    pub unsafe fn vec_mulo<T, U>(a: T, b: T) -> U
4594    where
4595        T: sealed::VectorMulo<U>,
4596    {
4597        a.vec_mulo(b)
4598    }
4599}
4600
4601#[unstable(feature = "stdarch_powerpc", issue = "111145")]
4602pub use self::endian::*;
4603
4604#[cfg(test)]
4605mod tests {
4606    use super::*;
4607
4608    use std::mem::transmute;
4609
4610    use crate::core_arch::simd::*;
4611    use stdarch_test::simd_test;
4612
4613    macro_rules! test_vec_2 {
4614        { $name: ident, $fn:ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
4615            test_vec_2! { $name, $fn, $ty -> $ty, [$($a),+], [$($b),+], [$($d),+] }
4616        };
4617        { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
4618            #[simd_test(enable = "altivec")]
4619            unsafe fn $name() {
4620                let a: s_t_l!($ty) = transmute($ty::new($($a),+));
4621                let b: s_t_l!($ty) = transmute($ty::new($($b),+));
4622
4623                let d = $ty_out::new($($d),+);
4624                let r : $ty_out = transmute($fn(a, b));
4625                assert_eq!(d, r);
4626            }
4627         };
4628         { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], $d:expr } => {
4629            #[simd_test(enable = "altivec")]
4630            unsafe fn $name() {
4631                let a: s_t_l!($ty) = transmute($ty::new($($a),+));
4632                let b: s_t_l!($ty) = transmute($ty::new($($b),+));
4633
4634                let r : $ty_out = transmute($fn(a, b));
4635                assert_eq!($d, r);
4636            }
4637         }
4638   }
4639
4640    macro_rules! test_vec_1 {
4641        { $name: ident, $fn:ident, f32x4, [$($a:expr),+], ~[$($d:expr),+] } => {
4642            #[simd_test(enable = "altivec")]
4643            unsafe fn $name() {
4644                let a: vector_float = transmute(f32x4::new($($a),+));
4645
4646                let d: vector_float = transmute(f32x4::new($($d),+));
4647                let r = transmute(vec_cmple(vec_abs(vec_sub($fn(a), d)), vec_splats(f32::EPSILON)));
4648                let e = m32x4::new(true, true, true, true);
4649                assert_eq!(e, r);
4650            }
4651        };
4652        { $name: ident, $fn:ident, $ty: ident, [$($a:expr),+], [$($d:expr),+] } => {
4653            test_vec_1! { $name, $fn, $ty -> $ty, [$($a),+], [$($d),+] }
4654        };
4655        { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($d:expr),+] } => {
4656            #[simd_test(enable = "altivec")]
4657            unsafe fn $name() {
4658                let a: s_t_l!($ty) = transmute($ty::new($($a),+));
4659
4660                let d = $ty_out::new($($d),+);
4661                let r : $ty_out = transmute($fn(a));
4662                assert_eq!(d, r);
4663            }
4664        }
4665    }
4666
4667    #[simd_test(enable = "altivec")]
4668    unsafe fn test_vec_ld() {
4669        let pat = [
4670            u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
4671            u8x16::new(
4672                16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
4673            ),
4674        ];
4675
4676        for off in 0..16 {
4677            let v: u8x16 = transmute(vec_ld(0, (pat.as_ptr() as *const u8).offset(off)));
4678            assert_eq!(
4679                v,
4680                u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
4681            );
4682        }
4683        for off in 16..32 {
4684            let v: u8x16 = transmute(vec_ld(0, (pat.as_ptr() as *const u8).offset(off)));
4685            assert_eq!(
4686                v,
4687                u8x16::new(
4688                    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
4689                )
4690            );
4691        }
4692    }
4693
4694    #[simd_test(enable = "altivec")]
4695    unsafe fn test_vec_xl() {
4696        let pat = [
4697            u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
4698            u8x16::new(
4699                16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
4700            ),
4701        ];
4702
4703        for off in 0..16 {
4704            let val: u8x16 = transmute(vec_xl(0, (pat.as_ptr() as *const u8).offset(off)));
4705            for i in 0..16 {
4706                let v = val.extract(i);
4707                assert_eq!(off as usize + i, v as usize);
4708            }
4709        }
4710    }
4711
4712    #[simd_test(enable = "altivec")]
4713    unsafe fn test_vec_xst() {
4714        let v: vector_unsigned_char = transmute(u8x16::new(
4715            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4716        ));
4717
4718        for off in 0..16 {
4719            let mut buf = [0u8; 32];
4720            vec_xst(v, 0, (buf.as_mut_ptr() as *mut u8).offset(off));
4721            for i in 0..16 {
4722                assert_eq!(i as u8, buf[off as usize..][i]);
4723            }
4724        }
4725    }
4726
4727    #[simd_test(enable = "altivec")]
4728    unsafe fn test_vec_ldl() {
4729        let pat = [
4730            u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
4731            u8x16::new(
4732                16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
4733            ),
4734        ];
4735
4736        for off in 0..16 {
4737            let v: u8x16 = transmute(vec_ldl(0, (pat.as_ptr() as *const u8).offset(off)));
4738            assert_eq!(
4739                v,
4740                u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
4741            );
4742        }
4743        for off in 16..32 {
4744            let v: u8x16 = transmute(vec_ldl(0, (pat.as_ptr() as *const u8).offset(off)));
4745            assert_eq!(
4746                v,
4747                u8x16::new(
4748                    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
4749                )
4750            );
4751        }
4752    }
4753
4754    #[simd_test(enable = "altivec")]
4755    unsafe fn test_vec_lde_u8() {
4756        let pat = [u8x16::new(
4757            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4758        )];
4759        for off in 0..16 {
4760            let v: u8x16 = transmute(vec_lde(off, pat.as_ptr() as *const u8));
4761            assert_eq!(off as u8, v.extract(off as _));
4762        }
4763    }
4764
4765    #[simd_test(enable = "altivec")]
4766    unsafe fn test_vec_lde_u16() {
4767        let pat = [u16x8::new(0, 1, 2, 3, 4, 5, 6, 7)];
4768        for off in 0..8 {
4769            let v: u16x8 = transmute(vec_lde(off * 2, pat.as_ptr() as *const u16));
4770            assert_eq!(off as u16, v.extract(off as _));
4771        }
4772    }
4773
4774    #[simd_test(enable = "altivec")]
4775    unsafe fn test_vec_lde_u32() {
4776        let pat = [u32x4::new(0, 1, 2, 3)];
4777        for off in 0..4 {
4778            let v: u32x4 = transmute(vec_lde(off * 4, pat.as_ptr() as *const u32));
4779            assert_eq!(off as u32, v.extract(off as _));
4780        }
4781    }
4782
4783    test_vec_1! { test_vec_floor, vec_floor, f32x4,
4784        [1.1, 1.9, -0.5, -0.9],
4785        [1.0, 1.0, -1.0, -1.0]
4786    }
4787
4788    test_vec_1! { test_vec_expte, vec_expte, f32x4,
4789        [0.0, 2.0, 2.0, -1.0],
4790        ~[1.0, 4.0, 4.0, 0.5]
4791    }
4792
4793    test_vec_2! { test_vec_cmpgt_i8, vec_cmpgt, i8x16 -> m8x16,
4794        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4795        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4796        [true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false]
4797    }
4798
4799    test_vec_2! { test_vec_cmpgt_u8, vec_cmpgt, u8x16 -> m8x16,
4800        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4801        [0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4802        [true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
4803    }
4804
4805    test_vec_2! { test_vec_cmpgt_i16, vec_cmpgt, i16x8 -> m16x8,
4806        [1, -1, 0, 0, 0, 0, 0, 0],
4807        [0, 0, -1, 1, 0, 0, 0, 0],
4808        [true, false, true, false, false, false, false, false]
4809    }
4810
4811    test_vec_2! { test_vec_cmpgt_u16, vec_cmpgt, u16x8 -> m16x8,
4812        [1, 255, 0, 0, 0, 0, 0, 0],
4813        [0, 0, 255, 1, 0, 0, 0, 0],
4814        [true, true, false, false, false, false, false, false]
4815    }
4816
4817    test_vec_2! { test_vec_cmpgt_i32, vec_cmpgt, i32x4 -> m32x4,
4818        [1, -1, 0, 0],
4819        [0, -1, 0, 1],
4820        [true, false, false, false]
4821    }
4822
4823    test_vec_2! { test_vec_cmpgt_u32, vec_cmpgt, u32x4 -> m32x4,
4824        [1, 255, 0, 0],
4825        [0, 255,  0, 1],
4826        [true, false, false, false]
4827    }
4828
4829    test_vec_2! { test_vec_cmpge, vec_cmpge, f32x4 -> m32x4,
4830        [0.1, -0.1, 0.0, 0.99],
4831        [0.1, 0.0, 0.1, 1.0],
4832        [true, false, false, false]
4833    }
4834
4835    test_vec_2! { test_vec_cmpeq_i8, vec_cmpeq, i8x16 -> m8x16,
4836        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4837        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4838        [false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true]
4839    }
4840
4841    test_vec_2! { test_vec_cmpeq_u8, vec_cmpeq, u8x16 -> m8x16,
4842        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4843        [0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4844        [false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true]
4845    }
4846
4847    test_vec_2! { test_vec_cmpeq_i16, vec_cmpeq, i16x8 -> m16x8,
4848        [1, -1, 0, 0, 0, 0, 0, 0],
4849        [0, 0, -1, 1, 0, 0, 0, 0],
4850        [false, false, false, false, true, true, true, true]
4851    }
4852
4853    test_vec_2! { test_vec_cmpeq_u16, vec_cmpeq, u16x8 -> m16x8,
4854        [1, 255, 0, 0, 0, 0, 0, 0],
4855        [0, 0, 255, 1, 0, 0, 0, 0],
4856        [false, false, false, false, true, true, true, true]
4857    }
4858
4859    test_vec_2! { test_vec_cmpeq_i32, vec_cmpeq, i32x4 -> m32x4,
4860        [1, -1, 0, 0],
4861        [0, -1, 0, 1],
4862        [false, true, true, false]
4863    }
4864
4865    test_vec_2! { test_vec_cmpeq_u32, vec_cmpeq, u32x4 -> m32x4,
4866        [1, 255, 0, 0],
4867        [0, 255,  0, 1],
4868        [false, true, true, false]
4869    }
4870
4871    test_vec_2! { test_vec_cmpne_i8, vec_cmpne, i8x16 -> m8x16,
4872        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4873        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4874        [true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false]
4875    }
4876
4877    test_vec_2! { test_vec_cmpne_u8, vec_cmpne, u8x16 -> m8x16,
4878        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4879        [0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4880        [true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false]
4881    }
4882
4883    test_vec_2! { test_vec_cmpne_i16, vec_cmpne, i16x8 -> m16x8,
4884        [1, -1, 0, 0, 0, 0, 0, 0],
4885        [0, 0, -1, 1, 0, 0, 0, 0],
4886        [true, true, true, true, false, false, false, false]
4887    }
4888
4889    test_vec_2! { test_vec_cmpne_u16, vec_cmpne, u16x8 -> m16x8,
4890        [1, 255, 0, 0, 0, 0, 0, 0],
4891        [0, 0, 255, 1, 0, 0, 0, 0],
4892        [true, true, true, true, false, false, false, false]
4893    }
4894
4895    test_vec_2! { test_vec_cmpne_i32, vec_cmpne, i32x4 -> m32x4,
4896        [1, -1, 0, 0],
4897        [0, -1, 0, 1],
4898        [true, false, false, true]
4899    }
4900
4901    test_vec_2! { test_vec_cmpne_u32, vec_cmpne, u32x4 -> m32x4,
4902        [1, 255, 0, 0],
4903        [0, 255,  0, 1],
4904        [true, false, false, true]
4905    }
4906
4907    test_vec_2! { test_vec_all_eq_i8_false, vec_all_eq, i8x16 -> bool,
4908        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4909        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4910        false
4911    }
4912
4913    test_vec_2! { test_vec_all_eq_u8_false, vec_all_eq, u8x16 -> bool,
4914        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4915        [0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4916        false
4917    }
4918
4919    test_vec_2! { test_vec_all_eq_i16_false, vec_all_eq, i16x8 -> bool,
4920        [1, -1, 0, 0, 0, 0, 0, 0],
4921        [0, 0, -1, 1, 0, 0, 0, 0],
4922        false
4923    }
4924
4925    test_vec_2! { test_vec_all_eq_u16_false, vec_all_eq, u16x8 -> bool,
4926        [1, 255, 0, 0, 0, 0, 0, 0],
4927        [0, 0, 255, 1, 0, 0, 0, 0],
4928        false
4929    }
4930
4931    test_vec_2! { test_vec_all_eq_i32_false, vec_all_eq, i32x4 -> bool,
4932        [1, -1, 0, 0],
4933        [0, -1, 0, 1],
4934        false
4935    }
4936
4937    test_vec_2! { test_vec_all_eq_u32_false, vec_all_eq, u32x4 -> bool,
4938        [1, 255, 0, 0],
4939        [0, 255,  0, 1],
4940        false
4941    }
4942
4943    test_vec_2! { test_vec_all_eq_i8_true, vec_all_eq, i8x16 -> bool,
4944        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4945        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4946        true
4947    }
4948
4949    test_vec_2! { test_vec_all_eq_u8_true, vec_all_eq, u8x16 -> bool,
4950        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4951        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4952        true
4953    }
4954
4955    test_vec_2! { test_vec_all_eq_i16_true, vec_all_eq, i16x8 -> bool,
4956        [1, -1, 1, 0, 0, 0, 0, 0],
4957        [1, -1, 1, 0, 0, 0, 0, 0],
4958        true
4959    }
4960
4961    test_vec_2! { test_vec_all_eq_u16_true, vec_all_eq, u16x8 -> bool,
4962        [1, 255, 1, 0, 0, 0, 0, 0],
4963        [1, 255, 1, 0, 0, 0, 0, 0],
4964        true
4965    }
4966
4967    test_vec_2! { test_vec_all_eq_i32_true, vec_all_eq, i32x4 -> bool,
4968        [1, -1, 0, 1],
4969        [1, -1, 0, 1],
4970        true
4971    }
4972
4973    test_vec_2! { test_vec_all_eq_u32_true, vec_all_eq, u32x4 -> bool,
4974        [1, 255, 0, 1],
4975        [1, 255, 0, 1],
4976        true
4977    }
4978
4979    test_vec_2! { test_vec_any_eq_i8_false, vec_any_eq, i8x16 -> bool,
4980        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4981        [0, 0, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
4982        false
4983    }
4984
4985    test_vec_2! { test_vec_any_eq_u8_false, vec_any_eq, u8x16 -> bool,
4986        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
4987        [0, 0, 255, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
4988        false
4989    }
4990
4991    test_vec_2! { test_vec_any_eq_i16_false, vec_any_eq, i16x8 -> bool,
4992        [1, -1, 0, 0, 0, 0, 0, 0],
4993        [0, 0, -1, 1, 1, 1, 1, 1],
4994        false
4995    }
4996
4997    test_vec_2! { test_vec_any_eq_u16_false, vec_any_eq, u16x8 -> bool,
4998        [1, 255, 0, 0, 0, 0, 0, 0],
4999        [0, 0, 255, 1, 1, 1, 1, 1],
5000        false
5001    }
5002
5003    test_vec_2! { test_vec_any_eq_i32_false, vec_any_eq, i32x4 -> bool,
5004        [1, -1, 0, 0],
5005        [0, -2, 1, 1],
5006        false
5007    }
5008
5009    test_vec_2! { test_vec_any_eq_u32_false, vec_any_eq, u32x4 -> bool,
5010        [1, 2, 1, 0],
5011        [0, 255,  0, 1],
5012        false
5013    }
5014
5015    test_vec_2! { test_vec_any_eq_i8_true, vec_any_eq, i8x16 -> bool,
5016        [1, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5017        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5018        true
5019    }
5020
5021    test_vec_2! { test_vec_any_eq_u8_true, vec_any_eq, u8x16 -> bool,
5022        [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5023        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5024        true
5025    }
5026
5027    test_vec_2! { test_vec_any_eq_i16_true, vec_any_eq, i16x8 -> bool,
5028        [0, -1, 1, 0, 0, 0, 0, 0],
5029        [1, -1, 1, 0, 0, 0, 0, 0],
5030        true
5031    }
5032
5033    test_vec_2! { test_vec_any_eq_u16_true, vec_any_eq, u16x8 -> bool,
5034        [0, 255, 1, 0, 0, 0, 0, 0],
5035        [1, 255, 1, 0, 0, 0, 0, 0],
5036        true
5037    }
5038
5039    test_vec_2! { test_vec_any_eq_i32_true, vec_any_eq, i32x4 -> bool,
5040        [0, -1, 0, 1],
5041        [1, -1, 0, 1],
5042        true
5043    }
5044
5045    test_vec_2! { test_vec_any_eq_u32_true, vec_any_eq, u32x4 -> bool,
5046        [0, 255, 0, 1],
5047        [1, 255, 0, 1],
5048        true
5049    }
5050
5051    test_vec_2! { test_vec_all_ge_i8_false, vec_all_ge, i8x16 -> bool,
5052        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5053        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5054        false
5055    }
5056
5057    test_vec_2! { test_vec_all_ge_u8_false, vec_all_ge, u8x16 -> bool,
5058        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5059        [0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5060        false
5061    }
5062
5063    test_vec_2! { test_vec_all_ge_i16_false, vec_all_ge, i16x8 -> bool,
5064        [1, -1, 0, 0, 0, 0, 0, 0],
5065        [0, 0, -1, 1, 0, 0, 0, 0],
5066        false
5067    }
5068
5069    test_vec_2! { test_vec_all_ge_u16_false, vec_all_ge, u16x8 -> bool,
5070        [1, 255, 0, 0, 0, 0, 0, 0],
5071        [0, 0, 255, 1, 0, 0, 0, 0],
5072        false
5073    }
5074
5075    test_vec_2! { test_vec_all_ge_i32_false, vec_all_ge, i32x4 -> bool,
5076        [1, -1, 0, 0],
5077        [0, -1, 0, 1],
5078        false
5079    }
5080
5081    test_vec_2! { test_vec_all_ge_u32_false, vec_all_ge, u32x4 -> bool,
5082        [1, 255, 0, 0],
5083        [0, 255,  1, 1],
5084        false
5085    }
5086
5087    test_vec_2! { test_vec_all_ge_i8_true, vec_all_ge, i8x16 -> bool,
5088        [0, 0, -1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
5089        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5090        true
5091    }
5092
5093    test_vec_2! { test_vec_all_ge_u8_true, vec_all_ge, u8x16 -> bool,
5094        [1, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5095        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5096        true
5097    }
5098
5099    test_vec_2! { test_vec_all_ge_i16_true, vec_all_ge, i16x8 -> bool,
5100        [1, -1, 42, 0, 0, 0, 0, 0],
5101        [1, -5, 2, 0, 0, 0, 0, 0],
5102        true
5103    }
5104
5105    test_vec_2! { test_vec_all_ge_u16_true, vec_all_ge, u16x8 -> bool,
5106        [42, 255, 1, 0, 0, 0, 0, 0],
5107        [2, 255, 1, 0, 0, 0, 0, 0],
5108        true
5109    }
5110
5111    test_vec_2! { test_vec_all_ge_i32_true, vec_all_ge, i32x4 -> bool,
5112        [1, -1, 0, 1],
5113        [0, -1, 0, 1],
5114        true
5115    }
5116
5117    test_vec_2! { test_vec_all_ge_u32_true, vec_all_ge, u32x4 -> bool,
5118        [1, 255, 0, 1],
5119        [1, 254, 0, 0],
5120        true
5121    }
5122
5123    test_vec_2! { test_vec_any_ge_i8_false, vec_any_ge, i8x16 -> bool,
5124        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5125        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5126        false
5127    }
5128
5129    test_vec_2! { test_vec_any_ge_u8_false, vec_any_ge, u8x16 -> bool,
5130        [1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5131        [42, 255, 255, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5132        false
5133    }
5134
5135    test_vec_2! { test_vec_any_ge_i16_false, vec_any_ge, i16x8 -> bool,
5136        [1, -1, -2, 0, 0, 0, 0, 0],
5137        [2, 0, -1, 1, 1, 1, 1, 1],
5138        false
5139    }
5140
5141    test_vec_2! { test_vec_any_ge_u16_false, vec_any_ge, u16x8 -> bool,
5142        [1, 2, 0, 0, 0, 0, 0, 0],
5143        [2, 42, 255, 1, 1, 1, 1, 1],
5144        false
5145    }
5146
5147    test_vec_2! { test_vec_any_ge_i32_false, vec_any_ge, i32x4 -> bool,
5148        [1, -1, 0, 0],
5149        [2, 0, 1, 1],
5150        false
5151    }
5152
5153    test_vec_2! { test_vec_any_ge_u32_false, vec_any_ge, u32x4 -> bool,
5154        [1, 2, 1, 0],
5155        [4, 255,  4, 1],
5156        false
5157    }
5158
5159    test_vec_2! { test_vec_any_ge_i8_true, vec_any_ge, i8x16 -> bool,
5160        [1, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5161        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5162        true
5163    }
5164
5165    test_vec_2! { test_vec_any_ge_u8_true, vec_any_ge, u8x16 -> bool,
5166        [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5167        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5168        true
5169    }
5170
5171    test_vec_2! { test_vec_any_ge_i16_true, vec_any_ge, i16x8 -> bool,
5172        [0, -1, 1, 0, 0, 0, 0, 0],
5173        [1, -1, 1, 0, 0, 0, 0, 0],
5174        true
5175    }
5176
5177    test_vec_2! { test_vec_any_ge_u16_true, vec_any_ge, u16x8 -> bool,
5178        [0, 255, 1, 0, 0, 0, 0, 0],
5179        [1, 255, 1, 0, 0, 0, 0, 0],
5180        true
5181    }
5182
5183    test_vec_2! { test_vec_any_ge_i32_true, vec_any_ge, i32x4 -> bool,
5184        [0, -1, 0, 1],
5185        [1, -1, 0, 1],
5186        true
5187    }
5188
5189    test_vec_2! { test_vec_any_ge_u32_true, vec_any_ge, u32x4 -> bool,
5190        [0, 255, 0, 1],
5191        [1, 255, 0, 1],
5192        true
5193    }
5194
5195    test_vec_2! { test_vec_all_gt_i8_false, vec_all_gt, i8x16 -> bool,
5196        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5197        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5198        false
5199    }
5200
5201    test_vec_2! { test_vec_all_gt_u8_false, vec_all_gt, u8x16 -> bool,
5202        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5203        [0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5204        false
5205    }
5206
5207    test_vec_2! { test_vec_all_gt_i16_false, vec_all_gt, i16x8 -> bool,
5208        [1, 0, 0, 0, 0, 0, 0, 0],
5209        [0, 0, -1, 1, 0, 0, 0, 0],
5210        false
5211    }
5212
5213    test_vec_2! { test_vec_all_gt_u16_false, vec_all_gt, u16x8 -> bool,
5214        [1, 0, 0, 0, 0, 0, 0, 0],
5215        [0, 0, 255, 1, 0, 0, 0, 0],
5216        false
5217    }
5218
5219    test_vec_2! { test_vec_all_gt_i32_false, vec_all_gt, i32x4 -> bool,
5220        [1, -1, 0, 0],
5221        [0, -1, 0, 1],
5222        false
5223    }
5224
5225    test_vec_2! { test_vec_all_gt_u32_false, vec_all_gt, u32x4 -> bool,
5226        [1, 255, 0, 0],
5227        [0, 255,  1, 1],
5228        false
5229    }
5230
5231    test_vec_2! { test_vec_all_gt_i8_true, vec_all_gt, i8x16 -> bool,
5232        [2, 1, -1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
5233        [0, 0, -2, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
5234        true
5235    }
5236
5237    test_vec_2! { test_vec_all_gt_u8_true, vec_all_gt, u8x16 -> bool,
5238        [1, 255, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5239        [0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5240        true
5241    }
5242
5243    test_vec_2! { test_vec_all_gt_i16_true, vec_all_gt, i16x8 -> bool,
5244        [1, -1, 42, 1, 1, 1, 1, 1],
5245        [0, -5, 2, 0, 0, 0, 0, 0],
5246        true
5247    }
5248
5249    test_vec_2! { test_vec_all_gt_u16_true, vec_all_gt, u16x8 -> bool,
5250        [42, 255, 1, 1, 1, 1, 1, 1],
5251        [2, 254, 0, 0, 0, 0, 0, 0],
5252        true
5253    }
5254
5255    test_vec_2! { test_vec_all_gt_i32_true, vec_all_gt, i32x4 -> bool,
5256        [1, -1, 1, 1],
5257        [0, -2, 0, 0],
5258        true
5259    }
5260
5261    test_vec_2! { test_vec_all_gt_u32_true, vec_all_gt, u32x4 -> bool,
5262        [1, 255, 1, 1],
5263        [0, 254, 0, 0],
5264        true
5265    }
5266
5267    test_vec_2! { test_vec_any_gt_i8_false, vec_any_gt, i8x16 -> bool,
5268        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5269        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5270        false
5271    }
5272
5273    test_vec_2! { test_vec_any_gt_u8_false, vec_any_gt, u8x16 -> bool,
5274        [1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5275        [42, 255, 255, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5276        false
5277    }
5278
5279    test_vec_2! { test_vec_any_gt_i16_false, vec_any_gt, i16x8 -> bool,
5280        [1, -1, -2, 0, 0, 0, 0, 0],
5281        [2, 0, -1, 1, 1, 1, 1, 1],
5282        false
5283    }
5284
5285    test_vec_2! { test_vec_any_gt_u16_false, vec_any_gt, u16x8 -> bool,
5286        [1, 2, 0, 0, 0, 0, 0, 0],
5287        [2, 42, 255, 1, 1, 1, 1, 1],
5288        false
5289    }
5290
5291    test_vec_2! { test_vec_any_gt_i32_false, vec_any_gt, i32x4 -> bool,
5292        [1, -1, 0, 0],
5293        [2, 0, 1, 1],
5294        false
5295    }
5296
5297    test_vec_2! { test_vec_any_gt_u32_false, vec_any_gt, u32x4 -> bool,
5298        [1, 2, 1, 0],
5299        [4, 255,  4, 1],
5300        false
5301    }
5302
5303    test_vec_2! { test_vec_any_gt_i8_true, vec_any_gt, i8x16 -> bool,
5304        [1, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5305        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5306        true
5307    }
5308
5309    test_vec_2! { test_vec_any_gt_u8_true, vec_any_gt, u8x16 -> bool,
5310        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5311        [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5312        true
5313    }
5314
5315    test_vec_2! { test_vec_any_gt_i16_true, vec_any_gt, i16x8 -> bool,
5316        [1, -1, 1, 0, 0, 0, 0, 0],
5317        [0, -1, 1, 0, 0, 0, 0, 0],
5318        true
5319    }
5320
5321    test_vec_2! { test_vec_any_gt_u16_true, vec_any_gt, u16x8 -> bool,
5322        [1, 255, 1, 0, 0, 0, 0, 0],
5323        [0, 255, 1, 0, 0, 0, 0, 0],
5324        true
5325    }
5326
5327    test_vec_2! { test_vec_any_gt_i32_true, vec_any_gt, i32x4 -> bool,
5328        [1, -1, 0, 1],
5329        [0, -1, 0, 1],
5330        true
5331    }
5332
5333    test_vec_2! { test_vec_any_gt_u32_true, vec_any_gt, u32x4 -> bool,
5334        [1, 255, 0, 1],
5335        [0, 255, 0, 1],
5336        true
5337    }
5338
5339    test_vec_2! { test_vec_all_in_true, vec_all_in, f32x4 -> bool,
5340        [0.0, -0.1, 0.0, 0.0],
5341        [0.1, 0.2, 0.0, 0.0],
5342        true
5343    }
5344
5345    test_vec_2! { test_vec_all_in_false, vec_all_in, f32x4 -> bool,
5346        [0.5, 0.4, -0.5, 0.8],
5347        [0.1, 0.4, -0.5, 0.8],
5348        false
5349    }
5350
5351    test_vec_2! { test_vec_all_le_i8_false, vec_all_le, i8x16 -> bool,
5352        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5353        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5354        false
5355    }
5356
5357    test_vec_2! { test_vec_all_le_u8_false, vec_all_le, u8x16 -> bool,
5358        [0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5359        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5360        false
5361    }
5362
5363    test_vec_2! { test_vec_all_le_i16_false, vec_all_le, i16x8 -> bool,
5364        [0, 0, -1, 1, 0, 0, 0, 0],
5365        [1, -1, 0, 0, 0, 0, 0, 0],
5366        false
5367    }
5368
5369    test_vec_2! { test_vec_all_le_u16_false, vec_all_le, u16x8 -> bool,
5370        [0, 0, 255, 1, 0, 0, 0, 0],
5371        [1, 255, 0, 0, 0, 0, 0, 0],
5372        false
5373    }
5374
5375    test_vec_2! { test_vec_all_le_i32_false, vec_all_le, i32x4 -> bool,
5376        [0, -1, 0, 1],
5377        [1, -1, 0, 0],
5378        false
5379    }
5380
5381    test_vec_2! { test_vec_all_le_u32_false, vec_all_le, u32x4 -> bool,
5382        [0, 255,  1, 1],
5383        [1, 255, 0, 0],
5384        false
5385    }
5386
5387    test_vec_2! { test_vec_all_le_i8_true, vec_all_le, i8x16 -> bool,
5388        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5389        [0, 0, -1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
5390        true
5391    }
5392
5393    test_vec_2! { test_vec_all_le_u8_true, vec_all_le, u8x16 -> bool,
5394        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5395        [1, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5396        true
5397    }
5398
5399    test_vec_2! { test_vec_all_le_i16_true, vec_all_le, i16x8 -> bool,
5400        [1, -5, 2, 0, 0, 0, 0, 0],
5401        [1, -1, 42, 0, 0, 0, 0, 0],
5402        true
5403    }
5404
5405    test_vec_2! { test_vec_all_le_u16_true, vec_all_le, u16x8 -> bool,
5406        [2, 255, 1, 0, 0, 0, 0, 0],
5407        [42, 255, 1, 0, 0, 0, 0, 0],
5408        true
5409    }
5410
5411    test_vec_2! { test_vec_all_le_i32_true, vec_all_le, i32x4 -> bool,
5412        [0, -1, 0, 1],
5413        [1, -1, 0, 1],
5414        true
5415    }
5416
5417    test_vec_2! { test_vec_all_le_u32_true, vec_all_le, u32x4 -> bool,
5418        [1, 254, 0, 0],
5419        [1, 255, 0, 1],
5420        true
5421    }
5422
5423    test_vec_2! { test_vec_any_le_i8_false, vec_any_le, i8x16 -> bool,
5424        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5425        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5426        false
5427    }
5428
5429    test_vec_2! { test_vec_any_le_u8_false, vec_any_le, u8x16 -> bool,
5430        [42, 255, 255, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5431        [1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5432        false
5433    }
5434
5435    test_vec_2! { test_vec_any_le_i16_false, vec_any_le, i16x8 -> bool,
5436        [2, 0, -1, 1, 1, 1, 1, 1],
5437        [1, -1, -2, 0, 0, 0, 0, 0],
5438        false
5439    }
5440
5441    test_vec_2! { test_vec_any_le_u16_false, vec_any_le, u16x8 -> bool,
5442        [2, 42, 255, 1, 1, 1, 1, 1],
5443        [1, 2, 0, 0, 0, 0, 0, 0],
5444        false
5445    }
5446
5447    test_vec_2! { test_vec_any_le_i32_false, vec_any_le, i32x4 -> bool,
5448        [2, 0, 1, 1],
5449        [1, -1, 0, 0],
5450        false
5451    }
5452
5453    test_vec_2! { test_vec_any_le_u32_false, vec_any_le, u32x4 -> bool,
5454        [4, 255,  4, 1],
5455        [1, 2, 1, 0],
5456        false
5457    }
5458
5459    test_vec_2! { test_vec_any_le_i8_true, vec_any_le, i8x16 -> bool,
5460        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5461        [1, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5462        true
5463    }
5464
5465    test_vec_2! { test_vec_any_le_u8_true, vec_any_le, u8x16 -> bool,
5466        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5467        [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5468        true
5469    }
5470
5471    test_vec_2! { test_vec_any_le_i16_true, vec_any_le, i16x8 -> bool,
5472        [1, -1, 1, 0, 0, 0, 0, 0],
5473        [0, -1, 1, 0, 0, 0, 0, 0],
5474        true
5475    }
5476
5477    test_vec_2! { test_vec_any_le_u16_true, vec_any_le, u16x8 -> bool,
5478        [1, 255, 1, 0, 0, 0, 0, 0],
5479        [0, 255, 1, 0, 0, 0, 0, 0],
5480        true
5481    }
5482
5483    test_vec_2! { test_vec_any_le_i32_true, vec_any_le, i32x4 -> bool,
5484        [1, -1, 0, 1],
5485        [0, -1, 0, 1],
5486        true
5487    }
5488
5489    test_vec_2! { test_vec_any_le_u32_true, vec_any_le, u32x4 -> bool,
5490        [1, 255, 0, 1],
5491        [0, 255, 0, 1],
5492        true
5493    }
5494
5495    test_vec_2! { test_vec_all_lt_i8_false, vec_all_lt, i8x16 -> bool,
5496        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5497        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5498        false
5499    }
5500
5501    test_vec_2! { test_vec_all_lt_u8_false, vec_all_lt, u8x16 -> bool,
5502        [0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5503        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5504        false
5505    }
5506
5507    test_vec_2! { test_vec_all_lt_i16_false, vec_all_lt, i16x8 -> bool,
5508        [0, 0, -1, 1, 0, 0, 0, 0],
5509        [1, 0, 0, 0, 0, 0, 0, 0],
5510        false
5511    }
5512
5513    test_vec_2! { test_vec_all_lt_u16_false, vec_all_lt, u16x8 -> bool,
5514        [0, 0, 255, 1, 0, 0, 0, 0],
5515        [1, 0, 0, 0, 0, 0, 0, 0],
5516        false
5517    }
5518
5519    test_vec_2! { test_vec_all_lt_i32_false, vec_all_lt, i32x4 -> bool,
5520        [0, -1, 0, 1],
5521        [1, -1, 0, 0],
5522        false
5523    }
5524
5525    test_vec_2! { test_vec_all_lt_u32_false, vec_all_lt, u32x4 -> bool,
5526        [0, 255,  1, 1],
5527        [1, 255, 0, 0],
5528        false
5529    }
5530
5531    test_vec_2! { test_vec_all_lt_i8_true, vec_all_lt, i8x16 -> bool,
5532        [0, 0, -2, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
5533        [2, 1, -1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
5534        true
5535    }
5536
5537    test_vec_2! { test_vec_all_lt_u8_true, vec_all_lt, u8x16 -> bool,
5538        [0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5539        [1, 255, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5540        true
5541    }
5542
5543    test_vec_2! { test_vec_all_lt_i16_true, vec_all_lt, i16x8 -> bool,
5544        [0, -5, 2, 0, 0, 0, 0, 0],
5545        [1, -1, 42, 1, 1, 1, 1, 1],
5546        true
5547    }
5548
5549    test_vec_2! { test_vec_all_lt_u16_true, vec_all_lt, u16x8 -> bool,
5550        [2, 254, 0, 0, 0, 0, 0, 0],
5551        [42, 255, 1, 1, 1, 1, 1, 1],
5552        true
5553    }
5554
5555    test_vec_2! { test_vec_all_lt_i32_true, vec_all_lt, i32x4 -> bool,
5556        [0, -2, 0, 0],
5557        [1, -1, 1, 1],
5558        true
5559    }
5560
5561    test_vec_2! { test_vec_all_lt_u32_true, vec_all_lt, u32x4 -> bool,
5562        [0, 254, 0, 0],
5563        [1, 255, 1, 1],
5564        true
5565    }
5566
5567    test_vec_2! { test_vec_any_lt_i8_false, vec_any_lt, i8x16 -> bool,
5568        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5569        [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5570        false
5571    }
5572
5573    test_vec_2! { test_vec_any_lt_u8_false, vec_any_lt, u8x16 -> bool,
5574        [42, 255, 255, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5575        [1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5576        false
5577    }
5578
5579    test_vec_2! { test_vec_any_lt_i16_false, vec_any_lt, i16x8 -> bool,
5580        [2, 0, -1, 1, 1, 1, 1, 1],
5581        [1, -1, -2, 0, 0, 0, 0, 0],
5582        false
5583    }
5584
5585    test_vec_2! { test_vec_any_lt_u16_false, vec_any_lt, u16x8 -> bool,
5586        [2, 42, 255, 1, 1, 1, 1, 1],
5587        [1, 2, 0, 0, 0, 0, 0, 0],
5588        false
5589    }
5590
5591    test_vec_2! { test_vec_any_lt_i32_false, vec_any_lt, i32x4 -> bool,
5592        [2, 0, 1, 1],
5593        [1, -1, 0, 0],
5594        false
5595    }
5596
5597    test_vec_2! { test_vec_any_lt_u32_false, vec_any_lt, u32x4 -> bool,
5598        [4, 255,  4, 1],
5599        [1, 2, 1, 0],
5600        false
5601    }
5602
5603    test_vec_2! { test_vec_any_lt_i8_true, vec_any_lt, i8x16 -> bool,
5604        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5605        [1, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5606        true
5607    }
5608
5609    test_vec_2! { test_vec_any_lt_u8_true, vec_any_lt, u8x16 -> bool,
5610        [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5611        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5612        true
5613    }
5614
5615    test_vec_2! { test_vec_any_lt_i16_true, vec_any_lt, i16x8 -> bool,
5616        [0, -1, 1, 0, 0, 0, 0, 0],
5617        [1, -1, 1, 0, 0, 0, 0, 0],
5618        true
5619    }
5620
5621    test_vec_2! { test_vec_any_lt_u16_true, vec_any_lt, u16x8 -> bool,
5622        [0, 255, 1, 0, 0, 0, 0, 0],
5623        [1, 255, 1, 0, 0, 0, 0, 0],
5624        true
5625    }
5626
5627    test_vec_2! { test_vec_any_lt_i32_true, vec_any_lt, i32x4 -> bool,
5628        [0, -1, 0, 1],
5629        [1, -1, 0, 1],
5630        true
5631    }
5632
5633    test_vec_2! { test_vec_any_lt_u32_true, vec_any_lt, u32x4 -> bool,
5634        [0, 255, 0, 1],
5635        [1, 255, 0, 1],
5636        true
5637    }
5638
5639    test_vec_2! { test_vec_all_ne_i8_false, vec_all_ne, i8x16 -> bool,
5640        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5641        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5642        false
5643    }
5644
5645    test_vec_2! { test_vec_all_ne_u8_false, vec_all_ne, u8x16 -> bool,
5646        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5647        [0, 0, 255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5648        false
5649    }
5650
5651    test_vec_2! { test_vec_all_ne_i16_false, vec_all_ne, i16x8 -> bool,
5652        [1, -1, 0, 0, 0, 0, 0, 0],
5653        [0, -1, 1, 0, 0, 0, 0, 0],
5654        false
5655    }
5656
5657    test_vec_2! { test_vec_all_ne_u16_false, vec_all_ne, u16x8 -> bool,
5658        [1, 255, 0, 0, 0, 0, 0, 0],
5659        [0, 255, 0, 1, 0, 0, 0, 0],
5660        false
5661    }
5662
5663    test_vec_2! { test_vec_all_ne_i32_false, vec_all_ne, i32x4 -> bool,
5664        [1, -1, 0, 0],
5665        [0, -1, 0, 1],
5666        false
5667    }
5668
5669    test_vec_2! { test_vec_all_ne_u32_false, vec_all_ne, u32x4 -> bool,
5670        [1, 255, 0, 0],
5671        [0, 255,  0, 1],
5672        false
5673    }
5674
5675    test_vec_2! { test_vec_all_ne_i8_true, vec_all_ne, i8x16 -> bool,
5676        [0, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5677        [1, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5678        true
5679    }
5680
5681    test_vec_2! { test_vec_all_ne_u8_true, vec_all_ne, u8x16 -> bool,
5682        [0, 254, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
5683        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5684        true
5685    }
5686
5687    test_vec_2! { test_vec_all_ne_i16_true, vec_all_ne, i16x8 -> bool,
5688        [2, -2, 0, 1, 1, 1, 1, 1],
5689        [1, -1, 1, 0, 0, 0, 0, 0],
5690        true
5691    }
5692
5693    test_vec_2! { test_vec_all_ne_u16_true, vec_all_ne, u16x8 -> bool,
5694        [0, 254, 1, 1, 0, 0, 1, 0],
5695        [1, 255, 0, 0, 1, 1, 0, 1],
5696        true
5697    }
5698
5699    test_vec_2! { test_vec_all_ne_i32_true, vec_all_ne, i32x4 -> bool,
5700        [0, -2, 0, 0],
5701        [1, -1, 1, 1],
5702        true
5703    }
5704
5705    test_vec_2! { test_vec_all_ne_u32_true, vec_all_ne, u32x4 -> bool,
5706        [1, 255, 0, 0],
5707        [0, 254, 1, 1],
5708        true
5709    }
5710
5711    test_vec_2! { test_vec_any_ne_i8_false, vec_any_ne, i8x16 -> bool,
5712        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5713        [1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5714        false
5715    }
5716
5717    test_vec_2! { test_vec_any_ne_u8_false, vec_any_ne, u8x16 -> bool,
5718        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5719        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5720        false
5721    }
5722
5723    test_vec_2! { test_vec_any_ne_i16_false, vec_any_ne, i16x8 -> bool,
5724        [1, -1, 0, 0, 0, 0, 0, 0],
5725        [1, -1, 0, 0, 0, 0, 0, 0],
5726        false
5727    }
5728
5729    test_vec_2! { test_vec_any_ne_u16_false, vec_any_ne, u16x8 -> bool,
5730        [1, 255, 1, 1, 1, 1, 1, 0],
5731        [1, 255, 1, 1, 1, 1, 1, 0],
5732        false
5733    }
5734
5735    test_vec_2! { test_vec_any_ne_i32_false, vec_any_ne, i32x4 -> bool,
5736        [0, -1, 1, 1],
5737        [0, -1, 1, 1],
5738        false
5739    }
5740
5741    test_vec_2! { test_vec_any_ne_u32_false, vec_any_ne, u32x4 -> bool,
5742        [1, 2, 1, 255],
5743        [1, 2, 1, 255],
5744        false
5745    }
5746
5747    test_vec_2! { test_vec_any_ne_i8_true, vec_any_ne, i8x16 -> bool,
5748        [1, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5749        [0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5750        true
5751    }
5752
5753    test_vec_2! { test_vec_any_ne_u8_true, vec_any_ne, u8x16 -> bool,
5754        [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5755        [1, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5756        true
5757    }
5758
5759    test_vec_2! { test_vec_any_ne_i16_true, vec_any_ne, i16x8 -> bool,
5760        [0, -1, 1, 0, 0, 0, 0, 0],
5761        [1, -1, 1, 0, 0, 0, 0, 0],
5762        true
5763    }
5764
5765    test_vec_2! { test_vec_any_ne_u16_true, vec_any_ne, u16x8 -> bool,
5766        [0, 255, 1, 0, 0, 0, 0, 0],
5767        [1, 255, 1, 0, 0, 0, 0, 0],
5768        true
5769    }
5770
5771    test_vec_2! { test_vec_any_ne_i32_true, vec_any_ne, i32x4 -> bool,
5772        [0, -1, 0, 1],
5773        [1, -1, 0, 1],
5774        true
5775    }
5776
5777    test_vec_2! { test_vec_any_ne_u32_true, vec_any_ne, u32x4 -> bool,
5778        [0, 255, 0, 1],
5779        [1, 255, 0, 1],
5780        true
5781    }
5782
5783    #[simd_test(enable = "altivec")]
5784    unsafe fn test_vec_cmpb() {
5785        let a: vector_float = transmute(f32x4::new(0.1, 0.5, 0.6, 0.9));
5786        let b: vector_float = transmute(f32x4::new(-0.1, 0.5, -0.6, 0.9));
5787        let d = i32x4::new(
5788            -0b10000000000000000000000000000000,
5789            0,
5790            -0b10000000000000000000000000000000,
5791            0,
5792        );
5793
5794        assert_eq!(d, transmute(vec_cmpb(a, b)));
5795    }
5796
5797    #[simd_test(enable = "altivec")]
5798    unsafe fn test_vec_ceil() {
5799        let a: vector_float = transmute(f32x4::new(0.1, 0.5, 0.6, 0.9));
5800        let d = f32x4::new(1.0, 1.0, 1.0, 1.0);
5801
5802        assert_eq!(d, transmute(vec_ceil(a)));
5803    }
5804
5805    test_vec_2! { test_vec_andc, vec_andc, i32x4,
5806    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
5807    [0b00110011, 0b11110011, 0b00001100, 0b10000000],
5808    [0b11001100, 0b00001100, 0b11000000, 0b01001100] }
5809
5810    test_vec_2! { test_vec_and, vec_and, i32x4,
5811    [0b11001100, 0b11001100, 0b11001100, 0b11001100],
5812    [0b00110011, 0b11110011, 0b00001100, 0b00000000],
5813    [0b00000000, 0b11000000, 0b00001100, 0b00000000] }
5814
5815    macro_rules! test_vec_avg {
5816        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
5817            test_vec_2! {$name, vec_avg, $ty, [$($a),+], [$($b),+], [$($d),+] }
5818        }
5819    }
5820
5821    test_vec_avg! { test_vec_avg_i32x4, i32x4,
5822    [i32::MIN, i32::MAX, 1, -1],
5823    [-1, 1, 1, -1],
5824    [-1073741824, 1073741824, 1, -1] }
5825
5826    test_vec_avg! { test_vec_avg_u32x4, u32x4,
5827    [u32::MAX, 0, 1, 2],
5828    [2, 1, 0, 0],
5829    [2147483649, 1, 1, 1] }
5830
5831    test_vec_avg! { test_vec_avg_i16x8, i16x8,
5832    [i16::MIN, i16::MAX, 1, -1, 0, 0, 0, 0],
5833    [-1, 1, 1, -1, 0, 0, 0, 0],
5834    [-16384, 16384, 1, -1, 0, 0, 0, 0] }
5835
5836    test_vec_avg! { test_vec_avg_u16x8, u16x8,
5837    [u16::MAX, 0, 1, 2, 0, 0, 0, 0],
5838    [2, 1, 0, 0, 0, 0, 0, 0],
5839    [32769, 1, 1, 1, 0, 0, 0, 0] }
5840
5841    test_vec_avg! { test_vec_avg_i8x16, i8x16,
5842    [i8::MIN, i8::MAX, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5843    [-1, 1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5844    [-64, 64, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
5845
5846    test_vec_avg! { test_vec_avg_u8x16, u8x16,
5847    [u8::MAX, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5848    [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5849    [129, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
5850
5851    macro_rules! test_vec_adds {
5852        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
5853            test_vec_2! {$name, vec_adds, $ty, [$($a),+], [$($b),+], [$($d),+] }
5854        }
5855    }
5856
5857    test_vec_adds! { test_vec_adds_i32x4, i32x4,
5858    [i32::MIN, i32::MAX, 1, -1],
5859    [-1, 1, 1, -1],
5860    [i32::MIN, i32::MAX, 2, -2] }
5861
5862    test_vec_adds! { test_vec_adds_u32x4, u32x4,
5863    [u32::MAX, 0, 1, 2],
5864    [2, 1, 0, 0],
5865    [u32::MAX, 1, 1, 2] }
5866
5867    test_vec_adds! { test_vec_adds_i16x8, i16x8,
5868    [i16::MIN, i16::MAX, 1, -1, 0, 0, 0, 0],
5869    [-1, 1, 1, -1, 0, 0, 0, 0],
5870    [i16::MIN, i16::MAX, 2, -2, 0, 0, 0, 0] }
5871
5872    test_vec_adds! { test_vec_adds_u16x8, u16x8,
5873    [u16::MAX, 0, 1, 2, 0, 0, 0, 0],
5874    [2, 1, 0, 0, 0, 0, 0, 0],
5875    [u16::MAX, 1, 1, 2, 0, 0, 0, 0] }
5876
5877    test_vec_adds! { test_vec_adds_i8x16, i8x16,
5878    [i8::MIN, i8::MAX, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5879    [-1, 1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5880    [i8::MIN, i8::MAX, 2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
5881
5882    test_vec_adds! { test_vec_adds_u8x16, u8x16,
5883    [u8::MAX, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5884    [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
5885    [u8::MAX, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
5886
5887    test_vec_2! { test_vec_addc, vec_addc, u32x4, [u32::MAX, 0, 0, 0], [1, 1, 1, 1], [1, 0, 0, 0] }
5888
5889    macro_rules! test_vec_abs {
5890        { $name: ident, $ty: ident, $a: expr, $d: expr } => {
5891            #[simd_test(enable = "altivec")]
5892            unsafe fn $name() {
5893                let a = vec_splats($a);
5894                let a: s_t_l!($ty) = vec_abs(a);
5895                let d = $ty::splat($d);
5896                assert_eq!(d, transmute(a));
5897            }
5898        }
5899    }
5900
5901    test_vec_abs! { test_vec_abs_i8, i8x16, -42i8, 42i8 }
5902    test_vec_abs! { test_vec_abs_i16, i16x8, -42i16, 42i16 }
5903    test_vec_abs! { test_vec_abs_i32, i32x4, -42i32, 42i32 }
5904    test_vec_abs! { test_vec_abs_f32, f32x4, -42f32, 42f32 }
5905
5906    macro_rules! test_vec_abss {
5907        { $name: ident, $ty: ident, $a: expr, $d: expr } => {
5908            #[simd_test(enable = "altivec")]
5909            unsafe fn $name() {
5910                let a = vec_splats($a);
5911                let a: s_t_l!($ty) = vec_abss(a);
5912                let d = $ty::splat($d);
5913                assert_eq!(d, transmute(a));
5914            }
5915        }
5916    }
5917
5918    test_vec_abss! { test_vec_abss_i8, i8x16, -127i8, 127i8 }
5919    test_vec_abss! { test_vec_abss_i16, i16x8, -42i16, 42i16 }
5920    test_vec_abss! { test_vec_abss_i32, i32x4, -42i32, 42i32 }
5921
5922    macro_rules! test_vec_splats {
5923        { $name: ident, $ty: ident, $a: expr } => {
5924            #[simd_test(enable = "altivec")]
5925            unsafe fn $name() {
5926                let a: s_t_l!($ty) = vec_splats($a);
5927                let d = $ty::splat($a);
5928                assert_eq!(d, transmute(a));
5929            }
5930        }
5931    }
5932
5933    test_vec_splats! { test_vec_splats_u8, u8x16, 42u8 }
5934    test_vec_splats! { test_vec_splats_u16, u16x8, 42u16 }
5935    test_vec_splats! { test_vec_splats_u32, u32x4, 42u32 }
5936    test_vec_splats! { test_vec_splats_i8, i8x16, 42i8 }
5937    test_vec_splats! { test_vec_splats_i16, i16x8, 42i16 }
5938    test_vec_splats! { test_vec_splats_i32, i32x4, 42i32 }
5939    test_vec_splats! { test_vec_splats_f32, f32x4, 42f32 }
5940
5941    macro_rules! test_vec_splat {
5942        { $name: ident, $fun: ident, $ty: ident, $a: expr, $b: expr} => {
5943            #[simd_test(enable = "altivec")]
5944            unsafe fn $name() {
5945                let a = $fun::<$a>();
5946                let d = $ty::splat($b);
5947                assert_eq!(d, transmute(a));
5948            }
5949        }
5950    }
5951
5952    test_vec_splat! { test_vec_splat_u8, vec_splat_u8, u8x16, -1, u8::MAX }
5953    test_vec_splat! { test_vec_splat_u16, vec_splat_u16, u16x8, -1, u16::MAX }
5954    test_vec_splat! { test_vec_splat_u32, vec_splat_u32, u32x4, -1, u32::MAX }
5955    test_vec_splat! { test_vec_splat_s8, vec_splat_s8, i8x16, -1, -1 }
5956    test_vec_splat! { test_vec_splat_s16, vec_splat_s16, i16x8, -1, -1 }
5957    test_vec_splat! { test_vec_splat_s32, vec_splat_s32, i32x4, -1, -1 }
5958
5959    macro_rules! test_vec_sub {
5960        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
5961            test_vec_2! {$name, vec_sub, $ty, [$($a),+], [$($b),+], [$($d),+] }
5962        }
5963    }
5964
5965    test_vec_sub! { test_vec_sub_f32x4, f32x4,
5966    [-1.0, 0.0, 1.0, 2.0],
5967    [2.0, 1.0, -1.0, -2.0],
5968    [-3.0, -1.0, 2.0, 4.0] }
5969
5970    test_vec_sub! { test_vec_sub_i32x4, i32x4,
5971    [-1, 0, 1, 2],
5972    [2, 1, -1, -2],
5973    [-3, -1, 2, 4] }
5974
5975    test_vec_sub! { test_vec_sub_u32x4, u32x4,
5976    [0, 0, 1, 2],
5977    [2, 1, 0, 0],
5978    [4294967294, 4294967295, 1, 2] }
5979
5980    test_vec_sub! { test_vec_sub_i16x8, i16x8,
5981    [-1, 0, 1, 2, -1, 0, 1, 2],
5982    [2, 1, -1, -2, 2, 1, -1, -2],
5983    [-3, -1, 2, 4, -3, -1, 2, 4] }
5984
5985    test_vec_sub! { test_vec_sub_u16x8, u16x8,
5986    [0, 0, 1, 2, 0, 0, 1, 2],
5987    [2, 1, 0, 0, 2, 1, 0, 0],
5988    [65534, 65535, 1, 2, 65534, 65535, 1, 2] }
5989
5990    test_vec_sub! { test_vec_sub_i8x16, i8x16,
5991    [-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
5992    [2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
5993    [-3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4] }
5994
5995    test_vec_sub! { test_vec_sub_u8x16, u8x16,
5996    [0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2],
5997    [2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
5998    [254, 255, 1, 2, 254, 255, 1, 2, 254, 255, 1, 2, 254, 255, 1, 2] }
5999
6000    macro_rules! test_vec_subs {
6001        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
6002            test_vec_2! {$name, vec_subs, $ty, [$($a),+], [$($b),+], [$($d),+] }
6003        }
6004    }
6005
6006    test_vec_subs! { test_vec_subs_i32x4, i32x4,
6007    [-1, 0, 1, 2],
6008    [2, 1, -1, -2],
6009    [-3, -1, 2, 4] }
6010
6011    test_vec_subs! { test_vec_subs_u32x4, u32x4,
6012    [0, 0, 1, 2],
6013    [2, 1, 0, 0],
6014    [0, 0, 1, 2] }
6015
6016    test_vec_subs! { test_vec_subs_i16x8, i16x8,
6017    [-1, 0, 1, 2, -1, 0, 1, 2],
6018    [2, 1, -1, -2, 2, 1, -1, -2],
6019    [-3, -1, 2, 4, -3, -1, 2, 4] }
6020
6021    test_vec_subs! { test_vec_subs_u16x8, u16x8,
6022    [0, 0, 1, 2, 0, 0, 1, 2],
6023    [2, 1, 0, 0, 2, 1, 0, 0],
6024    [0, 0, 1, 2, 0, 0, 1, 2] }
6025
6026    test_vec_subs! { test_vec_subs_i8x16, i8x16,
6027    [-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
6028    [2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
6029    [-3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4] }
6030
6031    test_vec_subs! { test_vec_subs_u8x16, u8x16,
6032    [0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2],
6033    [2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
6034    [0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2] }
6035
6036    macro_rules! test_vec_min {
6037        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
6038            #[simd_test(enable = "altivec")]
6039            unsafe fn $name() {
6040                let a: s_t_l!($ty) = transmute($ty::new($($a),+));
6041                let b: s_t_l!($ty) = transmute($ty::new($($b),+));
6042
6043                let d = $ty::new($($d),+);
6044                let r : $ty = transmute(vec_min(a, b));
6045                assert_eq!(d, r);
6046            }
6047         }
6048    }
6049
6050    test_vec_min! { test_vec_min_i32x4, i32x4,
6051    [-1, 0, 1, 2],
6052    [2, 1, -1, -2],
6053    [-1, 0, -1, -2] }
6054
6055    test_vec_min! { test_vec_min_u32x4, u32x4,
6056    [0, 0, 1, 2],
6057    [2, 1, 0, 0],
6058    [0, 0, 0, 0] }
6059
6060    test_vec_min! { test_vec_min_i16x8, i16x8,
6061    [-1, 0, 1, 2, -1, 0, 1, 2],
6062    [2, 1, -1, -2, 2, 1, -1, -2],
6063    [-1, 0, -1, -2, -1, 0, -1, -2] }
6064
6065    test_vec_min! { test_vec_min_u16x8, u16x8,
6066    [0, 0, 1, 2, 0, 0, 1, 2],
6067    [2, 1, 0, 0, 2, 1, 0, 0],
6068    [0, 0, 0, 0, 0, 0, 0, 0] }
6069
6070    test_vec_min! { test_vec_min_i8x16, i8x16,
6071    [-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
6072    [2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
6073    [-1, 0, -1, -2, -1, 0, -1, -2, -1, 0, -1, -2, -1, 0, -1, -2] }
6074
6075    test_vec_min! { test_vec_min_u8x16, u8x16,
6076    [0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2],
6077    [2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
6078    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
6079
6080    macro_rules! test_vec_max {
6081        { $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
6082            #[simd_test(enable = "altivec")]
6083            unsafe fn $name() {
6084                let a: s_t_l!($ty) = transmute($ty::new($($a),+));
6085                let b: s_t_l!($ty) = transmute($ty::new($($b),+));
6086
6087                let d = $ty::new($($d),+);
6088                let r : $ty = transmute(vec_max(a, b));
6089                assert_eq!(d, r);
6090            }
6091         }
6092    }
6093
6094    test_vec_max! { test_vec_max_i32x4, i32x4,
6095    [-1, 0, 1, 2],
6096    [2, 1, -1, -2],
6097    [2, 1, 1, 2] }
6098
6099    test_vec_max! { test_vec_max_u32x4, u32x4,
6100    [0, 0, 1, 2],
6101    [2, 1, 0, 0],
6102    [2, 1, 1, 2] }
6103
6104    test_vec_max! { test_vec_max_i16x8, i16x8,
6105    [-1, 0, 1, 2, -1, 0, 1, 2],
6106    [2, 1, -1, -2, 2, 1, -1, -2],
6107    [2, 1, 1, 2, 2, 1, 1, 2] }
6108
6109    test_vec_max! { test_vec_max_u16x8, u16x8,
6110    [0, 0, 1, 2, 0, 0, 1, 2],
6111    [2, 1, 0, 0, 2, 1, 0, 0],
6112    [2, 1, 1, 2, 2, 1, 1, 2] }
6113
6114    test_vec_max! { test_vec_max_i8x16, i8x16,
6115    [-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
6116    [2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
6117    [2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2] }
6118
6119    test_vec_max! { test_vec_max_u8x16, u8x16,
6120    [0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2],
6121    [2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
6122    [2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2] }
6123
6124    macro_rules! test_vec_perm {
6125        {$name:ident,
6126         $shorttype:ident, $longtype:ident,
6127         [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => {
6128            #[simd_test(enable = "altivec")]
6129            unsafe fn $name() {
6130                let a: $longtype = transmute($shorttype::new($($a),+));
6131                let b: $longtype = transmute($shorttype::new($($b),+));
6132                let c: vector_unsigned_char = transmute(u8x16::new($($c),+));
6133                let d = $shorttype::new($($d),+);
6134
6135                let r: $shorttype = transmute(vec_perm(a, b, c));
6136                assert_eq!(d, r);
6137            }
6138        }
6139    }
6140
6141    test_vec_perm! {test_vec_perm_u8x16,
6142    u8x16, vector_unsigned_char,
6143    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
6144    [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115],
6145    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6146     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6147    [0, 1, 100, 101, 2, 3, 102, 103, 4, 5, 104, 105, 6, 7, 106, 107]}
6148    test_vec_perm! {test_vec_perm_i8x16,
6149    i8x16, vector_signed_char,
6150    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
6151    [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115],
6152    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6153     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6154    [0, 1, 100, 101, 2, 3, 102, 103, 4, 5, 104, 105, 6, 7, 106, 107]}
6155
6156    test_vec_perm! {test_vec_perm_m8x16,
6157    m8x16, vector_bool_char,
6158    [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false],
6159    [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true],
6160    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6161     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6162    [false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true]}
6163    test_vec_perm! {test_vec_perm_u16x8,
6164    u16x8, vector_unsigned_short,
6165    [0, 1, 2, 3, 4, 5, 6, 7],
6166    [10, 11, 12, 13, 14, 15, 16, 17],
6167    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6168     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6169    [0, 10, 1, 11, 2, 12, 3, 13]}
6170    test_vec_perm! {test_vec_perm_i16x8,
6171    i16x8, vector_signed_short,
6172    [0, 1, 2, 3, 4, 5, 6, 7],
6173    [10, 11, 12, 13, 14, 15, 16, 17],
6174    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6175     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6176    [0, 10, 1, 11, 2, 12, 3, 13]}
6177    test_vec_perm! {test_vec_perm_m16x8,
6178    m16x8, vector_bool_short,
6179    [false, false, false, false, false, false, false, false],
6180    [true, true, true, true, true, true, true, true],
6181    [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
6182     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17],
6183    [false, true, false, true, false, true, false, true]}
6184
6185    test_vec_perm! {test_vec_perm_u32x4,
6186    u32x4, vector_unsigned_int,
6187    [0, 1, 2, 3],
6188    [10, 11, 12, 13],
6189    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
6190     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
6191    [0, 10, 1, 11]}
6192    test_vec_perm! {test_vec_perm_i32x4,
6193    i32x4, vector_signed_int,
6194    [0, 1, 2, 3],
6195    [10, 11, 12, 13],
6196    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
6197     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
6198    [0, 10, 1, 11]}
6199    test_vec_perm! {test_vec_perm_m32x4,
6200    m32x4, vector_bool_int,
6201    [false, false, false, false],
6202    [true, true, true, true],
6203    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
6204     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
6205    [false, true, false, true]}
6206    test_vec_perm! {test_vec_perm_f32x4,
6207    f32x4, vector_float,
6208    [0.0, 1.0, 2.0, 3.0],
6209    [1.0, 1.1, 1.2, 1.3],
6210    [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
6211     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17],
6212    [0.0, 1.0, 1.0, 1.1]}
6213
6214    #[simd_test(enable = "altivec")]
6215    unsafe fn test_vec_madds() {
6216        let a: vector_signed_short = transmute(i16x8::new(
6217            0 * 256,
6218            1 * 256,
6219            2 * 256,
6220            3 * 256,
6221            4 * 256,
6222            5 * 256,
6223            6 * 256,
6224            7 * 256,
6225        ));
6226        let b: vector_signed_short = transmute(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256));
6227        let c: vector_signed_short = transmute(i16x8::new(0, 1, 2, 3, 4, 5, 6, 7));
6228
6229        let d = i16x8::new(0, 3, 6, 9, 12, 15, 18, 21);
6230
6231        assert_eq!(d, transmute(vec_madds(a, b, c)));
6232    }
6233
6234    #[simd_test(enable = "altivec")]
6235    unsafe fn test_vec_madd_float() {
6236        let a: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4));
6237        let b: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4));
6238        let c: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4));
6239        let d = f32x4::new(
6240            0.1 * 0.1 + 0.1,
6241            0.2 * 0.2 + 0.2,
6242            0.3 * 0.3 + 0.3,
6243            0.4 * 0.4 + 0.4,
6244        );
6245
6246        assert_eq!(d, transmute(vec_madd(a, b, c)));
6247    }
6248
6249    #[simd_test(enable = "altivec")]
6250    unsafe fn test_vec_nmsub_float() {
6251        let a: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4));
6252        let b: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4));
6253        let c: vector_float = transmute(f32x4::new(0.1, 0.2, 0.3, 0.4));
6254        let d = f32x4::new(
6255            -(0.1 * 0.1 - 0.1),
6256            -(0.2 * 0.2 - 0.2),
6257            -(0.3 * 0.3 - 0.3),
6258            -(0.4 * 0.4 - 0.4),
6259        );
6260        assert_eq!(d, transmute(vec_nmsub(a, b, c)));
6261    }
6262
6263    #[simd_test(enable = "altivec")]
6264    unsafe fn test_vec_mradds() {
6265        let a: vector_signed_short = transmute(i16x8::new(
6266            0 * 256,
6267            1 * 256,
6268            2 * 256,
6269            3 * 256,
6270            4 * 256,
6271            5 * 256,
6272            6 * 256,
6273            7 * 256,
6274        ));
6275        let b: vector_signed_short = transmute(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256));
6276        let c: vector_signed_short = transmute(i16x8::new(0, 1, 2, 3, 4, 5, 6, i16::MAX - 1));
6277
6278        let d = i16x8::new(0, 3, 6, 9, 12, 15, 18, i16::MAX);
6279
6280        assert_eq!(d, transmute(vec_mradds(a, b, c)));
6281    }
6282
6283    macro_rules! test_vec_mladd {
6284        {$name:ident, $sa:ident, $la:ident, $sbc:ident, $lbc:ident, $sd:ident,
6285            [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => {
6286            #[simd_test(enable = "altivec")]
6287            unsafe fn $name() {
6288                let a: $la = transmute($sa::new($($a),+));
6289                let b: $lbc = transmute($sbc::new($($b),+));
6290                let c = transmute($sbc::new($($c),+));
6291                let d = $sd::new($($d),+);
6292
6293                assert_eq!(d, transmute(vec_mladd(a, b, c)));
6294            }
6295        }
6296    }
6297
6298    test_vec_mladd! { test_vec_mladd_u16x8_u16x8, u16x8, vector_unsigned_short, u16x8, vector_unsigned_short, u16x8,
6299        [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 6, 12, 20, 30, 42, 56]
6300    }
6301    test_vec_mladd! { test_vec_mladd_u16x8_i16x8, u16x8, vector_unsigned_short, i16x8, vector_unsigned_short, i16x8,
6302        [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 6, 12, 20, 30, 42, 56]
6303    }
6304    test_vec_mladd! { test_vec_mladd_i16x8_u16x8, i16x8, vector_signed_short, u16x8, vector_unsigned_short, i16x8,
6305        [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 6, 12, 20, 30, 42, 56]
6306    }
6307    test_vec_mladd! { test_vec_mladd_i16x8_i16x8, i16x8, vector_signed_short, i16x8, vector_unsigned_short, i16x8,
6308        [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 6, 12, 20, 30, 42, 56]
6309    }
6310
6311    #[simd_test(enable = "altivec")]
6312    unsafe fn test_vec_msum_unsigned_char() {
6313        let a: vector_unsigned_char =
6314            transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
6315        let b: vector_unsigned_char = transmute(u8x16::new(
6316            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
6317        ));
6318        let c: vector_unsigned_int = transmute(u32x4::new(0, 1, 2, 3));
6319        let d = u32x4::new(
6320            (0 + 1 + 2 + 3) * 255 + 0,
6321            (4 + 5 + 6 + 7) * 255 + 1,
6322            (0 + 1 + 2 + 3) * 255 + 2,
6323            (4 + 5 + 6 + 7) * 255 + 3,
6324        );
6325
6326        assert_eq!(d, transmute(vec_msum(a, b, c)));
6327    }
6328
6329    #[simd_test(enable = "altivec")]
6330    unsafe fn test_vec_msum_signed_char() {
6331        let a: vector_signed_char = transmute(i8x16::new(
6332            0, -1, 2, -3, 1, -1, 1, -1, 0, 1, 2, 3, 4, -5, -6, -7,
6333        ));
6334        let b: vector_unsigned_char =
6335            transmute(i8x16::new(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1));
6336        let c: vector_signed_int = transmute(u32x4::new(0, 1, 2, 3));
6337        let d = i32x4::new(
6338            (0 - 1 + 2 - 3) + 0,
6339            (0) + 1,
6340            (0 + 1 + 2 + 3) + 2,
6341            (4 - 5 - 6 - 7) + 3,
6342        );
6343
6344        assert_eq!(d, transmute(vec_msum(a, b, c)));
6345    }
6346    #[simd_test(enable = "altivec")]
6347    unsafe fn test_vec_msum_unsigned_short() {
6348        let a: vector_unsigned_short = transmute(u16x8::new(
6349            0 * 256,
6350            1 * 256,
6351            2 * 256,
6352            3 * 256,
6353            4 * 256,
6354            5 * 256,
6355            6 * 256,
6356            7 * 256,
6357        ));
6358        let b: vector_unsigned_short =
6359            transmute(u16x8::new(256, 256, 256, 256, 256, 256, 256, 256));
6360        let c: vector_unsigned_int = transmute(u32x4::new(0, 1, 2, 3));
6361        let d = u32x4::new(
6362            (0 + 1) * 256 * 256 + 0,
6363            (2 + 3) * 256 * 256 + 1,
6364            (4 + 5) * 256 * 256 + 2,
6365            (6 + 7) * 256 * 256 + 3,
6366        );
6367
6368        assert_eq!(d, transmute(vec_msum(a, b, c)));
6369    }
6370
6371    #[simd_test(enable = "altivec")]
6372    unsafe fn test_vec_msum_signed_short() {
6373        let a: vector_signed_short = transmute(i16x8::new(
6374            0 * 256,
6375            -1 * 256,
6376            2 * 256,
6377            -3 * 256,
6378            4 * 256,
6379            -5 * 256,
6380            6 * 256,
6381            -7 * 256,
6382        ));
6383        let b: vector_signed_short = transmute(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256));
6384        let c: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3));
6385        let d = i32x4::new(
6386            (0 - 1) * 256 * 256 + 0,
6387            (2 - 3) * 256 * 256 + 1,
6388            (4 - 5) * 256 * 256 + 2,
6389            (6 - 7) * 256 * 256 + 3,
6390        );
6391
6392        assert_eq!(d, transmute(vec_msum(a, b, c)));
6393    }
6394
6395    #[simd_test(enable = "altivec")]
6396    unsafe fn test_vec_msums_unsigned() {
6397        let a: vector_unsigned_short = transmute(u16x8::new(
6398            0 * 256,
6399            1 * 256,
6400            2 * 256,
6401            3 * 256,
6402            4 * 256,
6403            5 * 256,
6404            6 * 256,
6405            7 * 256,
6406        ));
6407        let b: vector_unsigned_short =
6408            transmute(u16x8::new(256, 256, 256, 256, 256, 256, 256, 256));
6409        let c: vector_unsigned_int = transmute(u32x4::new(0, 1, 2, 3));
6410        let d = u32x4::new(
6411            (0 + 1) * 256 * 256 + 0,
6412            (2 + 3) * 256 * 256 + 1,
6413            (4 + 5) * 256 * 256 + 2,
6414            (6 + 7) * 256 * 256 + 3,
6415        );
6416
6417        assert_eq!(d, transmute(vec_msums(a, b, c)));
6418    }
6419
6420    #[simd_test(enable = "altivec")]
6421    unsafe fn test_vec_msums_signed() {
6422        let a: vector_signed_short = transmute(i16x8::new(
6423            0 * 256,
6424            -1 * 256,
6425            2 * 256,
6426            -3 * 256,
6427            4 * 256,
6428            -5 * 256,
6429            6 * 256,
6430            -7 * 256,
6431        ));
6432        let b: vector_signed_short = transmute(i16x8::new(256, 256, 256, 256, 256, 256, 256, 256));
6433        let c: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3));
6434        let d = i32x4::new(
6435            (0 - 1) * 256 * 256 + 0,
6436            (2 - 3) * 256 * 256 + 1,
6437            (4 - 5) * 256 * 256 + 2,
6438            (6 - 7) * 256 * 256 + 3,
6439        );
6440
6441        assert_eq!(d, transmute(vec_msums(a, b, c)));
6442    }
6443
6444    #[simd_test(enable = "altivec")]
6445    unsafe fn test_vec_sum2s() {
6446        let a: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3));
6447        let b: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3));
6448        let d = i32x4::new(0, 0 + 1 + 1, 0, 2 + 3 + 3);
6449
6450        assert_eq!(d, transmute(vec_sum2s(a, b)));
6451    }
6452
6453    #[simd_test(enable = "altivec")]
6454    unsafe fn test_vec_sum4s_unsigned_char() {
6455        let a: vector_unsigned_char =
6456            transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
6457        let b: vector_unsigned_int = transmute(u32x4::new(0, 1, 2, 3));
6458        let d = u32x4::new(
6459            0 + 1 + 2 + 3 + 0,
6460            4 + 5 + 6 + 7 + 1,
6461            0 + 1 + 2 + 3 + 2,
6462            4 + 5 + 6 + 7 + 3,
6463        );
6464
6465        assert_eq!(d, transmute(vec_sum4s(a, b)));
6466    }
6467    #[simd_test(enable = "altivec")]
6468    unsafe fn test_vec_sum4s_signed_char() {
6469        let a: vector_signed_char =
6470            transmute(i8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
6471        let b: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3));
6472        let d = i32x4::new(
6473            0 + 1 + 2 + 3 + 0,
6474            4 + 5 + 6 + 7 + 1,
6475            0 + 1 + 2 + 3 + 2,
6476            4 + 5 + 6 + 7 + 3,
6477        );
6478
6479        assert_eq!(d, transmute(vec_sum4s(a, b)));
6480    }
6481    #[simd_test(enable = "altivec")]
6482    unsafe fn test_vec_sum4s_signed_short() {
6483        let a: vector_signed_short = transmute(i16x8::new(0, 1, 2, 3, 4, 5, 6, 7));
6484        let b: vector_signed_int = transmute(i32x4::new(0, 1, 2, 3));
6485        let d = i32x4::new(0 + 1 + 0, 2 + 3 + 1, 4 + 5 + 2, 6 + 7 + 3);
6486
6487        assert_eq!(d, transmute(vec_sum4s(a, b)));
6488    }
6489
6490    #[simd_test(enable = "altivec")]
6491    unsafe fn test_vec_mule_unsigned_char() {
6492        let a: vector_unsigned_char =
6493            transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
6494        let d = u16x8::new(0 * 0, 2 * 2, 4 * 4, 6 * 6, 0 * 0, 2 * 2, 4 * 4, 6 * 6);
6495
6496        assert_eq!(d, transmute(vec_mule(a, a)));
6497    }
6498
6499    #[simd_test(enable = "altivec")]
6500    unsafe fn test_vec_mule_signed_char() {
6501        let a: vector_signed_char = transmute(i8x16::new(
6502            0, 1, -2, 3, -4, 5, -6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
6503        ));
6504        let d = i16x8::new(0 * 0, 2 * 2, 4 * 4, 6 * 6, 0 * 0, 2 * 2, 4 * 4, 6 * 6);
6505
6506        assert_eq!(d, transmute(vec_mule(a, a)));
6507    }
6508
6509    #[simd_test(enable = "altivec")]
6510    unsafe fn test_vec_mule_unsigned_short() {
6511        let a: vector_unsigned_short = transmute(u16x8::new(0, 1, 2, 3, 4, 5, 6, 7));
6512        let d = u32x4::new(0 * 0, 2 * 2, 4 * 4, 6 * 6);
6513
6514        assert_eq!(d, transmute(vec_mule(a, a)));
6515    }
6516
6517    #[simd_test(enable = "altivec")]
6518    unsafe fn test_vec_mule_signed_short() {
6519        let a: vector_signed_short = transmute(i16x8::new(0, 1, -2, 3, -4, 5, -6, 7));
6520        let d = i32x4::new(0 * 0, 2 * 2, 4 * 4, 6 * 6);
6521
6522        assert_eq!(d, transmute(vec_mule(a, a)));
6523    }
6524
6525    #[simd_test(enable = "altivec")]
6526    unsafe fn test_vec_mulo_unsigned_char() {
6527        let a: vector_unsigned_char =
6528            transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
6529        let d = u16x8::new(1 * 1, 3 * 3, 5 * 5, 7 * 7, 1 * 1, 3 * 3, 5 * 5, 7 * 7);
6530
6531        assert_eq!(d, transmute(vec_mulo(a, a)));
6532    }
6533
6534    #[simd_test(enable = "altivec")]
6535    unsafe fn test_vec_mulo_signed_char() {
6536        let a: vector_signed_char = transmute(i8x16::new(
6537            0, 1, -2, 3, -4, 5, -6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
6538        ));
6539        let d = i16x8::new(1 * 1, 3 * 3, 5 * 5, 7 * 7, 1 * 1, 3 * 3, 5 * 5, 7 * 7);
6540
6541        assert_eq!(d, transmute(vec_mulo(a, a)));
6542    }
6543
6544    #[simd_test(enable = "altivec")]
6545    unsafe fn test_vec_mulo_unsigned_short() {
6546        let a: vector_unsigned_short = transmute(u16x8::new(0, 1, 2, 3, 4, 5, 6, 7));
6547        let d = u32x4::new(1 * 1, 3 * 3, 5 * 5, 7 * 7);
6548
6549        assert_eq!(d, transmute(vec_mulo(a, a)));
6550    }
6551
6552    #[simd_test(enable = "altivec")]
6553    unsafe fn test_vec_mulo_signed_short() {
6554        let a: vector_signed_short = transmute(i16x8::new(0, 1, -2, 3, -4, 5, -6, 7));
6555        let d = i32x4::new(1 * 1, 3 * 3, 5 * 5, 7 * 7);
6556
6557        assert_eq!(d, transmute(vec_mulo(a, a)));
6558    }
6559
6560    #[simd_test(enable = "altivec")]
6561    unsafe fn vec_add_i32x4_i32x4() {
6562        let x = i32x4::new(1, 2, 3, 4);
6563        let y = i32x4::new(4, 3, 2, 1);
6564        let x: vector_signed_int = transmute(x);
6565        let y: vector_signed_int = transmute(y);
6566        let z = vec_add(x, y);
6567        assert_eq!(i32x4::splat(5), transmute(z));
6568    }
6569
6570    #[simd_test(enable = "altivec")]
6571    unsafe fn vec_ctf_u32() {
6572        let v: vector_unsigned_int = transmute(u32x4::new(u32::MIN, u32::MAX, u32::MAX, 42));
6573        let v2 = vec_ctf::<1, _>(v);
6574        let r2: vector_float = transmute(f32x4::new(0.0, 2147483600.0, 2147483600.0, 21.0));
6575        let v4 = vec_ctf::<2, _>(v);
6576        let r4: vector_float = transmute(f32x4::new(0.0, 1073741800.0, 1073741800.0, 10.5));
6577        let v8 = vec_ctf::<3, _>(v);
6578        let r8: vector_float = transmute(f32x4::new(0.0, 536870900.0, 536870900.0, 5.25));
6579
6580        let check = |a, b| {
6581            let r = transmute(vec_cmple(vec_abs(vec_sub(a, b)), vec_splats(f32::EPSILON)));
6582            let e = m32x4::new(true, true, true, true);
6583            assert_eq!(e, r);
6584        };
6585
6586        check(v2, r2);
6587        check(v4, r4);
6588        check(v8, r8);
6589    }
6590
6591    #[simd_test(enable = "altivec")]
6592    unsafe fn test_vec_ctu() {
6593        let v = u32x4::new(u32::MIN, u32::MAX, u32::MAX, 42);
6594        let v2: u32x4 = transmute(vec_ctu::<1>(transmute(f32x4::new(
6595            0.0,
6596            2147483600.0,
6597            2147483600.0,
6598            21.0,
6599        ))));
6600        let v4: u32x4 = transmute(vec_ctu::<2>(transmute(f32x4::new(
6601            0.0,
6602            1073741800.0,
6603            1073741800.0,
6604            10.5,
6605        ))));
6606        let v8: u32x4 = transmute(vec_ctu::<3>(transmute(f32x4::new(
6607            0.0,
6608            536870900.0,
6609            536870900.0,
6610            5.25,
6611        ))));
6612
6613        assert_eq!(v2, v);
6614        assert_eq!(v4, v);
6615        assert_eq!(v8, v);
6616    }
6617
6618    #[simd_test(enable = "altivec")]
6619    unsafe fn vec_ctf_i32() {
6620        let v: vector_signed_int = transmute(i32x4::new(i32::MIN, i32::MAX, i32::MAX - 42, 42));
6621        let v2 = vec_ctf::<1, _>(v);
6622        let r2: vector_float =
6623            transmute(f32x4::new(-1073741800.0, 1073741800.0, 1073741800.0, 21.0));
6624        let v4 = vec_ctf::<2, _>(v);
6625        let r4: vector_float = transmute(f32x4::new(-536870900.0, 536870900.0, 536870900.0, 10.5));
6626        let v8 = vec_ctf::<3, _>(v);
6627        let r8: vector_float = transmute(f32x4::new(-268435460.0, 268435460.0, 268435460.0, 5.25));
6628
6629        let check = |a, b| {
6630            let r = transmute(vec_cmple(vec_abs(vec_sub(a, b)), vec_splats(f32::EPSILON)));
6631            println!("{:?} {:?}", a, b);
6632            let e = m32x4::new(true, true, true, true);
6633            assert_eq!(e, r);
6634        };
6635
6636        check(v2, r2);
6637        check(v4, r4);
6638        check(v8, r8);
6639    }
6640
6641    #[simd_test(enable = "altivec")]
6642    unsafe fn test_vec_cts() {
6643        let v = i32x4::new(i32::MIN, i32::MAX, i32::MAX, 42);
6644        let v2: i32x4 = transmute(vec_cts::<1>(transmute(f32x4::new(
6645            -1073741800.0,
6646            1073741800.0,
6647            1073741800.0,
6648            21.0,
6649        ))));
6650        let v4: i32x4 = transmute(vec_cts::<2>(transmute(f32x4::new(
6651            -536870900.0,
6652            536870900.0,
6653            536870900.0,
6654            10.5,
6655        ))));
6656        let v8: i32x4 = transmute(vec_cts::<3>(transmute(f32x4::new(
6657            -268435460.0,
6658            268435460.0,
6659            268435460.0,
6660            5.25,
6661        ))));
6662
6663        assert_eq!(v2, v);
6664        assert_eq!(v4, v);
6665        assert_eq!(v8, v);
6666    }
6667
6668    test_vec_2! { test_vec_rl, vec_rl, u32x4,
6669        [0x12345678, 0x9ABCDEF0, 0x0F0F0F0F, 0x12345678],
6670        [4, 8, 12, 68],
6671        [0x23456781, 0xBCDEF09A, 0xF0F0F0F0, 0x23456781]
6672    }
6673}