diff --git a/crates/core_arch/src/powerpc/altivec.rs b/crates/core_arch/src/powerpc/altivec.rs index 9f8b1a91b8..5a8f289b9c 100644 --- a/crates/core_arch/src/powerpc/altivec.rs +++ b/crates/core_arch/src/powerpc/altivec.rs @@ -213,6 +213,9 @@ extern "C" { #[link_name = "llvm.ppc.altivec.vsubuws"] fn vsubuws(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int; + #[link_name = "llvm.ppc.altivec.vsubcuw"] + fn vsubcuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int; + #[link_name = "llvm.ppc.altivec.vaddcuw"] fn vaddcuw(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int; @@ -377,6 +380,23 @@ extern "C" { fn vslv(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char; #[link_name = "llvm.ppc.altivec.srv"] fn vsrv(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char; + + #[link_name = "llvm.ctlz.v16i8"] + fn vclzb(a: vector_signed_char) -> vector_signed_char; + #[link_name = "llvm.ctlz.v8i16"] + fn vclzh(a: vector_signed_short) -> vector_signed_short; + #[link_name = "llvm.ctlz.v4i32"] + fn vclzw(a: vector_signed_int) -> vector_signed_int; + + #[link_name = "llvm.ppc.altivec.vrlb"] + fn vrlb(a: vector_signed_char, b: vector_unsigned_char) -> vector_signed_char; + #[link_name = "llvm.ppc.altivec.vrlh"] + fn vrlh(a: vector_signed_short, b: vector_unsigned_short) -> vector_signed_short; + #[link_name = "llvm.ppc.altivec.vrlw"] + fn vrlw(a: vector_signed_int, c: vector_unsigned_int) -> vector_signed_int; + + #[link_name = "llvm.ppc.altivec.vrfin"] + fn vrfin(a: vector_float) -> vector_float; } macro_rules! s_t_l { @@ -457,6 +477,27 @@ macro_rules! t_t_s { }; } +macro_rules! t_u { + (vector_unsigned_char) => { + vector_unsigned_char + }; + (vector_unsigned_short) => { + vector_unsigned_short + }; + (vector_unsigned_int) => { + vector_unsigned_int + }; + (vector_signed_char) => { + vector_unsigned_char + }; + (vector_signed_short) => { + vector_unsigned_short + }; + (vector_signed_int) => { + vector_unsigned_int + }; +} + macro_rules! impl_from { ($s: ident) => { #[unstable(feature = "stdarch_powerpc", issue = "111145")] @@ -1648,6 +1689,17 @@ mod sealed { impl_vec_trait! { [VectorSub vec_sub] ~(simd_sub, simd_sub, simd_sub, simd_sub, simd_sub, simd_sub) } impl_vec_trait! { [VectorSub vec_sub] simd_sub(vector_float, vector_float) -> vector_float } + test_impl! { vec_vsubcuw (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vsubcuw, vsubcuw] } + + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + pub trait VectorSubc { + type Result; + unsafe fn vec_subc(self, b: Other) -> Self::Result; + } + + impl_vec_trait! {[VectorSubc vec_subc]+ vec_vsubcuw(vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int } + impl_vec_trait! {[VectorSubc vec_subc]+ vec_vsubcuw(vector_signed_int, vector_signed_int) -> vector_signed_int } + test_impl! { vec_vminsb (a: vector_signed_char, b: vector_signed_char) -> vector_signed_char [vminsb, vminsb] } test_impl! { vec_vminsh (a: vector_signed_short, b: vector_signed_short) -> vector_signed_short [vminsh, vminsh] } test_impl! { vec_vminsw (a: vector_signed_int, b: vector_signed_int) -> vector_signed_int [vminsw, vminsw] } @@ -3090,6 +3142,82 @@ mod sealed { } impl_vec_shift_octect! { [VectorSro vec_sro] (vsro) } + + test_impl! { vec_vcntlzb(a: vector_signed_char) -> vector_signed_char [vclzb, vclzb] } + test_impl! { vec_vcntlzh(a: vector_signed_short) -> vector_signed_short [vclzh, vclzh] } + test_impl! { vec_vcntlzw(a: vector_signed_int) -> vector_signed_int [vclzw, vclzw] } + + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + pub trait VectorCntlz { + unsafe fn vec_cntlz(self) -> Self; + } + + macro_rules! impl_vec_cntlz { + ($fun:ident ($a:ty)) => { + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + impl VectorCntlz for $a { + #[inline] + #[target_feature(enable = "altivec")] + unsafe fn vec_cntlz(self) -> Self { + transmute($fun(transmute(self))) + } + } + }; + } + + impl_vec_cntlz! { vec_vcntlzb(vector_signed_char) } + impl_vec_cntlz! { vec_vcntlzb(vector_unsigned_char) } + impl_vec_cntlz! { vec_vcntlzh(vector_signed_short) } + impl_vec_cntlz! { vec_vcntlzh(vector_unsigned_short) } + impl_vec_cntlz! { vec_vcntlzw(vector_signed_int) } + impl_vec_cntlz! { vec_vcntlzw(vector_unsigned_int) } + + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + pub trait VectorRl { + type B; + unsafe fn vec_rl(self, b: Self::B) -> Self; + } + + macro_rules! impl_vec_rl { + ($fun:ident ($a:ident)) => { + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + impl VectorRl for $a { + type B = t_u!($a); + #[inline] + #[target_feature(enable = "altivec")] + unsafe fn vec_rl(self, b: Self::B) -> Self { + transmute($fun(transmute(self), b)) + } + } + }; + } + + test_impl! { vec_vrlb(a: vector_signed_char, b: vector_unsigned_char) -> vector_signed_char [vrlb, vrlb] } + test_impl! { vec_vrlh(a: vector_signed_short, b: vector_unsigned_short) -> vector_signed_short [vrlh, vrlh] } + test_impl! { vec_vrlw(a: vector_signed_int, b: vector_unsigned_int) -> vector_signed_int [vrlw, vrlw] } + + impl_vec_rl! { vec_vrlb(vector_signed_char) } + impl_vec_rl! { vec_vrlh(vector_signed_short) } + impl_vec_rl! { vec_vrlw(vector_signed_int) } + impl_vec_rl! { vec_vrlb(vector_unsigned_char) } + impl_vec_rl! { vec_vrlh(vector_unsigned_short) } + impl_vec_rl! { vec_vrlw(vector_unsigned_int) } + + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + pub trait VectorRound { + unsafe fn vec_round(self) -> Self; + } + + test_impl! { vec_vrfin(a: vector_float) -> vector_float [vrfin, vrfin] } + + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + impl VectorRound for vector_float { + #[inline] + #[target_feature(enable = "altivec")] + unsafe fn vec_round(self) -> Self { + vec_vrfin(self) + } + } } /// Vector Merge Low @@ -3679,6 +3807,45 @@ where a.vec_abss() } +/// Vector Rotate Left +/// +/// ## Purpose +/// Rotates each element of a vector left by a given number of bits. +/// +/// ## Result value +/// Each element of r is obtained by rotating the corresponding element of a left by +/// the number of bits specified by the corresponding element of b. +#[inline] +#[target_feature(enable = "altivec")] +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +pub unsafe fn vec_rl(a: T, b: ::B) -> T +where + T: sealed::VectorRl, +{ + a.vec_rl(b) +} + +/// Vector Round +/// +/// ## Purpose +/// Returns a vector containing the rounded values of the corresponding elements of the +/// source vector. +/// +/// ## Result value +/// Each element of r contains the value of the corresponding element of a, rounded +/// to the nearest representable floating-point integer, using IEEE round-to-nearest +/// rounding. +/// The current floating-point rounding mode is ignored. +#[inline] +#[target_feature(enable = "altivec")] +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +pub unsafe fn vec_round(a: T) -> T +where + T: sealed::VectorRound, +{ + a.vec_round() +} + /// Vector Splat #[inline] #[target_feature(enable = "altivec")] @@ -3719,6 +3886,26 @@ where a.vec_sub(b) } +/// Vector Subtract Carryout +/// +/// ## Purpose +/// Returns a vector wherein each element contains the carry produced by subtracting the +/// corresponding elements of the two source vectors. +/// +/// ## Result value +/// The value of each element of r is the complement of the carry produced by subtract- ing the +/// value of the corresponding element of b from the value of the corresponding element of a. The +/// value is 0 if a borrow occurred, or 1 if no borrow occurred. +#[inline] +#[target_feature(enable = "altivec")] +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +pub unsafe fn vec_subc(a: T, b: U) -> >::Result +where + T: sealed::VectorSubc, +{ + a.vec_subc(b) +} + /// Vector subs. #[inline] #[target_feature(enable = "altivec")] @@ -4219,6 +4406,25 @@ pub unsafe fn vec_any_numeric(a: vector_float) -> bool { vcmpgefp_p(1, a, a) != 0 } +/// Vector Count Leading Zeros +/// +/// ## Purpose +/// Returns a vector containing the number of most-significant bits equal to zero of each +/// corresponding element of the source vector. +/// +/// ## Result value +/// The value of each element of r is set to the number of leading zeros of the +/// corresponding element of a. +#[inline] +#[target_feature(enable = "altivec")] +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +pub unsafe fn vec_cntlz(a: T) -> T +where + T: sealed::VectorCntlz, +{ + a.vec_cntlz() +} + /// Any Element Out of Bounds #[inline] #[target_feature(enable = "altivec")]