@@ -17,54 +17,6 @@ fn report_simd_type_validation_error(
1717 crate :: trap:: trap_unreachable ( fx, "compilation should not have succeeded" ) ;
1818}
1919
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-
6820pub ( super ) fn codegen_simd_intrinsic_call < ' tcx > (
6921 fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
7022 intrinsic : Symbol ,
@@ -142,6 +94,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
14294 ( ty:: Float ( _) , sym:: simd_ge) => {
14395 fx. bcx. ins( ) . fcmp( FloatCC :: GreaterThanOrEqual , x_lane, y_lane)
14496 }
97+
14598 _ => unreachable!( ) ,
14699 } ;
147100
@@ -327,17 +280,34 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
327280 } ) ;
328281 } ;
329282
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+ } ) ;
341311 } ;
342312 simd_rem, ( c x, c y) {
343313 if !x. layout( ) . ty. is_simd( ) {
@@ -365,20 +335,31 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
365335 }
366336 } ) ;
367337 } ;
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+ } ) ;
382363 } ;
383364
384365 simd_fma, ( c a, c b, c c) {
@@ -407,11 +388,24 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
407388 }
408389 } ;
409390
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+ } ) ;
415409 } ;
416410
417411 simd_round, ( c a) {
0 commit comments