@@ -3809,6 +3809,186 @@ mod sealed {
3809
3809
vector_bool_int vector_unsigned_int vfeef vfenef vfeezf vfenezf vfeefs vfenefs vfeezfs vfenezfs
3810
3810
vector_unsigned_int vector_unsigned_int vfeef vfenef vfeezf vfenezf vfeefs vfenefs vfeezfs vfenezfs
3811
3811
}
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
+ }
3812
3992
}
3813
3993
3814
3994
/// Load Count to Block Boundary
@@ -5646,6 +5826,38 @@ pub unsafe fn vec_any_nge<T: sealed::VectorCompare>(a: T, b: T) -> i32 {
5646
5826
vec_any_lt ( a, b)
5647
5827
}
5648
5828
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
+
5649
5861
#[ cfg( test) ]
5650
5862
mod tests {
5651
5863
use super :: * ;
@@ -7189,4 +7401,35 @@ mod tests {
7189
7401
let d = unsafe { vec_mladd ( a, b, c) } ;
7190
7402
assert_eq ! ( d. as_array( ) , & [ -3 , -10 , -19 , -30 ] ) ;
7191
7403
}
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
+ }
7192
7435
}
0 commit comments