Add vec_xl_len and vec_xst_len
They are powerpc64-only.
This commit is contained in:
parent
1fbe4dddec
commit
d4c77d3228
5 changed files with 350 additions and 182 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
//! PowerPC intrinsics
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
pub(crate) mod macros;
|
||||
|
||||
mod altivec;
|
||||
#[unstable(feature = "stdarch_powerpc", issue = "111145")]
|
||||
|
|
|
|||
|
|
@ -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::*;
|
||||
|
|
|
|||
156
library/stdarch/crates/core_arch/src/powerpc64/vsx.rs
Normal file
156
library/stdarch/crates/core_arch/src/powerpc64/vsx.rs
Normal file
|
|
@ -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)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue