@@ -3,7 +3,7 @@ use std::iter;
3
3
use log:: trace;
4
4
5
5
use rustc_apfloat:: { Float , Round } ;
6
- use rustc_middle:: ty:: layout:: { IntegerExt , LayoutOf } ;
6
+ use rustc_middle:: ty:: layout:: { HasParamEnv , IntegerExt , LayoutOf } ;
7
7
use rustc_middle:: { mir, mir:: BinOp , ty, ty:: FloatTy } ;
8
8
use rustc_target:: abi:: { Align , Integer } ;
9
9
@@ -614,6 +614,45 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
614
614
this. write_immediate ( val, & dest. into ( ) ) ?;
615
615
}
616
616
}
617
+ "simd_shuffle" => {
618
+ let & [ ref left, ref right, ref index] = check_arg_count ( args) ?;
619
+ let ( left, left_len) = this. operand_to_simd ( left) ?;
620
+ let ( right, right_len) = this. operand_to_simd ( right) ?;
621
+ let ( dest, dest_len) = this. place_to_simd ( dest) ?;
622
+
623
+ // `index` is an array, not a SIMD type
624
+ let ty:: Array ( _, index_len) = index. layout . ty . kind ( ) else {
625
+ bug ! ( "simd_shuffle index argument has non-array type {}" , index. layout. ty)
626
+ } ;
627
+ let index_len = index_len. eval_usize ( * this. tcx , this. param_env ( ) ) ;
628
+
629
+ assert_eq ! ( left_len, right_len) ;
630
+ assert_eq ! ( index_len, dest_len) ;
631
+
632
+ for i in 0 ..dest_len {
633
+ let src_index: u64 = this
634
+ . read_immediate ( & this. operand_index ( & index, i) ?. into ( ) ) ?
635
+ . to_scalar ( ) ?
636
+ . to_u32 ( ) ?
637
+ . into ( ) ;
638
+ let dest = this. mplace_index ( & dest, i) ?;
639
+
640
+ let val = if src_index < left_len {
641
+ this. read_immediate ( & this. mplace_index ( & left, src_index) ?. into ( ) ) ?
642
+ } else if src_index < left_len. checked_add ( right_len) . unwrap ( ) {
643
+ this. read_immediate (
644
+ & this. mplace_index ( & right, src_index - left_len) ?. into ( ) ,
645
+ ) ?
646
+ } else {
647
+ bug ! (
648
+ "simd_shuffle index {} is out of bounds for 2 vectors of size {}" ,
649
+ src_index,
650
+ left_len
651
+ ) ;
652
+ } ;
653
+ this. write_immediate ( * val, & dest. into ( ) ) ?;
654
+ }
655
+ }
617
656
618
657
// Atomic operations
619
658
"atomic_load" => this. atomic_load ( args, dest, AtomicReadOp :: SeqCst ) ?,
0 commit comments