@@ -188,6 +188,14 @@ unsafe extern "unadjusted" {
188188 #[ link_name = "llvm.s390.vavglg" ] fn vavglg ( a : vector_unsigned_long_long , b : vector_unsigned_long_long ) -> vector_unsigned_long_long ;
189189
190190 #[ link_name = "llvm.s390.vcksm" ] fn vcksm ( a : vector_unsigned_int , b : vector_unsigned_int ) -> vector_unsigned_int ;
191+
192+ #[ link_name = "llvm.s390.vmeb" ] fn vmeb ( a : vector_signed_char , b : vector_signed_char ) -> vector_signed_short ;
193+ #[ link_name = "llvm.s390.vmeh" ] fn vmeh ( a : vector_signed_short , b : vector_signed_short ) -> vector_signed_int ;
194+ #[ link_name = "llvm.s390.vmef" ] fn vmef ( a : vector_signed_int , b : vector_signed_int ) -> vector_signed_long_long ;
195+
196+ #[ link_name = "llvm.s390.vmleb" ] fn vmleb ( a : vector_unsigned_char , b : vector_unsigned_char ) -> vector_unsigned_short ;
197+ #[ link_name = "llvm.s390.vmleh" ] fn vmleh ( a : vector_unsigned_short , b : vector_unsigned_short ) -> vector_unsigned_int ;
198+ #[ link_name = "llvm.s390.vmlef" ] fn vmlef ( a : vector_unsigned_int , b : vector_unsigned_int ) -> vector_unsigned_long_long ;
191199}
192200
193201impl_from ! { i8x16, u8x16, i16x8, u16x8, i32x4, u32x4, i64x2, u64x2, f32x4, f64x2 }
@@ -2388,6 +2396,59 @@ mod sealed {
23882396 }
23892397
23902398 impl_vec_trait ! { [ VectorAvg vec_avg] 2 ( vec_vavglb, vec_vavgb, vec_vavglh, vec_vavgh, vec_vavglf, vec_vavgf, vec_vavglg, vec_vavgg) }
2399+
2400+ macro_rules! impl_mul {
2401+ ( [ $Trait: ident $m: ident] $fun: ident ( $a: ty, $b: ty) -> $r: ty) => {
2402+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
2403+ impl $Trait<$r> for $a {
2404+ #[ inline]
2405+ #[ target_feature( enable = "vector" ) ]
2406+ unsafe fn $m( self , b: $b) -> $r {
2407+ $fun( transmute( self ) , transmute( b) )
2408+ }
2409+ }
2410+ } ;
2411+ }
2412+
2413+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
2414+ pub trait VectorMule < Result > {
2415+ unsafe fn vec_mule ( self , b : Self ) -> Result ;
2416+ }
2417+
2418+ // FIXME(llvm) sadly this does not yet work https://github.com/llvm/llvm-project/issues/129705
2419+ // #[target_feature(enable = "vector")]
2420+ // #[cfg_attr(test, assert_instr(vmleh))]
2421+ // unsafe fn vec_vmleh(a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int {
2422+ // let even_a: vector_unsigned_int = simd_as(simd_shuffle::<_, _, u16x4>(
2423+ // a,
2424+ // a,
2425+ // const { ShuffleMask([0, 2, 4, 6]) },
2426+ // ));
2427+ //
2428+ // let even_b: vector_unsigned_int = simd_as(simd_shuffle::<_, _, u16x4>(
2429+ // b,
2430+ // b,
2431+ // const { ShuffleMask([0, 2, 4, 6]) },
2432+ // ));
2433+ //
2434+ // simd_mul(even_a, even_b)
2435+ // }
2436+
2437+ test_impl ! { vec_vmeb( a: vector_signed_char, b: vector_signed_char) -> vector_signed_short [ vmeb, vmeb ] }
2438+ test_impl ! { vec_vmeh( a: vector_signed_short, b: vector_signed_short) -> vector_signed_int[ vmeh, vmeh ] }
2439+ test_impl ! { vec_vmef( a: vector_signed_int, b: vector_signed_int) -> vector_signed_long_long [ vmef, vmef ] }
2440+
2441+ test_impl ! { vec_vmleb( a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_short [ vmleb, vmleb ] }
2442+ test_impl ! { vec_vmleh( a: vector_unsigned_short, b: vector_unsigned_short) -> vector_unsigned_int[ vmleh, vmleh ] }
2443+ test_impl ! { vec_vmlef( a: vector_unsigned_int, b: vector_unsigned_int) -> vector_unsigned_long_long [ vmlef, vmlef ] }
2444+
2445+ impl_mul ! ( [ VectorMule vec_mule] vec_vmeb ( vector_signed_char, vector_signed_char) -> vector_signed_short ) ;
2446+ impl_mul ! ( [ VectorMule vec_mule] vec_vmeh ( vector_signed_short, vector_signed_short) -> vector_signed_int) ;
2447+ impl_mul ! ( [ VectorMule vec_mule] vec_vmef ( vector_signed_int, vector_signed_int) -> vector_signed_long_long ) ;
2448+
2449+ impl_mul ! ( [ VectorMule vec_mule] vec_vmleb ( vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_short ) ;
2450+ impl_mul ! ( [ VectorMule vec_mule] vec_vmleh ( vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_int) ;
2451+ impl_mul ! ( [ VectorMule vec_mule] vec_vmlef ( vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_long_long ) ;
23912452}
23922453
23932454/// Load Count to Block Boundary
@@ -3468,6 +3529,14 @@ pub unsafe fn vec_checksum(a: vector_unsigned_int, b: vector_unsigned_int) -> ve
34683529 vcksm ( a, b)
34693530}
34703531
3532+ /// Vector Multiply Even
3533+ #[ inline]
3534+ #[ target_feature( enable = "vector" ) ]
3535+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3536+ pub unsafe fn vec_mule < T : sealed:: VectorMule < U > , U > ( a : T , b : T ) -> U {
3537+ a. vec_mule ( b)
3538+ }
3539+
34713540#[ cfg( test) ]
34723541mod tests {
34733542 use super :: * ;
@@ -4366,4 +4435,16 @@ mod tests {
43664435 assert_eq ! ( d, 1 ) ;
43674436 }
43684437 }
4438+
4439+ test_vec_2 ! { test_vec_mule_u, vec_mule, u16x8, u16x8 -> u32x4,
4440+ [ 0xFFFF , 0 , 2 , 0 , 2 , 0 , 1 , 0 ] ,
4441+ [ 0xFFFF , 0 , 4 , 0 , 0xFFFF , 0 , 2 , 0 ] ,
4442+ [ 0xFFFE_0001 , 8 , 0x0001_FFFE , 2 ]
4443+ }
4444+
4445+ test_vec_2 ! { test_vec_mule_i, vec_mule, i16x8, i16x8 -> i32x4,
4446+ [ i16 :: MIN , 0 , -2 , 0 , 2 , 0 , 1 , 0 ] ,
4447+ [ i16 :: MIN , 0 , 4 , 0 , i16 :: MAX , 0 , 2 , 0 ] ,
4448+ [ 0x4000_0000 , -8 , 0xFFFE , 2 ]
4449+ }
43694450}
0 commit comments