@@ -17,28 +17,6 @@ fn report_simd_type_validation_error(
1717 crate :: trap:: trap_unreachable ( fx, "compilation should not have succeeded" ) ;
1818}
1919
20- macro simd_cmp( $fx: expr, $intrinsic: ident, $span: ident, $cc_u: ident|$cc_s: ident|$cc_f: 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, res_lane_ty, x_lane, y_lane| {
28- let res_lane = match lane_ty. kind ( ) {
29- ty:: Uint ( _) => fx. bcx . ins ( ) . icmp ( IntCC :: $cc_u, x_lane, y_lane) ,
30- ty:: Int ( _) => fx. bcx . ins ( ) . icmp ( IntCC :: $cc_s, x_lane, y_lane) ,
31- ty:: Float ( _) => fx. bcx . ins ( ) . fcmp ( FloatCC :: $cc_f, x_lane, y_lane) ,
32- _ => unreachable ! ( "{:?}" , lane_ty) ,
33- } ;
34-
35- let ty = fx. clif_type ( res_lane_ty) . unwrap ( ) ;
36-
37- let res_lane = fx. bcx . ins ( ) . bint ( ty, res_lane) ;
38- fx. bcx . ins ( ) . ineg ( res_lane)
39- } ) ;
40- }
41-
4220macro simd_int_binop ( $fx: expr, $intrinsic: ident, $span: ident, $op_u: ident|$op_s: ident( $x: ident, $y: ident) -> $ret: ident) {
4321 if !$x. layout ( ) . ty . is_simd ( ) {
4422 report_simd_type_validation_error ( $fx, $intrinsic, $span, $x. layout ( ) . ty ) ;
@@ -117,29 +95,61 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
11795 } ) ;
11896 } ;
11997
120- simd_eq, ( c x, c y) {
121- simd_cmp!( fx, intrinsic, span, Equal |Equal |Equal ( x, y) -> ret) ;
122- } ;
123- simd_ne, ( c x, c y) {
124- simd_cmp!( fx, intrinsic, span, NotEqual |NotEqual |NotEqual ( x, y) -> ret) ;
125- } ;
126- simd_lt, ( c x, c y) {
127- simd_cmp!( fx, intrinsic, span, UnsignedLessThan |SignedLessThan |LessThan ( x, y) -> ret) ;
128- } ;
129- simd_le, ( c x, c y) {
130- simd_cmp!( fx, intrinsic, span, UnsignedLessThanOrEqual |SignedLessThanOrEqual |LessThanOrEqual ( x, y) -> ret) ;
131- } ;
132- simd_gt, ( c x, c y) {
133- simd_cmp!( fx, intrinsic, span, UnsignedGreaterThan |SignedGreaterThan |GreaterThan ( x, y) -> ret) ;
134- } ;
135- simd_ge, ( c x, c y) {
136- simd_cmp!(
137- fx,
138- intrinsic,
139- span,
140- UnsignedGreaterThanOrEqual |SignedGreaterThanOrEqual |GreaterThanOrEqual
141- ( x, y) -> ret
142- ) ;
98+ simd_eq | simd_ne | simd_lt | simd_le | simd_gt | simd_ge, ( c x, c y) {
99+ if !x. layout( ) . ty. is_simd( ) {
100+ report_simd_type_validation_error( fx, intrinsic, span, x. layout( ) . ty) ;
101+ return ;
102+ }
103+
104+ // FIXME use vector instructions when possible
105+ simd_pair_for_each_lane( fx, x, y, ret, & |fx, lane_ty, res_lane_ty, x_lane, y_lane| {
106+ let res_lane = match ( lane_ty. kind( ) , intrinsic) {
107+ ( ty:: Uint ( _) , sym:: simd_eq) => fx. bcx. ins( ) . icmp( IntCC :: Equal , x_lane, y_lane) ,
108+ ( ty:: Uint ( _) , sym:: simd_ne) => fx. bcx. ins( ) . icmp( IntCC :: NotEqual , x_lane, y_lane) ,
109+ ( ty:: Uint ( _) , sym:: simd_lt) => {
110+ fx. bcx. ins( ) . icmp( IntCC :: UnsignedLessThan , x_lane, y_lane)
111+ }
112+ ( ty:: Uint ( _) , sym:: simd_le) => {
113+ fx. bcx. ins( ) . icmp( IntCC :: UnsignedLessThanOrEqual , x_lane, y_lane)
114+ }
115+ ( ty:: Uint ( _) , sym:: simd_gt) => {
116+ fx. bcx. ins( ) . icmp( IntCC :: UnsignedGreaterThan , x_lane, y_lane)
117+ }
118+ ( ty:: Uint ( _) , sym:: simd_ge) => {
119+ fx. bcx. ins( ) . icmp( IntCC :: UnsignedGreaterThanOrEqual , x_lane, y_lane)
120+ }
121+
122+ ( ty:: Int ( _) , sym:: simd_eq) => fx. bcx. ins( ) . icmp( IntCC :: Equal , x_lane, y_lane) ,
123+ ( ty:: Int ( _) , sym:: simd_ne) => fx. bcx. ins( ) . icmp( IntCC :: NotEqual , x_lane, y_lane) ,
124+ ( ty:: Int ( _) , sym:: simd_lt) => fx. bcx. ins( ) . icmp( IntCC :: SignedLessThan , x_lane, y_lane) ,
125+ ( ty:: Int ( _) , sym:: simd_le) => {
126+ fx. bcx. ins( ) . icmp( IntCC :: SignedLessThanOrEqual , x_lane, y_lane)
127+ }
128+ ( ty:: Int ( _) , sym:: simd_gt) => {
129+ fx. bcx. ins( ) . icmp( IntCC :: SignedGreaterThan , x_lane, y_lane)
130+ }
131+ ( ty:: Int ( _) , sym:: simd_ge) => {
132+ fx. bcx. ins( ) . icmp( IntCC :: SignedGreaterThanOrEqual , x_lane, y_lane)
133+ }
134+
135+ ( ty:: Float ( _) , sym:: simd_eq) => fx. bcx. ins( ) . fcmp( FloatCC :: Equal , x_lane, y_lane) ,
136+ ( ty:: Float ( _) , sym:: simd_ne) => fx. bcx. ins( ) . fcmp( FloatCC :: NotEqual , x_lane, y_lane) ,
137+ ( ty:: Float ( _) , sym:: simd_lt) => fx. bcx. ins( ) . fcmp( FloatCC :: LessThan , x_lane, y_lane) ,
138+ ( ty:: Float ( _) , sym:: simd_le) => {
139+ fx. bcx. ins( ) . fcmp( FloatCC :: LessThanOrEqual , x_lane, y_lane)
140+ }
141+ ( ty:: Float ( _) , sym:: simd_gt) => fx. bcx. ins( ) . fcmp( FloatCC :: GreaterThan , x_lane, y_lane) ,
142+ ( ty:: Float ( _) , sym:: simd_ge) => {
143+ fx. bcx. ins( ) . fcmp( FloatCC :: GreaterThanOrEqual , x_lane, y_lane)
144+ }
145+ _ => unreachable!( ) ,
146+ } ;
147+
148+ let ty = fx. clif_type( res_lane_ty) . unwrap( ) ;
149+
150+ let res_lane = fx. bcx. ins( ) . bint( ty, res_lane) ;
151+ fx. bcx. ins( ) . ineg( res_lane)
152+ } ) ;
143153 } ;
144154
145155 // simd_shuffle32<T, U>(x: T, y: T, idx: [u32; 32]) -> U
0 commit comments