@@ -17,54 +17,6 @@ fn report_simd_type_validation_error(
17
17
crate :: trap:: trap_unreachable ( fx, "compilation should not have succeeded" ) ;
18
18
}
19
19
20
- macro simd_int_binop ( $fx: expr, $intrinsic: ident, $span: ident, $op_u: ident|$op_s: ident( $x: ident, $y: ident) -> $ret: ident) {
21
- if !$x. layout ( ) . ty . is_simd ( ) {
22
- report_simd_type_validation_error ( $fx, $intrinsic, $span, $x. layout ( ) . ty ) ;
23
- return ;
24
- }
25
-
26
- // FIXME use vector instructions when possible
27
- simd_pair_for_each_lane ( $fx, $x, $y, $ret, & |fx, lane_ty, _ret_lane_ty, x_lane, y_lane| {
28
- match lane_ty. kind ( ) {
29
- ty:: Uint ( _) => fx. bcx . ins ( ) . $op_u( x_lane, y_lane) ,
30
- ty:: Int ( _) => fx. bcx . ins ( ) . $op_s( x_lane, y_lane) ,
31
- _ => unreachable ! ( "{:?}" , lane_ty) ,
32
- }
33
- } ) ;
34
- }
35
-
36
- macro simd_int_flt_binop ( $fx: expr, $intrinsic: ident, $span: ident, $op_u: ident|$op_s: ident|$op_f: ident( $x: ident, $y: ident) -> $ret: ident) {
37
- if !$x. layout ( ) . ty . is_simd ( ) {
38
- report_simd_type_validation_error ( $fx, $intrinsic, $span, $x. layout ( ) . ty ) ;
39
- return ;
40
- }
41
-
42
- // FIXME use vector instructions when possible
43
- simd_pair_for_each_lane ( $fx, $x, $y, $ret, & |fx, lane_ty, _ret_lane_ty, x_lane, y_lane| {
44
- match lane_ty. kind ( ) {
45
- ty:: Uint ( _) => fx. bcx . ins ( ) . $op_u( x_lane, y_lane) ,
46
- ty:: Int ( _) => fx. bcx . ins ( ) . $op_s( x_lane, y_lane) ,
47
- ty:: Float ( _) => fx. bcx . ins ( ) . $op_f( x_lane, y_lane) ,
48
- _ => unreachable ! ( "{:?}" , lane_ty) ,
49
- }
50
- } ) ;
51
- }
52
-
53
- macro simd_flt_binop ( $fx: expr, $intrinsic: ident, $span: ident, $op: ident( $x: ident, $y: ident) -> $ret: ident) {
54
- if !$x. layout ( ) . ty . is_simd ( ) {
55
- report_simd_type_validation_error ( $fx, $intrinsic, $span, $x. layout ( ) . ty ) ;
56
- return ;
57
- }
58
-
59
- // FIXME use vector instructions when possible
60
- simd_pair_for_each_lane ( $fx, $x, $y, $ret, & |fx, lane_ty, _ret_lane_ty, x_lane, y_lane| {
61
- match lane_ty. kind ( ) {
62
- ty:: Float ( _) => fx. bcx . ins ( ) . $op( x_lane, y_lane) ,
63
- _ => unreachable ! ( "{:?}" , lane_ty) ,
64
- }
65
- } ) ;
66
- }
67
-
68
20
pub ( super ) fn codegen_simd_intrinsic_call < ' tcx > (
69
21
fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
70
22
intrinsic : Symbol ,
@@ -142,6 +94,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
142
94
( ty:: Float ( _) , sym:: simd_ge) => {
143
95
fx. bcx. ins( ) . fcmp( FloatCC :: GreaterThanOrEqual , x_lane, y_lane)
144
96
}
97
+
145
98
_ => unreachable!( ) ,
146
99
} ;
147
100
@@ -327,17 +280,34 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
327
280
} ) ;
328
281
} ;
329
282
330
- simd_add, ( c x, c y) {
331
- simd_int_flt_binop!( fx, intrinsic, span, iadd|iadd|fadd( x, y) -> ret) ;
332
- } ;
333
- simd_sub, ( c x, c y) {
334
- simd_int_flt_binop!( fx, intrinsic, span, isub|isub|fsub( x, y) -> ret) ;
335
- } ;
336
- simd_mul, ( c x, c y) {
337
- simd_int_flt_binop!( fx, intrinsic, span, imul|imul|fmul( x, y) -> ret) ;
338
- } ;
339
- simd_div, ( c x, c y) {
340
- simd_int_flt_binop!( fx, intrinsic, span, udiv|sdiv|fdiv( x, y) -> ret) ;
283
+ simd_add | simd_sub | simd_mul | simd_div, ( c x, c y) {
284
+ if !x. layout( ) . ty. is_simd( ) {
285
+ report_simd_type_validation_error( fx, intrinsic, span, x. layout( ) . ty) ;
286
+ return ;
287
+ }
288
+
289
+ // FIXME use vector instructions when possible
290
+ simd_pair_for_each_lane( fx, x, y, ret, & |fx, lane_ty, _ret_lane_ty, x_lane, y_lane| match (
291
+ lane_ty. kind( ) ,
292
+ intrinsic,
293
+ ) {
294
+ ( ty:: Uint ( _) , sym:: simd_add) => fx. bcx. ins( ) . iadd( x_lane, y_lane) ,
295
+ ( ty:: Uint ( _) , sym:: simd_sub) => fx. bcx. ins( ) . isub( x_lane, y_lane) ,
296
+ ( ty:: Uint ( _) , sym:: simd_mul) => fx. bcx. ins( ) . imul( x_lane, y_lane) ,
297
+ ( ty:: Uint ( _) , sym:: simd_div) => fx. bcx. ins( ) . udiv( x_lane, y_lane) ,
298
+
299
+ ( ty:: Int ( _) , sym:: simd_add) => fx. bcx. ins( ) . iadd( x_lane, y_lane) ,
300
+ ( ty:: Int ( _) , sym:: simd_sub) => fx. bcx. ins( ) . isub( x_lane, y_lane) ,
301
+ ( ty:: Int ( _) , sym:: simd_mul) => fx. bcx. ins( ) . imul( x_lane, y_lane) ,
302
+ ( ty:: Int ( _) , sym:: simd_div) => fx. bcx. ins( ) . sdiv( x_lane, y_lane) ,
303
+
304
+ ( ty:: Float ( _) , sym:: simd_add) => fx. bcx. ins( ) . fadd( x_lane, y_lane) ,
305
+ ( ty:: Float ( _) , sym:: simd_sub) => fx. bcx. ins( ) . fsub( x_lane, y_lane) ,
306
+ ( ty:: Float ( _) , sym:: simd_mul) => fx. bcx. ins( ) . fmul( x_lane, y_lane) ,
307
+ ( ty:: Float ( _) , sym:: simd_div) => fx. bcx. ins( ) . fdiv( x_lane, y_lane) ,
308
+
309
+ _ => unreachable!( ) ,
310
+ } ) ;
341
311
} ;
342
312
simd_rem, ( c x, c y) {
343
313
if !x. layout( ) . ty. is_simd( ) {
@@ -365,20 +335,31 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
365
335
}
366
336
} ) ;
367
337
} ;
368
- simd_shl, ( c x, c y) {
369
- simd_int_binop!( fx, intrinsic, span, ishl|ishl( x, y) -> ret) ;
370
- } ;
371
- simd_shr, ( c x, c y) {
372
- simd_int_binop!( fx, intrinsic, span, ushr|sshr( x, y) -> ret) ;
373
- } ;
374
- simd_and, ( c x, c y) {
375
- simd_int_binop!( fx, intrinsic, span, band|band( x, y) -> ret) ;
376
- } ;
377
- simd_or, ( c x, c y) {
378
- simd_int_binop!( fx, intrinsic, span, bor|bor( x, y) -> ret) ;
379
- } ;
380
- simd_xor, ( c x, c y) {
381
- simd_int_binop!( fx, intrinsic, span, bxor|bxor( x, y) -> ret) ;
338
+ simd_shl | simd_shr | simd_and | simd_or | simd_xor, ( c x, c y) {
339
+ if !x. layout( ) . ty. is_simd( ) {
340
+ report_simd_type_validation_error( fx, intrinsic, span, x. layout( ) . ty) ;
341
+ return ;
342
+ }
343
+
344
+ // FIXME use vector instructions when possible
345
+ simd_pair_for_each_lane( fx, x, y, ret, & |fx, lane_ty, _ret_lane_ty, x_lane, y_lane| match (
346
+ lane_ty. kind( ) ,
347
+ intrinsic,
348
+ ) {
349
+ ( ty:: Uint ( _) , sym:: simd_shl) => fx. bcx. ins( ) . ishl( x_lane, y_lane) ,
350
+ ( ty:: Uint ( _) , sym:: simd_shr) => fx. bcx. ins( ) . ushr( x_lane, y_lane) ,
351
+ ( ty:: Uint ( _) , sym:: simd_and) => fx. bcx. ins( ) . band( x_lane, y_lane) ,
352
+ ( ty:: Uint ( _) , sym:: simd_or) => fx. bcx. ins( ) . bor( x_lane, y_lane) ,
353
+ ( ty:: Uint ( _) , sym:: simd_xor) => fx. bcx. ins( ) . bxor( x_lane, y_lane) ,
354
+
355
+ ( ty:: Int ( _) , sym:: simd_shl) => fx. bcx. ins( ) . ishl( x_lane, y_lane) ,
356
+ ( ty:: Int ( _) , sym:: simd_shr) => fx. bcx. ins( ) . sshr( x_lane, y_lane) ,
357
+ ( ty:: Int ( _) , sym:: simd_and) => fx. bcx. ins( ) . band( x_lane, y_lane) ,
358
+ ( ty:: Int ( _) , sym:: simd_or) => fx. bcx. ins( ) . bor( x_lane, y_lane) ,
359
+ ( ty:: Int ( _) , sym:: simd_xor) => fx. bcx. ins( ) . bxor( x_lane, y_lane) ,
360
+
361
+ _ => unreachable!( ) ,
362
+ } ) ;
382
363
} ;
383
364
384
365
simd_fma, ( c a, c b, c c) {
@@ -407,11 +388,24 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
407
388
}
408
389
} ;
409
390
410
- simd_fmin, ( c x, c y) {
411
- simd_flt_binop!( fx, intrinsic, span, fmin( x, y) -> ret) ;
412
- } ;
413
- simd_fmax, ( c x, c y) {
414
- simd_flt_binop!( fx, intrinsic, span, fmax( x, y) -> ret) ;
391
+ simd_fmin | simd_fmax, ( c x, c y) {
392
+ if !x. layout( ) . ty. is_simd( ) {
393
+ report_simd_type_validation_error( fx, intrinsic, span, x. layout( ) . ty) ;
394
+ return ;
395
+ }
396
+
397
+ // FIXME use vector instructions when possible
398
+ simd_pair_for_each_lane( fx, x, y, ret, & |fx, lane_ty, _ret_lane_ty, x_lane, y_lane| {
399
+ match lane_ty. kind( ) {
400
+ ty:: Float ( _) => { } ,
401
+ _ => unreachable!( "{:?}" , lane_ty) ,
402
+ }
403
+ match intrinsic {
404
+ sym:: simd_fmin => fx. bcx. ins( ) . fmin( x_lane, y_lane) ,
405
+ sym:: simd_fmax => fx. bcx. ins( ) . fmax( x_lane, y_lane) ,
406
+ _ => unreachable!( ) ,
407
+ }
408
+ } ) ;
415
409
} ;
416
410
417
411
simd_round, ( c a) {
0 commit comments