Skip to content

Commit 5ed2e5a

Browse files
folkertdevAmanieu
authored andcommitted
add vec_extract, vec_insert, vec_promote and vec_insert_and_zero
1 parent 7ae34fa commit 5ed2e5a

File tree

1 file changed

+243
-0
lines changed

1 file changed

+243
-0
lines changed

crates/core_arch/src/s390x/vector.rs

+243
Original file line numberDiff line numberDiff line change
@@ -3809,6 +3809,186 @@ mod sealed {
38093809
vector_bool_int vector_unsigned_int vfeef vfenef vfeezf vfenezf vfeefs vfenefs vfeezfs vfenezfs
38103810
vector_unsigned_int vector_unsigned_int vfeef vfenef vfeezf vfenezf vfeefs vfenefs vfeezfs vfenezfs
38113811
}
3812+
3813+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3814+
pub trait VectorExtract {
3815+
type ElementType;
3816+
3817+
unsafe fn vec_extract(a: Self, b: i32) -> Self::ElementType;
3818+
}
3819+
3820+
#[inline]
3821+
#[target_feature(enable = "vector")]
3822+
#[cfg_attr(test, assert_instr(vlgvb))]
3823+
unsafe fn vlgvb(a: vector_unsigned_char, b: i32) -> u8 {
3824+
simd_extract_dyn(a, b as u32 % 16)
3825+
}
3826+
3827+
#[inline]
3828+
#[target_feature(enable = "vector")]
3829+
#[cfg_attr(test, assert_instr(vlgvh))]
3830+
unsafe fn vlgvh(a: vector_unsigned_short, b: i32) -> u16 {
3831+
simd_extract_dyn(a, b as u32 % 8)
3832+
}
3833+
3834+
#[inline]
3835+
#[target_feature(enable = "vector")]
3836+
#[cfg_attr(test, assert_instr(vlgvf))]
3837+
unsafe fn vlgvf(a: vector_unsigned_int, b: i32) -> u32 {
3838+
simd_extract_dyn(a, b as u32 % 4)
3839+
}
3840+
3841+
#[inline]
3842+
#[target_feature(enable = "vector")]
3843+
#[cfg_attr(test, assert_instr(vlgvg))]
3844+
unsafe fn vlgvg(a: vector_unsigned_long_long, b: i32) -> u64 {
3845+
simd_extract_dyn(a, b as u32 % 2)
3846+
}
3847+
3848+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3849+
pub trait VectorInsert {
3850+
type ElementType;
3851+
3852+
unsafe fn vec_insert(a: Self::ElementType, b: Self, c: i32) -> Self;
3853+
}
3854+
3855+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3856+
pub trait VectorPromote: Sized {
3857+
type ElementType;
3858+
3859+
unsafe fn vec_promote(a: Self::ElementType, b: i32) -> MaybeUninit<Self>;
3860+
}
3861+
3862+
#[inline]
3863+
#[target_feature(enable = "vector")]
3864+
#[cfg_attr(test, assert_instr(vlvgb))]
3865+
unsafe fn vlvgb(a: u8, b: vector_unsigned_char, c: i32) -> vector_unsigned_char {
3866+
simd_insert_dyn(b, c as u32 % 16, a)
3867+
}
3868+
3869+
#[inline]
3870+
#[target_feature(enable = "vector")]
3871+
#[cfg_attr(test, assert_instr(vlvgh))]
3872+
unsafe fn vlvgh(a: u16, b: vector_unsigned_short, c: i32) -> vector_unsigned_short {
3873+
simd_insert_dyn(b, c as u32 % 8, a)
3874+
}
3875+
3876+
#[inline]
3877+
#[target_feature(enable = "vector")]
3878+
#[cfg_attr(test, assert_instr(vlvgf))]
3879+
unsafe fn vlvgf(a: u32, b: vector_unsigned_int, c: i32) -> vector_unsigned_int {
3880+
simd_insert_dyn(b, c as u32 % 4, a)
3881+
}
3882+
3883+
#[inline]
3884+
#[target_feature(enable = "vector")]
3885+
#[cfg_attr(test, assert_instr(vlvgg))]
3886+
unsafe fn vlvgg(a: u64, b: vector_unsigned_long_long, c: i32) -> vector_unsigned_long_long {
3887+
simd_insert_dyn(b, c as u32 % 2, a)
3888+
}
3889+
3890+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3891+
pub trait VectorInsertAndZero {
3892+
type ElementType;
3893+
3894+
unsafe fn vec_insert_and_zero(a: *const Self::ElementType) -> Self;
3895+
}
3896+
3897+
#[inline]
3898+
#[target_feature(enable = "vector")]
3899+
#[cfg_attr(test, assert_instr(vllezb))]
3900+
unsafe fn vllezb(x: *const u8) -> vector_unsigned_char {
3901+
vector_unsigned_char([0, 0, 0, 0, 0, 0, 0, *x, 0, 0, 0, 0, 0, 0, 0, 0])
3902+
}
3903+
3904+
#[inline]
3905+
#[target_feature(enable = "vector")]
3906+
#[cfg_attr(test, assert_instr(vllezh))]
3907+
unsafe fn vllezh(x: *const u16) -> vector_unsigned_short {
3908+
vector_unsigned_short([0, 0, 0, *x, 0, 0, 0, 0])
3909+
}
3910+
3911+
#[inline]
3912+
#[target_feature(enable = "vector")]
3913+
#[cfg_attr(test, assert_instr(vllezf))]
3914+
unsafe fn vllezf(x: *const u32) -> vector_unsigned_int {
3915+
vector_unsigned_int([0, *x, 0, 0])
3916+
}
3917+
3918+
#[inline]
3919+
#[target_feature(enable = "vector")]
3920+
#[cfg_attr(test, assert_instr(vllezg))]
3921+
unsafe fn vllezg(x: *const u64) -> vector_unsigned_long_long {
3922+
vector_unsigned_long_long([*x, 0])
3923+
}
3924+
3925+
macro_rules! impl_extract_insert {
3926+
($($ty:ident $extract_intr:ident $insert_intr:ident $insert_and_zero_intr:ident)*) => {
3927+
$(
3928+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3929+
impl VectorExtract for $ty {
3930+
type ElementType = l_t_t!($ty);
3931+
3932+
#[inline]
3933+
#[target_feature(enable = "vector")]
3934+
unsafe fn vec_extract(a: Self, b: i32) -> Self::ElementType {
3935+
transmute($extract_intr(transmute(a), b))
3936+
}
3937+
}
3938+
3939+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3940+
impl VectorInsert for $ty {
3941+
type ElementType = l_t_t!($ty);
3942+
3943+
#[inline]
3944+
#[target_feature(enable = "vector")]
3945+
unsafe fn vec_insert(a: Self::ElementType, b: Self, c: i32) -> Self {
3946+
transmute($insert_intr(transmute(a), transmute(b), c))
3947+
}
3948+
}
3949+
3950+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3951+
impl VectorInsertAndZero for $ty {
3952+
type ElementType = l_t_t!($ty);
3953+
3954+
#[inline]
3955+
#[target_feature(enable = "vector")]
3956+
unsafe fn vec_insert_and_zero(a: *const Self::ElementType) -> Self {
3957+
transmute($insert_and_zero_intr(a.cast()))
3958+
}
3959+
}
3960+
3961+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3962+
impl VectorPromote for $ty {
3963+
type ElementType = l_t_t!($ty);
3964+
3965+
#[inline]
3966+
#[target_feature(enable = "vector")]
3967+
unsafe fn vec_promote(a: Self::ElementType, c: i32) -> MaybeUninit<Self> {
3968+
// Rust does not currently support `MaybeUninit` element types to simd
3969+
// vectors. In C/LLVM that is allowed (using poison values). So rust will
3970+
// use an extra instruction to zero the memory.
3971+
let b = MaybeUninit::<$ty>::zeroed();
3972+
MaybeUninit::new(transmute($insert_intr(transmute(a), transmute(b), c)))
3973+
}
3974+
}
3975+
)*
3976+
}
3977+
3978+
}
3979+
3980+
impl_extract_insert! {
3981+
vector_signed_char vlgvb vlvgb vllezb
3982+
vector_unsigned_char vlgvb vlvgb vllezb
3983+
vector_signed_short vlgvh vlvgh vllezh
3984+
vector_unsigned_short vlgvh vlvgh vllezh
3985+
vector_signed_int vlgvf vlvgf vllezf
3986+
vector_unsigned_int vlgvf vlvgf vllezf
3987+
vector_signed_long_long vlgvg vlvgg vllezg
3988+
vector_unsigned_long_long vlgvg vlvgg vllezg
3989+
vector_float vlgvf vlvgf vllezf
3990+
vector_double vlgvg vlvgg vllezg
3991+
}
38123992
}
38133993

