@@ -130,108 +130,34 @@ impl<'ll, 'tcx> Deref for Builder<'_, 'll, 'tcx> {
130
130
}
131
131
}
132
132
133
- macro_rules! math_builder_methods {
134
- ( $( $name: ident( $( $arg: ident) ,* ) => $llvm_capi: ident) ,+ $( , ) ?) => {
135
- $( fn $name( & mut self , $( $arg: & ' ll Value ) ,* ) -> & ' ll Value {
136
- // Check if we're dealing with 128-bit integers and need emulation
137
- #[ allow( unused_variables) ]
138
- let needs_i128_emulation = false $( || self . is_i128( $arg) ) * ;
139
-
140
- if needs_i128_emulation {
141
-
142
- // Collect arguments into a vector for easier handling
143
- let args_vec: Vec <& ' ll Value > = vec![ $( $arg) ,* ] ;
144
-
145
- // Dispatch to i128 emulation or `compiler_builtins`-based intrinsic
146
- match stringify!( $name) {
147
- "add" | "unchecked_uadd" | "unchecked_sadd" => {
148
- assert_eq!( args_vec. len( ) , 2 ) ;
149
- return self . emulate_i128_add( args_vec[ 0 ] , args_vec[ 1 ] ) ;
150
- }
151
- "sub" | "unchecked_usub" | "unchecked_ssub" => {
152
- assert_eq!( args_vec. len( ) , 2 ) ;
153
- return self . emulate_i128_sub( args_vec[ 0 ] , args_vec[ 1 ] ) ;
154
- }
155
- "mul" | "unchecked_umul" | "unchecked_smul" => {
156
- assert_eq!( args_vec. len( ) , 2 ) ;
157
- return self . call_intrinsic( "__nvvm_multi3" , & [ args_vec[ 0 ] , args_vec[ 1 ] ] ) ;
158
- }
159
- "and" => {
160
- assert_eq!( args_vec. len( ) , 2 ) ;
161
- return self . emulate_i128_and( args_vec[ 0 ] , args_vec[ 1 ] ) ;
162
- }
163
- "or" => {
164
- assert_eq!( args_vec. len( ) , 2 ) ;
165
- return self . emulate_i128_or( args_vec[ 0 ] , args_vec[ 1 ] ) ;
166
- }
167
- "xor" => {
168
- assert_eq!( args_vec. len( ) , 2 ) ;
169
- return self . emulate_i128_xor( args_vec[ 0 ] , args_vec[ 1 ] ) ;
170
- }
171
- "shl" => {
172
- assert_eq!( args_vec. len( ) , 2 ) ;
173
- // Convert shift amount to i32 for compiler-builtins
174
- let shift_amt = self . trunc( args_vec[ 1 ] , self . type_i32( ) ) ;
175
- return self . call_intrinsic( "__nvvm_ashlti3" , & [ args_vec[ 0 ] , shift_amt] ) ;
176
- }
177
- "lshr" => {
178
- assert_eq!( args_vec. len( ) , 2 ) ;
179
- // Convert shift amount to i32 for compiler-builtins
180
- let shift_amt = self . trunc( args_vec[ 1 ] , self . type_i32( ) ) ;
181
- return self . call_intrinsic( "__nvvm_lshrti3" , & [ args_vec[ 0 ] , shift_amt] ) ;
182
- }
183
- "ashr" => {
184
- assert_eq!( args_vec. len( ) , 2 ) ;
185
- // Convert shift amount to i32 for compiler-builtins
186
- let shift_amt = self . trunc( args_vec[ 1 ] , self . type_i32( ) ) ;
187
- return self . call_intrinsic( "__nvvm_ashrti3" , & [ args_vec[ 0 ] , shift_amt] ) ;
188
- }
189
- "neg" => {
190
- assert_eq!( args_vec. len( ) , 1 ) ;
191
- return self . emulate_i128_neg( args_vec[ 0 ] ) ;
192
- }
193
- "not" => {
194
- assert_eq!( args_vec. len( ) , 1 ) ;
195
- return self . emulate_i128_not( args_vec[ 0 ] ) ;
196
- }
197
- "udiv" | "exactudiv" => {
198
- assert_eq!( args_vec. len( ) , 2 ) ;
199
- return self . call_intrinsic( "__nvvm_udivti3" , & [ args_vec[ 0 ] , args_vec[ 1 ] ] ) ;
200
- }
201
- "sdiv" | "exactsdiv" => {
202
- assert_eq!( args_vec. len( ) , 2 ) ;
203
- return self . call_intrinsic( "__nvvm_divti3" , & [ args_vec[ 0 ] , args_vec[ 1 ] ] ) ;
204
- }
205
- "urem" => {
206
- assert_eq!( args_vec. len( ) , 2 ) ;
207
- return self . call_intrinsic( "__nvvm_umodti3" , & [ args_vec[ 0 ] , args_vec[ 1 ] ] ) ;
208
- }
209
- "srem" => {
210
- assert_eq!( args_vec. len( ) , 2 ) ;
211
- return self . call_intrinsic( "__nvvm_modti3" , & [ args_vec[ 0 ] , args_vec[ 1 ] ] ) ;
212
- }
213
- _ => {
214
- self . cx. fatal( format!(
215
- "Unimplemented 128-bit integer operation '{}' with {} arguments. \
216
- This operation is not yet supported in Rust CUDA. \
217
- Consider using 64-bit integers or filing an issue at \
218
- https://github.com/Rust-GPU/rust-cuda/issues",
219
- stringify!( $name) ,
220
- args_vec. len( )
221
- ) ) ;
222
- }
133
+ macro_rules! imath_builder_methods {
134
+ ( $( $self_: ident. $name: ident( $( $arg: ident) ,* ) => $llvm_capi: ident => $op: block) +) => {
135
+ $( fn $name( & mut $self_, $( $arg: & ' ll Value ) ,* ) -> & ' ll Value {
136
+ // Dispatch to i128 emulation or `compiler_builtins`-based intrinsic
137
+ if $( $self_. is_i128( $arg) ) ||*
138
+ $op
139
+ else {
140
+ unsafe {
141
+ trace!( "binary expr: {:?} with args {:?}" , stringify!( $name) , [ $( $arg) ,* ] ) ;
142
+ llvm:: $llvm_capi( $self_. llbuilder, $( $arg, ) * UNNAMED )
223
143
}
224
144
}
145
+ } ) +
146
+ }
147
+ }
225
148
149
+ macro_rules! fmath_builder_methods {
150
+ ( $( $self_: ident. $name: ident( $( $arg: ident) ,* ) => $llvm_capi: ident) +) => {
151
+ $( fn $name( & mut $self_, $( $arg: & ' ll Value ) ,* ) -> & ' ll Value {
226
152
unsafe {
227
153
trace!( "binary expr: {:?} with args {:?}" , stringify!( $name) , [ $( $arg) ,* ] ) ;
228
- llvm:: $llvm_capi( self . llbuilder, $( $arg, ) * UNNAMED )
154
+ llvm:: $llvm_capi( $self_ . llbuilder, $( $arg, ) * UNNAMED )
229
155
}
230
156
} ) +
231
157
}
232
158
}
233
159
234
- macro_rules! set_math_builder_methods {
160
+ macro_rules! set_fmath_builder_methods {
235
161
( $( $name: ident( $( $arg: ident) ,* ) => ( $llvm_capi: ident, $llvm_set_math: ident) ) ,+ $( , ) ?) => {
236
162
$( fn $name( & mut self , $( $arg: & ' ll Value ) ,* ) -> & ' ll Value {
237
163
unsafe {
@@ -384,39 +310,66 @@ impl<'ll, 'tcx, 'a> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
384
310
}
385
311
}
386
312
387
- math_builder_methods ! {
388
- add( a, b) => LLVMBuildAdd ,
389
- fadd( a, b) => LLVMBuildFAdd ,
390
- sub( a, b) => LLVMBuildSub ,
391
- fsub( a, b) => LLVMBuildFSub ,
392
- mul( a, b) => LLVMBuildMul ,
393
- fmul( a, b) => LLVMBuildFMul ,
394
- udiv( a, b) => LLVMBuildUDiv ,
395
- exactudiv( a, b) => LLVMBuildExactUDiv ,
396
- sdiv( a, b) => LLVMBuildSDiv ,
397
- exactsdiv( a, b) => LLVMBuildExactSDiv ,
398
- fdiv( a, b) => LLVMBuildFDiv ,
399
- urem( a, b) => LLVMBuildURem ,
400
- srem( a, b) => LLVMBuildSRem ,
401
- frem( a, b) => LLVMBuildFRem ,
402
- shl( a, b) => LLVMBuildShl ,
403
- lshr( a, b) => LLVMBuildLShr ,
404
- ashr( a, b) => LLVMBuildAShr ,
405
- and( a, b) => LLVMBuildAnd ,
406
- or( a, b) => LLVMBuildOr ,
407
- xor( a, b) => LLVMBuildXor ,
408
- neg( x) => LLVMBuildNeg ,
409
- fneg( x) => LLVMBuildFNeg ,
410
- not( x) => LLVMBuildNot ,
411
- unchecked_sadd( x, y) => LLVMBuildNSWAdd ,
412
- unchecked_uadd( x, y) => LLVMBuildNUWAdd ,
413
- unchecked_ssub( x, y) => LLVMBuildNSWSub ,
414
- unchecked_usub( x, y) => LLVMBuildNUWSub ,
415
- unchecked_smul( x, y) => LLVMBuildNSWMul ,
416
- unchecked_umul( x, y) => LLVMBuildNUWMul ,
417
- }
418
-
419
- set_math_builder_methods ! {
313
+ imath_builder_methods ! {
314
+ self . add( a, b) => LLVMBuildAdd => { self . emulate_i128_add( a, b) }
315
+ self . unchecked_uadd( a, b) => LLVMBuildNUWAdd => { self . emulate_i128_add( a, b) }
316
+ self . unchecked_sadd( a, b) => LLVMBuildNSWAdd => { self . emulate_i128_add( a, b) }
317
+
318
+ self . sub( a, b) => LLVMBuildSub => { self . emulate_i128_sub( a, b) }
319
+ self . unchecked_usub( a, b) => LLVMBuildNUWSub => { self . emulate_i128_sub( a, b) }
320
+ self . unchecked_ssub( a, b) => LLVMBuildNSWSub => { self . emulate_i128_sub( a, b) }
321
+
322
+ self . mul( a, b) => LLVMBuildMul => { self . call_intrinsic( "__nvvm_multi3" , & [ a, b] ) }
323
+ self . unchecked_umul( a, b) => LLVMBuildNUWMul => {
324
+ self . call_intrinsic( "__nvvm_multi3" , & [ a, b] )
325
+ }
326
+ self . unchecked_smul( a, b) => LLVMBuildNSWMul => {
327
+ self . call_intrinsic( "__nvvm_multi3" , & [ a, b] )
328
+ }
329
+
330
+ self . udiv( a, b) => LLVMBuildUDiv => { self . call_intrinsic( "__nvvm_udivti3" , & [ a, b] ) }
331
+ self . exactudiv( a, b) => LLVMBuildExactUDiv => {
332
+ self . call_intrinsic( "__nvvm_udivti3" , & [ a, b] )
333
+ }
334
+ self . sdiv( a, b) => LLVMBuildSDiv => { self . call_intrinsic( "__nvvm_divti3" , & [ a, b] ) }
335
+ self . exactsdiv( a, b) => LLVMBuildExactSDiv => {
336
+ self . call_intrinsic( "__nvvm_divti3" , & [ a, b] )
337
+ }
338
+ self . urem( a, b) => LLVMBuildURem => { self . call_intrinsic( "__nvvm_umodti3" , & [ a, b] ) }
339
+ self . srem( a, b) => LLVMBuildSRem => { self . call_intrinsic( "__nvvm_modti3" , & [ a, b] ) }
340
+
341
+ self . shl( a, b) => LLVMBuildShl => {
342
+ // Convert shift amount to i32 for compiler-builtins.
343
+ let b = self . trunc( b, self . type_i32( ) ) ;
344
+ self . call_intrinsic( "__nvvm_ashlti3" , & [ a, b] )
345
+ }
346
+ self . lshr( a, b) => LLVMBuildLShr => {
347
+ // Convert shift amount to i32 for compiler-builtins.
348
+ let b = self . trunc( b, self . type_i32( ) ) ;
349
+ self . call_intrinsic( "__nvvm_lshrti3" , & [ a, b] )
350
+ }
351
+ self . ashr( a, b) => LLVMBuildAShr => {
352
+ // Convert shift amount to i32 for compiler-builtins.
353
+ let b = self . trunc( b, self . type_i32( ) ) ;
354
+ self . call_intrinsic( "__nvvm_ashrti3" , & [ a, b] )
355
+ }
356
+ self . and( a, b) => LLVMBuildAnd => { self . emulate_i128_and( a, b) }
357
+ self . or( a, b) => LLVMBuildOr => { self . emulate_i128_or( a, b) }
358
+ self . xor( a, b) => LLVMBuildXor => { self . emulate_i128_xor( a, b) }
359
+ self . neg( a) => LLVMBuildNeg => { self . emulate_i128_neg( a) }
360
+ self . not( a) => LLVMBuildNot => { self . emulate_i128_not( a) }
361
+ }
362
+
363
+ fmath_builder_methods ! {
364
+ self . fadd( a, b) => LLVMBuildFAdd
365
+ self . fsub( a, b) => LLVMBuildFSub
366
+ self . fmul( a, b) => LLVMBuildFMul
367
+ self . fdiv( a, b) => LLVMBuildFDiv
368
+ self . frem( a, b) => LLVMBuildFRem
369
+ self . fneg( a) => LLVMBuildFNeg
370
+ }
371
+
372
+ set_fmath_builder_methods ! {
420
373
fadd_fast( x, y) => ( LLVMBuildFAdd , LLVMRustSetFastMath ) ,
421
374
fsub_fast( x, y) => ( LLVMBuildFSub , LLVMRustSetFastMath ) ,
422
375
fmul_fast( x, y) => ( LLVMBuildFMul , LLVMRustSetFastMath ) ,
0 commit comments