@@ -1120,6 +1120,114 @@ mod sealed {
1120
1120
transmute ( transmute :: < _ , vector_signed_long_long > ( self ) . vec_revb ( ) )
1121
1121
}
1122
1122
}
1123
+
1124
+ #[ repr( simd) ]
1125
+ struct MergeMask < const N : usize > ( [ u32 ; N ] ) ;
1126
+
1127
+ impl < const N : usize > MergeMask < N > {
1128
+ const fn merge_low ( ) -> Self {
1129
+ let mut mask = [ 0 ; N ] ;
1130
+ let mut i = N / 2 ;
1131
+ let mut index = 0 ;
1132
+ while index < N {
1133
+ mask[ index] = i as u32 ;
1134
+ mask[ index + 1 ] = ( i + N ) as u32 ;
1135
+
1136
+ i += 1 ;
1137
+ index += 2 ;
1138
+ }
1139
+ MergeMask ( mask)
1140
+ }
1141
+
1142
+ const fn merge_high ( ) -> Self {
1143
+ let mut mask = [ 0 ; N ] ;
1144
+ let mut i = 0 ;
1145
+ let mut index = 0 ;
1146
+ while index < N {
1147
+ mask[ index] = i as u32 ;
1148
+ mask[ index + 1 ] = ( i + N ) as u32 ;
1149
+
1150
+ i += 1 ;
1151
+ index += 2 ;
1152
+ }
1153
+ MergeMask ( mask)
1154
+ }
1155
+ }
1156
+
1157
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1158
+ pub trait VectorMergel {
1159
+ unsafe fn vec_mergel ( self , other : Self ) -> Self ;
1160
+ }
1161
+
1162
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1163
+ pub trait VectorMergeh {
1164
+ unsafe fn vec_mergeh ( self , other : Self ) -> Self ;
1165
+ }
1166
+
1167
+ macro_rules! impl_merge {
1168
+ ( $( $ty: ident, $mergel: ident, $mergeh: ident) ,* ) => {
1169
+ $(
1170
+ #[ inline]
1171
+ #[ target_feature( enable = "vector" ) ]
1172
+ #[ cfg_attr( test, assert_instr( $mergel) ) ]
1173
+ unsafe fn $mergel( a: $ty, b: $ty) -> $ty {
1174
+ const N : usize = core:: mem:: size_of:: <$ty>( ) / core:: mem:: size_of:: <l_t_t!( $ty) >( ) ;
1175
+ simd_shuffle( a, b, const { MergeMask :: <N >:: merge_low( ) } )
1176
+ }
1177
+
1178
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1179
+ impl VectorMergel for $ty {
1180
+ #[ inline]
1181
+ #[ target_feature( enable = "vector" ) ]
1182
+ unsafe fn vec_mergel( self , other: Self ) -> Self {
1183
+ $mergel( self , other)
1184
+ }
1185
+ }
1186
+
1187
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1188
+ impl VectorMergel for t_u!( $ty) {
1189
+ #[ inline]
1190
+ #[ target_feature( enable = "vector" ) ]
1191
+ unsafe fn vec_mergel( self , other: Self ) -> Self {
1192
+ transmute( $mergel( transmute( self ) , transmute( other) ) )
1193
+ }
1194
+ }
1195
+
1196
+ #[ inline]
1197
+ #[ target_feature( enable = "vector" ) ]
1198
+ #[ cfg_attr( test, assert_instr( $mergeh) ) ]
1199
+ unsafe fn $mergeh( a: $ty, b: $ty) -> $ty {
1200
+ const N : usize = core:: mem:: size_of:: <$ty>( ) / core:: mem:: size_of:: <l_t_t!( $ty) >( ) ;
1201
+ simd_shuffle( a, b, const { MergeMask :: <N >:: merge_high( ) } )
1202
+ }
1203
+
1204
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1205
+ impl VectorMergeh for $ty {
1206
+ #[ inline]
1207
+ #[ target_feature( enable = "vector" ) ]
1208
+ unsafe fn vec_mergeh( self , other: Self ) -> Self {
1209
+ $mergeh( self , other)
1210
+ }
1211
+ }
1212
+
1213
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1214
+ impl VectorMergeh for t_u!( $ty) {
1215
+ #[ inline]
1216
+ #[ target_feature( enable = "vector" ) ]
1217
+ unsafe fn vec_mergeh( self , other: Self ) -> Self {
1218
+ transmute( $mergeh( transmute( self ) , transmute( other) ) )
1219
+ }
1220
+ }
1221
+ ) *
1222
+ }
1223
+ }
1224
+
1225
+ impl_merge ! {
1226
+ vector_signed_char, vmrlb, vmrhb,
1227
+ vector_signed_short, vmrlh, vmrhh,
1228
+ vector_signed_int, vmrlf, vmrhf,
1229
+ vector_signed_long_long, vmrlg, vmrhg
1230
+ }
1123
1231
}
1124
1232
1125
1233
/// Vector element-wise addition.
@@ -1602,6 +1710,28 @@ where
1602
1710
a. vec_revb ( )
1603
1711
}
1604
1712
1713
+ /// Merges the most significant ("high") halves of two vectors.
1714
+ #[ inline]
1715
+ #[ target_feature( enable = "vector" ) ]
1716
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1717
+ pub unsafe fn vec_mergeh < T > ( a : T , b : T ) -> T
1718
+ where
1719
+ T : sealed:: VectorMergeh ,
1720
+ {
1721
+ a. vec_mergeh ( b)
1722
+ }
1723
+
1724
+ /// Merges the least significant ("low") halves of two vectors.
1725
+ #[ inline]
1726
+ #[ target_feature( enable = "vector" ) ]
1727
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1728
+ pub unsafe fn vec_mergel < T > ( a : T , b : T ) -> T
1729
+ where
1730
+ T : sealed:: VectorMergel ,
1731
+ {
1732
+ a. vec_mergel ( b)
1733
+ }
1734
+
1605
1735
#[ cfg( test) ]
1606
1736
mod tests {
1607
1737
use super :: * ;
@@ -1967,4 +2097,16 @@ mod tests {
1967
2097
[ 0xAABBCCDD , 0xEEFF0011 , 0x22334455 , 0x66778899 ] ,
1968
2098
[ 0xDDCCBBAA , 0x1100FFEE , 0x55443322 , 0x99887766 ]
1969
2099
}
2100
+
2101
+ test_vec_2 ! { test_vec_mergeh_u32, vec_mergeh, u32x4,
2102
+ [ 0xAAAAAAAA , 0xBBBBBBBB , 0xCCCCCCCC , 0xDDDDDDDD ] ,
2103
+ [ 0x00000000 , 0x11111111 , 0x22222222 , 0x33333333 ] ,
2104
+ [ 0xAAAAAAAA , 0x00000000 , 0xBBBBBBBB , 0x11111111 ]
2105
+ }
2106
+
2107
+ test_vec_2 ! { test_vec_mergel_u32, vec_mergel, u32x4,
2108
+ [ 0xAAAAAAAA , 0xBBBBBBBB , 0xCCCCCCCC , 0xDDDDDDDD ] ,
2109
+ [ 0x00000000 , 0x11111111 , 0x22222222 , 0x33333333 ] ,
2110
+ [ 0xCCCCCCCC , 0x22222222 , 0xDDDDDDDD , 0x33333333 ]
2111
+ }
1970
2112
}
0 commit comments