diff options
Diffstat (limited to 'library/stdarch')
5 files changed, 350 insertions, 182 deletions
diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs index f55cb664e8c..2a01f4aca26 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs @@ -18,6 +18,8 @@ use crate::{core_arch::simd::*, intrinsics::simd::*, mem, mem::transmute}; #[cfg(test)] use stdarch_test::assert_instr; +use super::macros::*; + types! { /// PowerPC-specific 128-bit wide vector of sixteen packed `i8` #[unstable(feature = "stdarch_powerpc", issue = "111145")] @@ -395,183 +397,8 @@ extern "C" { fn vrfin(a: vector_float) -> vector_float; } -macro_rules! s_t_l { - (i32x4) => { - vector_signed_int - }; - (i16x8) => { - vector_signed_short - }; - (i8x16) => { - vector_signed_char - }; - - (u32x4) => { - vector_unsigned_int - }; - (u16x8) => { - vector_unsigned_short - }; - (u8x16) => { - vector_unsigned_char - }; - - (f32x4) => { - vector_float - }; -} - -macro_rules! t_t_l { - (i32) => { - vector_signed_int - }; - (i16) => { - vector_signed_short - }; - (i8) => { - vector_signed_char - }; - - (u32) => { - vector_unsigned_int - }; - (u16) => { - vector_unsigned_short - }; - (u8) => { - vector_unsigned_char - }; - - (f32) => { - vector_float - }; -} - -macro_rules! t_t_s { - (i32) => { - i32x4 - }; - (i16) => { - i16x8 - }; - (i8) => { - i8x16 - }; - - (u32) => { - u32x4 - }; - (u16) => { - u16x8 - }; - (u8) => { - u8x16 - }; - - (f32) => { - f32x4 - }; -} - -macro_rules! t_u { - (vector_bool_char) => { - vector_unsigned_char - }; - (vector_bool_short) => { - vector_unsigned_short - }; - (vector_bool_int) => { - vector_unsigned_int - }; - (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 - }; - (vector_float) => { - vector_unsigned_int - }; -} - -macro_rules! t_b { - (vector_bool_char) => { - vector_bool_char - }; - (vector_bool_short) => { - vector_bool_short - }; - (vector_bool_int) => { - vector_bool_int - }; - (vector_signed_char) => { - vector_bool_char - }; - (vector_signed_short) => { - vector_bool_short - }; - (vector_signed_int) => { - vector_bool_int - }; - (vector_unsigned_char) => { - vector_bool_char - }; - (vector_unsigned_short) => { - vector_bool_short - }; - (vector_unsigned_int) => { - vector_bool_int - }; - (vector_float) => { - vector_bool_int - }; -} - -macro_rules! impl_from { - ($s: ident) => { - #[unstable(feature = "stdarch_powerpc", issue = "111145")] - impl From<$s> for s_t_l!($s) { - fn from (v: $s) -> Self { - unsafe { - transmute(v) - } - } - } - }; - ($($s: ident),*) => { - $( - impl_from! { $s } - )* - }; -} - impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, f32x4 } -macro_rules! impl_neg { - ($s: ident : $zero: expr) => { - #[unstable(feature = "stdarch_powerpc", issue = "111145")] - impl crate::ops::Neg for s_t_l!($s) { - type Output = s_t_l!($s); - fn neg(self) -> Self::Output { - let zero = $s::splat($zero); - unsafe { transmute(simd_sub(zero, transmute(self))) } - } - } - }; -} - impl_neg! { i8x16 : 0 } impl_neg! { i16x8 : 0 } impl_neg! { i32x4 : 0 } @@ -4641,11 +4468,7 @@ pub use self::endian::*; #[cfg(test)] mod tests { - #[cfg(target_arch = "powerpc")] - use crate::core_arch::arch::powerpc::*; - - #[cfg(target_arch = "powerpc64")] - use crate::core_arch::arch::powerpc64::*; + use super::*; use std::mem::transmute; diff --git a/library/stdarch/crates/core_arch/src/powerpc/macros.rs b/library/stdarch/crates/core_arch/src/powerpc/macros.rs index a4fcef12803..bd92ea17dec 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/macros.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/macros.rs @@ -122,3 +122,188 @@ macro_rules! impl_vec_trait { impl_vec_trait!{ [$Trait $m]+ $w (vector_signed_int, vector_signed_int) -> vector_signed_int } } } + +macro_rules! s_t_l { + (i32x4) => { + vector_signed_int + }; + (i16x8) => { + vector_signed_short + }; + (i8x16) => { + vector_signed_char + }; + + (u32x4) => { + vector_unsigned_int + }; + (u16x8) => { + vector_unsigned_short + }; + (u8x16) => { + vector_unsigned_char + }; + + (f32x4) => { + vector_float + }; +} + +macro_rules! t_t_l { + (i32) => { + vector_signed_int + }; + (i16) => { + vector_signed_short + }; + (i8) => { + vector_signed_char + }; + + (u32) => { + vector_unsigned_int + }; + (u16) => { + vector_unsigned_short + }; + (u8) => { + vector_unsigned_char + }; + + (f32) => { + vector_float + }; +} + +macro_rules! t_t_s { + (i32) => { + i32x4 + }; + (i16) => { + i16x8 + }; + (i8) => { + i8x16 + }; + + (u32) => { + u32x4 + }; + (u16) => { + u16x8 + }; + (u8) => { + u8x16 + }; + + (f32) => { + f32x4 + }; +} + +macro_rules! t_u { + (vector_bool_char) => { + vector_unsigned_char + }; + (vector_bool_short) => { + vector_unsigned_short + }; + (vector_bool_int) => { + vector_unsigned_int + }; + (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 + }; + (vector_float) => { + vector_unsigned_int + }; +} + +macro_rules! t_b { + (vector_bool_char) => { + vector_bool_char + }; + (vector_bool_short) => { + vector_bool_short + }; + (vector_bool_int) => { + vector_bool_int + }; + (vector_signed_char) => { + vector_bool_char + }; + (vector_signed_short) => { + vector_bool_short + }; + (vector_signed_int) => { + vector_bool_int + }; + (vector_unsigned_char) => { + vector_bool_char + }; + (vector_unsigned_short) => { + vector_bool_short + }; + (vector_unsigned_int) => { + vector_bool_int + }; + (vector_float) => { + vector_bool_int + }; +} + +macro_rules! impl_from { + ($s: ident) => { + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + impl From<$s> for s_t_l!($s) { + fn from (v: $s) -> Self { + unsafe { + transmute(v) + } + } + } + }; + ($($s: ident),*) => { + $( + impl_from! { $s } + )* + }; +} + +macro_rules! impl_neg { + ($s: ident : $zero: expr) => { + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + impl crate::ops::Neg for s_t_l!($s) { + type Output = s_t_l!($s); + fn neg(self) -> Self::Output { + let zero = $s::splat($zero); + unsafe { transmute(simd_sub(zero, transmute(self))) } + } + } + }; +} + +pub(crate) use impl_from; +pub(crate) use impl_neg; +pub(crate) use impl_vec_trait; +pub(crate) use s_t_l; +pub(crate) use t_b; +pub(crate) use t_t_l; +pub(crate) use t_t_s; +pub(crate) use t_u; +pub(crate) use test_impl; diff --git a/library/stdarch/crates/core_arch/src/powerpc/mod.rs b/library/stdarch/crates/core_arch/src/powerpc/mod.rs index 2f6948c7491..53227215d94 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/mod.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/mod.rs @@ -1,7 +1,6 @@ //! PowerPC intrinsics -#[macro_use] -mod macros; +pub(crate) mod macros; mod altivec; #[unstable(feature = "stdarch_powerpc", issue = "111145")] diff --git a/library/stdarch/crates/core_arch/src/powerpc64/mod.rs b/library/stdarch/crates/core_arch/src/powerpc64/mod.rs index dac998df6b5..e361c55a907 100644 --- a/library/stdarch/crates/core_arch/src/powerpc64/mod.rs +++ b/library/stdarch/crates/core_arch/src/powerpc64/mod.rs @@ -5,5 +5,10 @@ //! //! [64-Bit ELF V2 ABI Specification - Power Architecture]: http://openpowerfoundation.org/wp-content/uploads/resources/leabi/leabi-20170510.pdf +mod vsx; + #[unstable(feature = "stdarch_powerpc", issue = "111145")] pub use crate::core_arch::powerpc::*; + +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +pub use self::vsx::*; diff --git a/library/stdarch/crates/core_arch/src/powerpc64/vsx.rs b/library/stdarch/crates/core_arch/src/powerpc64/vsx.rs new file mode 100644 index 00000000000..d74d1b0495d --- /dev/null +++ b/library/stdarch/crates/core_arch/src/powerpc64/vsx.rs @@ -0,0 +1,156 @@ +//! PowerPC Vector Scalar eXtensions (VSX) intrinsics. +//! +//! The references are: [POWER ISA v2.07B (for POWER8 & POWER8 with NVIDIA +//! NVlink)] and [POWER ISA v3.0B (for POWER9)]. +//! +//! [POWER ISA v2.07B (for POWER8 & POWER8 with NVIDIA NVlink)]: https://ibm.box.com/s/jd5w15gz301s5b5dt375mshpq9c3lh4u +//! [POWER ISA v3.0B (for POWER9)]: https://ibm.box.com/s/1hzcwkwf8rbju5h9iyf44wm94amnlcrv + +#![allow(non_camel_case_types)] + +use crate::core_arch::powerpc::macros::*; +use crate::core_arch::powerpc::*; + +#[cfg(test)] +use stdarch_test::assert_instr; + +use crate::mem::transmute; + +#[allow(improper_ctypes)] +extern "C" { + #[link_name = "llvm.ppc.vsx.lxvl"] + fn lxvl(a: *const u8, l: usize) -> vector_signed_int; + + #[link_name = "llvm.ppc.vsx.stxvl"] + fn stxvl(v: vector_signed_int, a: *mut u8, l: usize); +} + +mod sealed { + use super::*; + + #[inline] + #[target_feature(enable = "power9-vector")] + #[cfg_attr(test, assert_instr(lxvl))] + unsafe fn vec_lxvl(p: *const u8, l: usize) -> vector_signed_int { + lxvl(p, l << 56) + } + + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + pub trait VectorXloads { + type Result; + unsafe fn vec_xl_len(self, l: usize) -> Self::Result; + } + + macro_rules! impl_vsx_loads { + ($ty:ident) => { + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + impl VectorXloads for *const $ty { + type Result = t_t_l!($ty); + #[inline] + #[target_feature(enable = "power9-vector")] + unsafe fn vec_xl_len(self, l: usize) -> Self::Result { + transmute(vec_lxvl(self as *const u8, l)) + } + } + }; + } + + impl_vsx_loads! { i8 } + impl_vsx_loads! { u8 } + impl_vsx_loads! { i16 } + impl_vsx_loads! { u16 } + impl_vsx_loads! { i32 } + impl_vsx_loads! { u32 } + impl_vsx_loads! { f32 } + + #[inline] + #[target_feature(enable = "power9-vector")] + #[cfg_attr(test, assert_instr(stxvl))] + unsafe fn vec_stxvl(v: vector_signed_int, a: *mut u8, l: usize) { + stxvl(v, a, l << 56); + } + + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + pub trait VectorXstores { + type Out; + unsafe fn vec_xst_len(self, p: Self::Out, l: usize); + } + + macro_rules! impl_stores { + ($ty:ident) => { + #[unstable(feature = "stdarch_powerpc", issue = "111145")] + impl VectorXstores for t_t_l!($ty) { + type Out = *mut $ty; + #[inline] + #[target_feature(enable = "power9-vector")] + unsafe fn vec_xst_len(self, a: Self::Out, l: usize) { + stxvl(transmute(self), a as *mut u8, l) + } + } + }; + } + + impl_stores! { i8 } + impl_stores! { u8 } + impl_stores! { i16 } + impl_stores! { u16 } + impl_stores! { i32 } + impl_stores! { u32 } + impl_stores! { f32 } +} + +/// Vector Load with Length +/// +/// ## Purpose +/// Loads a vector of a specified byte length. +/// +/// ## Result value +/// Loads the number of bytes specified by b from the address specified in a. +/// Initializes elements in order from the byte stream (as defined by the endianness of the +/// target). Any bytes of elements that cannot be initialized from the number of loaded bytes have +/// a zero value. +/// +/// Between 0 and 16 bytes, inclusive, will be loaded. The length is specified by the +/// least-significant byte of b, as min (b mod 256, 16). The behavior is undefined if the length +/// argument is outside of the range 0–255, or if it is not a multiple of the vector element size. +/// +/// ## Notes +/// vec_xl_len should not be used to load from cache-inhibited memory. +#[inline] +#[target_feature(enable = "power9-vector")] +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +pub unsafe fn vec_xl_len<T>(p: T, len: usize) -> <T as sealed::VectorXloads>::Result +where + T: sealed::VectorXloads, +{ + p.vec_xl_len(len) +} + +/// Vector Store with Length +/// +/// ## Purpose +/// +/// Stores a vector of a specified byte length. +/// +/// ## Operation +/// +/// Stores the number of bytes specified by c of the vector a to the address specified +/// in b. The bytes are obtained starting from the lowest-numbered byte of the lowest-numbered +/// element (as defined by the endianness of the target). All bytes of an element are accessed +/// before proceeding to the next higher element. +/// +/// Between 0 and 16 bytes, inclusive, will be stored. The length is specified by the +/// least-significant byte of c, as min (c mod 256, 16). The behavior is undefined if the length +/// argument is outside of the range 0–255, or if it is not a multiple of the vector element size. +/// +/// ## Notes +/// vec_xst_len should not be used to store to cache-inhibited memory. +#[inline] +#[target_feature(enable = "power9-vector")] +#[unstable(feature = "stdarch_powerpc", issue = "111145")] +pub unsafe fn vec_xst_len<T>(v: T, a: <T as sealed::VectorXstores>::Out, l: usize) +where + T: sealed::VectorXstores, +{ + v.vec_xst_len(a, l) +} |
