Skip to content

Commit 83146e0

Browse files
committed
add vec_mule
1 parent dcfb896 commit 83146e0

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

crates/core_arch/src/s390x/vector.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,14 @@ unsafe extern "unadjusted" {
188188
#[link_name = "llvm.s390.vavglg"] fn vavglg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long;
189189

190190
#[link_name = "llvm.s390.vcksm"] fn vcksm(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int;
191+
192+
#[link_name = "llvm.s390.vmeb"] fn vmeb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_short;
193+
#[link_name = "llvm.s390.vmeh"] fn vmeh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_int;
194+
#[link_name = "llvm.s390.vmef"] fn vmef(a: vector_signed_int, b: vector_signed_int) -> vector_signed_long_long;
195+
196+
#[link_name = "llvm.s390.vmleb"] fn vmleb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_short;
197+
#[link_name = "llvm.s390.vmleh"] fn vmleh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int;
198+
#[link_name = "llvm.s390.vmlef"] fn vmlef(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long;
191199
}
192200

193201
impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 }
@@ -2388,6 +2396,59 @@ mod sealed {
23882396
}
23892397

23902398
impl_vec_trait! { [VectorAvg vec_avg] 2 (vec_vavglb, vec_vavgb, vec_vavglh, vec_vavgh, vec_vavglf, vec_vavgf, vec_vavglg, vec_vavgg) }
2399+
2400+
macro_rules! impl_mul {
2401+
([$Trait:ident $m:ident] $fun:ident ($a:ty, $b:ty) -> $r:ty) => {
2402+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2403+
impl $Trait<$r> for $a {
2404+
#[inline]
2405+
#[target_feature(enable = "vector")]
2406+
unsafe fn $m(self, b: $b) -> $r {
2407+
$fun(transmute(self), transmute(b))
2408+
}
2409+
}
2410+
};
2411+
}
2412+
2413+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
2414+
pub trait VectorMule<Result> {
2415+
unsafe fn vec_mule(self, b: Self) -> Result;
2416+
}
2417+
2418+
// FIXME(llvm) sadly this does not yet work https://github.com/llvm/llvm-project/issues/129705
2419+
// #[target_feature(enable = "vector")]
2420+
// #[cfg_attr(test, assert_instr(vmleh))]
2421+
// unsafe fn vec_vmleh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int {
2422+
// let even_a: vector_unsigned_int = simd_as(simd_shuffle::<_, _, u16x4>(
2423+
// a,
2424+
// a,
2425+
// const { ShuffleMask([0, 2, 4, 6]) },
2426+
// ));
2427+
//
2428+
// let even_b: vector_unsigned_int = simd_as(simd_shuffle::<_, _, u16x4>(
2429+
// b,
2430+
// b,
2431+
// const { ShuffleMask([0, 2, 4, 6]) },
2432+
// ));
2433+
//
2434+
// simd_mul(even_a, even_b)
2435+
// }
2436+
2437+
test_impl! { vec_vmeb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_short [ vmeb, vmeb ] }
2438+
test_impl! { vec_vmeh(a: vector_signed_short, b: vector_signed_short) -> vector_signed_int[ vmeh, vmeh ] }
2439+
test_impl! { vec_vmef(a: vector_signed_int, b: vector_signed_int) -> vector_signed_long_long [ vmef, vmef ] }
2440+
2441+
test_impl! { vec_vmleb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_short [ vmleb, vmleb ] }
2442+
test_impl! { vec_vmleh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int[ vmleh, vmleh ] }
2443+
test_impl! { vec_vmlef(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long [ vmlef, vmlef ] }
2444+
2445+
impl_mul!([VectorMule vec_mule] vec_vmeb (vector_signed_char, vector_signed_char) -> vector_signed_short );
2446+
impl_mul!([VectorMule vec_mule] vec_vmeh (vector_signed_short, vector_signed_short) -> vector_signed_int);
2447+
impl_mul!([VectorMule vec_mule] vec_vmef (vector_signed_int, vector_signed_int) -> vector_signed_long_long );
2448+
2449+
impl_mul!([VectorMule vec_mule] vec_vmleb (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_short );
2450+
impl_mul!([VectorMule vec_mule] vec_vmleh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_int);
2451+
impl_mul!([VectorMule vec_mule] vec_vmlef (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_long_long );
23912452
}
23922453

23932454
/// Load Count to Block Boundary
@@ -3468,6 +3529,14 @@ pub unsafe fn vec_checksum(a: vector_unsigned_int, b: vector_unsigned_int) -> ve
34683529
vcksm(a, b)
34693530
}
34703531

3532+
/// Vector Multiply Even
3533+
#[inline]
3534+
#[target_feature(enable = "vector")]
3535+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
3536+
pub unsafe fn vec_mule<T: sealed::VectorMule<U>, U>(a: T, b: T) -> U {
3537+
a.vec_mule(b)
3538+
}
3539+
34713540
#[cfg(test)]
34723541
mod tests {
34733542
use super::*;
@@ -4366,4 +4435,16 @@ mod tests {
43664435
assert_eq!(d, 1);
43674436
}
43684437
}
4438+
4439+
test_vec_2! { test_vec_mule_u, vec_mule, u16x8, u16x8 -> u32x4,
4440+
[0xFFFF, 0, 2, 0, 2, 0, 1, 0],
4441+
[0xFFFF, 0, 4, 0, 0xFFFF, 0, 2, 0],
4442+
[0xFFFE_0001, 8, 0x0001_FFFE, 2]
4443+
}
4444+
4445+
test_vec_2! { test_vec_mule_i, vec_mule, i16x8, i16x8 -> i32x4,
4446+
[i16::MIN, 0, -2, 0, 2, 0, 1, 0],
4447+
[i16::MIN, 0, 4, 0, i16::MAX, 0, 2, 0],
4448+
[0x4000_0000, -8, 0xFFFE, 2]
4449+
}
43694450
}

0 commit comments

Comments
 (0)