@@ -206,6 +206,28 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
206
206
) ;
207
207
}
208
208
209
+ #[ cfg( feature = "master" ) ]
210
+ if name == sym:: simd_funnel_shl {
211
+ return Ok ( simd_funnel_shift (
212
+ bx,
213
+ args[ 0 ] . immediate ( ) ,
214
+ args[ 1 ] . immediate ( ) ,
215
+ args[ 2 ] . immediate ( ) ,
216
+ true ,
217
+ ) ) ;
218
+ }
219
+
220
+ #[ cfg( feature = "master" ) ]
221
+ if name == sym:: simd_funnel_shr {
222
+ return Ok ( simd_funnel_shift (
223
+ bx,
224
+ args[ 0 ] . immediate ( ) ,
225
+ args[ 1 ] . immediate ( ) ,
226
+ args[ 2 ] . immediate ( ) ,
227
+ false ,
228
+ ) ) ;
229
+ }
230
+
209
231
if name == sym:: simd_bswap {
210
232
return Ok ( simd_bswap ( bx, args[ 0 ] . immediate ( ) ) ) ;
211
233
}
@@ -1434,3 +1456,52 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
1434
1456
1435
1457
unimplemented ! ( "simd {}" , name) ;
1436
1458
}
1459
+
1460
+ #[ cfg( feature = "master" ) ]
1461
+ fn simd_funnel_shift < ' a , ' gcc , ' tcx > (
1462
+ bx : & mut Builder < ' a , ' gcc , ' tcx > ,
1463
+ a : RValue < ' gcc > ,
1464
+ b : RValue < ' gcc > ,
1465
+ shift : RValue < ' gcc > ,
1466
+ shift_left : bool ,
1467
+ ) -> RValue < ' gcc > {
1468
+ let a_type = a. get_type ( ) ;
1469
+ println ! ( "Vector type: {:?}" , a_type. unqualified( ) ) ;
1470
+ let vector_type = a_type. unqualified ( ) . dyncast_vector ( ) . expect ( "vector type" ) ;
1471
+ let num_units = vector_type. get_num_units ( ) ;
1472
+ let elem_type = vector_type. get_element_type ( ) ;
1473
+
1474
+ let ( new_int_type, int_shift_val, int_mask) = if elem_type. is_compatible_with ( bx. u8_type ) {
1475
+ ( bx. u16_type , 8 , u8:: MAX as u64 )
1476
+ } else if elem_type. is_compatible_with ( bx. u16_type ) {
1477
+ ( bx. u32_type , 16 , u16:: MAX as u64 )
1478
+ } else if elem_type. is_compatible_with ( bx. u32_type ) {
1479
+ ( bx. u64_type , 32 , u32:: MAX as u64 )
1480
+ } else if elem_type. is_compatible_with ( bx. u64_type ) {
1481
+ ( bx. u128_type , 64 , u64:: MAX )
1482
+ } else {
1483
+ unimplemented ! ( "funnel shift on {:?}" , elem_type) ;
1484
+ } ;
1485
+
1486
+ let int_mask = bx. context . new_rvalue_from_long ( new_int_type, int_mask as i64 ) ;
1487
+ let int_shift_val = bx. context . new_rvalue_from_int ( new_int_type, int_shift_val) ;
1488
+ let mut elements = vec ! [ ] ;
1489
+ for i in 0 ..num_units {
1490
+ let index = bx. context . new_rvalue_from_int ( bx. int_type , i as i32 ) ;
1491
+ let a_val = bx. context . new_vector_access ( None , a, index) . to_rvalue ( ) ;
1492
+ let a_val = bx. context . new_cast ( None , a_val, new_int_type) ;
1493
+ let b_val = bx. context . new_vector_access ( None , b, index) . to_rvalue ( ) ;
1494
+ let b_val = bx. context . new_cast ( None , b_val, new_int_type) ;
1495
+ let shift_val = bx. context . new_vector_access ( None , shift, index) . to_rvalue ( ) ;
1496
+ let shift_val = bx. context . new_cast ( None , shift_val, new_int_type) ;
1497
+ let mut val = a_val << int_shift_val | b_val;
1498
+ if shift_left {
1499
+ val = ( val << shift_val) >> int_shift_val;
1500
+ } else {
1501
+ val = ( val >> shift_val) & int_mask;
1502
+ }
1503
+ let val = bx. context . new_cast ( None , val, elem_type) ;
1504
+ elements. push ( val) ;
1505
+ }
1506
+ bx. context . new_rvalue_from_vector ( None , a_type, & elements)
1507
+ }
0 commit comments