@@ -3809,6 +3809,186 @@ mod sealed {
38093809 vector_bool_int vector_unsigned_int vfeef vfenef vfeezf vfenezf vfeefs vfenefs vfeezfs vfenezfs
38103810 vector_unsigned_int vector_unsigned_int vfeef vfenef vfeezf vfenezf vfeefs vfenefs vfeezfs vfenezfs
38113811 }
3812+
3813+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3814+ pub trait VectorExtract {
3815+ type ElementType ;
3816+
3817+ unsafe fn vec_extract ( a : Self , b : i32 ) -> Self :: ElementType ;
3818+ }
3819+
3820+ #[ inline]
3821+ #[ target_feature( enable = "vector" ) ]
3822+ #[ cfg_attr( test, assert_instr( vlgvb) ) ]
3823+ unsafe fn vlgvb ( a : vector_unsigned_char , b : i32 ) -> u8 {
3824+ simd_extract_dyn ( a, b as u32 % 16 )
3825+ }
3826+
3827+ #[ inline]
3828+ #[ target_feature( enable = "vector" ) ]
3829+ #[ cfg_attr( test, assert_instr( vlgvh) ) ]
3830+ unsafe fn vlgvh ( a : vector_unsigned_short , b : i32 ) -> u16 {
3831+ simd_extract_dyn ( a, b as u32 % 8 )
3832+ }
3833+
3834+ #[ inline]
3835+ #[ target_feature( enable = "vector" ) ]
3836+ #[ cfg_attr( test, assert_instr( vlgvf) ) ]
3837+ unsafe fn vlgvf ( a : vector_unsigned_int , b : i32 ) -> u32 {
3838+ simd_extract_dyn ( a, b as u32 % 4 )
3839+ }
3840+
3841+ #[ inline]
3842+ #[ target_feature( enable = "vector" ) ]
3843+ #[ cfg_attr( test, assert_instr( vlgvg) ) ]
3844+ unsafe fn vlgvg ( a : vector_unsigned_long_long , b : i32 ) -> u64 {
3845+ simd_extract_dyn ( a, b as u32 % 2 )
3846+ }
3847+
3848+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3849+ pub trait VectorInsert {
3850+ type ElementType ;
3851+
3852+ unsafe fn vec_insert ( a : Self :: ElementType , b : Self , c : i32 ) -> Self ;
3853+ }
3854+
3855+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3856+ pub trait VectorPromote : Sized {
3857+ type ElementType ;
3858+
3859+ unsafe fn vec_promote ( a : Self :: ElementType , b : i32 ) -> MaybeUninit < Self > ;
3860+ }
3861+
3862+ #[ inline]
3863+ #[ target_feature( enable = "vector" ) ]
3864+ #[ cfg_attr( test, assert_instr( vlvgb) ) ]
3865+ unsafe fn vlvgb ( a : u8 , b : vector_unsigned_char , c : i32 ) -> vector_unsigned_char {
3866+ simd_insert_dyn ( b, c as u32 % 16 , a)
3867+ }
3868+
3869+ #[ inline]
3870+ #[ target_feature( enable = "vector" ) ]
3871+ #[ cfg_attr( test, assert_instr( vlvgh) ) ]
3872+ unsafe fn vlvgh ( a : u16 , b : vector_unsigned_short , c : i32 ) -> vector_unsigned_short {
3873+ simd_insert_dyn ( b, c as u32 % 8 , a)
3874+ }
3875+
3876+ #[ inline]
3877+ #[ target_feature( enable = "vector" ) ]
3878+ #[ cfg_attr( test, assert_instr( vlvgf) ) ]
3879+ unsafe fn vlvgf ( a : u32 , b : vector_unsigned_int , c : i32 ) -> vector_unsigned_int {
3880+ simd_insert_dyn ( b, c as u32 % 4 , a)
3881+ }
3882+
3883+ #[ inline]
3884+ #[ target_feature( enable = "vector" ) ]
3885+ #[ cfg_attr( test, assert_instr( vlvgg) ) ]
3886+ unsafe fn vlvgg ( a : u64 , b : vector_unsigned_long_long , c : i32 ) -> vector_unsigned_long_long {
3887+ simd_insert_dyn ( b, c as u32 % 2 , a)
3888+ }
3889+
3890+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3891+ pub trait VectorInsertAndZero {
3892+ type ElementType ;
3893+
3894+ unsafe fn vec_insert_and_zero ( a : * const Self :: ElementType ) -> Self ;
3895+ }
3896+
3897+ #[ inline]
3898+ #[ target_feature( enable = "vector" ) ]
3899+ #[ cfg_attr( test, assert_instr( vllezb) ) ]
3900+ unsafe fn vllezb ( x : * const u8 ) -> vector_unsigned_char {
3901+ vector_unsigned_char ( [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , * x, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] )
3902+ }
3903+
3904+ #[ inline]
3905+ #[ target_feature( enable = "vector" ) ]
3906+ #[ cfg_attr( test, assert_instr( vllezh) ) ]
3907+ unsafe fn vllezh ( x : * const u16 ) -> vector_unsigned_short {
3908+ vector_unsigned_short ( [ 0 , 0 , 0 , * x, 0 , 0 , 0 , 0 ] )
3909+ }
3910+
3911+ #[ inline]
3912+ #[ target_feature( enable = "vector" ) ]
3913+ #[ cfg_attr( test, assert_instr( vllezf) ) ]
3914+ unsafe fn vllezf ( x : * const u32 ) -> vector_unsigned_int {
3915+ vector_unsigned_int ( [ 0 , * x, 0 , 0 ] )
3916+ }
3917+
3918+ #[ inline]
3919+ #[ target_feature( enable = "vector" ) ]
3920+ #[ cfg_attr( test, assert_instr( vllezg) ) ]
3921+ unsafe fn vllezg ( x : * const u64 ) -> vector_unsigned_long_long {
3922+ vector_unsigned_long_long ( [ * x, 0 ] )
3923+ }
3924+
3925+ macro_rules! impl_extract_insert {
3926+ ( $( $ty: ident $extract_intr: ident $insert_intr: ident $insert_and_zero_intr: ident) * ) => {
3927+ $(
3928+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3929+ impl VectorExtract for $ty {
3930+ type ElementType = l_t_t!( $ty) ;
3931+
3932+ #[ inline]
3933+ #[ target_feature( enable = "vector" ) ]
3934+ unsafe fn vec_extract( a: Self , b: i32 ) -> Self :: ElementType {
3935+ transmute( $extract_intr( transmute( a) , b) )
3936+ }
3937+ }
3938+
3939+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3940+ impl VectorInsert for $ty {
3941+ type ElementType = l_t_t!( $ty) ;
3942+
3943+ #[ inline]
3944+ #[ target_feature( enable = "vector" ) ]
3945+ unsafe fn vec_insert( a: Self :: ElementType , b: Self , c: i32 ) -> Self {
3946+ transmute( $insert_intr( transmute( a) , transmute( b) , c) )
3947+ }
3948+ }
3949+
3950+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3951+ impl VectorInsertAndZero for $ty {
3952+ type ElementType = l_t_t!( $ty) ;
3953+
3954+ #[ inline]
3955+ #[ target_feature( enable = "vector" ) ]
3956+ unsafe fn vec_insert_and_zero( a: * const Self :: ElementType ) -> Self {
3957+ transmute( $insert_and_zero_intr( a. cast( ) ) )
3958+ }
3959+ }
3960+
3961+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
3962+ impl VectorPromote for $ty {
3963+ type ElementType = l_t_t!( $ty) ;
3964+
3965+ #[ inline]
3966+ #[ target_feature( enable = "vector" ) ]
3967+ unsafe fn vec_promote( a: Self :: ElementType , c: i32 ) -> MaybeUninit <Self > {
3968+ // Rust does not currently support `MaybeUninit` element types to simd
3969+ // vectors. In C/LLVM that is allowed (using poison values). So rust will
3970+ // use an extra instruction to zero the memory.
3971+ let b = MaybeUninit :: <$ty>:: zeroed( ) ;
3972+ MaybeUninit :: new( transmute( $insert_intr( transmute( a) , transmute( b) , c) ) )
3973+ }
3974+ }
3975+ ) *
3976+ }
3977+
3978+ }
3979+
3980+ impl_extract_insert ! {
3981+ vector_signed_char vlgvb vlvgb vllezb
3982+ vector_unsigned_char vlgvb vlvgb vllezb
3983+ vector_signed_short vlgvh vlvgh vllezh
3984+ vector_unsigned_short vlgvh vlvgh vllezh
3985+ vector_signed_int vlgvf vlvgf vllezf
3986+ vector_unsigned_int vlgvf vlvgf vllezf
3987+ vector_signed_long_long vlgvg vlvgg vllezg
3988+ vector_unsigned_long_long vlgvg vlvgg vllezg
3989+ vector_float vlgvf vlvgf vllezf
3990+ vector_double vlgvg vlvgg vllezg
3991+ }
38123992}
38133993
38143994/// Load Count to Block Boundary
@@ -5646,6 +5826,38 @@ pub unsafe fn vec_any_nge<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
56465826 vec_any_lt ( a, b)
56475827}
56485828
5829+ /// Vector Extract
5830+ #[ inline]
5831+ #[ target_feature( enable = "vector" ) ]
5832+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
5833+ pub unsafe fn vec_extract < T : sealed:: VectorExtract > ( a : T , b : i32 ) -> T :: ElementType {
5834+ T :: vec_extract ( a, b)
5835+ }
5836+
5837+ /// Vector Insert
5838+ #[ inline]
5839+ #[ target_feature( enable = "vector" ) ]
5840+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
5841+ pub unsafe fn vec_insert < T : sealed:: VectorInsert > ( a : T :: ElementType , b : T , c : i32 ) -> T {
5842+ T :: vec_insert ( a, b, c)
5843+ }
5844+
5845+ /// Vector Insert and Zero
5846+ #[ inline]
5847+ #[ target_feature( enable = "vector" ) ]
5848+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
5849+ pub unsafe fn vec_insert_and_zero < T : sealed:: VectorInsertAndZero > ( a : * const T :: ElementType ) -> T {
5850+ T :: vec_insert_and_zero ( a)
5851+ }
5852+
5853+ /// Vector Promote
5854+ #[ inline]
5855+ #[ target_feature( enable = "vector" ) ]
5856+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
5857+ pub unsafe fn vec_promote < T : sealed:: VectorPromote > ( a : T :: ElementType , b : i32 ) -> MaybeUninit < T > {
5858+ T :: vec_promote ( a, b)
5859+ }
5860+
56495861#[ cfg( test) ]
56505862mod tests {
56515863 use super :: * ;
@@ -7189,4 +7401,35 @@ mod tests {
71897401 let d = unsafe { vec_mladd ( a, b, c) } ;
71907402 assert_eq ! ( d. as_array( ) , & [ -3 , -10 , -19 , -30 ] ) ;
71917403 }
7404+
7405+ #[ simd_test( enable = "vector" ) ]
7406+ fn test_vec_extract ( ) {
7407+ let v = vector_unsigned_int ( [ 1 , 2 , 3 , 4 ] ) ;
7408+
7409+ assert_eq ! ( unsafe { vec_extract( v, 1 ) } , 2 ) ;
7410+ assert_eq ! ( unsafe { vec_extract( v, 4 + 2 ) } , 3 ) ;
7411+ }
7412+
7413+ #[ simd_test( enable = "vector" ) ]
7414+ fn test_vec_insert ( ) {
7415+ let mut v = vector_unsigned_int ( [ 1 , 2 , 3 , 4 ] ) ;
7416+
7417+ v = unsafe { vec_insert ( 42 , v, 1 ) } ;
7418+ assert_eq ! ( v. as_array( ) , & [ 1 , 42 , 3 , 4 ] ) ;
7419+
7420+ v = unsafe { vec_insert ( 64 , v, 6 ) } ;
7421+ assert_eq ! ( v. as_array( ) , & [ 1 , 42 , 64 , 4 ] ) ;
7422+ }
7423+
7424+ #[ simd_test( enable = "vector" ) ]
7425+ fn test_vec_promote ( ) {
7426+ let v: vector_unsigned_int = unsafe { vec_promote ( 42 , 1 ) . assume_init ( ) } ;
7427+ assert_eq ! ( v. as_array( ) , & [ 0 , 42 , 0 , 0 ] ) ;
7428+ }
7429+
7430+ #[ simd_test( enable = "vector" ) ]
7431+ fn test_vec_insert_and_zero ( ) {
7432+ let v = unsafe { vec_insert_and_zero :: < vector_unsigned_int > ( & 42u32 ) } ;
7433+ assert_eq ! ( v. as_array( ) , vector_unsigned_int( [ 0 , 42 , 0 , 0 ] ) . as_array( ) ) ;
7434+ }
71927435}
0 commit comments