@@ -154,6 +154,39 @@ impl<const N: usize> ShuffleMask<N> {
154
154
}
155
155
}
156
156
157
+ const fn genmask < const MASK : u16 > ( ) -> [ u8 ; 16 ] {
158
+ let mut bits = MASK ;
159
+ let mut elements = [ 0u8 ; 16 ] ;
160
+
161
+ let mut i = 0 ;
162
+ while i < 16 {
163
+ elements[ i] = match bits & ( 1u16 << 15 ) {
164
+ 0 => 0 ,
165
+ _ => 0xFF ,
166
+ } ;
167
+
168
+ bits <<= 1 ;
169
+ i += 1 ;
170
+ }
171
+
172
+ elements
173
+ }
174
+
175
+ const fn genmasks ( bit_width : u32 , a : u8 , b : u8 ) -> u64 {
176
+ let bit_width = bit_width as u8 ;
177
+ let a = a % bit_width;
178
+ let mut b = b % bit_width;
179
+ if a > b {
180
+ b = bit_width - 1 ;
181
+ }
182
+
183
+ // of course these indices start from the left
184
+ let a = ( bit_width - 1 ) - a;
185
+ let b = ( bit_width - 1 ) - b;
186
+
187
+ ( ( 1u64 . wrapping_shl ( a as u32 + 1 ) ) - 1 ) & !( ( 1u64 . wrapping_shl ( b as u32 ) ) - 1 )
188
+ }
189
+
157
190
#[ macro_use]
158
191
mod sealed {
159
192
use super :: * ;
@@ -1731,6 +1764,52 @@ where
1731
1764
a. vec_mergel ( b)
1732
1765
}
1733
1766
1767
+ /// Generates byte masks for elements in the return vector. For each bit in a, if the bit is one, all bit positions
1768
+ /// in the corresponding byte element of d are set to ones. Otherwise, if the bit is zero, the corresponding byte element is set to zero.
1769
+ #[ inline]
1770
+ #[ target_feature( enable = "vector" ) ]
1771
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1772
+ #[ cfg_attr( test, assert_instr( vgbm, MASK = 0x00FF ) ) ]
1773
+ pub unsafe fn vec_genmask < const MASK : u16 > ( ) -> vector_unsigned_char {
1774
+ vector_unsigned_char ( const { genmask :: < MASK > ( ) } )
1775
+ }
1776
+
1777
+ /// Vector Generate Mask (Byte)
1778
+ #[ inline]
1779
+ #[ target_feature( enable = "vector" ) ]
1780
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1781
+ #[ cfg_attr( test, assert_instr( vrepib, L = 3 , H = 5 ) ) ]
1782
+ pub unsafe fn vec_genmasks_8 < const L : u8 , const H : u8 > ( ) -> vector_unsigned_char {
1783
+ vector_unsigned_char ( const { [ genmasks ( u8:: BITS , L , H ) as u8 ; 16 ] } )
1784
+ }
1785
+
1786
+ /// Vector Generate Mask (Halfword)
1787
+ #[ inline]
1788
+ #[ target_feature( enable = "vector" ) ]
1789
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1790
+ #[ cfg_attr( test, assert_instr( vrepih, L = 3 , H = 5 ) ) ]
1791
+ pub unsafe fn vec_genmasks_16 < const L : u8 , const H : u8 > ( ) -> vector_unsigned_short {
1792
+ vector_unsigned_short ( const { [ genmasks ( u16:: BITS , L , H ) as u16 ; 8 ] } )
1793
+ }
1794
+
1795
+ /// Vector Generate Mask (Word)
1796
+ #[ inline]
1797
+ #[ target_feature( enable = "vector" ) ]
1798
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1799
+ #[ cfg_attr( test, assert_instr( vgmf, L = 3 , H = 5 ) ) ]
1800
+ pub unsafe fn vec_genmasks_32 < const L : u8 , const H : u8 > ( ) -> vector_unsigned_int {
1801
+ vector_unsigned_int ( const { [ genmasks ( u32:: BITS , L , H ) as u32 ; 4 ] } )
1802
+ }
1803
+
1804
+ /// Vector Generate Mask (Doubleword)
1805
+ #[ inline]
1806
+ #[ target_feature( enable = "vector" ) ]
1807
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1808
+ #[ cfg_attr( test, assert_instr( vgmg, L = 3 , H = 5 ) ) ]
1809
+ pub unsafe fn vec_genmasks_64 < const L : u8 , const H : u8 > ( ) -> vector_unsigned_long_long {
1810
+ vector_unsigned_long_long ( const { [ genmasks ( u64:: BITS , L , H ) ; 2 ] } )
1811
+ }
1812
+
1734
1813
#[ cfg( test) ]
1735
1814
mod tests {
1736
1815
use super :: * ;
@@ -1755,6 +1834,36 @@ mod tests {
1755
1834
assert_eq ! ( ShuffleMask :: <4 >:: merge_high( ) . 0 , [ 0 , 4 , 1 , 5 ] ) ;
1756
1835
}
1757
1836
1837
+ #[ test]
1838
+ fn test_vec_mask ( ) {
1839
+ assert_eq ! (
1840
+ genmask:: <0x00FF >( ) ,
1841
+ [
1842
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
1843
+ ]
1844
+ ) ;
1845
+ }
1846
+
1847
+ #[ test]
1848
+ fn test_genmasks ( ) {
1849
+ assert_eq ! ( genmasks( u8 :: BITS , 3 , 5 ) , 28 ) ;
1850
+ assert_eq ! ( genmasks( u8 :: BITS , 3 , 7 ) , 31 ) ;
1851
+
1852
+ // If a or b is greater than 8, the operation is performed as if the value gets modulo by 8.
1853
+ assert_eq ! ( genmasks( u8 :: BITS , 3 + 8 , 7 + 8 ) , 31 ) ;
1854
+ // If a is greater than b, the operation is perform as if b equals 7.
1855
+ assert_eq ! ( genmasks( u8 :: BITS , 5 , 4 ) , genmasks( u8 :: BITS , 5 , 7 ) ) ;
1856
+
1857
+ assert_eq ! (
1858
+ genmasks( u16 :: BITS , 4 , 12 ) as u16 ,
1859
+ u16 :: from_be_bytes( [ 15 , -8i8 as u8 ] )
1860
+ ) ;
1861
+ assert_eq ! (
1862
+ genmasks( u32 :: BITS , 4 , 29 ) as u32 ,
1863
+ u32 :: from_be_bytes( [ 15 , 0xFF , 0xFF , -4i8 as u8 ] )
1864
+ ) ;
1865
+ }
1866
+
1758
1867
macro_rules! test_vec_1 {
1759
1868
{ $name: ident, $fn: ident, f32x4, [ $( $a: expr) ,+] , ~[ $( $d: expr) ,+] } => {
1760
1869
#[ simd_test( enable = "vector" ) ]
0 commit comments