Skip to main content

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