@@ -207,40 +207,108 @@ where
207
207
}
208
208
209
209
#[ inline]
210
- pub ( crate ) fn to_bitmask_integer ( self ) -> u64 {
211
- let resized = self . to_int ( ) . extend :: < 64 > ( T :: FALSE ) ;
210
+ unsafe fn to_bitmask_impl < U : ReverseBits , const M : usize > ( self ) -> U
211
+ where
212
+ LaneCount < M > : SupportedLaneCount ,
213
+ {
214
+ let resized = self . to_int ( ) . resize :: < M > ( T :: FALSE ) ;
212
215
213
- // SAFETY : `resized` is an integer vector with length 64
214
- let bitmask: u64 = unsafe { intrinsics:: simd_bitmask ( resized) } ;
216
+ // Safety : `resized` is an integer vector with length M, which must match T
217
+ let bitmask: U = unsafe { intrinsics:: simd_bitmask ( resized) } ;
215
218
216
219
// LLVM assumes bit order should match endianness
217
220
if cfg ! ( target_endian = "big" ) {
218
- bitmask. reverse_bits ( )
221
+ bitmask. reverse_bits ( M )
219
222
} else {
220
223
bitmask
221
224
}
222
225
}
223
226
224
227
#[ inline]
225
- pub ( crate ) fn from_bitmask_integer ( bitmask : u64 ) -> Self {
228
+ unsafe fn from_bitmask_impl < U : ReverseBits , const M : usize > ( bitmask : U ) -> Self
229
+ where
230
+ LaneCount < M > : SupportedLaneCount ,
231
+ {
226
232
// LLVM assumes bit order should match endianness
227
233
let bitmask = if cfg ! ( target_endian = "big" ) {
228
- bitmask. reverse_bits ( )
234
+ bitmask. reverse_bits ( M )
229
235
} else {
230
236
bitmask
231
237
} ;
232
238
233
239
// SAFETY: `mask` is the correct bitmask type for a u64 bitmask
234
- let mask: Simd < T , 64 > = unsafe {
240
+ let mask: Simd < T , M > = unsafe {
235
241
intrinsics:: simd_select_bitmask (
236
242
bitmask,
237
- Simd :: < T , 64 > :: splat ( T :: TRUE ) ,
238
- Simd :: < T , 64 > :: splat ( T :: FALSE ) ,
243
+ Simd :: < T , M > :: splat ( T :: TRUE ) ,
244
+ Simd :: < T , M > :: splat ( T :: FALSE ) ,
239
245
)
240
246
} ;
241
247
242
248
// SAFETY: `mask` only contains `T::TRUE` or `T::FALSE`
243
- unsafe { Self :: from_int_unchecked ( mask. extend :: < N > ( T :: FALSE ) ) }
249
+ unsafe { Self :: from_int_unchecked ( mask. resize :: < N > ( T :: FALSE ) ) }
250
+ }
251
+
252
+ #[ inline]
253
+ pub ( crate ) fn to_bitmask_integer ( self ) -> u64 {
254
+ // TODO modify simd_bitmask to zero-extend output, making this unnecessary
255
+ macro_rules! bitmask {
256
+ { $( $ty: ty: $( $len: literal) ,* ; ) * } => {
257
+ match N {
258
+ $( $(
259
+ // Safety: bitmask matches length
260
+ $len => unsafe { self . to_bitmask_impl:: <$ty, $len>( ) as u64 } ,
261
+ ) * ) *
262
+ // Safety: bitmask matches length
263
+ _ => unsafe { self . to_bitmask_impl:: <u64 , 64 >( ) } ,
264
+ }
265
+ }
266
+ }
267
+ #[ cfg( all_lane_counts) ]
268
+ bitmask ! {
269
+ u8 : 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ;
270
+ u16 : 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ;
271
+ u32 : 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 ;
272
+ u64 : 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 ;
273
+ }
274
+ #[ cfg( not( all_lane_counts) ) ]
275
+ bitmask ! {
276
+ u8 : 1 , 2 , 4 , 8 ;
277
+ u16 : 16 ;
278
+ u32 : 32 ;
279
+ u64 : 64 ;
280
+ }
281
+ }
282
+
283
+ #[ inline]
284
+ pub ( crate ) fn from_bitmask_integer ( bitmask : u64 ) -> Self {
285
+ // TODO modify simd_bitmask_select to truncate input, making this unnecessary
286
+ macro_rules! bitmask {
287
+ { $( $ty: ty: $( $len: literal) ,* ; ) * } => {
288
+ match N {
289
+ $( $(
290
+ // Safety: bitmask matches length
291
+ $len => unsafe { Self :: from_bitmask_impl:: <$ty, $len>( bitmask as $ty) } ,
292
+ ) * ) *
293
+ // Safety: bitmask matches length
294
+ _ => unsafe { Self :: from_bitmask_impl:: <u64 , 64 >( bitmask) } ,
295
+ }
296
+ }
297
+ }
298
+ #[ cfg( all_lane_counts) ]
299
+ bitmask ! {
300
+ u8 : 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ;
301
+ u16 : 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ;
302
+ u32 : 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 ;
303
+ u64 : 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 ;
304
+ }
305
+ #[ cfg( not( all_lane_counts) ) ]
306
+ bitmask ! {
307
+ u8 : 1 , 2 , 4 , 8 ;
308
+ u16 : 16 ;
309
+ u32 : 32 ;
310
+ u64 : 64 ;
311
+ }
244
312
}
245
313
246
314
#[ inline]
0 commit comments