@@ -12,11 +12,14 @@ macro_rules! intrinsic_pat {
12
12
}
13
13
14
14
macro_rules! intrinsic_arg {
15
- ( c $fx: expr, $arg: ident) => {
15
+ ( o $fx: expr, $arg: ident) => {
16
16
$arg
17
17
} ;
18
+ ( c $fx: expr, $arg: ident) => {
19
+ trans_operand( $fx, $arg)
20
+ } ;
18
21
( v $fx: expr, $arg: ident) => {
19
- $ arg. load_scalar( $fx)
22
+ trans_operand ( $fx , $ arg) . load_scalar( $fx)
20
23
} ;
21
24
}
22
25
@@ -40,9 +43,9 @@ macro_rules! intrinsic_match {
40
43
$(
41
44
intrinsic_substs!( $substs, 0 , $( $subst) ,* ) ;
42
45
) ?
43
- if let [ $( $arg) ,* ] = * $args {
44
- let ( $( $arg) , * ) = (
45
- $( intrinsic_arg!( $a $fx, $arg) ) , *
46
+ if let [ $( $arg) ,* ] = $args {
47
+ let ( $( $arg, ) * ) = (
48
+ $( intrinsic_arg!( $a $fx, $arg) , ) *
46
49
) ;
47
50
#[ warn( unused_parens, non_snake_case) ]
48
51
{
@@ -67,7 +70,10 @@ macro_rules! call_intrinsic_match {
67
70
$(
68
71
stringify!( $name) => {
69
72
assert!( $substs. is_noop( ) ) ;
70
- if let [ $( $arg) ,* ] = * $args {
73
+ if let [ $( ref $arg) ,* ] = * $args {
74
+ let ( $( $arg, ) * ) = (
75
+ $( trans_operand( $fx, $arg) , ) *
76
+ ) ;
71
77
let res = $fx. easy_call( stringify!( $func) , & [ $( $arg) ,* ] , $fx. tcx. types. $ty) ;
72
78
$ret. write_cvalue( $fx, res) ;
73
79
@@ -120,10 +126,10 @@ fn lane_type_and_count<'tcx>(
120
126
fx : & FunctionCx < ' _ , ' tcx , impl Backend > ,
121
127
layout : TyLayout < ' tcx > ,
122
128
intrinsic : & str ,
123
- ) -> ( TyLayout < ' tcx > , usize ) {
129
+ ) -> ( TyLayout < ' tcx > , u32 ) {
124
130
assert ! ( layout. ty. is_simd( ) ) ;
125
131
let lane_count = match layout. fields {
126
- layout:: FieldPlacement :: Array { stride : _, count } => usize :: try_from ( count) . unwrap ( ) ,
132
+ layout:: FieldPlacement :: Array { stride : _, count } => u32 :: try_from ( count) . unwrap ( ) ,
127
133
_ => panic ! ( "Non vector type {:?} passed to or returned from simd_* intrinsic {}" , layout. ty, intrinsic) ,
128
134
} ;
129
135
let lane_layout = layout. field ( fx, 0 ) ;
@@ -146,7 +152,7 @@ fn simd_for_each_lane<'tcx, B: Backend>(
146
152
assert_eq ! ( lane_count, ret_lane_count) ;
147
153
148
154
for lane in 0 ..lane_count {
149
- let lane = mir:: Field :: new ( lane) ;
155
+ let lane = mir:: Field :: new ( lane. try_into ( ) . unwrap ( ) ) ;
150
156
let x_lane = x. value_field ( fx, lane) . load_scalar ( fx) ;
151
157
let y_lane = y. value_field ( fx, lane) . load_scalar ( fx) ;
152
158
@@ -212,7 +218,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
212
218
fx : & mut FunctionCx < ' a , ' tcx , impl Backend > ,
213
219
def_id : DefId ,
214
220
substs : SubstsRef < ' tcx > ,
215
- args : Vec < CValue < ' tcx > > ,
221
+ args : & [ mir :: Operand < ' tcx > ] ,
216
222
destination : Option < ( CPlace < ' tcx > , BasicBlock ) > ,
217
223
) {
218
224
let intrinsic = fx. tcx . item_name ( def_id) . as_str ( ) ;
@@ -499,7 +505,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
499
505
let ptr_diff = fx. bcx. ins( ) . imul_imm( offset, pointee_size as i64 ) ;
500
506
let base_val = base. load_scalar( fx) ;
501
507
let res = fx. bcx. ins( ) . iadd( base_val, ptr_diff) ;
502
- ret. write_cvalue( fx, CValue :: by_val( res, args [ 0 ] . layout( ) ) ) ;
508
+ ret. write_cvalue( fx, CValue :: by_val( res, base . layout( ) ) ) ;
503
509
} ;
504
510
505
511
transmute, <src_ty, dst_ty> ( c from) {
@@ -807,8 +813,8 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
807
813
} ;
808
814
809
815
// simd_shuffle32<T, U>(x: T, y: T, idx: [u32; 32]) -> U
810
- _ if intrinsic. starts_with( "simd_shuffle" ) , ( c x, c y, c idx) {
811
- let n: usize = intrinsic[ "simd_shuffle" . len( ) ..] . parse( ) . unwrap( ) ;
816
+ _ if intrinsic. starts_with( "simd_shuffle" ) , ( c x, c y, o idx) {
817
+ let n: u32 = intrinsic[ "simd_shuffle" . len( ) ..] . parse( ) . unwrap( ) ;
812
818
813
819
assert_eq!( x. layout( ) , y. layout( ) ) ;
814
820
let layout = x. layout( ) ;
@@ -821,9 +827,60 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
821
827
822
828
let total_len = lane_count * 2 ;
823
829
824
- // TODO get shuffle indices
825
- fx. tcx. sess. warn( "simd_shuffle* not yet implemented" ) ;
826
- crate :: trap:: trap_unimplemented( fx, "simd_shuffle* not yet implemented" ) ;
830
+ let indexes = {
831
+ use rustc:: mir:: interpret:: * ;
832
+ let idx_place = match idx {
833
+ Operand :: Copy ( idx_place) => {
834
+ idx_place
835
+ }
836
+ _ => panic!( "simd_shuffle* idx is not Operand::Copy, but {:?}" , idx) ,
837
+ } ;
838
+
839
+ assert!( idx_place. projection. is_none( ) ) ;
840
+ let static_ = match & idx_place. base {
841
+ PlaceBase :: Static ( static_) => {
842
+ static_
843
+ }
844
+ PlaceBase :: Local ( _) => panic!( "simd_shuffle* idx is not constant, but a local" ) ,
845
+ } ;
846
+
847
+ let idx_const = match & static_. kind {
848
+ StaticKind :: Static ( _) => unimplemented!( ) ,
849
+ StaticKind :: Promoted ( promoted) => {
850
+ fx. tcx. const_eval( ParamEnv :: reveal_all( ) . and( GlobalId {
851
+ instance: fx. instance,
852
+ promoted: Some ( * promoted) ,
853
+ } ) ) . unwrap( )
854
+ }
855
+ } ;
856
+
857
+ let idx_bytes = match idx_const. val {
858
+ ConstValue :: ByRef { align: _, offset, alloc } => {
859
+ let ptr = Pointer :: new( AllocId ( 0 /* dummy */ ) , offset) ;
860
+ let size = Size :: from_bytes( 4 * u64 :: from( ret_lane_count) /* size_of([u32; ret_lane_count]) */ ) ;
861
+ alloc. get_bytes( fx, ptr, size) . unwrap( )
862
+ }
863
+ _ => unreachable!( "{:?}" , idx_const) ,
864
+ } ;
865
+
866
+ ( 0 ..ret_lane_count) . map( |i| {
867
+ let i = usize :: try_from( i) . unwrap( ) ;
868
+ let idx = rustc:: mir:: interpret:: read_target_uint(
869
+ fx. tcx. data_layout. endian,
870
+ & idx_bytes[ 4 * i.. 4 * i + 4 ] ,
871
+ ) . expect( "read_target_uint" ) ;
872
+ u32 :: try_from( idx) . expect( "try_from u32" )
873
+ } ) . collect:: <Vec <u32 >>( )
874
+ } ;
875
+
876
+ for & idx in & indexes {
877
+ assert!( idx < total_len, "idx {} out of range 0..{}" , idx, total_len) ;
878
+ }
879
+
880
+
881
+
882
+ println!( "{:?}" , indexes) ;
883
+ unimplemented!( ) ;
827
884
} ;
828
885
829
886
simd_add, ( c x, c y) {
0 commit comments