@@ -997,6 +997,92 @@ mod sealed {
997
997
vector_signed_int, verimf, test_verimf,
998
998
vector_signed_long_long, verimg, test_verimg
999
999
}
1000
+
1001
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1002
+ pub trait VectorReve {
1003
+ unsafe fn vec_reve ( self ) -> Self ;
1004
+ }
1005
+
1006
+ #[ repr( simd) ]
1007
+ struct ReverseMask < const N : usize > ( [ u32 ; N ] ) ;
1008
+
1009
+ impl < const N : usize > ReverseMask < N > {
1010
+ const fn new ( ) -> Self {
1011
+ let mut index = [ 0 ; N ] ;
1012
+ let mut i = 0 ;
1013
+ while i < N {
1014
+ index[ i] = ( N - i - 1 ) as u32 ;
1015
+ i += 1 ;
1016
+ }
1017
+ ReverseMask ( index)
1018
+ }
1019
+ }
1020
+
1021
+ macro_rules! impl_reve {
1022
+ ( $( $ty: ident, $fun: ident, $instr: ident) ,* ) => {
1023
+ $(
1024
+ #[ inline]
1025
+ #[ target_feature( enable = "vector" ) ]
1026
+ #[ cfg_attr( test, assert_instr( $instr) ) ]
1027
+ unsafe fn $fun( a: $ty) -> $ty {
1028
+ const N : usize = core:: mem:: size_of:: <$ty>( ) / core:: mem:: size_of:: <l_t_t!( $ty) >( ) ;
1029
+ simd_shuffle( a, a, const { ReverseMask :: <N >:: new( ) } )
1030
+ }
1031
+
1032
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1033
+ impl VectorReve for $ty {
1034
+ #[ inline]
1035
+ #[ target_feature( enable = "vector" ) ]
1036
+ unsafe fn vec_reve( self ) -> Self {
1037
+ $fun( self )
1038
+ }
1039
+ }
1040
+
1041
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1042
+ impl VectorReve for t_u!( $ty) {
1043
+ #[ inline]
1044
+ #[ target_feature( enable = "vector" ) ]
1045
+ unsafe fn vec_reve( self ) -> Self {
1046
+ transmute( $fun( transmute( self ) ) )
1047
+ }
1048
+ }
1049
+
1050
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1051
+ impl VectorReve for t_b!( $ty) {
1052
+ #[ inline]
1053
+ #[ target_feature( enable = "vector" ) ]
1054
+ unsafe fn vec_reve( self ) -> Self {
1055
+ transmute( $fun( transmute( self ) ) )
1056
+ }
1057
+ }
1058
+ ) *
1059
+ }
1060
+ }
1061
+
1062
+ impl_reve ! {
1063
+ vector_signed_char, reveb, vperm,
1064
+ vector_signed_short, reveh, vperm,
1065
+ vector_signed_int, revef, vperm,
1066
+ vector_signed_long_long, reveg, vpdi
1067
+ }
1068
+
1069
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1070
+ impl VectorReve for vector_float {
1071
+ #[ inline]
1072
+ #[ target_feature( enable = "vector" ) ]
1073
+ unsafe fn vec_reve ( self ) -> Self {
1074
+ transmute ( transmute :: < _ , vector_signed_int > ( self ) . vec_reve ( ) )
1075
+ }
1076
+ }
1077
+
1078
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1079
+ impl VectorReve for vector_double {
1080
+ #[ inline]
1081
+ #[ target_feature( enable = "vector" ) ]
1082
+ unsafe fn vec_reve ( self ) -> Self {
1083
+ transmute ( transmute :: < _ , vector_signed_long_long > ( self ) . vec_reve ( ) )
1084
+ }
1085
+ }
1000
1086
}
1001
1087
1002
1088
/// Vector element-wise addition.
@@ -1457,6 +1543,17 @@ where
1457
1543
a. vec_rli ( bits)
1458
1544
}
1459
1545
1546
+ /// Returns a vector with the elements of the input vector in reversed order.
1547
+ #[ inline]
1548
+ #[ target_feature( enable = "vector" ) ]
1549
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1550
+ pub unsafe fn vec_reve < T > ( a : T ) -> T
1551
+ where
1552
+ T : sealed:: VectorReve ,
1553
+ {
1554
+ a. vec_reve ( )
1555
+ }
1556
+
1460
1557
#[ cfg( test) ]
1461
1558
mod tests {
1462
1559
use super :: * ;
@@ -1812,4 +1909,9 @@ mod tests {
1812
1909
[ 0x12345678 , 0x9ABCDEF0 , 0x0F0F0F0F , 0x12345678 ] ,
1813
1910
[ 4 , 8 , 12 , 68 ] ,
1814
1911
[ 0x23456781 , 0xBCDEF09A , 0xF0F0F0F0 , 0x23456781 ] }
1912
+
1913
+ test_vec_1 ! { test_vec_reve_f32, vec_reve, f32x4,
1914
+ [ 0.1 , 0.5 , 0.6 , 0.9 ] ,
1915
+ [ 0.9 , 0.6 , 0.5 , 0.1 ]
1916
+ }
1815
1917
}
0 commit comments