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