@@ -141,6 +141,72 @@ macro_rules! simple_op {
141
141
} ;
142
142
}
143
143
144
+ // shl and shr allow different types as their operands
145
+ macro_rules! simple_shift_op {
146
+ (
147
+ $func_name: ident
148
+ $( , int: $inst_int: ident) ?
149
+ $( , uint: $inst_uint: ident) ?
150
+ $( , sint: $inst_sint: ident) ?
151
+ $( , fold_const {
152
+ $( int( $int_lhs: ident, $int_rhs: ident) => $fold_int: expr; ) ?
153
+ $( uint( $uint_lhs: ident, $uint_rhs: ident) => $fold_uint: expr; ) ?
154
+ $( sint( $sint_lhs: ident, $sint_rhs: ident) => $fold_sint: expr; ) ?
155
+ } ) ?
156
+ ) => {
157
+ fn $func_name( & mut self , lhs: Self :: Value , rhs: Self :: Value ) -> Self :: Value {
158
+ let result_type = lhs. ty;
159
+
160
+ $(
161
+ #[ allow( unreachable_patterns, clippy:: collapsible_match) ]
162
+ if let Some ( const_lhs) = self . try_get_const_value( lhs)
163
+ && let Some ( const_rhs) = self . try_get_const_value( rhs)
164
+ {
165
+ #[ allow( unreachable_patterns) ]
166
+ match ( const_lhs, const_rhs) {
167
+ $(
168
+ ( ConstValue :: Unsigned ( $int_lhs) , ConstValue :: Unsigned ( $int_rhs) ) => return self . const_uint_big( result_type, $fold_int) ,
169
+ ( ConstValue :: Unsigned ( $int_lhs) , ConstValue :: Signed ( $int_rhs) ) => return self . const_uint_big( result_type, $fold_int) ,
170
+ ( ConstValue :: Signed ( $int_lhs) , ConstValue :: Unsigned ( $int_rhs) ) => return self . const_uint_big( result_type, $fold_int as u128 ) ,
171
+ ( ConstValue :: Signed ( $int_lhs) , ConstValue :: Signed ( $int_rhs) ) => return self . const_uint_big( result_type, $fold_int as u128 ) ,
172
+ ) ?
173
+ $(
174
+ ( ConstValue :: Unsigned ( $uint_lhs) , ConstValue :: Unsigned ( $uint_rhs) ) => return self . const_uint_big( result_type, $fold_uint) ,
175
+ ( ConstValue :: Unsigned ( $uint_lhs) , ConstValue :: Signed ( $uint_rhs) ) => return self . const_uint_big( result_type, $fold_uint) ,
176
+ ) ?
177
+ $(
178
+ ( ConstValue :: Signed ( $sint_lhs) , ConstValue :: Unsigned ( $sint_rhs) ) => return self . const_uint_big( result_type, $fold_sint as u128 ) ,
179
+ ( ConstValue :: Signed ( $sint_lhs) , ConstValue :: Signed ( $sint_rhs) ) => return self . const_uint_big( result_type, $fold_sint as u128 ) ,
180
+ ) ?
181
+ _ => ( ) ,
182
+ }
183
+ }
184
+ ) ?
185
+
186
+ match self . lookup_type( result_type) {
187
+ $( SpirvType :: Integer ( _, _) => {
188
+ self . emit( )
189
+ . $inst_int( result_type, None , lhs. def( self ) , rhs. def( self ) )
190
+ } ) ?
191
+ $( SpirvType :: Integer ( _, false ) => {
192
+ self . emit( )
193
+ . $inst_uint( result_type, None , lhs. def( self ) , rhs. def( self ) )
194
+ } ) ?
195
+ $( SpirvType :: Integer ( _, true ) => {
196
+ self . emit( )
197
+ . $inst_sint( result_type, None , lhs. def( self ) , rhs. def( self ) )
198
+ } ) ?
199
+ o => self . fatal( format!(
200
+ concat!( stringify!( $func_name) , "() not implemented for type {}" ) ,
201
+ o. debug( result_type, self )
202
+ ) ) ,
203
+ }
204
+ . unwrap( )
205
+ . with_type( result_type)
206
+ }
207
+ } ;
208
+ }
209
+
144
210
macro_rules! simple_uni_op {
145
211
(
146
212
$func_name: ident
@@ -1533,24 +1599,24 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
1533
1599
simple_op ! { frem_algebraic, float: f_rem} // algebraic=normal
1534
1600
simple_shift_op ! {
1535
1601
shl,
1536
- int: shift_left_logical
1537
- // fold_const {
1538
- // int(a, b) => a.wrapping_shl(b as u32);
1539
- // }
1602
+ int: shift_left_logical,
1603
+ fold_const {
1604
+ int( a, b) => a. wrapping_shl( b as u32 ) ;
1605
+ }
1540
1606
}
1541
1607
simple_shift_op ! {
1542
1608
lshr,
1543
- int : shift_right_logical
1544
- // fold_const {
1545
- // int (a, b) => a.wrapping_shr(b as u32);
1546
- // }
1609
+ uint : shift_right_logical,
1610
+ fold_const {
1611
+ uint ( a, b) => a. wrapping_shr( b as u32 ) ;
1612
+ }
1547
1613
}
1548
1614
simple_shift_op ! {
1549
1615
ashr,
1550
- int : shift_right_arithmetic
1551
- // fold_const {
1552
- // int (a, b) => a.wrapping_shr(b as u32);
1553
- // }
1616
+ sint : shift_right_arithmetic,
1617
+ fold_const {
1618
+ sint ( a, b) => a. wrapping_shr( b as u32 ) ;
1619
+ }
1554
1620
}
1555
1621
simple_uni_op ! {
1556
1622
neg,
0 commit comments