@@ -12,6 +12,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
12
12
fn emulate_simd_intrinsic (
13
13
& mut self ,
14
14
intrinsic_name : & str ,
15
+ generic_args : ty:: GenericArgsRef < ' tcx > ,
15
16
args : & [ OpTy < ' tcx , Provenance > ] ,
16
17
dest : & PlaceTy < ' tcx , Provenance > ,
17
18
) -> InterpResult < ' tcx > {
@@ -490,6 +491,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
490
491
this. write_immediate ( val, & dest) ?;
491
492
}
492
493
}
494
+ "shuffle_generic" => {
495
+ let [ left, right] = check_arg_count ( args) ?;
496
+ let ( left, left_len) = this. operand_to_simd ( left) ?;
497
+ let ( right, right_len) = this. operand_to_simd ( right) ?;
498
+ let ( dest, dest_len) = this. place_to_simd ( dest) ?;
499
+
500
+ let index = generic_args[ 2 ] . expect_const ( ) . eval ( * this. tcx , this. param_env ( ) , Some ( this. tcx . span ) ) . unwrap ( ) . unwrap_branch ( ) ;
501
+ let index_len = index. len ( ) ;
502
+
503
+ assert_eq ! ( left_len, right_len) ;
504
+ assert_eq ! ( index_len as u64 , dest_len) ;
505
+
506
+ for i in 0 ..dest_len {
507
+ let src_index: u64 = index[ i as usize ] . unwrap_leaf ( )
508
+ . try_to_u32 ( ) . unwrap ( )
509
+ . into ( ) ;
510
+ let dest = this. project_index ( & dest, i) ?;
511
+
512
+ let val = if src_index < left_len {
513
+ this. read_immediate ( & this. project_index ( & left, src_index) ?) ?
514
+ } else if src_index < left_len. checked_add ( right_len) . unwrap ( ) {
515
+ let right_idx = src_index. checked_sub ( left_len) . unwrap ( ) ;
516
+ this. read_immediate ( & this. project_index ( & right, right_idx) ?) ?
517
+ } else {
518
+ span_bug ! (
519
+ this. cur_span( ) ,
520
+ "simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}" ,
521
+ ) ;
522
+ } ;
523
+ this. write_immediate ( * val, & dest) ?;
524
+ }
525
+ }
493
526
"shuffle" => {
494
527
let [ left, right, index] = check_arg_count ( args) ?;
495
528
let ( left, left_len) = this. operand_to_simd ( left) ?;
0 commit comments