@@ -144,7 +144,7 @@ pub fn lane_type_and_count<'tcx>(
144
144
( lane_layout, lane_count)
145
145
}
146
146
147
- fn simd_for_each_lane < ' tcx , B : Backend > (
147
+ pub fn simd_for_each_lane < ' tcx , B : Backend > (
148
148
fx: & mut FunctionCx < ' _ , ' tcx , B > ,
149
149
intrinsic: & str,
150
150
x: CValue < ' tcx > ,
@@ -170,23 +170,37 @@ fn simd_for_each_lane<'tcx, B: Backend>(
170
170
}
171
171
}
172
172
173
- fn bool_to_zero_or_max_uint < ' tcx > (
173
+ pub fn bool_to_zero_or_max_uint < ' tcx > (
174
174
fx: & mut FunctionCx < ' _ , ' tcx , impl Backend > ,
175
175
layout: TyLayout < ' tcx > ,
176
176
val: Value ,
177
177
) -> CValue < ' tcx > {
178
178
let ty = fx. clif_type( layout. ty) . unwrap( ) ;
179
179
180
- let zero = fx. bcx. ins( ) . iconst( ty, 0 ) ;
181
- let max = fx. bcx. ins( ) . iconst( ty, ( u64:: max_value( ) >> ( 64 - ty. bits( ) ) ) as i64 ) ;
182
- let res = crate :: common:: codegen_select( & mut fx. bcx, val, max, zero) ;
180
+ let int_ty = match ty {
181
+ types:: F32 => types:: I32 ,
182
+ types:: F64 => types:: I64 ,
183
+ ty => ty,
184
+ } ;
185
+
186
+ let zero = fx. bcx. ins( ) . iconst( int_ty, 0 ) ;
187
+ let max = fx. bcx. ins( ) . iconst( int_ty, ( u64:: max_value( ) >> ( 64 - int_ty. bits( ) ) ) as i64 ) ;
188
+ let mut res = crate :: common:: codegen_select( & mut fx. bcx, val, max, zero) ;
189
+
190
+ if ty. is_float( ) {
191
+ res = fx. bcx. ins( ) . bitcast( ty, res) ;
192
+ }
193
+
183
194
CValue :: by_val( res, layout)
184
195
}
185
196
186
197
macro_rules! simd_cmp {
187
198
( $fx: expr, $intrinsic: expr, $cc: ident( $x: ident, $y: ident) -> $ret: ident) => {
188
- simd_for_each_lane( $fx, $intrinsic, $x, $y, $ret, |fx, _lane_layout, res_lane_layout, x_lane, y_lane| {
189
- let res_lane = fx. bcx. ins( ) . icmp( IntCC :: $cc, x_lane, y_lane) ;
199
+ simd_for_each_lane( $fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, res_lane_layout, x_lane, y_lane| {
200
+ let res_lane = match lane_layout. ty. sty {
201
+ ty : : Uint ( _) | ty:: Int ( _) => fx. bcx. ins( ) . icmp( IntCC :: $cc, x_lane, y_lane) ,
202
+ _ => unreachable ! ( "{:?}" , lane_layout. ty) ,
203
+ } ;
190
204
bool_to_zero_or_max_uint( fx, res_lane_layout, res_lane)
191
205
} ) ;
192
206
} ;
@@ -203,10 +217,13 @@ macro_rules! simd_cmp {
203
217
204
218
}
205
219
206
- macro_rules! simd_binop {
220
+ macro_rules! simd_int_binop {
207
221
( $fx: expr, $intrinsic: expr, $op: ident( $x: ident, $y: ident) -> $ret: ident) => {
208
- simd_for_each_lane( $fx, $intrinsic, $x, $y, $ret, |fx, _lane_layout, ret_lane_layout, x_lane, y_lane| {
209
- let res_lane = fx. bcx. ins( ) . $op( x_lane, y_lane) ;
222
+ simd_for_each_lane( $fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
223
+ let res_lane = match lane_layout. ty. sty {
224
+ ty : : Uint ( _) | ty:: Int ( _) => fx. bcx. ins( ) . $op( x_lane, y_lane) ,
225
+ _ => unreachable ! ( "{:?}" , lane_layout. ty) ,
226
+ } ;
210
227
CValue :: by_val( res_lane, ret_lane_layout)
211
228
} ) ;
212
229
} ;
@@ -222,6 +239,42 @@ macro_rules! simd_binop {
222
239
} ;
223
240
}
224
241
242
+ macro_rules! simd_int_flt_binop {
243
+ ( $fx: expr, $intrinsic: expr, $op: ident|$op_f: ident( $x: ident, $y: ident) -> $ret: ident) => {
244
+ simd_for_each_lane( $fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
245
+ let res_lane = match lane_layout. ty. sty {
246
+ ty: : Uint ( _) | ty:: Int ( _) => fx. bcx. ins( ) . $op( x_lane, y_lane) ,
247
+ ty:: Float ( _) => fx. bcx. ins( ) . $op_f( x_lane, y_lane) ,
248
+ _ => unreachable ! ( "{:?}" , lane_layout. ty) ,
249
+ } ;
250
+ CValue :: by_val( res_lane, ret_lane_layout)
251
+ } ) ;
252
+ } ;
253
+ ( $fx: expr, $intrinsic: expr, $op_u: ident|$op_s: ident |$op_f: ident( $x: ident, $y: ident) -> $ret: ident) => {
254
+ simd_for_each_lane( $fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
255
+ let res_lane = match lane_layout. ty. sty {
256
+ ty: : Uint ( _) => fx. bcx. ins( ) . $op_u( x_lane, y_lane) ,
257
+ ty:: Int ( _) => fx. bcx. ins( ) . $op_s( x_lane, y_lane) ,
258
+ ty:: Float ( _) => fx. bcx. ins( ) . $op_f( x_lane, y_lane) ,
259
+ _ => unreachable ! ( "{:?}" , lane_layout. ty) ,
260
+ } ;
261
+ CValue :: by_val( res_lane, ret_lane_layout)
262
+ } ) ;
263
+ } ;
264
+ }
265
+
266
+ macro_rules! simd_flt_binop {
267
+ ( $fx: expr, $intrinsic: expr, $op: ident( $x: ident, $y: ident) -> $ret: ident) => {
268
+ simd_for_each_lane( $fx, $intrinsic, $x, $y, $ret, |fx, lane_layout, ret_lane_layout, x_lane, y_lane| {
269
+ let res_lane = match lane_layout. ty. sty {
270
+ ty : : Float ( _) => fx. bcx. ins( ) . $op( x_lane, y_lane) ,
271
+ _ => unreachable ! ( "{:?}" , lane_layout. ty) ,
272
+ } ;
273
+ CValue :: by_val( res_lane, ret_lane_layout)
274
+ } ) ;
275
+ }
276
+ }
277
+
225
278
pub fn codegen_intrinsic_call < ' a , ' tcx : ' a > (
226
279
fx: & mut FunctionCx < ' a , ' tcx , impl Backend > ,
227
280
def_id: DefId ,
@@ -840,30 +893,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
840
893
841
894
let indexes = {
842
895
use rustc:: mir:: interpret:: * ;
843
- let idx_place = match idx {
844
- Operand :: Copy ( idx_place) => {
845
- idx_place
846
- }
847
- _ => panic!( "simd_shuffle* idx is not Operand::Copy, but {:?}" , idx) ,
848
- } ;
849
-
850
- assert!( idx_place. projection. is_none( ) ) ;
851
- let static_ = match & idx_place. base {
852
- PlaceBase :: Static ( static_) => {
853
- static_
854
- }
855
- PlaceBase :: Local ( _) => panic!( "simd_shuffle* idx is not constant, but a local" ) ,
856
- } ;
857
-
858
- let idx_const = match & static_. kind {
859
- StaticKind :: Static ( _) => unimplemented!( ) ,
860
- StaticKind :: Promoted ( promoted) => {
861
- fx. tcx. const_eval( ParamEnv :: reveal_all( ) . and( GlobalId {
862
- instance: fx. instance,
863
- promoted: Some ( * promoted) ,
864
- } ) ) . unwrap( )
865
- }
866
- } ;
896
+ let idx_const = crate :: constant:: mir_operand_get_const_val( fx, idx) . expect( "simd_shuffle* idx not const" ) ;
867
897
868
898
let idx_bytes = match idx_const. val {
869
899
ConstValue :: ByRef { align: _, offset, alloc } => {
@@ -900,41 +930,38 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
900
930
} ;
901
931
902
932
simd_add, ( c x, c y) {
903
- simd_binop !( fx, intrinsic, iadd( x, y) -> ret) ;
933
+ simd_int_flt_binop !( fx, intrinsic, iadd|fadd ( x, y) -> ret) ;
904
934
} ;
905
935
simd_sub, ( c x, c y) {
906
- simd_binop !( fx, intrinsic, isub( x, y) -> ret) ;
936
+ simd_int_flt_binop !( fx, intrinsic, isub|fsub ( x, y) -> ret) ;
907
937
} ;
908
938
simd_mul, ( c x, c y) {
909
- simd_binop !( fx, intrinsic, imul( x, y) -> ret) ;
939
+ simd_int_flt_binop !( fx, intrinsic, imul|fmul ( x, y) -> ret) ;
910
940
} ;
911
941
simd_div, ( c x, c y) {
912
- simd_binop!( fx, intrinsic, udiv|sdiv( x, y) -> ret) ;
913
- } ;
914
- simd_rem, ( c x, c y) {
915
- simd_binop!( fx, intrinsic, urem|srem( x, y) -> ret) ;
942
+ simd_int_flt_binop!( fx, intrinsic, udiv|sdiv|fdiv( x, y) -> ret) ;
916
943
} ;
917
944
simd_shl, ( c x, c y) {
918
- simd_binop !( fx, intrinsic, ishl( x, y) -> ret) ;
945
+ simd_int_binop !( fx, intrinsic, ishl( x, y) -> ret) ;
919
946
} ;
920
947
simd_shr, ( c x, c y) {
921
- simd_binop !( fx, intrinsic, ushr|sshr( x, y) -> ret) ;
948
+ simd_int_binop !( fx, intrinsic, ushr|sshr( x, y) -> ret) ;
922
949
} ;
923
950
simd_and, ( c x, c y) {
924
- simd_binop !( fx, intrinsic, band( x, y) -> ret) ;
951
+ simd_int_binop !( fx, intrinsic, band( x, y) -> ret) ;
925
952
} ;
926
953
simd_or, ( c x, c y) {
927
- simd_binop !( fx, intrinsic, bor( x, y) -> ret) ;
954
+ simd_int_binop !( fx, intrinsic, bor( x, y) -> ret) ;
928
955
} ;
929
956
simd_xor, ( c x, c y) {
930
- simd_binop !( fx, intrinsic, bxor( x, y) -> ret) ;
957
+ simd_int_binop !( fx, intrinsic, bxor( x, y) -> ret) ;
931
958
} ;
932
959
933
960
simd_fmin, ( c x, c y) {
934
- simd_binop !( fx, intrinsic, fmin( x, y) -> ret) ;
961
+ simd_flt_binop !( fx, intrinsic, fmin( x, y) -> ret) ;
935
962
} ;
936
963
simd_fmax, ( c x, c y) {
937
- simd_binop !( fx, intrinsic, fmax( x, y) -> ret) ;
964
+ simd_flt_binop !( fx, intrinsic, fmax( x, y) -> ret) ;
938
965
} ;
939
966
}
940
967
0 commit comments