@@ -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 :: * ;
@@ -1727,6 +1760,52 @@ where
1727
1760
a. vec_mergel ( b)
1728
1761
}
1729
1762
1763
+ /// Generates byte masks for elements in the return vector. For each bit in a, if the bit is one, all bit positions
1764
+ /// 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.
1765
+ #[ inline]
1766
+ #[ target_feature( enable = "vector" ) ]
1767
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1768
+ #[ cfg_attr( test, assert_instr( vgbm, MASK = 0x00FF ) ) ]
1769
+ pub unsafe fn vec_genmask < const MASK : u16 > ( ) -> vector_unsigned_char {
1770
+ vector_unsigned_char ( const { genmask :: < MASK > ( ) } )
1771
+ }
1772
+
1773
+ /// Vector Generate Mask (Byte)
1774
+ #[ inline]
1775
+ #[ target_feature( enable = "vector" ) ]
1776
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1777
+ #[ cfg_attr( test, assert_instr( vrepib, L = 3 , H = 5 ) ) ]
1778
+ pub unsafe fn vec_genmasks_8 < const L : u8 , const H : u8 > ( ) -> vector_unsigned_char {
1779
+ vector_unsigned_char ( const { [ genmasks ( u8:: BITS , L , H ) as u8 ; 16 ] } )
1780
+ }
1781
+
1782
+ /// Vector Generate Mask (Halfword)
1783
+ #[ inline]
1784
+ #[ target_feature( enable = "vector" ) ]
1785
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1786
+ #[ cfg_attr( test, assert_instr( vrepih, L = 3 , H = 5 ) ) ]
1787
+ pub unsafe fn vec_genmasks_16 < const L : u8 , const H : u8 > ( ) -> vector_unsigned_short {
1788
+ vector_unsigned_short ( const { [ genmasks ( u16:: BITS , L , H ) as u16 ; 8 ] } )
1789
+ }
1790
+
1791
+ /// Vector Generate Mask (Word)
1792
+ #[ inline]
1793
+ #[ target_feature( enable = "vector" ) ]
1794
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1795
+ #[ cfg_attr( test, assert_instr( vgmf, L = 3 , H = 5 ) ) ]
1796
+ pub unsafe fn vec_genmasks_32 < const L : u8 , const H : u8 > ( ) -> vector_unsigned_int {
1797
+ vector_unsigned_int ( const { [ genmasks ( u32:: BITS , L , H ) as u32 ; 4 ] } )
1798
+ }
1799
+
1800
+ /// Vector Generate Mask (Doubleword)
1801
+ #[ inline]
1802
+ #[ target_feature( enable = "vector" ) ]
1803
+ #[ unstable( feature = "stdarch_s390x" , issue = "135681" ) ]
1804
+ #[ cfg_attr( test, assert_instr( vgmg, L = 3 , H = 5 ) ) ]
1805
+ pub unsafe fn vec_genmasks_64 < const L : u8 , const H : u8 > ( ) -> vector_unsigned_long_long {
1806
+ vector_unsigned_long_long ( const { [ genmasks ( u64:: BITS , L , H ) ; 2 ] } )
1807
+ }
1808
+
1730
1809
#[ cfg( test) ]
1731
1810
mod tests {
1732
1811
use super :: * ;
@@ -1751,6 +1830,36 @@ mod tests {
1751
1830
assert_eq ! ( ShuffleMask :: <4 >:: merge_high( ) . 0 , [ 0 , 4 , 1 , 5 ] ) ;
1752
1831
}
1753
1832
1833
+ #[ test]
1834
+ fn test_vec_mask ( ) {
1835
+ assert_eq ! (
1836
+ genmask:: <0x00FF >( ) ,
1837
+ [
1838
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
1839
+ ]
1840
+ ) ;
1841
+ }
1842
+
1843
+ #[ test]
1844
+ fn test_genmasks ( ) {
1845
+ assert_eq ! ( genmasks( u8 :: BITS , 3 , 5 ) , 28 ) ;
1846
+ assert_eq ! ( genmasks( u8 :: BITS , 3 , 7 ) , 31 ) ;
1847
+
1848
+ // If a or b is greater than 8, the operation is performed as if the value gets modulo by 8.
1849
+ assert_eq ! ( genmasks( u8 :: BITS , 3 + 8 , 7 + 8 ) , 31 ) ;
1850
+ // If a is greater than b, the operation is perform as if b equals 7.
1851
+ assert_eq ! ( genmasks( u8 :: BITS , 5 , 4 ) , genmasks( u8 :: BITS , 5 , 7 ) ) ;
1852
+
1853
+ assert_eq ! (
1854
+ genmasks( u16 :: BITS , 4 , 12 ) as u16 ,
1855
+ u16 :: from_be_bytes( [ 15 , -8i8 as u8 ] )
1856
+ ) ;
1857
+ assert_eq ! (
1858
+ genmasks( u32 :: BITS , 4 , 29 ) as u32 ,
1859
+ u32 :: from_be_bytes( [ 15 , 0xFF , 0xFF , -4i8 as u8 ] )
1860
+ ) ;
1861
+ }
1862
+
1754
1863
macro_rules! test_vec_1 {
1755
1864
{ $name: ident, $fn: ident, f32x4, [ $( $a: expr) ,+] , ~[ $( $d: expr) ,+] } => {
1756
1865
#[ simd_test( enable = "vector" ) ]
0 commit comments