38143994
/// Load Count to Block Boundary
@@ -5646,6 +5826,38 @@ pub unsafe fn vec_any_nge<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
56465826
vec_any_lt(a, b)
56475827
}
56485828

5829+
/// Vector Extract
5830+
#[inline]
5831+
#[target_feature(enable = "vector")]
5832+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
5833+
pub unsafe fn vec_extract<T: sealed::VectorExtract>(a: T, b: i32) -> T::ElementType {
5834+
T::vec_extract(a, b)
5835+
}
5836+
5837+
/// Vector Insert
5838+
#[inline]
5839+
#[target_feature(enable = "vector")]
5840+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
5841+
pub unsafe fn vec_insert<T: sealed::VectorInsert>(a: T::ElementType, b: T, c: i32) -> T {
5842+
T::vec_insert(a, b, c)
5843+
}
5844+
5845+
/// Vector Insert and Zero
5846+
#[inline]
5847+
#[target_feature(enable = "vector")]
5848+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
5849+
pub unsafe fn vec_insert_and_zero<T: sealed::VectorInsertAndZero>(a: *const T::ElementType) -> T {
5850+
T::vec_insert_and_zero(a)
5851+
}
5852+
5853+
/// Vector Promote
5854+
#[inline]
5855+
#[target_feature(enable = "vector")]
5856+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
5857+
pub unsafe fn vec_promote<T: sealed::VectorPromote>(a: T::ElementType, b: i32) -> MaybeUninit<T> {
5858+
T::vec_promote(a, b)
5859+
}
5860+
56495861
#[cfg(test)]
56505862
mod tests {
56515863
use super::*;
@@ -7189,4 +7401,35 @@ mod tests {
71897401
let d = unsafe { vec_mladd(a, b, c) };
71907402
assert_eq!(d.as_array(), &[-3, -10, -19, -30]);
71917403
}
7404+
7405+
#[simd_test(enable = "vector")]
7406+
fn test_vec_extract() {
7407+
let v = vector_unsigned_int([1, 2, 3, 4]);
7408+
7409+
assert_eq!(unsafe { vec_extract(v, 1) }, 2);
7410+
assert_eq!(unsafe { vec_extract(v, 4 + 2) }, 3);
7411+
}
7412+
7413+
#[simd_test(enable = "vector")]
7414+
fn test_vec_insert() {
7415+
let mut v = vector_unsigned_int([1, 2, 3, 4]);
7416+
7417+
v = unsafe { vec_insert(42, v, 1) };
7418+
assert_eq!(v.as_array(), &[1, 42, 3, 4]);
7419+
7420+
v = unsafe { vec_insert(64, v, 6) };
7421+
assert_eq!(v.as_array(), &[1, 42, 64, 4]);
7422+
}
7423+
7424+
#[simd_test(enable = "vector")]
7425+
fn test_vec_promote() {
7426+
let v: vector_unsigned_int = unsafe { vec_promote(42, 1).assume_init() };
7427+
assert_eq!(v.as_array(), &[0, 42, 0, 0]);
7428+
}
7429+
7430+
#[simd_test(enable = "vector")]
7431+
fn test_vec_insert_and_zero() {
7432+
let v = unsafe { vec_insert_and_zero::<vector_unsigned_int>(&42u32) };
7433+
assert_eq!(v.as_array(), vector_unsigned_int([0, 42, 0, 0]).as_array());
7434+
}
71927435
}

0 commit comments

Comments
 (0)