Skip to content

Commit 1dcc3b0

Browse files
committed
s390x: implement vec_sld using fshl
1 parent 52cc719 commit 1dcc3b0

File tree

1 file changed

+46
-9
lines changed

1 file changed

+46
-9
lines changed

crates/core_arch/src/s390x/vector.rs

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ unsafe extern "unadjusted" {
9494
#[link_name = "llvm.s390.vsrlb"] fn vsrlb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
9595
#[link_name = "llvm.s390.vslb"] fn vslb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char;
9696

97-
#[link_name = "llvm.s390.vsldb"] fn vsldb(a: i8x16, b: i8x16, c: u32) -> i8x16;
98-
#[link_name = "llvm.s390.vsld"] fn vsld(a: i8x16, b: i8x16, c: u32) -> i8x16;
9997
#[link_name = "llvm.s390.vsrd"] fn vsrd(a: i8x16, b: i8x16, c: u32) -> i8x16;
10098

10199
#[link_name = "llvm.s390.verimb"] fn verimb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char, d: i32) -> vector_signed_char;
@@ -3484,10 +3482,44 @@ mod sealed {
34843482
unsafe fn vec_sldb<const C: u32>(self, b: Self) -> Self;
34853483
}
34863484

3487-
// FIXME(llvm) https://github.com/llvm/llvm-project/issues/129955
3488-
// ideally we could implement this in terms of llvm.fshl.i128
3489-
// #[link_name = "llvm.fshl.i128"] fn fshl_i128(a: u128, b: u128, c: u128) -> u128;
3490-
// transmute(fshl_i128(transmute(a), transmute(b), const { C * 8 } ))
3485+
#[inline]
3486+
#[target_feature(enable = "vector")]
3487+
#[cfg_attr(test, assert_instr(vsldb))]
3488+
unsafe fn test_vec_sld(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
3489+
a.vec_sld::<13>(b)
3490+
}
3491+
3492+
#[inline]
3493+
#[target_feature(enable = "vector")]
3494+
#[cfg_attr(test, assert_instr(vsldb))]
3495+
unsafe fn test_vec_sldw(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
3496+
a.vec_sldw::<3>(b)
3497+
}
3498+
3499+
#[inline]
3500+
#[target_feature(enable = "vector-enhancements-2")]
3501+
#[cfg_attr(test, assert_instr(vsld))]
3502+
unsafe fn test_vec_sldb(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
3503+
a.vec_sldb::<7>(b)
3504+
}
3505+
3506+
#[inline]
3507+
#[target_feature(enable = "vector-enhancements-2")]
3508+
#[cfg_attr(test, assert_instr(vsrd))]
3509+
unsafe fn test_vec_srdb(a: vector_signed_int, b: vector_signed_int) -> vector_signed_int {
3510+
a.vec_srdb::<7>(b)
3511+
}
3512+
3513+
unsafe fn funnel_shl_u128(a: u128, b: u128, c: u128) -> u128 {
3514+
#[repr(simd)]
3515+
struct Single([u128; 1]);
3516+
3517+
transmute(simd_funnel_shl::<Single>(
3518+
transmute(a),
3519+
transmute(b),
3520+
transmute(c),
3521+
))
3522+
}
34913523

34923524
macro_rules! impl_vec_sld {
34933525
($($ty:ident)*) => {
@@ -3498,21 +3530,21 @@ mod sealed {
34983530
#[target_feature(enable = "vector")]
34993531
unsafe fn vec_sld<const C: u32>(self, b: Self) -> Self {
35003532
static_assert_uimm_bits!(C, 4);
3501-
transmute(vsldb(transmute(self), transmute(b), C))
3533+
transmute(funnel_shl_u128(transmute(self), transmute(b), const { C as u128 * 8 }))
35023534
}
35033535

35043536
#[inline]
35053537
#[target_feature(enable = "vector")]
35063538
unsafe fn vec_sldw<const C: u32>(self, b: Self) -> Self {
35073539
static_assert_uimm_bits!(C, 2);
3508-
transmute(vsldb(transmute(self), transmute(b), const { 4 * C }))
3540+
transmute(funnel_shl_u128(transmute(self), transmute(b), const { C as u128 * 4 * 8 }))
35093541
}
35103542

35113543
#[inline]
35123544
#[target_feature(enable = "vector-enhancements-2")]
35133545
unsafe fn vec_sldb<const C: u32>(self, b: Self) -> Self {
35143546
static_assert_uimm_bits!(C, 3);
3515-
transmute(vsld(transmute(self), transmute(b), C))
3547+
transmute(funnel_shl_u128(transmute(self), transmute(b), const { C as u128 }))
35163548
}
35173549
}
35183550

@@ -3523,6 +3555,11 @@ mod sealed {
35233555
unsafe fn vec_srdb<const C: u32>(self, b: Self) -> Self {
35243556
static_assert_uimm_bits!(C, 3);
35253557
transmute(vsrd(transmute(self), transmute(b), C))
3558+
// FIXME(llvm): https://github.com/llvm/llvm-project/issues/129955#issuecomment-3207488190
3559+
// LLVM currently rewrites `fshr` to `fshl`, and the logic in the s390x
3560+
// backend cannot deal with that yet.
3561+
// #[link_name = "llvm.fshr.i128"] fn fshr_i128(a: u128, b: u128, c: u128) -> u128;
3562+
// transmute(fshr_i128(transmute(self), transmute(b), const { C as u128 }))
35263563
}
35273564
}
35283565
)*

0 commit comments

Comments
 (0)