@@ -251,41 +251,41 @@ fn codegen_float_intrinsic_call<'tcx>(
251
251
args : & [ mir:: Operand < ' tcx > ] ,
252
252
ret : CPlace < ' tcx > ,
253
253
) -> bool {
254
- let ( name, arg_count, ty) = match intrinsic {
255
- sym:: expf32 => ( "expf" , 1 , fx. tcx . types . f32 ) ,
256
- sym:: expf64 => ( "exp" , 1 , fx. tcx . types . f64 ) ,
257
- sym:: exp2f32 => ( "exp2f" , 1 , fx. tcx . types . f32 ) ,
258
- sym:: exp2f64 => ( "exp2" , 1 , fx. tcx . types . f64 ) ,
259
- sym:: sqrtf32 => ( "sqrtf" , 1 , fx. tcx . types . f32 ) ,
260
- sym:: sqrtf64 => ( "sqrt" , 1 , fx. tcx . types . f64 ) ,
261
- sym:: powif32 => ( "__powisf2" , 2 , fx. tcx . types . f32 ) , // compiler-builtins
262
- sym:: powif64 => ( "__powidf2" , 2 , fx. tcx . types . f64 ) , // compiler-builtins
263
- sym:: powf32 => ( "powf" , 2 , fx. tcx . types . f32 ) ,
264
- sym:: powf64 => ( "pow" , 2 , fx. tcx . types . f64 ) ,
265
- sym:: logf32 => ( "logf" , 1 , fx. tcx . types . f32 ) ,
266
- sym:: logf64 => ( "log" , 1 , fx. tcx . types . f64 ) ,
267
- sym:: log2f32 => ( "log2f" , 1 , fx. tcx . types . f32 ) ,
268
- sym:: log2f64 => ( "log2" , 1 , fx. tcx . types . f64 ) ,
269
- sym:: log10f32 => ( "log10f" , 1 , fx. tcx . types . f32 ) ,
270
- sym:: log10f64 => ( "log10" , 1 , fx. tcx . types . f64 ) ,
271
- sym:: fabsf32 => ( "fabsf" , 1 , fx. tcx . types . f32 ) ,
272
- sym:: fabsf64 => ( "fabs" , 1 , fx. tcx . types . f64 ) ,
273
- sym:: fmaf32 => ( "fmaf" , 3 , fx. tcx . types . f32 ) ,
274
- sym:: fmaf64 => ( "fma" , 3 , fx. tcx . types . f64 ) ,
275
- sym:: copysignf32 => ( "copysignf" , 2 , fx. tcx . types . f32 ) ,
276
- sym:: copysignf64 => ( "copysign" , 2 , fx. tcx . types . f64 ) ,
277
- sym:: floorf32 => ( "floorf" , 1 , fx. tcx . types . f32 ) ,
278
- sym:: floorf64 => ( "floor" , 1 , fx. tcx . types . f64 ) ,
279
- sym:: ceilf32 => ( "ceilf" , 1 , fx. tcx . types . f32 ) ,
280
- sym:: ceilf64 => ( "ceil" , 1 , fx. tcx . types . f64 ) ,
281
- sym:: truncf32 => ( "truncf" , 1 , fx. tcx . types . f32 ) ,
282
- sym:: truncf64 => ( "trunc" , 1 , fx. tcx . types . f64 ) ,
283
- sym:: roundf32 => ( "roundf" , 1 , fx. tcx . types . f32 ) ,
284
- sym:: roundf64 => ( "round" , 1 , fx. tcx . types . f64 ) ,
285
- sym:: sinf32 => ( "sinf" , 1 , fx. tcx . types . f32 ) ,
286
- sym:: sinf64 => ( "sin" , 1 , fx. tcx . types . f64 ) ,
287
- sym:: cosf32 => ( "cosf" , 1 , fx. tcx . types . f32 ) ,
288
- sym:: cosf64 => ( "cos" , 1 , fx. tcx . types . f64 ) ,
254
+ let ( name, arg_count, ty, clif_ty ) = match intrinsic {
255
+ sym:: expf32 => ( "expf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
256
+ sym:: expf64 => ( "exp" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
257
+ sym:: exp2f32 => ( "exp2f" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
258
+ sym:: exp2f64 => ( "exp2" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
259
+ sym:: sqrtf32 => ( "sqrtf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
260
+ sym:: sqrtf64 => ( "sqrt" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
261
+ sym:: powif32 => ( "__powisf2" , 2 , fx. tcx . types . f32 , types :: F32 ) , // compiler-builtins
262
+ sym:: powif64 => ( "__powidf2" , 2 , fx. tcx . types . f64 , types :: F64 ) , // compiler-builtins
263
+ sym:: powf32 => ( "powf" , 2 , fx. tcx . types . f32 , types :: F32 ) ,
264
+ sym:: powf64 => ( "pow" , 2 , fx. tcx . types . f64 , types :: F64 ) ,
265
+ sym:: logf32 => ( "logf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
266
+ sym:: logf64 => ( "log" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
267
+ sym:: log2f32 => ( "log2f" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
268
+ sym:: log2f64 => ( "log2" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
269
+ sym:: log10f32 => ( "log10f" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
270
+ sym:: log10f64 => ( "log10" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
271
+ sym:: fabsf32 => ( "fabsf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
272
+ sym:: fabsf64 => ( "fabs" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
273
+ sym:: fmaf32 => ( "fmaf" , 3 , fx. tcx . types . f32 , types :: F32 ) ,
274
+ sym:: fmaf64 => ( "fma" , 3 , fx. tcx . types . f64 , types :: F64 ) ,
275
+ sym:: copysignf32 => ( "copysignf" , 2 , fx. tcx . types . f32 , types :: F32 ) ,
276
+ sym:: copysignf64 => ( "copysign" , 2 , fx. tcx . types . f64 , types :: F64 ) ,
277
+ sym:: floorf32 => ( "floorf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
278
+ sym:: floorf64 => ( "floor" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
279
+ sym:: ceilf32 => ( "ceilf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
280
+ sym:: ceilf64 => ( "ceil" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
281
+ sym:: truncf32 => ( "truncf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
282
+ sym:: truncf64 => ( "trunc" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
283
+ sym:: roundf32 => ( "roundf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
284
+ sym:: roundf64 => ( "round" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
285
+ sym:: sinf32 => ( "sinf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
286
+ sym:: sinf64 => ( "sin" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
287
+ sym:: cosf32 => ( "cosf" , 1 , fx. tcx . types . f32 , types :: F32 ) ,
288
+ sym:: cosf64 => ( "cos" , 1 , fx. tcx . types . f64 , types :: F64 ) ,
289
289
_ => return false ,
290
290
} ;
291
291
@@ -296,15 +296,19 @@ fn codegen_float_intrinsic_call<'tcx>(
296
296
let ( a, b, c) ;
297
297
let args = match args {
298
298
[ x] => {
299
- a = [ codegen_operand ( fx, x) ] ;
299
+ a = [ codegen_operand ( fx, x) . load_scalar ( fx ) ] ;
300
300
& a as & [ _ ]
301
301
}
302
302
[ x, y] => {
303
- b = [ codegen_operand ( fx, x) , codegen_operand ( fx, y) ] ;
303
+ b = [ codegen_operand ( fx, x) . load_scalar ( fx ) , codegen_operand ( fx, y) . load_scalar ( fx ) ] ;
304
304
& b
305
305
}
306
306
[ x, y, z] => {
307
- c = [ codegen_operand ( fx, x) , codegen_operand ( fx, y) , codegen_operand ( fx, z) ] ;
307
+ c = [
308
+ codegen_operand ( fx, x) . load_scalar ( fx) ,
309
+ codegen_operand ( fx, y) . load_scalar ( fx) ,
310
+ codegen_operand ( fx, z) . load_scalar ( fx) ,
311
+ ] ;
308
312
& c
309
313
}
310
314
_ => unreachable ! ( ) ,
@@ -313,15 +317,10 @@ fn codegen_float_intrinsic_call<'tcx>(
313
317
let layout = fx. layout_of ( ty) ;
314
318
let res = match intrinsic {
315
319
sym:: fmaf32 | sym:: fmaf64 => {
316
- let a = args[ 0 ] . load_scalar ( fx) ;
317
- let b = args[ 1 ] . load_scalar ( fx) ;
318
- let c = args[ 2 ] . load_scalar ( fx) ;
319
- CValue :: by_val ( fx. bcx . ins ( ) . fma ( a, b, c) , layout)
320
+ CValue :: by_val ( fx. bcx . ins ( ) . fma ( args[ 0 ] , args[ 1 ] , args[ 2 ] ) , layout)
320
321
}
321
322
sym:: copysignf32 | sym:: copysignf64 => {
322
- let a = args[ 0 ] . load_scalar ( fx) ;
323
- let b = args[ 1 ] . load_scalar ( fx) ;
324
- CValue :: by_val ( fx. bcx . ins ( ) . fcopysign ( a, b) , layout)
323
+ CValue :: by_val ( fx. bcx . ins ( ) . fcopysign ( args[ 0 ] , args[ 1 ] ) , layout)
325
324
}
326
325
sym:: fabsf32
327
326
| sym:: fabsf64
@@ -331,21 +330,29 @@ fn codegen_float_intrinsic_call<'tcx>(
331
330
| sym:: ceilf64
332
331
| sym:: truncf32
333
332
| sym:: truncf64 => {
334
- let a = args[ 0 ] . load_scalar ( fx) ;
335
-
336
333
let val = match intrinsic {
337
- sym:: fabsf32 | sym:: fabsf64 => fx. bcx . ins ( ) . fabs ( a ) ,
338
- sym:: floorf32 | sym:: floorf64 => fx. bcx . ins ( ) . floor ( a ) ,
339
- sym:: ceilf32 | sym:: ceilf64 => fx. bcx . ins ( ) . ceil ( a ) ,
340
- sym:: truncf32 | sym:: truncf64 => fx. bcx . ins ( ) . trunc ( a ) ,
334
+ sym:: fabsf32 | sym:: fabsf64 => fx. bcx . ins ( ) . fabs ( args [ 0 ] ) ,
335
+ sym:: floorf32 | sym:: floorf64 => fx. bcx . ins ( ) . floor ( args [ 0 ] ) ,
336
+ sym:: ceilf32 | sym:: ceilf64 => fx. bcx . ins ( ) . ceil ( args [ 0 ] ) ,
337
+ sym:: truncf32 | sym:: truncf64 => fx. bcx . ins ( ) . trunc ( args [ 0 ] ) ,
341
338
_ => unreachable ! ( ) ,
342
339
} ;
343
340
344
341
CValue :: by_val ( val, layout)
345
342
}
343
+
346
344
// These intrinsics aren't supported natively by Cranelift.
347
345
// Lower them to a libcall.
348
- _ => fx. easy_call ( name, & args, ty) ,
346
+ sym:: powif32 | sym:: powif64 => {
347
+ let input_tys: Vec < _ > = vec ! [ AbiParam :: new( clif_ty) , AbiParam :: new( types:: I32 ) ] ;
348
+ let ret_val = fx. lib_call ( name, input_tys, vec ! [ AbiParam :: new( clif_ty) ] , & args) [ 0 ] ;
349
+ CValue :: by_val ( ret_val, fx. layout_of ( ty) )
350
+ }
351
+ _ => {
352
+ let input_tys: Vec < _ > = args. iter ( ) . map ( |_| AbiParam :: new ( clif_ty) ) . collect ( ) ;
353
+ let ret_val = fx. lib_call ( name, input_tys, vec ! [ AbiParam :: new( clif_ty) ] , & args) [ 0 ] ;
354
+ CValue :: by_val ( ret_val, fx. layout_of ( ty) )
355
+ }
349
356
} ;
350
357
351
358
ret. write_cvalue ( fx, res) ;
0 commit comments