From 3bca04f0bf3603ea62539e2e45d5cb5359d8af61 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 17 Feb 2025 21:34:23 +0100 Subject: [PATCH 01/22] implement the long bitshifts --- crates/core_arch/src/s390x/vector.rs | 105 ++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 1b59a4c474..36ce9934cf 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -82,6 +82,10 @@ unsafe extern "unadjusted" { #[link_name = "llvm.roundeven.v4f32"] fn roundeven_v4f32(a: vector_float) -> vector_float; #[link_name = "llvm.roundeven.v2f64"] fn roundeven_v2f64(a: vector_double) -> vector_double; + + #[link_name = "llvm.s390.vsra"] fn vsra(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; + #[link_name = "llvm.s390.vsrl"] fn vsrl(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; + #[link_name = "llvm.s390.vsl"] fn vsl(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; } impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } @@ -701,6 +705,43 @@ mod sealed { impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_float) } impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_double) } + + macro_rules! impl_vec_shift_long { + ([$trait:ident $m:ident] ($f:ident)) => { + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_char, vector_unsigned_char) -> vector_signed_char } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_short, vector_unsigned_char) -> vector_unsigned_short } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_short, vector_unsigned_char) -> vector_signed_short } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_int, vector_unsigned_char) -> vector_unsigned_int } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_int, vector_unsigned_char) -> vector_signed_int } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_long_long, vector_unsigned_char) -> vector_unsigned_long_long } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_long_long, vector_unsigned_char) -> vector_signed_long_long } + }; + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSrl { + type Result; + unsafe fn vec_srl(self, b: Other) -> Self::Result; + } + + impl_vec_shift_long! { [VectorSrl vec_srl] (vsrl) } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSral { + type Result; + unsafe fn vec_sral(self, b: Other) -> Self::Result; + } + + impl_vec_shift_long! { [VectorSral vec_sral] (vsra) } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSll { + type Result; + unsafe fn vec_sll(self, b: Other) -> Self::Result; + } + + impl_vec_shift_long! { [VectorSll vec_sll] (vsl) } } /// Vector element-wise addition. @@ -1035,6 +1076,43 @@ where a.vec_rint() } +/// Performs a left shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding +/// element of a left by the number of bits specified by the last 3 bits of every byte of b. The bits that are shifted out are replaced by zeros. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_sll(a: T, b: vector_unsigned_char) -> T +where + T: sealed::VectorSll, +{ + a.vec_sll(b) +} + +/// Performs a right shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding +/// element of a right by the number of bits specified by the last 3 bits of every byte of b. The bits that are shifted out are replaced by zeros. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_srl(a: T, b: vector_unsigned_char) -> T +where + T: sealed::VectorSrl, +{ + a.vec_srl(b) +} + +/// Performs an algebraic right shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding +/// element of a right by the number of bits specified by the last 3 bits of every byte of b. The bits that are shifted out are replaced by copies of +/// the most significant bit of the element of a. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_sral(a: T, b: vector_unsigned_char) -> T +where + T: sealed::VectorSral, +{ + a.vec_sral(b) +} + #[cfg(test)] mod tests { use super::*; @@ -1076,10 +1154,13 @@ mod tests { test_vec_2! { $name, $fn, $ty -> $ty, [$($a),+], [$($b),+], [$($d),+] } }; { $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => { + test_vec_2! { $name, $fn, $ty, $ty -> $ty, [$($a),+], [$($b),+], [$($d),+] } + }; + { $name: ident, $fn:ident, $ty1: ident, $ty2: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => { #[simd_test(enable = "vector")] unsafe fn $name() { - let a: s_t_l!($ty) = transmute($ty::new($($a),+)); - let b: s_t_l!($ty) = transmute($ty::new($($b),+)); + let a: s_t_l!($ty1) = transmute($ty1::new($($a),+)); + let b: s_t_l!($ty2) = transmute($ty2::new($($b),+)); let d = $ty_out::new($($d),+); let r : $ty_out = transmute($fn(a, b)); @@ -1362,4 +1443,24 @@ mod tests { [0.6, 0.9], [1.0, 1.0] } + + test_vec_2! { test_vec_sll, vec_sll, i32x4, u8x16 -> i32x4, + [1, 1, 1, 1], + [0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 8], + [1 << 2, 1 << 3, 1 << 4, 1] } + + test_vec_2! { test_vec_srl, vec_srl, i32x4, u8x16 -> i32x4, + [0b1000, 0b1000, 0b1000, 0b1000], + [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16], + [4, 2, 1, 8] } + + test_vec_2! { test_vec_sral_pos, vec_sral, u32x4, u8x16 -> i32x4, + [0b1000, 0b1000, 0b1000, 0b1000], + [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16], + [4, 2, 1, 8] } + + test_vec_2! { test_vec_sral_neg, vec_sral, i32x4, u8x16 -> i32x4, + [-8, -8, -8, -8], + [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16], + [-4, -2, -1, -8] } } From 083e97ea9a116e56e9a25856021516e0d050f659 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 17 Feb 2025 21:56:33 +0100 Subject: [PATCH 02/22] implement standard bitshifts --- crates/core_arch/src/s390x/vector.rs | 100 +++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 36ce9934cf..1df3cb28d7 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -706,6 +706,73 @@ mod sealed { impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_float) } impl_vec_trait! { [VectorFloor vec_floor] simd_floor (vector_double) } + macro_rules! impl_vec_shift { + ([$Trait:ident $m:ident] ($b:ident, $h:ident, $w:ident, $g:ident)) => { + impl_vec_trait!{ [$Trait $m]+ $b (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char } + impl_vec_trait!{ [$Trait $m]+ $b (vector_signed_char, vector_unsigned_char) -> vector_signed_char } + impl_vec_trait!{ [$Trait $m]+ $h (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short } + impl_vec_trait!{ [$Trait $m]+ $h (vector_signed_short, vector_unsigned_short) -> vector_signed_short } + impl_vec_trait!{ [$Trait $m]+ $w (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int } + impl_vec_trait!{ [$Trait $m]+ $w (vector_signed_int, vector_unsigned_int) -> vector_signed_int } + impl_vec_trait!{ [$Trait $m]+ $g (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long } + impl_vec_trait!{ [$Trait $m]+ $g (vector_signed_long_long, vector_unsigned_long_long) -> vector_signed_long_long } + }; + } + + macro_rules! impl_shift { + ($fun:ident $intr:ident $ty:ident) => { + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr($fun))] + unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) { + let a = transmute(a); + // use the remainder of b by the width of a's elements to prevent UB + let b = simd_rem(transmute(b), ::splat($ty::BITS as $ty)); + + transmute($intr(a, b)) + } + }; + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSl { + type Result; + unsafe fn vec_sl(self, b: Other) -> Self::Result; + } + + impl_shift! { veslvb simd_shl u8 } + impl_shift! { veslvh simd_shl u16 } + impl_shift! { veslvf simd_shl u32 } + impl_shift! { veslvg simd_shl u64 } + + impl_vec_shift! { [VectorSl vec_sl] (veslvb, veslvh, veslvf, veslvg) } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSr { + type Result; + unsafe fn vec_sr(self, b: Other) -> Self::Result; + } + + impl_shift! { vesrlvb simd_shr u8 } + impl_shift! { vesrlvh simd_shr u16 } + impl_shift! { vesrlvf simd_shr u32 } + impl_shift! { vesrlvg simd_shr u64 } + + impl_vec_shift! { [VectorSr vec_sr] (vesrlvb, vesrlvh, vesrlvf, vesrlvg) } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSra { + type Result; + unsafe fn vec_sra(self, b: Other) -> Self::Result; + } + + impl_shift! { vesravb simd_shr i8 } + impl_shift! { vesravh simd_shr i16 } + impl_shift! { vesravf simd_shr i32 } + impl_shift! { vesravg simd_shr i64 } + + impl_vec_shift! { [VectorSra vec_sra] (vesravb, vesravh, vesravf, vesravg) } + macro_rules! impl_vec_shift_long { ([$trait:ident $m:ident] ($f:ident)) => { impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char } @@ -1076,6 +1143,39 @@ where a.vec_rint() } +/// Vector Shift Left +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_sl(a: T, b: U) -> >::Result +where + T: sealed::VectorSl, +{ + a.vec_sl(b) +} + +/// Vector Shift Right +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_sr(a: T, b: U) -> >::Result +where + T: sealed::VectorSr, +{ + a.vec_sr(b) +} + +/// Vector Shift Right Algebraic +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_sra(a: T, b: U) -> >::Result +where + T: sealed::VectorSra, +{ + a.vec_sra(b) +} + /// Performs a left shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding /// element of a left by the number of bits specified by the last 3 bits of every byte of b. The bits that are shifted out are replaced by zeros. #[inline] From 92d9f46f8cf3272799623a6d16fa16e44552c0ae Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 19 Feb 2025 11:14:35 +0100 Subject: [PATCH 03/22] implement rotate left --- crates/core_arch/src/s390x/vector.rs | 45 ++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 1df3cb28d7..f323eb1894 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -86,6 +86,11 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vsra"] fn vsra(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; #[link_name = "llvm.s390.vsrl"] fn vsrl(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; #[link_name = "llvm.s390.vsl"] fn vsl(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; + + #[link_name = "llvm.fshl.v16i8"] fn fshlb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> vector_unsigned_char; + #[link_name = "llvm.fshl.v8i16"] fn fshlh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short; + #[link_name = "llvm.fshl.v4i32"] fn fshlf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int; + #[link_name = "llvm.fshl.v2i64"] fn fshlg(a: vector_unsigned_long_long, b: vector_unsigned_long_long, c: vector_unsigned_long_long) -> vector_unsigned_long_long; } impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } @@ -809,6 +814,30 @@ mod sealed { } impl_vec_shift_long! { [VectorSll vec_sll] (vsl) } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorRl { + type Result; + unsafe fn vec_rl(self, b: Other) -> Self::Result; + } + + macro_rules! impl_rot { + ($fun:ident $intr:ident $ty:ident) => { + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr($fun))] + unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) { + transmute($intr(transmute(a), transmute(a), transmute(b))) + } + }; + } + + impl_rot! { verllvb fshlb u8 } + impl_rot! { verllvh fshlh u16 } + impl_rot! { verllvf fshlf u32 } + impl_rot! { verllvg fshlg u64 } + + impl_vec_shift! { [VectorRl vec_rl] (verllvb, verllvh, verllvf, verllvg) } } /// Vector element-wise addition. @@ -1176,6 +1205,17 @@ where a.vec_sra(b) } +/// Vector Element Rotate Left +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_rl(a: T, b: U) -> >::Result +where + T: sealed::VectorRl, +{ + a.vec_rl(b) +} + /// Performs a left shift for a vector by a given number of bits. Each element of the result is obtained by shifting the corresponding /// element of a left by the number of bits specified by the last 3 bits of every byte of b. The bits that are shifted out are replaced by zeros. #[inline] @@ -1563,4 +1603,9 @@ mod tests { [-8, -8, -8, -8], [0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16], [-4, -2, -1, -8] } + + test_vec_2! { test_vec_rl, vec_rl, u32x4, + [0x12345678, 0x9ABCDEF0, 0x0F0F0F0F, 0x12345678], + [4, 8, 12, 68], + [0x23456781, 0xBCDEF09A, 0xF0F0F0F0, 0x23456781] } } From 9921060750f19abf64ae9d0ff0f7e7533e42891e Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 19 Feb 2025 12:03:49 +0100 Subject: [PATCH 04/22] add vector shift by byte --- crates/core_arch/src/s390x/vector.rs | 86 ++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index f323eb1894..e06f30c676 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -87,6 +87,10 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vsrl"] fn vsrl(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; #[link_name = "llvm.s390.vsl"] fn vsl(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; + #[link_name = "llvm.s390.vsrab"] fn vsrab(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; + #[link_name = "llvm.s390.vsrlb"] fn vsrlb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; + #[link_name = "llvm.s390.vslb"] fn vslb(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char; + #[link_name = "llvm.fshl.v16i8"] fn fshlb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> vector_unsigned_char; #[link_name = "llvm.fshl.v8i16"] fn fshlh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short; #[link_name = "llvm.fshl.v4i32"] fn fshlf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int; @@ -778,6 +782,55 @@ mod sealed { impl_vec_shift! { [VectorSra vec_sra] (vesravb, vesravh, vesravf, vesravg) } + macro_rules! impl_vec_shift_byte { + ([$trait:ident $m:ident] ($f:ident)) => { + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_signed_char) -> vector_unsigned_char } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_char, vector_signed_char) -> vector_signed_char } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_char, vector_unsigned_char) -> vector_signed_char } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_short, vector_signed_short) -> vector_unsigned_short } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_short, vector_signed_short) -> vector_signed_short } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_short, vector_unsigned_short) -> vector_signed_short } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_int, vector_signed_int) -> vector_unsigned_int } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_int, vector_signed_int) -> vector_signed_int } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_int, vector_unsigned_int) -> vector_signed_int } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_long_long, vector_signed_long_long) -> vector_unsigned_long_long } + impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_long_long, vector_signed_long_long) -> vector_signed_long_long } + impl_vec_trait!{ [$trait $m]+ $f (vector_signed_long_long, vector_unsigned_long_long) -> vector_signed_long_long } + impl_vec_trait!{ [$trait $m]+ $f (vector_float, vector_signed_int) -> vector_float } + impl_vec_trait!{ [$trait $m]+ $f (vector_float, vector_unsigned_int) -> vector_float } + impl_vec_trait!{ [$trait $m]+ $f (vector_double, vector_signed_long_long) -> vector_double } + impl_vec_trait!{ [$trait $m]+ $f (vector_double, vector_unsigned_long_long) -> vector_double } + }; + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSlb { + type Result; + unsafe fn vec_slb(self, b: Other) -> Self::Result; + } + + impl_vec_shift_byte! { [VectorSlb vec_slb] (vslb) } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSrab { + type Result; + unsafe fn vec_srab(self, b: Other) -> Self::Result; + } + + impl_vec_shift_byte! { [VectorSrab vec_srab] (vsrab) } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSrb { + type Result; + unsafe fn vec_srb(self, b: Other) -> Self::Result; + } + + impl_vec_shift_byte! { [VectorSrb vec_srb] (vsrlb) } + macro_rules! impl_vec_shift_long { ([$trait:ident $m:ident] ($f:ident)) => { impl_vec_trait!{ [$trait $m]+ $f (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char } @@ -1205,6 +1258,39 @@ where a.vec_sra(b) } +/// Vector Shift Left by Byte +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_slb(a: T, b: U) -> >::Result +where + T: sealed::VectorSlb, +{ + a.vec_slb(b) +} + +/// Vector Shift Right by Byte +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_srb(a: T, b: U) -> >::Result +where + T: sealed::VectorSrb, +{ + a.vec_srb(b) +} + +/// Vector Shift Right Algebraic by Byte +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_srab(a: T, b: U) -> >::Result +where + T: sealed::VectorSrab, +{ + a.vec_srab(b) +} + /// Vector Element Rotate Left #[inline] #[target_feature(enable = "vector")] From 26955d9043db5cea05ca0fbc77f1dedbf59e1582 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 19 Feb 2025 16:09:55 +0100 Subject: [PATCH 05/22] add `vec_rli` --- crates/core_arch/src/s390x/macros.rs | 2 +- crates/core_arch/src/s390x/vector.rs | 69 ++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/crates/core_arch/src/s390x/macros.rs b/crates/core_arch/src/s390x/macros.rs index fd260bbc74..3b59f9b258 100644 --- a/crates/core_arch/src/s390x/macros.rs +++ b/crates/core_arch/src/s390x/macros.rs @@ -315,7 +315,7 @@ macro_rules! t_u { vector_unsigned_int }; (vector_signed_long_long) => { - vector_signed_long_long + vector_unsigned_long_long }; (vector_float) => { vector_unsigned_int diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index e06f30c676..2f6577d209 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -891,6 +891,63 @@ mod sealed { impl_rot! { verllvg fshlg u64 } impl_vec_shift! { [VectorRl vec_rl] (verllvb, verllvh, verllvf, verllvg) } + + macro_rules! test_rot_imm { + ($fun:ident $instr:ident $intr:ident $ty:ident) => { + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr($instr))] + unsafe fn $fun(a: t_t_l!($ty), bits: core::ffi::c_ulong) -> t_t_l!($ty) { + // mod by the number of bits in a's element type to prevent UB + let bits = (bits % $ty::BITS as core::ffi::c_ulong) as $ty; + let a = transmute(a); + let b = ::splat(bits); + + transmute($intr(a, a, transmute(b))) + } + }; + } + + test_rot_imm! { verllvb_imm verllb fshlb u8 } + test_rot_imm! { verllvh_imm verllh fshlh u16 } + test_rot_imm! { verllvf_imm verllf fshlf u32 } + test_rot_imm! { verllvg_imm verllg fshlg u64 } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorRli { + unsafe fn vec_rli(self, bits: core::ffi::c_ulong) -> Self; + } + + macro_rules! impl_rot_imm { + ($($ty:ident, $intr:ident),*) => { + $( + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorRli for $ty { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_rli(self, bits: core::ffi::c_ulong) -> Self { + transmute($intr(transmute(self), bits)) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorRli for t_u!($ty) { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_rli(self, bits: core::ffi::c_ulong) -> Self { + $intr(self, bits) + } + } + )* + } + } + + impl_rot_imm! { + vector_signed_char, verllvb_imm, + vector_signed_short, verllvh_imm, + vector_signed_int, verllvf_imm, + vector_signed_long_long, verllvg_imm + } } /// Vector element-wise addition. @@ -1339,6 +1396,18 @@ where a.vec_sral(b) } +/// Rotates each element of a vector left by a given number of bits. Each element of the result is obtained by rotating the corresponding element +/// of a left by the number of bits specified by b, modulo the number of bits in the element. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_rli(a: T, bits: core::ffi::c_ulong) -> T +where + T: sealed::VectorRli, +{ + a.vec_rli(bits) +} + #[cfg(test)] mod tests { use super::*; From 98e2e1e50230eb599d2203880894f4ba6cbc8ea7 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 19 Feb 2025 16:35:33 +0100 Subject: [PATCH 06/22] add `vec_rl_mask` --- crates/core_arch/src/s390x/macros.rs | 36 ++++++++++++++++++++ crates/core_arch/src/s390x/vector.rs | 49 ++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/crates/core_arch/src/s390x/macros.rs b/crates/core_arch/src/s390x/macros.rs index 3b59f9b258..10aa43ad6e 100644 --- a/crates/core_arch/src/s390x/macros.rs +++ b/crates/core_arch/src/s390x/macros.rs @@ -213,6 +213,41 @@ macro_rules! s_t_l { }; } +macro_rules! l_t_t { + (vector_signed_long_long) => { + i64 + }; + (vector_signed_int) => { + i32 + }; + (vector_signed_short) => { + i16 + }; + (vector_signed_char) => { + i8 + }; + + (vector_unsigned_long_long ) => { + u64 + }; + (vector_unsigned_int ) => { + u32 + }; + (vector_unsigned_short ) => { + u16 + }; + (vector_unsigned_char ) => { + u8 + }; + + (vector_float) => { + f32 + }; + (vector_double) => { + f64 + }; +} + macro_rules! t_t_l { (i64) => { vector_signed_long_long @@ -401,6 +436,7 @@ macro_rules! impl_neg { pub(crate) use impl_from; pub(crate) use impl_neg; pub(crate) use impl_vec_trait; +pub(crate) use l_t_t; pub(crate) use s_t_l; pub(crate) use t_b; pub(crate) use t_t_l; diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 2f6577d209..41fa16cc20 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -95,6 +95,11 @@ unsafe extern "unadjusted" { #[link_name = "llvm.fshl.v8i16"] fn fshlh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short; #[link_name = "llvm.fshl.v4i32"] fn fshlf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int; #[link_name = "llvm.fshl.v2i64"] fn fshlg(a: vector_unsigned_long_long, b: vector_unsigned_long_long, c: vector_unsigned_long_long) -> vector_unsigned_long_long; + + #[link_name = "llvm.s390.verimb"] fn verimb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char, d: i32) -> vector_signed_char; + #[link_name = "llvm.s390.verimh"] fn verimh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short, d: i32) -> vector_signed_short; + #[link_name = "llvm.s390.verimf"] fn verimf(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int, d: i32) -> vector_signed_int; + #[link_name = "llvm.s390.verimg"] fn verimg(a: vector_signed_long_long, b: vector_signed_long_long, c: vector_signed_long_long, d: i32) -> vector_signed_long_long; } impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } @@ -948,6 +953,50 @@ mod sealed { vector_signed_int, verllvf_imm, vector_signed_long_long, verllvg_imm } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorRlMask { + unsafe fn vec_rl_mask(self, other: Other) -> Self; + } + + macro_rules! impl_rl_mask { + ($($ty:ident, $intr:ident, $fun:ident),*) => { + $( + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr($intr, IMM8 = 6))] + unsafe fn $fun(a: $ty, b: t_u!($ty)) -> $ty { + // mod by the number of bits in a's element type to prevent UB + $intr(a, a, transmute(b), const { (IMM8 % ::BITS as u8) as i32 }) + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorRlMask for $ty { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_rl_mask(self, other: t_u!($ty)) -> Self { + $fun::(self, other) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorRlMask for t_u!($ty) { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_rl_mask(self, other: t_u!($ty)) -> Self { + transmute($fun::(transmute(self), transmute(other))) + } + } + )* + } + } + + impl_rl_mask! { + vector_signed_char, verimb, test_verimb, + vector_signed_short, verimh, test_verimh, + vector_signed_int, verimf, test_verimf, + vector_signed_long_long, verimg, test_verimg + } } /// Vector element-wise addition. From b30cd911de4ae880305dfabebcb114b197a89293 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 19 Feb 2025 23:16:37 +0100 Subject: [PATCH 07/22] add `vec_reve` --- crates/core_arch/src/s390x/vector.rs | 102 +++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 41fa16cc20..1f57841ae8 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -997,6 +997,92 @@ mod sealed { vector_signed_int, verimf, test_verimf, vector_signed_long_long, verimg, test_verimg } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorReve { + unsafe fn vec_reve(self) -> Self; + } + + #[repr(simd)] + struct ReverseMask([u32; N]); + + impl ReverseMask { + const fn new() -> Self { + let mut index = [0; N]; + let mut i = 0; + while i < N { + index[i] = (N - i - 1) as u32; + i += 1; + } + ReverseMask(index) + } + } + + macro_rules! impl_reve { + ($($ty:ident, $fun:ident, $instr:ident),*) => { + $( + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr($instr))] + unsafe fn $fun(a: $ty) -> $ty { + const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::(); + simd_shuffle(a, a, const { ReverseMask::::new() }) + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorReve for $ty { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_reve(self) -> Self { + $fun(self) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorReve for t_u!($ty) { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_reve(self) -> Self { + transmute($fun(transmute(self))) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorReve for t_b!($ty) { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_reve(self) -> Self { + transmute($fun(transmute(self))) + } + } + )* + } + } + + impl_reve! { + vector_signed_char, reveb, vperm, + vector_signed_short, reveh, vperm, + vector_signed_int, revef, vperm, + vector_signed_long_long, reveg, vpdi + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorReve for vector_float { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_reve(self) -> Self { + transmute(transmute::<_, vector_signed_int>(self).vec_reve()) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorReve for vector_double { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_reve(self) -> Self { + transmute(transmute::<_, vector_signed_long_long>(self).vec_reve()) + } + } } /// Vector element-wise addition. @@ -1457,6 +1543,17 @@ where a.vec_rli(bits) } +/// Returns a vector with the elements of the input vector in reversed order. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_reve(a: T) -> T +where + T: sealed::VectorReve, +{ + a.vec_reve() +} + #[cfg(test)] mod tests { use super::*; @@ -1812,4 +1909,9 @@ mod tests { [0x12345678, 0x9ABCDEF0, 0x0F0F0F0F, 0x12345678], [4, 8, 12, 68], [0x23456781, 0xBCDEF09A, 0xF0F0F0F0, 0x23456781] } + + test_vec_1! { test_vec_reve_f32, vec_reve, f32x4, + [0.1, 0.5, 0.6, 0.9], + [0.9, 0.6, 0.5, 0.1] + } } From 2ac112a56f83532d5ff2ee9c03ebaada393f9c24 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 19 Feb 2025 23:38:19 +0100 Subject: [PATCH 08/22] add `vec_revb` --- crates/core_arch/src/s390x/macros.rs | 10 ++++++ crates/core_arch/src/s390x/vector.rs | 53 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/crates/core_arch/src/s390x/macros.rs b/crates/core_arch/src/s390x/macros.rs index 10aa43ad6e..565465c348 100644 --- a/crates/core_arch/src/s390x/macros.rs +++ b/crates/core_arch/src/s390x/macros.rs @@ -55,6 +55,16 @@ macro_rules! impl_vec_trait { } } }; + ([$Trait:ident $m:ident]+ $fun:ident ($a:ty)) => { + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl $Trait for $a { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn $m(self) -> Self { + transmute($fun(transmute(self))) + } + } + }; ([$Trait:ident $m:ident] $fun:ident ($a:ty) -> $r:ty) => { #[unstable(feature = "stdarch_s390x", issue = "135681")] impl $Trait for $a { diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 1f57841ae8..f788fca9a9 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -1083,6 +1083,43 @@ mod sealed { transmute(transmute::<_, vector_signed_long_long>(self).vec_reve()) } } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorRevb { + unsafe fn vec_revb(self) -> Self; + } + + test_impl! { bswapb (a: vector_signed_char) -> vector_signed_char [simd_bswap, _] } + test_impl! { bswaph (a: vector_signed_short) -> vector_signed_short [simd_bswap, vperm] } + test_impl! { bswapf (a: vector_signed_int) -> vector_signed_int [simd_bswap, vperm] } + test_impl! { bswapg (a: vector_signed_long_long) -> vector_signed_long_long [simd_bswap, vperm] } + + impl_vec_trait! { [VectorRevb vec_revb]+ bswapb (vector_unsigned_char) } + impl_vec_trait! { [VectorRevb vec_revb]+ bswapb (vector_signed_char) } + impl_vec_trait! { [VectorRevb vec_revb]+ bswaph (vector_unsigned_short) } + impl_vec_trait! { [VectorRevb vec_revb]+ bswaph (vector_signed_short) } + impl_vec_trait! { [VectorRevb vec_revb]+ bswapf (vector_unsigned_int) } + impl_vec_trait! { [VectorRevb vec_revb]+ bswapf (vector_signed_int) } + impl_vec_trait! { [VectorRevb vec_revb]+ bswapg (vector_unsigned_long_long) } + impl_vec_trait! { [VectorRevb vec_revb]+ bswapg (vector_signed_long_long) } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorRevb for vector_float { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_revb(self) -> Self { + transmute(transmute::<_, vector_signed_int>(self).vec_revb()) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorRevb for vector_double { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_revb(self) -> Self { + transmute(transmute::<_, vector_signed_long_long>(self).vec_revb()) + } + } } /// Vector element-wise addition. @@ -1554,6 +1591,17 @@ where a.vec_reve() } +/// Returns a vector where each vector element contains the corresponding byte-reversed vector element of the input vector. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_revb(a: T) -> T +where + T: sealed::VectorRevb, +{ + a.vec_revb() +} + #[cfg(test)] mod tests { use super::*; @@ -1914,4 +1962,9 @@ mod tests { [0.1, 0.5, 0.6, 0.9], [0.9, 0.6, 0.5, 0.1] } + + test_vec_1! { test_vec_revb_u32, vec_revb, u32x4, + [0xAABBCCDD, 0xEEFF0011, 0x22334455, 0x66778899], + [0xDDCCBBAA, 0x1100FFEE, 0x55443322, 0x99887766] + } } From f2ac01db461413e19a2d95a63a9f77f22d6f164f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 20 Feb 2025 00:19:22 +0100 Subject: [PATCH 09/22] add `vec_mergel` and `vec_mergeh` --- crates/core_arch/src/s390x/vector.rs | 142 +++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index f788fca9a9..5838e59693 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -1120,6 +1120,114 @@ mod sealed { transmute(transmute::<_, vector_signed_long_long>(self).vec_revb()) } } + + #[repr(simd)] + struct MergeMask([u32; N]); + + impl MergeMask { + const fn merge_low() -> Self { + let mut mask = [0; N]; + let mut i = N / 2; + let mut index = 0; + while index < N { + mask[index] = i as u32; + mask[index + 1] = (i + N) as u32; + + i += 1; + index += 2; + } + MergeMask(mask) + } + + const fn merge_high() -> Self { + let mut mask = [0; N]; + let mut i = 0; + let mut index = 0; + while index < N { + mask[index] = i as u32; + mask[index + 1] = (i + N) as u32; + + i += 1; + index += 2; + } + MergeMask(mask) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorMergel { + unsafe fn vec_mergel(self, other: Self) -> Self; + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorMergeh { + unsafe fn vec_mergeh(self, other: Self) -> Self; + } + + macro_rules! impl_merge { + ($($ty:ident, $mergel:ident, $mergeh:ident),*) => { + $( + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr($mergel))] + unsafe fn $mergel(a: $ty, b: $ty) -> $ty { + const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::(); + simd_shuffle(a, b, const { MergeMask::::merge_low() }) + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorMergel for $ty { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_mergel(self, other: Self) -> Self { + $mergel(self, other) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorMergel for t_u!($ty) { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_mergel(self, other: Self) -> Self { + transmute($mergel(transmute(self), transmute(other))) + } + } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr($mergeh))] + unsafe fn $mergeh(a: $ty, b: $ty) -> $ty { + const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::(); + simd_shuffle(a, b, const { MergeMask::::merge_high() }) + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorMergeh for $ty { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_mergeh(self, other: Self) -> Self { + $mergeh(self, other) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorMergeh for t_u!($ty) { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_mergeh(self, other: Self) -> Self { + transmute($mergeh(transmute(self), transmute(other))) + } + } + )* + } + } + + impl_merge! { + vector_signed_char, vmrlb, vmrhb, + vector_signed_short, vmrlh, vmrhh, + vector_signed_int, vmrlf, vmrhf, + vector_signed_long_long, vmrlg, vmrhg + } } /// Vector element-wise addition. @@ -1602,6 +1710,28 @@ where a.vec_revb() } +/// Merges the most significant ("high") halves of two vectors. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_mergeh(a: T, b: T) -> T +where + T: sealed::VectorMergeh, +{ + a.vec_mergeh(b) +} + +/// Merges the least significant ("low") halves of two vectors. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_mergel(a: T, b: T) -> T +where + T: sealed::VectorMergel, +{ + a.vec_mergel(b) +} + #[cfg(test)] mod tests { use super::*; @@ -1967,4 +2097,16 @@ mod tests { [0xAABBCCDD, 0xEEFF0011, 0x22334455, 0x66778899], [0xDDCCBBAA, 0x1100FFEE, 0x55443322, 0x99887766] } + + test_vec_2! { test_vec_mergeh_u32, vec_mergeh, u32x4, + [0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD], + [0x00000000, 0x11111111, 0x22222222, 0x33333333], + [0xAAAAAAAA, 0x00000000, 0xBBBBBBBB, 0x11111111] + } + + test_vec_2! { test_vec_mergel_u32, vec_mergel, u32x4, + [0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC, 0xDDDDDDDD], + [0x00000000, 0x11111111, 0x22222222, 0x33333333], + [0xCCCCCCCC, 0x22222222, 0xDDDDDDDD, 0x33333333] + } } From 1fb0cae3e8b9e58cbb6453b87d6757c95368a791 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 20 Feb 2025 10:42:25 +0100 Subject: [PATCH 10/22] pull out `ShuffleMask` --- crates/core_arch/src/s390x/vector.rs | 112 +++++++++++++++------------ 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 5838e59693..7acdffb0d0 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -111,6 +111,49 @@ impl_neg! { i64x2 : 0 } impl_neg! { f32x4 : 0f32 } impl_neg! { f64x2 : 0f64 } +#[repr(simd)] +struct ShuffleMask([u32; N]); + +impl ShuffleMask { + const fn reverse() -> Self { + let mut index = [0; N]; + let mut i = 0; + while i < N { + index[i] = (N - i - 1) as u32; + i += 1; + } + ShuffleMask(index) + } + + const fn merge_low() -> Self { + let mut mask = [0; N]; + let mut i = N / 2; + let mut index = 0; + while index < N { + mask[index] = i as u32; + mask[index + 1] = (i + N) as u32; + + i += 1; + index += 2; + } + ShuffleMask(mask) + } + + const fn merge_high() -> Self { + let mut mask = [0; N]; + let mut i = 0; + let mut index = 0; + while index < N { + mask[index] = i as u32; + mask[index + 1] = (i + N) as u32; + + i += 1; + index += 2; + } + ShuffleMask(mask) + } +} + #[macro_use] mod sealed { use super::*; @@ -1003,21 +1046,6 @@ mod sealed { unsafe fn vec_reve(self) -> Self; } - #[repr(simd)] - struct ReverseMask([u32; N]); - - impl ReverseMask { - const fn new() -> Self { - let mut index = [0; N]; - let mut i = 0; - while i < N { - index[i] = (N - i - 1) as u32; - i += 1; - } - ReverseMask(index) - } - } - macro_rules! impl_reve { ($($ty:ident, $fun:ident, $instr:ident),*) => { $( @@ -1026,7 +1054,7 @@ mod sealed { #[cfg_attr(test, assert_instr($instr))] unsafe fn $fun(a: $ty) -> $ty { const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::(); - simd_shuffle(a, a, const { ReverseMask::::new() }) + simd_shuffle(a, a, const { ShuffleMask::::reverse() }) } #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1121,39 +1149,6 @@ mod sealed { } } - #[repr(simd)] - struct MergeMask([u32; N]); - - impl MergeMask { - const fn merge_low() -> Self { - let mut mask = [0; N]; - let mut i = N / 2; - let mut index = 0; - while index < N { - mask[index] = i as u32; - mask[index + 1] = (i + N) as u32; - - i += 1; - index += 2; - } - MergeMask(mask) - } - - const fn merge_high() -> Self { - let mut mask = [0; N]; - let mut i = 0; - let mut index = 0; - while index < N { - mask[index] = i as u32; - mask[index + 1] = (i + N) as u32; - - i += 1; - index += 2; - } - MergeMask(mask) - } - } - #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorMergel { unsafe fn vec_mergel(self, other: Self) -> Self; @@ -1172,7 +1167,7 @@ mod sealed { #[cfg_attr(test, assert_instr($mergel))] unsafe fn $mergel(a: $ty, b: $ty) -> $ty { const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::(); - simd_shuffle(a, b, const { MergeMask::::merge_low() }) + simd_shuffle(a, b, const { ShuffleMask::::merge_low() }) } #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1198,7 +1193,7 @@ mod sealed { #[cfg_attr(test, assert_instr($mergeh))] unsafe fn $mergeh(a: $ty, b: $ty) -> $ty { const N: usize = core::mem::size_of::<$ty>() / core::mem::size_of::(); - simd_shuffle(a, b, const { MergeMask::::merge_high() }) + simd_shuffle(a, b, const { ShuffleMask::::merge_high() }) } #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1741,6 +1736,21 @@ mod tests { use crate::core_arch::simd::*; use stdarch_test::simd_test; + #[test] + fn reverse_mask() { + assert_eq!(ShuffleMask::<4>::reverse().0, [3, 2, 1, 0]); + } + + #[test] + fn mergel_mask() { + assert_eq!(ShuffleMask::<4>::merge_low().0, [2, 6, 3, 7]); + } + + #[test] + fn mergeh_mask() { + assert_eq!(ShuffleMask::<4>::merge_high().0, [0, 4, 1, 5]); + } + macro_rules! test_vec_1 { { $name: ident, $fn:ident, f32x4, [$($a:expr),+], ~[$($d:expr),+] } => { #[simd_test(enable = "vector")] From 041580ef56022adaf0b55ea5eeab23116994ec81 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 20 Feb 2025 23:30:45 +0100 Subject: [PATCH 11/22] add `vec_genmask` and `vec_genmasks` --- crates/core_arch/src/s390x/vector.rs | 109 +++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 7acdffb0d0..4b0e6a594a 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -154,6 +154,39 @@ impl ShuffleMask { } } +const fn genmask() -> [u8; 16] { + let mut bits = MASK; + let mut elements = [0u8; 16]; + + let mut i = 0; + while i < 16 { + elements[i] = match bits & (1u16 << 15) { + 0 => 0, + _ => 0xFF, + }; + + bits <<= 1; + i += 1; + } + + elements +} + +const fn genmasks(bit_width: u32, a: u8, b: u8) -> u64 { + let bit_width = bit_width as u8; + let a = a % bit_width; + let mut b = b % bit_width; + if a > b { + b = bit_width - 1; + } + + // of course these indices start from the left + let a = (bit_width - 1) - a; + let b = (bit_width - 1) - b; + + ((1u64.wrapping_shl(a as u32 + 1)) - 1) & !((1u64.wrapping_shl(b as u32)) - 1) +} + #[macro_use] mod sealed { use super::*; @@ -1727,6 +1760,52 @@ where a.vec_mergel(b) } +/// Generates byte masks for elements in the return vector. For each bit in a, if the bit is one, all bit positions +/// in the corresponding byte element of d are set to ones. Otherwise, if the bit is zero, the corresponding byte element is set to zero. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vgbm, MASK = 0x00FF))] +pub unsafe fn vec_genmask() -> vector_unsigned_char { + vector_unsigned_char(const { genmask::() }) +} + +/// Vector Generate Mask (Byte) +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepib, L = 3, H = 5))] +pub unsafe fn vec_genmasks_8() -> vector_unsigned_char { + vector_unsigned_char(const { [genmasks(u8::BITS, L, H) as u8; 16] }) +} + +/// Vector Generate Mask (Halfword) +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepih, L = 3, H = 5))] +pub unsafe fn vec_genmasks_16() -> vector_unsigned_short { + vector_unsigned_short(const { [genmasks(u16::BITS, L, H) as u16; 8] }) +} + +/// Vector Generate Mask (Word) +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vgmf, L = 3, H = 5))] +pub unsafe fn vec_genmasks_32() -> vector_unsigned_int { + vector_unsigned_int(const { [genmasks(u32::BITS, L, H) as u32; 4] }) +} + +/// Vector Generate Mask (Doubleword) +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vgmg, L = 3, H = 5))] +pub unsafe fn vec_genmasks_64() -> vector_unsigned_long_long { + vector_unsigned_long_long(const { [genmasks(u64::BITS, L, H); 2] }) +} + #[cfg(test)] mod tests { use super::*; @@ -1751,6 +1830,36 @@ mod tests { assert_eq!(ShuffleMask::<4>::merge_high().0, [0, 4, 1, 5]); } + #[test] + fn test_vec_mask() { + assert_eq!( + genmask::<0x00FF>(), + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + ] + ); + } + + #[test] + fn test_genmasks() { + assert_eq!(genmasks(u8::BITS, 3, 5), 28); + assert_eq!(genmasks(u8::BITS, 3, 7), 31); + + // If a or b is greater than 8, the operation is performed as if the value gets modulo by 8. + assert_eq!(genmasks(u8::BITS, 3 + 8, 7 + 8), 31); + // If a is greater than b, the operation is perform as if b equals 7. + assert_eq!(genmasks(u8::BITS, 5, 4), genmasks(u8::BITS, 5, 7)); + + assert_eq!( + genmasks(u16::BITS, 4, 12) as u16, + u16::from_be_bytes([15, -8i8 as u8]) + ); + assert_eq!( + genmasks(u32::BITS, 4, 29) as u32, + u32::from_be_bytes([15, 0xFF, 0xFF, -4i8 as u8]) + ); + } + macro_rules! test_vec_1 { { $name: ident, $fn:ident, f32x4, [$($a:expr),+], ~[$($d:expr),+] } => { #[simd_test(enable = "vector")] From f691f4f4721f2be291a9d44cb189a37682b1f9a1 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 21 Feb 2025 17:43:41 +0100 Subject: [PATCH 12/22] add `vec_perm` --- crates/core_arch/src/s390x/vector.rs | 139 +++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 4b0e6a594a..e5d12b4c5d 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -100,6 +100,8 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.verimh"] fn verimh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short, d: i32) -> vector_signed_short; #[link_name = "llvm.s390.verimf"] fn verimf(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int, d: i32) -> vector_signed_int; #[link_name = "llvm.s390.verimg"] fn verimg(a: vector_signed_long_long, b: vector_signed_long_long, c: vector_signed_long_long, d: i32) -> vector_signed_long_long; + + #[link_name = "llvm.s390.vperm"] fn vperm(a: vector_signed_char, b: vector_signed_char, c: vector_unsigned_char) -> vector_signed_char; } impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } @@ -1256,6 +1258,43 @@ mod sealed { vector_signed_int, vmrlf, vmrhf, vector_signed_long_long, vmrlg, vmrhg } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorPerm { + unsafe fn vec_perm(self, other: Self, c: vector_unsigned_char) -> Self; + } + + macro_rules! impl_merge { + ($($ty:ident),*) => { + $( + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorPerm for $ty { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_perm(self, other: Self, c: vector_unsigned_char) -> Self { + transmute(vperm(transmute(self), transmute(other), c)) + } + } + )* + } + } + + impl_merge! { + vector_signed_char, + vector_signed_short, + vector_signed_int, + vector_signed_long_long, + vector_unsigned_char, + vector_unsigned_short, + vector_unsigned_int, + vector_unsigned_long_long, + vector_bool_char, + vector_bool_short, + vector_bool_int, + vector_bool_long_long, + vector_float, + vector_double + } } /// Vector element-wise addition. @@ -1806,6 +1845,16 @@ pub unsafe fn vec_genmasks_64() -> vector_unsigned_lon vector_unsigned_long_long(const { [genmasks(u64::BITS, L, H); 2] }) } +/// Returns a vector that contains some elements of two vectors, in the order specified by a third vector. +/// Each byte of the result is selected by using the least significant 5 bits of the corresponding byte of c as an index into the concatenated bytes of a and b. +/// Note: The vector generate mask built-in function [`vec_genmask`] could help generate the mask c. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_perm(a: T, b: T, c: vector_unsigned_char) -> T { + a.vec_perm(b, c) +} + #[cfg(test)] mod tests { use super::*; @@ -2228,4 +2277,94 @@ mod tests { [0x00000000, 0x11111111, 0x22222222, 0x33333333], [0xCCCCCCCC, 0x22222222, 0xDDDDDDDD, 0x33333333] } + + macro_rules! test_vec_perm { + {$name:ident, + $shorttype:ident, $longtype:ident, + [$($a:expr),+], [$($b:expr),+], [$($c:expr),+], [$($d:expr),+]} => { + #[simd_test(enable = "vector")] + unsafe fn $name() { + let a: $longtype = transmute($shorttype::new($($a),+)); + let b: $longtype = transmute($shorttype::new($($b),+)); + let c: vector_unsigned_char = transmute(u8x16::new($($c),+)); + let d = $shorttype::new($($d),+); + + let r: $shorttype = transmute(vec_perm(a, b, c)); + assert_eq!(d, r); + } + } + } + + test_vec_perm! {test_vec_perm_u8x16, + u8x16, vector_unsigned_char, + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115], + [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, + 0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17], + [0, 1, 100, 101, 2, 3, 102, 103, 4, 5, 104, 105, 6, 7, 106, 107]} + test_vec_perm! {test_vec_perm_i8x16, + i8x16, vector_signed_char, + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115], + [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, + 0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17], + [0, 1, 100, 101, 2, 3, 102, 103, 4, 5, 104, 105, 6, 7, 106, 107]} + + test_vec_perm! {test_vec_perm_m8x16, + m8x16, vector_bool_char, + [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false], + [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true], + [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, + 0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17], + [false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true]} + test_vec_perm! {test_vec_perm_u16x8, + u16x8, vector_unsigned_short, + [0, 1, 2, 3, 4, 5, 6, 7], + [10, 11, 12, 13, 14, 15, 16, 17], + [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, + 0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17], + [0, 10, 1, 11, 2, 12, 3, 13]} + test_vec_perm! {test_vec_perm_i16x8, + i16x8, vector_signed_short, + [0, 1, 2, 3, 4, 5, 6, 7], + [10, 11, 12, 13, 14, 15, 16, 17], + [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, + 0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17], + [0, 10, 1, 11, 2, 12, 3, 13]} + test_vec_perm! {test_vec_perm_m16x8, + m16x8, vector_bool_short, + [false, false, false, false, false, false, false, false], + [true, true, true, true, true, true, true, true], + [0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, + 0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17], + [false, true, false, true, false, true, false, true]} + + test_vec_perm! {test_vec_perm_u32x4, + u32x4, vector_unsigned_int, + [0, 1, 2, 3], + [10, 11, 12, 13], + [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, + 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17], + [0, 10, 1, 11]} + test_vec_perm! {test_vec_perm_i32x4, + i32x4, vector_signed_int, + [0, 1, 2, 3], + [10, 11, 12, 13], + [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, + 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17], + [0, 10, 1, 11]} + test_vec_perm! {test_vec_perm_m32x4, + m32x4, vector_bool_int, + [false, false, false, false], + [true, true, true, true], + [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, + 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17], + [false, true, false, true]} + test_vec_perm! {test_vec_perm_f32x4, + f32x4, vector_float, + [0.0, 1.0, 2.0, 3.0], + [1.0, 1.1, 1.2, 1.3], + [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, + 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17], + [0.0, 1.0, 1.0, 1.1]} } From acbffdddeac32ec785f9a0a8b12c7ccc0915904c Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 21 Feb 2025 19:53:11 +0100 Subject: [PATCH 13/22] add `vec_sum2`, `vec_sum4` and `vec_sum_u128` --- crates/core_arch/src/s390x/vector.rs | 132 +++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index e5d12b4c5d..bbf842c161 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -102,6 +102,16 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.verimg"] fn verimg(a: vector_signed_long_long, b: vector_signed_long_long, c: vector_signed_long_long, d: i32) -> vector_signed_long_long; #[link_name = "llvm.s390.vperm"] fn vperm(a: vector_signed_char, b: vector_signed_char, c: vector_unsigned_char) -> vector_signed_char; + + #[link_name = "llvm.s390.vsumb"] fn vsumb(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_int; + #[link_name = "llvm.s390.vsumh"] fn vsumh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int; + + #[link_name = "llvm.s390.vsumgh"] fn vsumgh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_long_long; + #[link_name = "llvm.s390.vsumgf"] fn vsumgf(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long; + + #[link_name = "llvm.s390.vsumqf"] fn vsumqf(a: vector_unsigned_int, b: vector_unsigned_int) -> u128; + #[link_name = "llvm.s390.vsumqg"] fn vsumqg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> u128; + } impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } @@ -1295,6 +1305,95 @@ mod sealed { vector_float, vector_double } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSumU128 { + unsafe fn vec_sum_u128(self, other: Self) -> vector_unsigned_char; + } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vsumqf))] + pub unsafe fn vec_vsumqf(a: vector_unsigned_int, b: vector_unsigned_int) -> u128 { + transmute(vsumqf(a, b)) + } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vsumqg))] + pub unsafe fn vec_vsumqg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> u128 { + transmute(vsumqg(a, b)) + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorSumU128 for vector_unsigned_int { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_sum_u128(self, other: Self) -> vector_unsigned_char { + transmute(vec_vsumqf(self, other)) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorSumU128 for vector_unsigned_long_long { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_sum_u128(self, other: Self) -> vector_unsigned_char { + transmute(vec_vsumqg(self, other)) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSum2 { + unsafe fn vec_sum2(self, other: Self) -> vector_unsigned_long_long; + } + + test_impl! { vec_vsumgh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_long_long [vsumgh, vsumgh] } + test_impl! { vec_vsumgf (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long [vsumgf, vsumgf] } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorSum2 for vector_unsigned_short { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_sum2(self, other: Self) -> vector_unsigned_long_long { + vec_vsumgh(self, other) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorSum2 for vector_unsigned_int { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_sum2(self, other: Self) -> vector_unsigned_long_long { + vec_vsumgf(self, other) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSum4 { + unsafe fn vec_sum4(self, other: Self) -> vector_unsigned_int; + } + + test_impl! { vec_vsumb (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_int [vsumb, vsumb] } + test_impl! { vec_vsumh (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int [vsumh, vsumh] } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorSum4 for vector_unsigned_char { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_sum4(self, other: Self) -> vector_unsigned_int { + vec_vsumb(self, other) + } + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorSum4 for vector_unsigned_short { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_sum4(self, other: Self) -> vector_unsigned_int { + vec_vsumh(self, other) + } + } } /// Vector element-wise addition. @@ -1855,6 +1954,39 @@ pub unsafe fn vec_perm(a: T, b: T, c: vector_unsigned_cha a.vec_perm(b, c) } +/// Vector Sum Across Quadword +/// +/// Returns a vector containing the results of performing a sum across all the elements in each of the quadword of vector a, +/// and the rightmost word or doubleword element of the b. The result is an unsigned 128-bit integer. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_sum_u128(a: T, b: T) -> vector_unsigned_char { + a.vec_sum_u128(b) +} + +/// Vector Sum Across Doubleword +/// +/// Returns a vector containing the results of performing a sum across all the elements in each of the doubleword of vector a, +/// and the rightmost sub-element of the corresponding doubleword of b. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_sum2(a: T, b: T) -> vector_unsigned_long_long { + a.vec_sum2(b) +} + +/// Vector Sum Across Word +/// +/// Returns a vector containing the results of performing a sum across all the elements in each of the word of vector a, +/// and the rightmost sub-element of the corresponding word of b. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_sum4(a: T, b: T) -> vector_unsigned_int { + a.vec_sum4(b) +} + #[cfg(test)] mod tests { use super::*; From 4118015e402ddb82c5b89c5b16369f30a3c3c942 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 21 Feb 2025 20:39:29 +0100 Subject: [PATCH 14/22] add `vec_subc_u128`, `vec_sube_u128`, `vec_subec_u128`, `vec_sub_u128` and `vec_subc` --- crates/core_arch/src/s390x/vector.rs | 112 +++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index bbf842c161..27153ae9ae 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -112,6 +112,15 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vsumqf"] fn vsumqf(a: vector_unsigned_int, b: vector_unsigned_int) -> u128; #[link_name = "llvm.s390.vsumqg"] fn vsumqg(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> u128; + #[link_name = "llvm.s390.vscbiq"] fn vscbiq(a: u128, b: u128) -> u128; + #[link_name = "llvm.s390.vsbiq"] fn vsbiq(a: u128, b: u128, c: u128) -> u128; + #[link_name = "llvm.s390.vsbcbiq"] fn vsbcbiq(a: u128, b: u128, c: u128) -> u128; + + #[link_name = "llvm.s390.vscbib"] fn vscbib(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char; + #[link_name = "llvm.s390.vscbih"] fn vscbih(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short; + #[link_name = "llvm.s390.vscbif"] fn vscbif(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int; + #[link_name = "llvm.s390.vscbig"] fn vscbig(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long; + } impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } @@ -1394,6 +1403,22 @@ mod sealed { vec_vsumh(self, other) } } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSubc { + type Result; + unsafe fn vec_subc(self, b: Other) -> Self::Result; + } + + test_impl! { vec_vscbib (a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char [vscbib, vscbib] } + test_impl! { vec_vscbih (a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_short [vscbih, vscbih] } + test_impl! { vec_vscbif (a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int [vscbif, vscbif] } + test_impl! { vec_vscbig (a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long [vscbig, vscbig] } + + impl_vec_trait! {[VectorSubc vec_subc] vec_vscbib (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char } + impl_vec_trait! {[VectorSubc vec_subc] vec_vscbih (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short } + impl_vec_trait! {[VectorSubc vec_subc] vec_vscbif (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int } + impl_vec_trait! {[VectorSubc vec_subc] vec_vscbig (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long } } /// Vector element-wise addition. @@ -1987,6 +2012,93 @@ pub unsafe fn vec_sum4(a: T, b: T) -> vector_unsigned_int a.vec_sum4(b) } +/// Vector Subtract unsigned 128-bits +/// +/// Subtracts unsigned quadword values. +/// +/// This function operates on the vectors as 128-bit unsigned integers. It returns low 128 bits of a - b. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vsq))] +pub unsafe fn vec_sub_u128( + a: vector_unsigned_char, + b: vector_unsigned_char, +) -> vector_unsigned_char { + let a: u128 = transmute(a); + let b: u128 = transmute(b); + + transmute(a.wrapping_sub(b)) +} + +/// Vector Subtract Carryout +/// +/// Returns a vector containing the borrow produced by subtracting each of corresponding elements of b from a. +/// +/// On each resulting element, the value is 0 if a borrow occurred, or 1 if no borrow occurred. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_subc(a: T, b: U) -> >::Result +where + T: sealed::VectorSubc, +{ + a.vec_subc(b) +} + +/// Gets the carry bit of the 128-bit subtraction of two quadword values. +/// This function operates on the vectors as 128-bit unsigned integers. It returns a vector containing the borrow produced by subtracting b from a, as unsigned 128-bits integers. +/// If no borrow occurred, the bit 127 of d is 1; otherwise it is set to 0. All other bits of d are 0. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vscbiq))] +pub unsafe fn vec_subc_u128( + a: vector_unsigned_char, + b: vector_unsigned_char, +) -> vector_unsigned_char { + transmute(vscbiq(transmute(a), transmute(b))) +} + +/// Subtracts unsigned quadword values with carry bit from a previous operation. +/// +/// This function operates on the vectors as 128-bit unsigned integers. It returns a vector containing the result of subtracting of b from a, +/// and the carryout bit from a previous operation. +/// +/// Note: Only the borrow indication bit (127-bit) of c is used, and the other bits are ignored. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vsbiq))] +pub unsafe fn vec_sube_u128( + a: vector_unsigned_char, + b: vector_unsigned_char, + c: vector_unsigned_char, +) -> vector_unsigned_char { + transmute(vsbiq(transmute(a), transmute(b), transmute(c))) +} + +/// Vector Subtract with Carryout, Carryout +/// +/// Gets the carry bit of the 128-bit subtraction of two quadword values with carry bit from the previous operation. +/// +/// It returns a vector containing the carryout produced from the result of subtracting of b from a, +/// and the carryout bit from a previous operation. If no borrow occurred, the 127-bit of d is 1, otherwise 0. +/// All other bits of d are 0. +/// +/// Note: Only the borrow indication bit (127-bit) of c is used, and the other bits are ignored. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vsbcbiq))] +pub unsafe fn vec_subec_u128( + a: vector_unsigned_char, + b: vector_unsigned_char, + c: vector_unsigned_char, +) -> vector_unsigned_char { + transmute(vsbcbiq(transmute(a), transmute(b), transmute(c))) +} + #[cfg(test)] mod tests { use super::*; From 23a874199c2464cff31e58131cb51a636667ba95 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 22 Feb 2025 19:40:02 +0100 Subject: [PATCH 15/22] add `vec_nabs` --- crates/core_arch/src/s390x/macros.rs | 3 +-- crates/core_arch/src/s390x/vector.rs | 40 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/crates/core_arch/src/s390x/macros.rs b/crates/core_arch/src/s390x/macros.rs index 565465c348..2c40fedae2 100644 --- a/crates/core_arch/src/s390x/macros.rs +++ b/crates/core_arch/src/s390x/macros.rs @@ -436,8 +436,7 @@ macro_rules! impl_neg { 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))) } + unsafe { simd_neg(self) } } } }; diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 27153ae9ae..22e0eb5ec9 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -506,6 +506,31 @@ mod sealed { impl_vec_trait! { [VectorAbs vec_abs] vec_abs_f32 (vector_float) } impl_vec_trait! { [VectorAbs vec_abs] vec_abs_f64 (vector_double) } + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorNabs { + unsafe fn vec_nabs(self) -> Self; + } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr( + all(test, target_feature = "vector-enhancements-1"), + assert_instr(vflnsb) + )] + unsafe fn vec_nabs_f32(a: vector_float) -> vector_float { + simd_neg(simd_fabs(a)) + } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vflndb))] + unsafe fn vec_nabs_f64(a: vector_double) -> vector_double { + simd_neg(simd_fabs(a)) + } + + impl_vec_trait! { [VectorNabs vec_nabs] vec_nabs_f32 (vector_float) } + impl_vec_trait! { [VectorNabs vec_nabs] vec_nabs_f64 (vector_double) } + #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorSplats { unsafe fn vec_splats(self) -> Output; @@ -1528,6 +1553,17 @@ where a.vec_abs() } +/// Vector negative abs. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_nabs(a: T) -> T +where + T: sealed::VectorNabs, +{ + a.vec_nabs() +} + /// Vector splats. #[inline] #[target_feature(enable = "vector")] @@ -2351,6 +2387,10 @@ mod tests { test_vec_abs! { test_vec_abs_f32, f32x4, -42f32, 42f32 } test_vec_abs! { test_vec_abs_f64, f64x2, -42f64, 42f64 } + test_vec_1! { test_vec_nabs, vec_nabs, f32x4, + [core::f32::consts::PI, 1.0, 0.0, -1.0], + [-core::f32::consts::PI, -1.0, 0.0, -1.0] } + test_vec_2! { test_vec_andc, vec_andc, i32x4, [0b11001100, 0b11001100, 0b11001100, 0b11001100], [0b00110011, 0b11110011, 0b00001100, 0b10000000], From 05f9e8f662a5dec34a3d417a36433c7aab30d550 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 22 Feb 2025 19:54:50 +0100 Subject: [PATCH 16/22] add `vec_sqrt` --- crates/core_arch/src/s390x/vector.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 22e0eb5ec9..c3030c45a5 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -1444,6 +1444,17 @@ mod sealed { impl_vec_trait! {[VectorSubc vec_subc] vec_vscbih (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short } impl_vec_trait! {[VectorSubc vec_subc] vec_vscbif (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int } impl_vec_trait! {[VectorSubc vec_subc] vec_vscbig (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSqrt { + unsafe fn vec_sqrt(self) -> Self; + } + + test_impl! { vec_sqrt_f32 (v: vector_float) -> vector_float [ simd_fsqrt, "vector-enhancements-1" vfsqsb ] } + test_impl! { vec_sqrt_f64 (v: vector_double) -> vector_double [ simd_fsqrt, vfsqdb ] } + + impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f32 (vector_float) } + impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f64 (vector_double) } } /// Vector element-wise addition. @@ -1564,6 +1575,17 @@ where a.vec_nabs() } +/// Vector square root. +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_sqrt(a: T) -> T +where + T: sealed::VectorSqrt, +{ + a.vec_sqrt() +} + /// Vector splats. #[inline] #[target_feature(enable = "vector")] @@ -2651,4 +2673,8 @@ mod tests { [0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17], [0.0, 1.0, 1.0, 1.1]} + + test_vec_1! { test_vec_sqrt, vec_sqrt, f32x4, + [core::f32::consts::PI, 1.0, 25.0, 2.0], + [core::f32::consts::PI.sqrt(), 1.0, 5.0, core::f32::consts::SQRT_2] } } From 8b9e5028f38b49c22b7dea585cdc89d070283228 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 22 Feb 2025 20:51:41 +0100 Subject: [PATCH 17/22] add `vec_splat` and friends --- crates/core_arch/src/s390x/vector.rs | 149 +++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index c3030c45a5..81a64b18bd 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -531,6 +531,72 @@ mod sealed { impl_vec_trait! { [VectorNabs vec_nabs] vec_nabs_f32 (vector_float) } impl_vec_trait! { [VectorNabs vec_nabs] vec_nabs_f64 (vector_double) } + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorSplat { + unsafe fn vec_splat(self) -> Self; + } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vrepb, IMM2 = 1))] + unsafe fn vrepb(a: vector_signed_char) -> vector_signed_char { + static_assert_uimm_bits!(IMM2, 4); + simd_shuffle(a, a, const { u32x16::from_array([IMM2; 16]) }) + } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vreph, IMM2 = 1))] + unsafe fn vreph(a: vector_signed_short) -> vector_signed_short { + static_assert_uimm_bits!(IMM2, 3); + simd_shuffle(a, a, const { u32x8::from_array([IMM2; 8]) }) + } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vrepf, IMM2 = 1))] + unsafe fn vrepf(a: vector_signed_int) -> vector_signed_int { + static_assert_uimm_bits!(IMM2, 2); + simd_shuffle(a, a, const { u32x4::from_array([IMM2; 4]) }) + } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vrepg, IMM2 = 1))] + unsafe fn vrepg(a: vector_signed_long_long) -> vector_signed_long_long { + static_assert_uimm_bits!(IMM2, 1); + simd_shuffle(a, a, const { u32x2::from_array([IMM2; 2]) }) + } + + macro_rules! impl_vec_splat { + ($ty:ty, $fun:ident) => { + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl VectorSplat for $ty { + #[inline] + #[target_feature(enable = "vector")] + unsafe fn vec_splat(self) -> Self { + transmute($fun::(transmute(self))) + } + } + }; + } + + impl_vec_splat! { vector_signed_char, vrepb } + impl_vec_splat! { vector_unsigned_char, vrepb } + impl_vec_splat! { vector_bool_char, vrepb } + impl_vec_splat! { vector_signed_short, vreph } + impl_vec_splat! { vector_unsigned_short, vreph } + impl_vec_splat! { vector_bool_short, vreph } + impl_vec_splat! { vector_signed_int, vrepf } + impl_vec_splat! { vector_unsigned_int, vrepf } + impl_vec_splat! { vector_bool_int, vrepf } + impl_vec_splat! { vector_signed_long_long, vrepg } + impl_vec_splat! { vector_unsigned_long_long, vrepg } + impl_vec_splat! { vector_bool_long_long, vrepg } + + impl_vec_splat! { vector_float, vrepf } + impl_vec_splat! { vector_double, vrepg } + #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorSplats { unsafe fn vec_splats(self) -> Output; @@ -1586,6 +1652,17 @@ where a.vec_sqrt() } +/// Vector Splat +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_splat(a: T) -> T +where + T: sealed::VectorSplat, +{ + a.vec_splat::() +} + /// Vector splats. #[inline] #[target_feature(enable = "vector")] @@ -2157,6 +2234,78 @@ pub unsafe fn vec_subec_u128( transmute(vsbcbiq(transmute(a), transmute(b), transmute(c))) } +/// Vector Splat Signed Byte +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepib, IMM = 42))] +pub unsafe fn vec_splat_i8() -> vector_signed_char { + vector_signed_char([IMM; 16]) +} + +/// Vector Splat Signed Halfword +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepih, IMM = 42))] +pub unsafe fn vec_splat_i16() -> vector_signed_short { + vector_signed_short([IMM as i16; 8]) +} + +/// Vector Splat Signed Word +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepif, IMM = 42))] +pub unsafe fn vec_splat_i32() -> vector_signed_int { + vector_signed_int([IMM as i32; 4]) +} + +/// Vector Splat Signed Doubleword +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepig, IMM = 42))] +pub unsafe fn vec_splat_i64() -> vector_signed_long_long { + vector_signed_long_long([IMM as i64; 2]) +} + +/// Vector Splat Unsigned Byte +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepib, IMM = 42))] +pub unsafe fn vec_splat_u8() -> vector_unsigned_char { + vector_unsigned_char([IMM; 16]) +} + +/// Vector Splat Unsigned Halfword +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepih, IMM = 42))] +pub unsafe fn vec_splat_u16() -> vector_unsigned_short { + vector_unsigned_short([IMM as u16; 8]) +} + +/// Vector Splat Unsigned Word +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepif, IMM = 42))] +pub unsafe fn vec_splat_u32() -> vector_unsigned_int { + vector_unsigned_int([IMM as u32; 4]) +} + +/// Vector Splat Unsigned Doubleword +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +#[cfg_attr(test, assert_instr(vrepig, IMM = 42))] +pub unsafe fn vec_splat_u64() -> vector_unsigned_long_long { + vector_unsigned_long_long([IMM as u64; 2]) +} + #[cfg(test)] mod tests { use super::*; From 4ac66862951f818965d4a3fcd19a5038842586f1 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 23 Feb 2025 16:36:15 +0100 Subject: [PATCH 18/22] add `vec_find_any_eq` and `vec_find_any_ne` --- crates/core_arch/src/s390x/vector.rs | 119 +++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 81a64b18bd..c4fb07967f 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -121,6 +121,9 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vscbif"] fn vscbif(a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_int; #[link_name = "llvm.s390.vscbig"] fn vscbig(a: vector_unsigned_long_long, b: vector_unsigned_long_long) -> vector_unsigned_long_long; + #[link_name = "llvm.s390.vfaeb"] fn vfaeb(a: vector_signed_char, b: vector_signed_char, c: i32) -> vector_signed_char; + #[link_name = "llvm.s390.vfaeh"] fn vfaeh(a: vector_signed_short, b: vector_signed_short, c: i32) -> vector_signed_short; + #[link_name = "llvm.s390.vfaef"] fn vfaef(a: vector_signed_int, b: vector_signed_int, c: i32) -> vector_signed_int; } impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } @@ -1521,6 +1524,90 @@ mod sealed { impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f32 (vector_float) } impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f64 (vector_double) } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vfaeb, IMM = 0))] + unsafe fn vfaeb( + a: vector_signed_char, + b: vector_signed_char, + ) -> vector_signed_char { + super::vfaeb(a, b, IMM) + } + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vfaeh, IMM = 0))] + unsafe fn vfaeh( + a: vector_signed_short, + b: vector_signed_short, + ) -> vector_signed_short { + super::vfaeh(a, b, IMM) + } + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vfaef, IMM = 0))] + unsafe fn vfaef( + a: vector_signed_int, + b: vector_signed_int, + ) -> vector_signed_int { + super::vfaef(a, b, IMM) + } + + macro_rules! impl_vfae { + ([$Trait:ident $m:ident] $imm:literal $($fun:ident $ty:ident)*) => { + $( + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl $Trait for $ty { + type Result = t_b!($ty); + #[inline] + #[target_feature(enable = "vector")] + unsafe fn $m(self, b: Self) -> Self::Result { + transmute($fun::<$imm>(transmute(self), transmute(b))) + } + } + )* + }; + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyEq { + type Result; + unsafe fn vec_find_any_eq(self, other: Other) -> Self::Result; + } + + impl_vfae! { [VectorFindAnyEq vec_find_any_eq] 4 + vfaeb vector_signed_char + vfaeb vector_unsigned_char + vfaeb vector_bool_char + + vfaeh vector_signed_short + vfaeh vector_unsigned_short + vfaeh vector_bool_short + + vfaef vector_signed_int + vfaef vector_unsigned_int + vfaef vector_bool_int + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyNe { + type Result; + unsafe fn vec_find_any_ne(self, other: Other) -> Self::Result; + } + + impl_vfae! { [VectorFindAnyNe vec_find_any_ne] 12 + vfaeb vector_signed_char + vfaeb vector_unsigned_char + vfaeb vector_bool_char + + vfaeh vector_signed_short + vfaeh vector_unsigned_short + vfaeh vector_bool_short + + vfaef vector_signed_int + vfaef vector_unsigned_int + vfaef vector_bool_int + } } /// Vector element-wise addition. @@ -2306,6 +2393,26 @@ pub unsafe fn vec_splat_u64() -> vector_unsigned_long_long { vector_unsigned_long_long([IMM as u64; 2]) } +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_find_any_eq(a: T, b: U) -> >::Result +where + T: sealed::VectorFindAnyEq, +{ + a.vec_find_any_eq(b) +} + +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_find_any_ne(a: T, b: U) -> >::Result +where + T: sealed::VectorFindAnyNe, +{ + a.vec_find_any_ne(b) +} + #[cfg(test)] mod tests { use super::*; @@ -2826,4 +2933,16 @@ mod tests { test_vec_1! { test_vec_sqrt, vec_sqrt, f32x4, [core::f32::consts::PI, 1.0, 25.0, 2.0], [core::f32::consts::PI.sqrt(), 1.0, 5.0, core::f32::consts::SQRT_2] } + + test_vec_2! { test_vec_find_any_eq, vec_find_any_eq, i32x4, i32x4 -> u32x4, + [1, -2, 3, -4], + [-5, 3, -7, 8], + [0, 0, 0xFFFFFFFF, 0] + } + + test_vec_2! { test_vec_find_any_ne, vec_find_any_ne, i32x4, i32x4 -> u32x4, + [1, -2, 3, -4], + [-5, 3, -7, 8], + [0xFFFFFFFF, 0xFFFFFFFF, 0, 0xFFFFFFFF] + } } From 2053bdea6a295f18843ebd54b5f3a5871ce52471 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 23 Feb 2025 16:59:41 +0100 Subject: [PATCH 19/22] add `vec_find_any_eq_idx` and `vec_find_any_ne_idx` --- crates/core_arch/src/s390x/vector.rs | 95 ++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index c4fb07967f..e65c8508ed 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -1554,6 +1554,19 @@ mod sealed { } macro_rules! impl_vfae { + ([idx $Trait:ident $m:ident] $imm:literal $($fun:ident $ty:ident $r:ident)*) => { + $( + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl $Trait for $ty { + type Result = $r; + #[inline] + #[target_feature(enable = "vector")] + unsafe fn $m(self, b: Self) -> Self::Result { + transmute($fun::<$imm>(transmute(self), transmute(b))) + } + } + )* + }; ([$Trait:ident $m:ident] $imm:literal $($fun:ident $ty:ident)*) => { $( #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1608,6 +1621,46 @@ mod sealed { vfaef vector_unsigned_int vfaef vector_bool_int } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyEqIdx { + type Result; + unsafe fn vec_find_any_eq_idx(self, other: Other) -> Self::Result; + } + + impl_vfae! { [idx VectorFindAnyEqIdx vec_find_any_eq_idx] 0 + vfaeb vector_signed_char vector_signed_char + vfaeb vector_unsigned_char vector_unsigned_char + vfaeb vector_bool_char vector_unsigned_char + + vfaeh vector_signed_short vector_signed_short + vfaeh vector_unsigned_short vector_unsigned_short + vfaeh vector_bool_short vector_unsigned_short + + vfaef vector_signed_int vector_signed_int + vfaef vector_unsigned_int vector_unsigned_int + vfaef vector_bool_int vector_unsigned_int + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyNeIdx { + type Result; + unsafe fn vec_find_any_ne_idx(self, other: Other) -> Self::Result; + } + + impl_vfae! { [idx VectorFindAnyNeIdx vec_find_any_ne_idx] 8 + vfaeb vector_signed_char vector_signed_char + vfaeb vector_unsigned_char vector_unsigned_char + vfaeb vector_bool_char vector_unsigned_char + + vfaeh vector_signed_short vector_signed_short + vfaeh vector_unsigned_short vector_unsigned_short + vfaeh vector_bool_short vector_unsigned_short + + vfaef vector_signed_int vector_signed_int + vfaef vector_unsigned_int vector_unsigned_int + vfaef vector_bool_int vector_unsigned_int + } } /// Vector element-wise addition. @@ -2413,6 +2466,26 @@ where a.vec_find_any_ne(b) } +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_find_any_eq_idx(a: T, b: U) -> >::Result +where + T: sealed::VectorFindAnyEqIdx, +{ + a.vec_find_any_eq_idx(b) +} + +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_find_any_ne_idx(a: T, b: U) -> >::Result +where + T: sealed::VectorFindAnyNeIdx, +{ + a.vec_find_any_ne_idx(b) +} + #[cfg(test)] mod tests { use super::*; @@ -2945,4 +3018,26 @@ mod tests { [-5, 3, -7, 8], [0xFFFFFFFF, 0xFFFFFFFF, 0, 0xFFFFFFFF] } + + test_vec_2! { test_vec_find_any_eq_idx_1, vec_find_any_eq_idx, i32x4, i32x4 -> u32x4, + [1, 2, 3, 4], + [5, 3, 7, 8], + [0, 8, 0, 0] + } + test_vec_2! { test_vec_find_any_eq_idx_2, vec_find_any_eq_idx, i32x4, i32x4 -> u32x4, + [1, 2, 3, 4], + [5, 6, 7, 8], + [0, 16, 0, 0] + } + + test_vec_2! { test_vec_find_any_ne_idx_1, vec_find_any_ne_idx, i32x4, i32x4 -> u32x4, + [1, 2, 3, 4], + [1, 5, 3, 4], + [0, 4, 0, 0] + } + test_vec_2! { test_vec_find_any_ne_idx_2, vec_find_any_ne_idx, i32x4, i32x4 -> u32x4, + [1, 2, 3, 4], + [1, 2, 3, 4], + [0, 16, 0, 0] + } } From 5c304ec4b9c0913d8d1247196f09567ca673a5aa Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 23 Feb 2025 18:24:51 +0100 Subject: [PATCH 20/22] add `vec_find_any_eq_cc` and `vec_find_any_ne_cc` --- crates/core_arch/src/macros.rs | 24 ++++ crates/core_arch/src/s390x/vector.rs | 157 +++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) diff --git a/crates/core_arch/src/macros.rs b/crates/core_arch/src/macros.rs index f9c650b2ca..f59e278bb7 100644 --- a/crates/core_arch/src/macros.rs +++ b/crates/core_arch/src/macros.rs @@ -102,6 +102,30 @@ macro_rules! types { // a simd type with exactly one element. unsafe { simd_shuffle!(one, one, [0; $len]) } } + + /// Returns an array reference containing the entire SIMD vector. + $v const fn as_array(&self) -> &[$elem_type; $len] { + // SAFETY: this type is just an overaligned `[T; N]` with + // potential padding at the end, so pointer casting to a + // `&[T; N]` is safe. + // + // NOTE: This deliberately doesn't just use `&self.0` because it may soon be banned + // see https://github.com/rust-lang/compiler-team/issues/838 + unsafe { &*(self as *const Self as *const [$elem_type; $len]) } + + } + + /// Returns a mutable array reference containing the entire SIMD vector. + #[inline] + $v fn as_mut_array(&mut self) -> &mut [$elem_type; $len] { + // SAFETY: this type is just an overaligned `[T; N]` with + // potential padding at the end, so pointer casting to a + // `&mut [T; N]` is safe. + // + // NOTE: This deliberately doesn't just use `&mut self.0` because it may soon be banned + // see https://github.com/rust-lang/compiler-team/issues/838 + unsafe { &mut *(self as *mut Self as *mut [$elem_type; $len]) } + } } $(#[$stability])+ diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index e65c8508ed..7499dfad06 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -51,6 +51,12 @@ types! { pub struct vector_double(2 x f64); } +#[repr(packed)] +struct PackedTuple { + x: T, + y: U, +} + #[allow(improper_ctypes)] #[rustfmt::skip] unsafe extern "unadjusted" { @@ -124,6 +130,10 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vfaeb"] fn vfaeb(a: vector_signed_char, b: vector_signed_char, c: i32) -> vector_signed_char; #[link_name = "llvm.s390.vfaeh"] fn vfaeh(a: vector_signed_short, b: vector_signed_short, c: i32) -> vector_signed_short; #[link_name = "llvm.s390.vfaef"] fn vfaef(a: vector_signed_int, b: vector_signed_int, c: i32) -> vector_signed_int; + + #[link_name = "llvm.s390.vfaebs"] fn vfaebs(a: vector_signed_char, b: vector_signed_char, c: i32) -> PackedTuple; + #[link_name = "llvm.s390.vfaehs"] fn vfaehs(a: vector_signed_short, b: vector_signed_short, c: i32) -> PackedTuple; + #[link_name = "llvm.s390.vfaefs"] fn vfaefs(a: vector_signed_int, b: vector_signed_int, c: i32) -> PackedTuple; } impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } @@ -1554,6 +1564,21 @@ mod sealed { } macro_rules! impl_vfae { + ([cc $Trait:ident $m:ident] $imm:literal $($fun:ident $ty:ident)*) => { + $( + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl $Trait for $ty { + type Result = t_b!($ty); + #[inline] + #[target_feature(enable = "vector")] + unsafe fn $m(self, b: Self, c: *mut i32) -> Self::Result { + let PackedTuple { x, y } = $fun::<$imm>(transmute(self), transmute(b)); + c.write(y); + transmute(x) + } + } + )* + }; ([idx $Trait:ident $m:ident] $imm:literal $($fun:ident $ty:ident $r:ident)*) => { $( #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1661,6 +1686,74 @@ mod sealed { vfaef vector_unsigned_int vector_unsigned_int vfaef vector_bool_int vector_unsigned_int } + + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vfaebs, IMM = 0))] + unsafe fn vfaebs( + a: vector_signed_char, + b: vector_signed_char, + ) -> PackedTuple { + super::vfaebs(a, b, IMM) + } + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vfaehs, IMM = 0))] + unsafe fn vfaehs( + a: vector_signed_short, + b: vector_signed_short, + ) -> PackedTuple { + super::vfaehs(a, b, IMM) + } + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr(vfaefs, IMM = 0))] + unsafe fn vfaefs( + a: vector_signed_int, + b: vector_signed_int, + ) -> PackedTuple { + super::vfaefs(a, b, IMM) + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyEqCC { + type Result; + unsafe fn vec_find_any_eq_cc(self, other: Other, c: *mut i32) -> Self::Result; + } + + impl_vfae! { [cc VectorFindAnyEqCC vec_find_any_eq_cc] 4 + vfaebs vector_signed_char + vfaebs vector_unsigned_char + vfaebs vector_bool_char + + vfaehs vector_signed_short + vfaehs vector_unsigned_short + vfaehs vector_bool_short + + vfaefs vector_signed_int + vfaefs vector_unsigned_int + vfaefs vector_bool_int + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyNeCC { + type Result; + unsafe fn vec_find_any_ne_cc(self, other: Other, c: *mut i32) -> Self::Result; + } + + impl_vfae! { [cc VectorFindAnyNeCC vec_find_any_ne_cc] 12 + vfaebs vector_signed_char + vfaebs vector_unsigned_char + vfaebs vector_bool_char + + vfaehs vector_signed_short + vfaehs vector_unsigned_short + vfaehs vector_bool_short + + vfaefs vector_signed_int + vfaefs vector_unsigned_int + vfaefs vector_bool_int + } } /// Vector element-wise addition. @@ -2486,6 +2579,34 @@ where a.vec_find_any_ne_idx(b) } +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_find_any_eq_cc( + a: T, + b: U, + c: *mut i32, +) -> >::Result +where + T: sealed::VectorFindAnyEqCC, +{ + a.vec_find_any_eq_cc(b, c) +} + +#[inline] +#[target_feature(enable = "vector")] +#[unstable(feature = "stdarch_s390x", issue = "135681")] +pub unsafe fn vec_find_any_ne_cc( + a: T, + b: U, + c: *mut i32, +) -> >::Result +where + T: sealed::VectorFindAnyNeCC, +{ + a.vec_find_any_ne_cc(b, c) +} + #[cfg(test)] mod tests { use super::*; @@ -3040,4 +3161,40 @@ mod tests { [1, 2, 3, 4], [0, 16, 0, 0] } + + #[simd_test(enable = "vector")] + fn test_vec_find_any_eq_cc() { + let mut c = 0i32; + + let a = vector_unsigned_int([1, 2, 3, 4]); + let b = vector_unsigned_int([5, 3, 7, 8]); + + let d = unsafe { vec_find_any_eq_cc(a, b, &mut c) }; + assert_eq!(c, 1); + assert_eq!(d.as_array(), &[0, 0, -1, 0]); + + let a = vector_unsigned_int([1, 2, 3, 4]); + let b = vector_unsigned_int([5, 6, 7, 8]); + let d = unsafe { vec_find_any_eq_cc(a, b, &mut c) }; + assert_eq!(c, 3); + assert_eq!(d.as_array(), &[0, 0, 0, 0]); + } + + #[simd_test(enable = "vector")] + fn test_vec_find_any_ne_cc() { + let mut c = 0i32; + + let a = vector_unsigned_int([1, 2, 3, 4]); + let b = vector_unsigned_int([5, 3, 7, 8]); + + let d = unsafe { vec_find_any_ne_cc(a, b, &mut c) }; + assert_eq!(c, 1); + assert_eq!(d.as_array(), &[-1, -1, 0, -1]); + + let a = vector_unsigned_int([1, 2, 3, 4]); + let b = vector_unsigned_int([1, 2, 3, 4]); + let d = unsafe { vec_find_any_ne_cc(a, b, &mut c) }; + assert_eq!(c, 3); + assert_eq!(d.as_array(), &[0, 0, 0, 0]); + } } From 4ef31f0683b98289d6f0f928f0128133ce139a50 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 23 Feb 2025 19:04:14 +0100 Subject: [PATCH 21/22] add `vec_find_any_eq_or_0_idx` and `vec_find_any_ne_or_0_idx` --- crates/core_arch/src/s390x/vector.rs | 184 +++++++++++++++++++++------ 1 file changed, 146 insertions(+), 38 deletions(-) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index 7499dfad06..a48b7e3dbc 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -131,9 +131,17 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vfaeh"] fn vfaeh(a: vector_signed_short, b: vector_signed_short, c: i32) -> vector_signed_short; #[link_name = "llvm.s390.vfaef"] fn vfaef(a: vector_signed_int, b: vector_signed_int, c: i32) -> vector_signed_int; + #[link_name = "llvm.s390.vfaezb"] fn vfaezb(a: vector_signed_char, b: vector_signed_char, c: i32) -> vector_signed_char; + #[link_name = "llvm.s390.vfaezh"] fn vfaezh(a: vector_signed_short, b: vector_signed_short, c: i32) -> vector_signed_short; + #[link_name = "llvm.s390.vfaezf"] fn vfaezf(a: vector_signed_int, b: vector_signed_int, c: i32) -> vector_signed_int; + #[link_name = "llvm.s390.vfaebs"] fn vfaebs(a: vector_signed_char, b: vector_signed_char, c: i32) -> PackedTuple; #[link_name = "llvm.s390.vfaehs"] fn vfaehs(a: vector_signed_short, b: vector_signed_short, c: i32) -> PackedTuple; #[link_name = "llvm.s390.vfaefs"] fn vfaefs(a: vector_signed_int, b: vector_signed_int, c: i32) -> PackedTuple; + + #[link_name = "llvm.s390.vfaezbs"] fn vfaezbs(a: vector_signed_char, b: vector_signed_char, c: i32) -> PackedTuple; + #[link_name = "llvm.s390.vfaezhs"] fn vfaezhs(a: vector_signed_short, b: vector_signed_short, c: i32) -> PackedTuple; + #[link_name = "llvm.s390.vfaezfs"] fn vfaezfs(a: vector_signed_int, b: vector_signed_int, c: i32) -> PackedTuple; } impl_from! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 } @@ -1535,36 +1543,49 @@ mod sealed { impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f32 (vector_float) } impl_vec_trait! { [VectorSqrt vec_sqrt] vec_sqrt_f64 (vector_double) } - #[inline] - #[target_feature(enable = "vector")] - #[cfg_attr(test, assert_instr(vfaeb, IMM = 0))] - unsafe fn vfaeb( - a: vector_signed_char, - b: vector_signed_char, - ) -> vector_signed_char { - super::vfaeb(a, b, IMM) - } - #[inline] - #[target_feature(enable = "vector")] - #[cfg_attr(test, assert_instr(vfaeh, IMM = 0))] - unsafe fn vfaeh( - a: vector_signed_short, - b: vector_signed_short, - ) -> vector_signed_short { - super::vfaeh(a, b, IMM) - } - #[inline] - #[target_feature(enable = "vector")] - #[cfg_attr(test, assert_instr(vfaef, IMM = 0))] - unsafe fn vfaef( - a: vector_signed_int, - b: vector_signed_int, - ) -> vector_signed_int { - super::vfaef(a, b, IMM) + macro_rules! vfae_wrapper { + ($($name:ident $ty:ident)*) => { + $( + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr($name, IMM = 0))] + unsafe fn $name( + a: $ty, + b: $ty, + ) -> $ty { + super::$name(a, b, IMM) + } + )* + } + } + + vfae_wrapper! { + vfaeb vector_signed_char + vfaeh vector_signed_short + vfaef vector_signed_int + + vfaezb vector_signed_char + vfaezh vector_signed_short + vfaezf vector_signed_int } macro_rules! impl_vfae { - ([cc $Trait:ident $m:ident] $imm:literal $($fun:ident $ty:ident)*) => { + ([idx_cc $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident $r:ident)*) => { + $( + #[unstable(feature = "stdarch_s390x", issue = "135681")] + impl $Trait for $ty { + type Result = $r; + #[inline] + #[target_feature(enable = "vector")] + unsafe fn $m(self, b: Self, c: *mut i32) -> Self::Result { + let PackedTuple { x, y } = $fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b)); + c.write(y); + transmute(x) + } + } + )* + }; + ([cc $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident)*) => { $( #[unstable(feature = "stdarch_s390x", issue = "135681")] impl $Trait for $ty { @@ -1572,14 +1593,14 @@ mod sealed { #[inline] #[target_feature(enable = "vector")] unsafe fn $m(self, b: Self, c: *mut i32) -> Self::Result { - let PackedTuple { x, y } = $fun::<$imm>(transmute(self), transmute(b)); + let PackedTuple { x, y } = $fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b)); c.write(y); transmute(x) } } )* }; - ([idx $Trait:ident $m:ident] $imm:literal $($fun:ident $ty:ident $r:ident)*) => { + ([idx $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident $r:ident)*) => { $( #[unstable(feature = "stdarch_s390x", issue = "135681")] impl $Trait for $ty { @@ -1587,12 +1608,12 @@ mod sealed { #[inline] #[target_feature(enable = "vector")] unsafe fn $m(self, b: Self) -> Self::Result { - transmute($fun::<$imm>(transmute(self), transmute(b))) + transmute($fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b))) } } )* }; - ([$Trait:ident $m:ident] $imm:literal $($fun:ident $ty:ident)*) => { + ([$Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident)*) => { $( #[unstable(feature = "stdarch_s390x", issue = "135681")] impl $Trait for $ty { @@ -1600,20 +1621,27 @@ mod sealed { #[inline] #[target_feature(enable = "vector")] unsafe fn $m(self, b: Self) -> Self::Result { - transmute($fun::<$imm>(transmute(self), transmute(b))) + transmute($fun::<{ FindImm::$imm as i32 }>(transmute(self), transmute(b))) } } )* }; } + enum FindImm { + Eq = 4, + Ne = 12, + EqIdx = 0, + NeIdx = 8, + } + #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorFindAnyEq { type Result; unsafe fn vec_find_any_eq(self, other: Other) -> Self::Result; } - impl_vfae! { [VectorFindAnyEq vec_find_any_eq] 4 + impl_vfae! { [VectorFindAnyEq vec_find_any_eq] Eq vfaeb vector_signed_char vfaeb vector_unsigned_char vfaeb vector_bool_char @@ -1633,7 +1661,7 @@ mod sealed { unsafe fn vec_find_any_ne(self, other: Other) -> Self::Result; } - impl_vfae! { [VectorFindAnyNe vec_find_any_ne] 12 + impl_vfae! { [VectorFindAnyNe vec_find_any_ne] Ne vfaeb vector_signed_char vfaeb vector_unsigned_char vfaeb vector_bool_char @@ -1647,13 +1675,53 @@ mod sealed { vfaef vector_bool_int } + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyEqOrZeroIdx { + type Result; + unsafe fn vec_find_any_eq_or_0_idx(self, other: Other) -> Self::Result; + } + + impl_vfae! { [idx VectorFindAnyEqOrZeroIdx vec_find_any_eq_or_0_idx] Eq + vfaezb vector_signed_char vector_signed_char + vfaezb vector_unsigned_char vector_unsigned_char + vfaezb vector_bool_char vector_unsigned_char + + vfaezh vector_signed_short vector_signed_short + vfaezh vector_unsigned_short vector_unsigned_short + vfaezh vector_bool_short vector_unsigned_short + + vfaezf vector_signed_int vector_signed_int + vfaezf vector_unsigned_int vector_unsigned_int + vfaezf vector_bool_int vector_unsigned_int + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyNeOrZeroIdx { + type Result; + unsafe fn vec_find_any_ne_or_0_idx(self, other: Other) -> Self::Result; + } + + impl_vfae! { [idx VectorFindAnyNeOrZeroIdx vec_find_any_ne_or_0_idx] Ne + vfaezb vector_signed_char vector_signed_char + vfaezb vector_unsigned_char vector_unsigned_char + vfaezb vector_bool_char vector_unsigned_char + + vfaezh vector_signed_short vector_signed_short + vfaezh vector_unsigned_short vector_unsigned_short + vfaezh vector_bool_short vector_unsigned_short + + vfaezf vector_signed_int vector_signed_int + vfaezf vector_unsigned_int vector_unsigned_int + vfaezf vector_bool_int vector_unsigned_int + } + #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorFindAnyEqIdx { type Result; unsafe fn vec_find_any_eq_idx(self, other: Other) -> Self::Result; } - impl_vfae! { [idx VectorFindAnyEqIdx vec_find_any_eq_idx] 0 + impl_vfae! { [idx VectorFindAnyEqIdx vec_find_any_eq_idx] EqIdx vfaeb vector_signed_char vector_signed_char vfaeb vector_unsigned_char vector_unsigned_char vfaeb vector_bool_char vector_unsigned_char @@ -1673,7 +1741,7 @@ mod sealed { unsafe fn vec_find_any_ne_idx(self, other: Other) -> Self::Result; } - impl_vfae! { [idx VectorFindAnyNeIdx vec_find_any_ne_idx] 8 + impl_vfae! { [idx VectorFindAnyNeIdx vec_find_any_ne_idx] NeIdx vfaeb vector_signed_char vector_signed_char vfaeb vector_unsigned_char vector_unsigned_char vfaeb vector_bool_char vector_unsigned_char @@ -1721,7 +1789,7 @@ mod sealed { unsafe fn vec_find_any_eq_cc(self, other: Other, c: *mut i32) -> Self::Result; } - impl_vfae! { [cc VectorFindAnyEqCC vec_find_any_eq_cc] 4 + impl_vfae! { [cc VectorFindAnyEqCC vec_find_any_eq_cc] Eq vfaebs vector_signed_char vfaebs vector_unsigned_char vfaebs vector_bool_char @@ -1741,7 +1809,7 @@ mod sealed { unsafe fn vec_find_any_ne_cc(self, other: Other, c: *mut i32) -> Self::Result; } - impl_vfae! { [cc VectorFindAnyNeCC vec_find_any_ne_cc] 12 + impl_vfae! { [cc VectorFindAnyNeCC vec_find_any_ne_cc] Ne vfaebs vector_signed_char vfaebs vector_unsigned_char vfaebs vector_bool_char @@ -1754,6 +1822,46 @@ mod sealed { vfaefs vector_unsigned_int vfaefs vector_bool_int } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyEqIdxCC { + type Result; + unsafe fn vec_find_any_eq_idx_cc(self, other: Other, c: *mut i32) -> Self::Result; + } + + impl_vfae! { [idx_cc VectorFindAnyEqIdxCC vec_find_any_eq_idx_cc] EqIdx + vfaebs vector_signed_char vector_signed_char + vfaebs vector_unsigned_char vector_unsigned_char + vfaebs vector_bool_char vector_unsigned_char + + vfaehs vector_signed_short vector_signed_short + vfaehs vector_unsigned_short vector_unsigned_short + vfaehs vector_bool_short vector_unsigned_short + + vfaefs vector_signed_int vector_signed_int + vfaefs vector_unsigned_int vector_unsigned_int + vfaefs vector_bool_int vector_unsigned_int + } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyNeIdxCC { + type Result; + unsafe fn vec_find_any_ne_idx_cc(self, other: Other, c: *mut i32) -> Self::Result; + } + + impl_vfae! { [idx_cc VectorFindAnyNeIdxCC vec_find_any_ne_idx_cc] NeIdx + vfaebs vector_signed_char vector_signed_char + vfaebs vector_unsigned_char vector_unsigned_char + vfaebs vector_bool_char vector_unsigned_char + + vfaehs vector_signed_short vector_signed_short + vfaehs vector_unsigned_short vector_unsigned_short + vfaehs vector_bool_short vector_unsigned_short + + vfaefs vector_signed_int vector_signed_int + vfaefs vector_unsigned_int vector_unsigned_int + vfaefs vector_bool_int vector_unsigned_int + } } /// Vector element-wise addition. From 3081f144eeba2ded89f240c0998115d74aff6570 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 23 Feb 2025 21:20:06 +0100 Subject: [PATCH 22/22] add `vec_find_any_eq_or_0_idx_cc` and `vec_find_any_ne_or_0_idx_cc` --- crates/core_arch/src/s390x/vector.rs | 447 ++++++++++++++++----------- 1 file changed, 260 insertions(+), 187 deletions(-) diff --git a/crates/core_arch/src/s390x/vector.rs b/crates/core_arch/src/s390x/vector.rs index a48b7e3dbc..795e426384 100644 --- a/crates/core_arch/src/s390x/vector.rs +++ b/crates/core_arch/src/s390x/vector.rs @@ -1570,6 +1570,21 @@ mod sealed { } macro_rules! impl_vfae { + ([idx_cc $Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => { + impl_vfae! { [idx_cc $Trait $m] $imm + $b vector_signed_char vector_signed_char + $b vector_unsigned_char vector_unsigned_char + $b vector_bool_char vector_unsigned_char + + $h vector_signed_short vector_signed_short + $h vector_unsigned_short vector_unsigned_short + $h vector_bool_short vector_unsigned_short + + $f vector_signed_int vector_signed_int + $f vector_unsigned_int vector_unsigned_int + $f vector_bool_int vector_unsigned_int + } + }; ([idx_cc $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident $r:ident)*) => { $( #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1585,6 +1600,21 @@ mod sealed { } )* }; + ([cc $Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => { + impl_vfae! { [cc $Trait $m] $imm + $b vector_signed_char + $b vector_unsigned_char + $b vector_bool_char + + $h vector_signed_short + $h vector_unsigned_short + $h vector_bool_short + + $f vector_signed_int + $f vector_unsigned_int + $f vector_bool_int + } + }; ([cc $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident)*) => { $( #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1600,6 +1630,21 @@ mod sealed { } )* }; + ([idx $Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => { + impl_vfae! { [idx $Trait $m] $imm + $b vector_signed_char vector_signed_char + $b vector_unsigned_char vector_unsigned_char + $b vector_bool_char vector_unsigned_char + + $h vector_signed_short vector_signed_short + $h vector_unsigned_short vector_unsigned_short + $h vector_bool_short vector_unsigned_short + + $f vector_signed_int vector_signed_int + $f vector_unsigned_int vector_unsigned_int + $f vector_bool_int vector_unsigned_int + } + }; ([idx $Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident $r:ident)*) => { $( #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1613,6 +1658,21 @@ mod sealed { } )* }; + ([$Trait:ident $m:ident] $imm:ident $b:ident $h:ident $f:ident) => { + impl_vfae! { [$Trait $m] $imm + $b vector_signed_char + $b vector_unsigned_char + $b vector_bool_char + + $h vector_signed_short + $h vector_unsigned_short + $h vector_bool_short + + $f vector_signed_int + $f vector_unsigned_int + $f vector_bool_int + } + }; ([$Trait:ident $m:ident] $imm:ident $($fun:ident $ty:ident)*) => { $( #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1641,19 +1701,7 @@ mod sealed { unsafe fn vec_find_any_eq(self, other: Other) -> Self::Result; } - impl_vfae! { [VectorFindAnyEq vec_find_any_eq] Eq - vfaeb vector_signed_char - vfaeb vector_unsigned_char - vfaeb vector_bool_char - - vfaeh vector_signed_short - vfaeh vector_unsigned_short - vfaeh vector_bool_short - - vfaef vector_signed_int - vfaef vector_unsigned_int - vfaef vector_bool_int - } + impl_vfae! { [VectorFindAnyEq vec_find_any_eq] Eq vfaeb vfaeh vfaef } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorFindAnyNe { @@ -1661,19 +1709,7 @@ mod sealed { unsafe fn vec_find_any_ne(self, other: Other) -> Self::Result; } - impl_vfae! { [VectorFindAnyNe vec_find_any_ne] Ne - vfaeb vector_signed_char - vfaeb vector_unsigned_char - vfaeb vector_bool_char - - vfaeh vector_signed_short - vfaeh vector_unsigned_short - vfaeh vector_bool_short - - vfaef vector_signed_int - vfaef vector_unsigned_int - vfaef vector_bool_int - } + impl_vfae! { [VectorFindAnyNe vec_find_any_ne] Ne vfaeb vfaeh vfaef } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorFindAnyEqOrZeroIdx { @@ -1681,7 +1717,7 @@ mod sealed { unsafe fn vec_find_any_eq_or_0_idx(self, other: Other) -> Self::Result; } - impl_vfae! { [idx VectorFindAnyEqOrZeroIdx vec_find_any_eq_or_0_idx] Eq + impl_vfae! { [idx VectorFindAnyEqOrZeroIdx vec_find_any_eq_or_0_idx] EqIdx vfaezb vector_signed_char vector_signed_char vfaezb vector_unsigned_char vector_unsigned_char vfaezb vector_bool_char vector_unsigned_char @@ -1701,7 +1737,7 @@ mod sealed { unsafe fn vec_find_any_ne_or_0_idx(self, other: Other) -> Self::Result; } - impl_vfae! { [idx VectorFindAnyNeOrZeroIdx vec_find_any_ne_or_0_idx] Ne + impl_vfae! { [idx VectorFindAnyNeOrZeroIdx vec_find_any_ne_or_0_idx] NeIdx vfaezb vector_signed_char vector_signed_char vfaezb vector_unsigned_char vector_unsigned_char vfaezb vector_bool_char vector_unsigned_char @@ -1721,19 +1757,7 @@ mod sealed { unsafe fn vec_find_any_eq_idx(self, other: Other) -> Self::Result; } - impl_vfae! { [idx VectorFindAnyEqIdx vec_find_any_eq_idx] EqIdx - vfaeb vector_signed_char vector_signed_char - vfaeb vector_unsigned_char vector_unsigned_char - vfaeb vector_bool_char vector_unsigned_char - - vfaeh vector_signed_short vector_signed_short - vfaeh vector_unsigned_short vector_unsigned_short - vfaeh vector_bool_short vector_unsigned_short - - vfaef vector_signed_int vector_signed_int - vfaef vector_unsigned_int vector_unsigned_int - vfaef vector_bool_int vector_unsigned_int - } + impl_vfae! { [idx VectorFindAnyEqIdx vec_find_any_eq_idx] EqIdx vfaeb vfaeh vfaef } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorFindAnyNeIdx { @@ -1741,46 +1765,32 @@ mod sealed { unsafe fn vec_find_any_ne_idx(self, other: Other) -> Self::Result; } - impl_vfae! { [idx VectorFindAnyNeIdx vec_find_any_ne_idx] NeIdx - vfaeb vector_signed_char vector_signed_char - vfaeb vector_unsigned_char vector_unsigned_char - vfaeb vector_bool_char vector_unsigned_char + impl_vfae! { [idx VectorFindAnyNeIdx vec_find_any_ne_idx] NeIdx vfaeb vfaeh vfaef } - vfaeh vector_signed_short vector_signed_short - vfaeh vector_unsigned_short vector_unsigned_short - vfaeh vector_bool_short vector_unsigned_short + macro_rules! vfaes_wrapper { + ($($name:ident $ty:ident)*) => { + $( + #[inline] + #[target_feature(enable = "vector")] + #[cfg_attr(test, assert_instr($name, IMM = 0))] + unsafe fn $name( + a: $ty, + b: $ty, + ) -> PackedTuple<$ty, i32> { + super::$name(a, b, IMM) + } + )* + } + } - vfaef vector_signed_int vector_signed_int - vfaef vector_unsigned_int vector_unsigned_int - vfaef vector_bool_int vector_unsigned_int - } + vfaes_wrapper! { + vfaebs vector_signed_char + vfaehs vector_signed_short + vfaefs vector_signed_int - #[inline] - #[target_feature(enable = "vector")] - #[cfg_attr(test, assert_instr(vfaebs, IMM = 0))] - unsafe fn vfaebs( - a: vector_signed_char, - b: vector_signed_char, - ) -> PackedTuple { - super::vfaebs(a, b, IMM) - } - #[inline] - #[target_feature(enable = "vector")] - #[cfg_attr(test, assert_instr(vfaehs, IMM = 0))] - unsafe fn vfaehs( - a: vector_signed_short, - b: vector_signed_short, - ) -> PackedTuple { - super::vfaehs(a, b, IMM) - } - #[inline] - #[target_feature(enable = "vector")] - #[cfg_attr(test, assert_instr(vfaefs, IMM = 0))] - unsafe fn vfaefs( - a: vector_signed_int, - b: vector_signed_int, - ) -> PackedTuple { - super::vfaefs(a, b, IMM) + vfaezbs vector_signed_char + vfaezhs vector_signed_short + vfaezfs vector_signed_int } #[unstable(feature = "stdarch_s390x", issue = "135681")] @@ -1789,19 +1799,7 @@ mod sealed { unsafe fn vec_find_any_eq_cc(self, other: Other, c: *mut i32) -> Self::Result; } - impl_vfae! { [cc VectorFindAnyEqCC vec_find_any_eq_cc] Eq - vfaebs vector_signed_char - vfaebs vector_unsigned_char - vfaebs vector_bool_char - - vfaehs vector_signed_short - vfaehs vector_unsigned_short - vfaehs vector_bool_short - - vfaefs vector_signed_int - vfaefs vector_unsigned_int - vfaefs vector_bool_int - } + impl_vfae! { [cc VectorFindAnyEqCC vec_find_any_eq_cc] Eq vfaebs vfaehs vfaefs } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorFindAnyNeCC { @@ -1809,19 +1807,7 @@ mod sealed { unsafe fn vec_find_any_ne_cc(self, other: Other, c: *mut i32) -> Self::Result; } - impl_vfae! { [cc VectorFindAnyNeCC vec_find_any_ne_cc] Ne - vfaebs vector_signed_char - vfaebs vector_unsigned_char - vfaebs vector_bool_char - - vfaehs vector_signed_short - vfaehs vector_unsigned_short - vfaehs vector_bool_short - - vfaefs vector_signed_int - vfaefs vector_unsigned_int - vfaefs vector_bool_int - } + impl_vfae! { [cc VectorFindAnyNeCC vec_find_any_ne_cc] Ne vfaebs vfaehs vfaefs } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorFindAnyEqIdxCC { @@ -1829,19 +1815,7 @@ mod sealed { unsafe fn vec_find_any_eq_idx_cc(self, other: Other, c: *mut i32) -> Self::Result; } - impl_vfae! { [idx_cc VectorFindAnyEqIdxCC vec_find_any_eq_idx_cc] EqIdx - vfaebs vector_signed_char vector_signed_char - vfaebs vector_unsigned_char vector_unsigned_char - vfaebs vector_bool_char vector_unsigned_char - - vfaehs vector_signed_short vector_signed_short - vfaehs vector_unsigned_short vector_unsigned_short - vfaehs vector_bool_short vector_unsigned_short - - vfaefs vector_signed_int vector_signed_int - vfaefs vector_unsigned_int vector_unsigned_int - vfaefs vector_bool_int vector_unsigned_int - } + impl_vfae! { [idx_cc VectorFindAnyEqIdxCC vec_find_any_eq_idx_cc] EqIdx vfaebs vfaehs vfaefs } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorFindAnyNeIdxCC { @@ -1849,19 +1823,23 @@ mod sealed { unsafe fn vec_find_any_ne_idx_cc(self, other: Other, c: *mut i32) -> Self::Result; } - impl_vfae! { [idx_cc VectorFindAnyNeIdxCC vec_find_any_ne_idx_cc] NeIdx - vfaebs vector_signed_char vector_signed_char - vfaebs vector_unsigned_char vector_unsigned_char - vfaebs vector_bool_char vector_unsigned_char + impl_vfae! { [idx_cc VectorFindAnyNeIdxCC vec_find_any_ne_idx_cc] NeIdx vfaebs vfaehs vfaefs } + + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyEqOrZeroIdxCC { + type Result; + unsafe fn vec_find_any_eq_or_0_idx_cc(self, other: Other, c: *mut i32) -> Self::Result; + } - vfaehs vector_signed_short vector_signed_short - vfaehs vector_unsigned_short vector_unsigned_short - vfaehs vector_bool_short vector_unsigned_short + impl_vfae! { [idx_cc VectorFindAnyEqOrZeroIdxCC vec_find_any_eq_or_0_idx_cc] EqIdx vfaezbs vfaezhs vfaezfs } - vfaefs vector_signed_int vector_signed_int - vfaefs vector_unsigned_int vector_unsigned_int - vfaefs vector_bool_int vector_unsigned_int + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub trait VectorFindAnyNeOrZeroIdxCC { + type Result; + unsafe fn vec_find_any_ne_or_0_idx_cc(self, other: Other, c: *mut i32) -> Self::Result; } + + impl_vfae! { [idx_cc VectorFindAnyNeOrZeroIdxCC vec_find_any_ne_or_0_idx_cc] NeIdx vfaezbs vfaezhs vfaezfs } } /// Vector element-wise addition. @@ -2647,72 +2625,54 @@ pub unsafe fn vec_splat_u64() -> vector_unsigned_long_long { vector_unsigned_long_long([IMM as u64; 2]) } -#[inline] -#[target_feature(enable = "vector")] -#[unstable(feature = "stdarch_s390x", issue = "135681")] -pub unsafe fn vec_find_any_eq(a: T, b: U) -> >::Result -where - T: sealed::VectorFindAnyEq, -{ - a.vec_find_any_eq(b) -} - -#[inline] -#[target_feature(enable = "vector")] -#[unstable(feature = "stdarch_s390x", issue = "135681")] -pub unsafe fn vec_find_any_ne(a: T, b: U) -> >::Result -where - T: sealed::VectorFindAnyNe, -{ - a.vec_find_any_ne(b) +macro_rules! vec_find_any { + ($($Trait:ident $fun:ident)*) => { + $( + #[inline] + #[target_feature(enable = "vector")] + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub unsafe fn $fun(a: T, b: U) -> >::Result + where + T: sealed::$Trait, + { + a.$fun(b) + } + )* + } } -#[inline] -#[target_feature(enable = "vector")] -#[unstable(feature = "stdarch_s390x", issue = "135681")] -pub unsafe fn vec_find_any_eq_idx(a: T, b: U) -> >::Result -where - T: sealed::VectorFindAnyEqIdx, -{ - a.vec_find_any_eq_idx(b) +vec_find_any! { + VectorFindAnyEq vec_find_any_eq + VectorFindAnyNe vec_find_any_ne + VectorFindAnyEqIdx vec_find_any_eq_idx + VectorFindAnyNeIdx vec_find_any_ne_idx + VectorFindAnyEqOrZeroIdx vec_find_any_eq_or_0_idx + VectorFindAnyNeOrZeroIdx vec_find_any_ne_or_0_idx } -#[inline] -#[target_feature(enable = "vector")] -#[unstable(feature = "stdarch_s390x", issue = "135681")] -pub unsafe fn vec_find_any_ne_idx(a: T, b: U) -> >::Result -where - T: sealed::VectorFindAnyNeIdx, -{ - a.vec_find_any_ne_idx(b) -} - -#[inline] -#[target_feature(enable = "vector")] -#[unstable(feature = "stdarch_s390x", issue = "135681")] -pub unsafe fn vec_find_any_eq_cc( - a: T, - b: U, - c: *mut i32, -) -> >::Result -where - T: sealed::VectorFindAnyEqCC, -{ - a.vec_find_any_eq_cc(b, c) +macro_rules! vec_find_any_cc { + ($($Trait:ident $fun:ident)*) => { + $( + #[inline] + #[target_feature(enable = "vector")] + #[unstable(feature = "stdarch_s390x", issue = "135681")] + pub unsafe fn $fun(a: T, b: U, c: *mut i32) -> >::Result + where + T: sealed::$Trait, + { + a.$fun(b, c) + } + )* + } } -#[inline] -#[target_feature(enable = "vector")] -#[unstable(feature = "stdarch_s390x", issue = "135681")] -pub unsafe fn vec_find_any_ne_cc( - a: T, - b: U, - c: *mut i32, -) -> >::Result -where - T: sealed::VectorFindAnyNeCC, -{ - a.vec_find_any_ne_cc(b, c) +vec_find_any_cc! { + VectorFindAnyEqCC vec_find_any_eq_cc + VectorFindAnyNeCC vec_find_any_ne_cc + VectorFindAnyEqIdxCC vec_find_any_eq_idx_cc + VectorFindAnyNeIdxCC vec_find_any_ne_idx_cc + VectorFindAnyEqOrZeroIdxCC vec_find_any_eq_or_0_idx_cc + VectorFindAnyNeOrZeroIdxCC vec_find_any_ne_or_0_idx_cc } #[cfg(test)] @@ -3270,6 +3230,17 @@ mod tests { [0, 16, 0, 0] } + test_vec_2! { test_vec_find_any_eq_or_0_idx_1, vec_find_any_eq_or_0_idx, i32x4, i32x4 -> u32x4, + [1, 2, 0, 4], + [5, 6, 7, 8], + [0, 8, 0, 0] + } + test_vec_2! { test_vec_find_any_ne_or_0_idx_1, vec_find_any_ne_or_0_idx, i32x4, i32x4 -> u32x4, + [1, 2, 0, 4], + [1, 2, 3, 4], + [0, 8, 0, 0] + } + #[simd_test(enable = "vector")] fn test_vec_find_any_eq_cc() { let mut c = 0i32; @@ -3305,4 +3276,106 @@ mod tests { assert_eq!(c, 3); assert_eq!(d.as_array(), &[0, 0, 0, 0]); } + + #[simd_test(enable = "vector")] + fn test_vec_find_any_eq_idx_cc() { + let mut c = 0i32; + + let a = vector_unsigned_int([1, 2, 3, 4]); + let b = vector_unsigned_int([5, 3, 7, 8]); + + let d = unsafe { vec_find_any_eq_idx_cc(a, b, &mut c) }; + assert_eq!(c, 1); + assert_eq!(d.as_array(), &[0, 8, 0, 0]); + + let a = vector_unsigned_int([1, 2, 3, 4]); + let b = vector_unsigned_int([5, 6, 7, 8]); + let d = unsafe { vec_find_any_eq_idx_cc(a, b, &mut c) }; + assert_eq!(c, 3); + assert_eq!(d.as_array(), &[0, 16, 0, 0]); + } + + #[simd_test(enable = "vector")] + fn test_vec_find_any_ne_idx_cc() { + let mut c = 0i32; + + let a = vector_unsigned_int([5, 2, 3, 4]); + let b = vector_unsigned_int([5, 3, 7, 8]); + + let d = unsafe { vec_find_any_ne_idx_cc(a, b, &mut c) }; + assert_eq!(c, 1); + assert_eq!(d.as_array(), &[0, 4, 0, 0]); + + let a = vector_unsigned_int([1, 2, 3, 4]); + let b = vector_unsigned_int([1, 2, 3, 4]); + let d = unsafe { vec_find_any_ne_idx_cc(a, b, &mut c) }; + assert_eq!(c, 3); + assert_eq!(d.as_array(), &[0, 16, 0, 0]); + } + + #[simd_test(enable = "vector")] + fn test_vec_find_any_eq_or_0_idx_cc() { + let mut c = 0i32; + + // if no element of a matches any element of b with an equal value, and there is at least one element from a with a value of 0 + let a = vector_unsigned_int([0, 1, 2, 3]); + let b = vector_unsigned_int([4, 5, 6, 7]); + let d = unsafe { vec_find_any_eq_or_0_idx_cc(a, b, &mut c) }; + assert_eq!(c, 0); + assert_eq!(d.as_array(), &[0, 0, 0, 0]); + + // if at least one element of a matches any element of b with an equal value, and no elements of a with a value of 0 + let a = vector_unsigned_int([1, 2, 3, 4]); + let b = vector_unsigned_int([5, 2, 3, 4]); + let d = unsafe { vec_find_any_eq_or_0_idx_cc(a, b, &mut c) }; + assert_eq!(c, 1); + assert_eq!(d.as_array(), &[0, 4, 0, 0]); + + // if at least one element of a matches any element of b with an equal value, and there is at least one element from a has a value of 0 + let a = vector_unsigned_int([1, 2, 3, 0]); + let b = vector_unsigned_int([1, 2, 3, 4]); + let d = unsafe { vec_find_any_eq_or_0_idx_cc(a, b, &mut c) }; + assert_eq!(c, 2); + assert_eq!(d.as_array(), &[0, 0, 0, 0]); + + // if no element of a matches any element of b with an equal value, and there is no element from a with a value of 0. + let a = vector_unsigned_int([1, 2, 3, 4]); + let b = vector_unsigned_int([5, 6, 7, 8]); + let d = unsafe { vec_find_any_eq_or_0_idx_cc(a, b, &mut c) }; + assert_eq!(c, 3); + assert_eq!(d.as_array(), &[0, 16, 0, 0]); + } + + #[simd_test(enable = "vector")] + fn test_vec_find_any_ne_or_0_idx_cc() { + let mut c = 0i32; + + // if no element of a matches any element of b with a not equal value, and there is at least one element from a with a value of 0. + let a = vector_unsigned_int([0, 1, 2, 3]); + let b = vector_unsigned_int([4, 1, 2, 3]); + let d = unsafe { vec_find_any_ne_or_0_idx_cc(a, b, &mut c) }; + assert_eq!(c, 0); + assert_eq!(d.as_array(), &[0, 0, 0, 0]); + + // if at least one element of a matches any element of b with a not equal value, and no elements of a with a value of 0. + let a = vector_unsigned_int([4, 2, 3, 4]); + let b = vector_unsigned_int([4, 5, 6, 7]); + let d = unsafe { vec_find_any_ne_or_0_idx_cc(a, b, &mut c) }; + assert_eq!(c, 1); + assert_eq!(d.as_array(), &[0, 4, 0, 0]); + + // if at least one element of a matches any element of b with a not equal value, and there is at least one element from a has a value of 0. + let a = vector_unsigned_int([1, 0, 1, 1]); + let b = vector_unsigned_int([4, 5, 6, 7]); + let d = unsafe { vec_find_any_ne_or_0_idx_cc(a, b, &mut c) }; + assert_eq!(c, 2); + assert_eq!(d.as_array(), &[0, 0, 0, 0]); + + // if no element of a matches any element of b with a not equal value, and there is no element from a with a value of 0. + let a = vector_unsigned_int([4, 4, 4, 4]); + let b = vector_unsigned_int([4, 5, 6, 7]); + let d = unsafe { vec_find_any_ne_or_0_idx_cc(a, b, &mut c) }; + assert_eq!(c, 3); + assert_eq!(d.as_array(), &[0, 16, 0, 0]); + } }