Skip to content

Commit 0afccca

Browse files
folkertdevAmanieu
authored andcommitted
add vec_gather_element
1 parent 3c1bdfe commit 0afccca

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

crates/core_arch/src/s390x/macros.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,19 @@ macro_rules! l_t_t {
250250
u8
251251
};
252252

253+
(vector_bool_long_long ) => {
254+
u64
255+
};
256+
(vector_bool_int ) => {
257+
u32
258+
};
259+
(vector_bool_short ) => {
260+
u16
261+
};
262+
(vector_bool_char ) => {
263+
u8
264+
};
265+
253266
(vector_float) => {
254267
f32
255268
};
@@ -338,6 +351,9 @@ macro_rules! t_u {
338351
(vector_bool_int) => {
339352
vector_unsigned_int
340353
};
354+
(vector_bool_long_long) => {
355+
vector_unsigned_long_long
356+
};
341357
(vector_unsigned_char) => {
342358
vector_unsigned_char
343359
};

crates/core_arch/src/s390x/vector.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,78 @@ mod sealed {
25932593
vec_vgfmaf(self, b, c)
25942594
}
25952595
}
2596+
2597+
#[inline]
2598+
#[target_feature(enable = "vector")]
2599+
#[cfg_attr(test, assert_instr(vgef, D = 3))]
2600+
unsafe fn vgef<const D: u32>(
2601+
a: vector_unsigned_int,
2602+
b: vector_unsigned_int,
2603+
c: *const u32,
2604+
) -> vector_unsigned_int {
2605+
static_assert_uimm_bits!(D, 2);
2606+
let offset: u32 = simd_extract(b, D);
2607+
let ptr = c.byte_offset(offset as isize);
2608+
let value = ptr.read();
2609+
simd_insert(a, D, value)
2610+
}
2611+
2612+
#[inline]
2613+
#[target_feature(enable = "vector")]
2614+
#[cfg_attr(test, assert_instr(vgeg, D = 1))]
2615+
unsafe fn vgeg<const D: u32>(
2616+
a: vector_unsigned_long_long,
2617+
b: vector_unsigned_long_long,
2618+
c: *const u64,
2619+
) -> vector_unsigned_long_long {
2620+
static_assert_uimm_bits!(D, 1);
2621+
let offset: u64 = simd_extract(b, D);
2622+
let ptr = c.byte_offset(offset as isize);
2623+
let value = ptr.read();
2624+
simd_insert(a, D, value)
2625+
}
2626+
2627+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2628+
pub trait VectorGatherElement {
2629+
type Element;
2630+
type Offset;
2631+
unsafe fn vec_gather_element<const D: u32>(
2632+
self,
2633+
b: Self::Offset,
2634+
c: *const Self::Element,
2635+
) -> Self;
2636+
}
2637+
2638+
macro_rules! impl_vec_gather_element {
2639+
($($instr:ident $ty:ident)*) => {
2640+
$(
2641+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2642+
impl VectorGatherElement for $ty {
2643+
type Element = l_t_t!($ty);
2644+
type Offset = t_u!($ty);
2645+
2646+
#[inline]
2647+
#[target_feature(enable = "vector")]
2648+
unsafe fn vec_gather_element<const D: u32>(self, b: Self::Offset, c: *const Self::Element) -> Self {
2649+
transmute($instr::<D>(transmute(self), b, c.cast()))
2650+
}
2651+
}
2652+
)*
2653+
}
2654+
}
2655+
2656+
impl_vec_gather_element! {
2657+
vgef vector_signed_int
2658+
vgef vector_bool_int
2659+
vgef vector_unsigned_int
2660+
2661+
vgeg vector_signed_long_long
2662+
vgeg vector_bool_long_long
2663+
vgeg vector_unsigned_long_long
2664+
2665+
vgef vector_float
2666+
vgeg vector_double
2667+
}
25962668
}
25972669

25982670
/// Load Count to Block Boundary
@@ -3739,6 +3811,17 @@ pub unsafe fn vec_gfmsum_accum_128(
37393811
transmute(vgfmag(a, b, transmute(c)))
37403812
}
37413813

3814+
#[inline]
3815+
#[target_feature(enable = "vector")]
3816+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3817+
pub unsafe fn vec_gather_element<T: sealed::VectorGatherElement, const D: u32>(
3818+
a: T,
3819+
b: T::Offset,
3820+
c: *const T::Element,
3821+
) -> T {
3822+
a.vec_gather_element::<D>(b, c)
3823+
}
3824+
37423825
#[cfg(test)]
37433826
mod tests {
37443827
use super::*;
@@ -4676,4 +4759,28 @@ mod tests {
46764759
let d: u128 = unsafe { transmute(vec_gfmsum_128(a, b)) };
46774760
assert_eq!(d, 0xE000E000E000E000E000E000E000E);
46784761
}
4762+
4763+
#[simd_test(enable = "vector")]
4764+
fn test_vec_gather_element() {
4765+
let a1: [u32; 10] = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
4766+
let a2: [u32; 10] = [20, 21, 22, 23, 24, 25, 26, 27, 28, 29];
4767+
4768+
let v1 = vector_unsigned_int([1, 2, 3, 4]);
4769+
let v2 = vector_unsigned_int([1, 2, 3, 4]);
4770+
4771+
let sizeof_int = core::mem::size_of::<u32>() as u32;
4772+
let v3 = vector_unsigned_int([
4773+
5 * sizeof_int,
4774+
8 * sizeof_int,
4775+
9 * sizeof_int,
4776+
6 * sizeof_int,
4777+
]);
4778+
4779+
unsafe {
4780+
let d1 = vec_gather_element::<_, 0>(v1, v3, a1.as_ptr());
4781+
assert_eq!(d1.as_array(), &[15, 2, 3, 4]);
4782+
let d2 = vec_gather_element::<_, 0>(v2, v3, a2.as_ptr());
4783+
assert_eq!(d2.as_array(), &[25, 2, 3, 4]);
4784+
}
4785+
}
46794786
}

0 commit comments

Comments
 (0)