@@ -17,28 +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_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
-
42
20
macro simd_int_binop ( $fx: expr, $intrinsic: ident, $span: ident, $op_u: ident|$op_s: ident( $x: ident, $y: ident) -> $ret: ident) {
43
21
if !$x. layout ( ) . ty . is_simd ( ) {
44
22
report_simd_type_validation_error ( $fx, $intrinsic, $span, $x. layout ( ) . ty ) ;
@@ -117,29 +95,61 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
117
95
} ) ;
118
96
} ;
119
97
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
+ } ) ;
143
153
} ;
144
154
145
155
// simd_shuffle32<T, U>(x: T, y: T, idx: [u32; 32]) -> U
0 commit comments