@@ -249,8 +249,10 @@ fn bool_to_zero_or_max_uint<'tcx>(
249
249
let ty = fx. clif_type ( ty) . unwrap ( ) ;
250
250
251
251
let int_ty = match ty {
252
+ types:: F16 => types:: I16 ,
252
253
types:: F32 => types:: I32 ,
253
254
types:: F64 => types:: I64 ,
255
+ types:: F128 => types:: I128 ,
254
256
ty => ty,
255
257
} ;
256
258
@@ -309,45 +311,83 @@ fn codegen_float_intrinsic_call<'tcx>(
309
311
ret : CPlace < ' tcx > ,
310
312
) -> bool {
311
313
let ( name, arg_count, ty, clif_ty) = match intrinsic {
314
+ sym:: expf16 => ( "expf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
312
315
sym:: expf32 => ( "expf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
313
316
sym:: expf64 => ( "exp" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
317
+ sym:: expf128 => ( "expf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
318
+ sym:: exp2f16 => ( "exp2f16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
314
319
sym:: exp2f32 => ( "exp2f" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
315
320
sym:: exp2f64 => ( "exp2" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
321
+ sym:: exp2f128 => ( "exp2f128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
322
+ sym:: sqrtf16 => ( "sqrtf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
316
323
sym:: sqrtf32 => ( "sqrtf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
317
324
sym:: sqrtf64 => ( "sqrt" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
325
+ sym:: sqrtf128 => ( "sqrtf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
326
+ sym:: powif16 => ( "__powisf2" , 2 , fx. tcx . types . f16 , types:: F16 ) , // compiler-builtins
318
327
sym:: powif32 => ( "__powisf2" , 2 , fx. tcx . types . f32 , types:: F32 ) , // compiler-builtins
319
328
sym:: powif64 => ( "__powidf2" , 2 , fx. tcx . types . f64 , types:: F64 ) , // compiler-builtins
329
+ sym:: powif128 => ( "__powitf2" , 2 , fx. tcx . types . f128 , types:: F128 ) , // compiler-builtins
330
+ sym:: powf16 => ( "powf16" , 2 , fx. tcx . types . f16 , types:: F16 ) ,
320
331
sym:: powf32 => ( "powf" , 2 , fx. tcx . types . f32 , types:: F32 ) ,
321
332
sym:: powf64 => ( "pow" , 2 , fx. tcx . types . f64 , types:: F64 ) ,
333
+ sym:: powf128 => ( "powf128" , 2 , fx. tcx . types . f128 , types:: F128 ) ,
334
+ sym:: logf16 => ( "logf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
322
335
sym:: logf32 => ( "logf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
323
336
sym:: logf64 => ( "log" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
337
+ sym:: logf128 => ( "logf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
338
+ sym:: log2f16 => ( "log2f16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
324
339
sym:: log2f32 => ( "log2f" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
325
340
sym:: log2f64 => ( "log2" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
341
+ sym:: log2f128 => ( "log2f128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
342
+ sym:: log10f16 => ( "log10f16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
326
343
sym:: log10f32 => ( "log10f" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
327
344
sym:: log10f64 => ( "log10" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
345
+ sym:: log10f128 => ( "log10f128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
346
+ sym:: fabsf16 => ( "fabsf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
328
347
sym:: fabsf32 => ( "fabsf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
329
348
sym:: fabsf64 => ( "fabs" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
349
+ sym:: fabsf128 => ( "fabsf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
350
+ sym:: fmaf16 => ( "fmaf16" , 3 , fx. tcx . types . f16 , types:: F16 ) ,
330
351
sym:: fmaf32 => ( "fmaf" , 3 , fx. tcx . types . f32 , types:: F32 ) ,
331
352
sym:: fmaf64 => ( "fma" , 3 , fx. tcx . types . f64 , types:: F64 ) ,
353
+ sym:: fmaf128 => ( "fmaf128" , 3 , fx. tcx . types . f128 , types:: F128 ) ,
332
354
// FIXME: calling `fma` from libc without FMA target feature uses expensive sofware emulation
355
+ sym:: fmuladdf16 => ( "fmaf16" , 3 , fx. tcx . types . f16 , types:: F16 ) , // TODO: use cranelift intrinsic analogous to llvm.fmuladd.f16
333
356
sym:: fmuladdf32 => ( "fmaf" , 3 , fx. tcx . types . f32 , types:: F32 ) , // TODO: use cranelift intrinsic analogous to llvm.fmuladd.f32
334
357
sym:: fmuladdf64 => ( "fma" , 3 , fx. tcx . types . f64 , types:: F64 ) , // TODO: use cranelift intrinsic analogous to llvm.fmuladd.f64
358
+ sym:: fmuladdf128 => ( "fmaf128" , 3 , fx. tcx . types . f128 , types:: F128 ) , // TODO: use cranelift intrinsic analogous to llvm.fmuladd.f128
359
+ sym:: copysignf16 => ( "copysignf16" , 2 , fx. tcx . types . f16 , types:: F16 ) ,
335
360
sym:: copysignf32 => ( "copysignf" , 2 , fx. tcx . types . f32 , types:: F32 ) ,
336
361
sym:: copysignf64 => ( "copysign" , 2 , fx. tcx . types . f64 , types:: F64 ) ,
362
+ sym:: copysignf128 => ( "copysignf128" , 2 , fx. tcx . types . f128 , types:: F128 ) ,
363
+ sym:: floorf16 => ( "floorf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
337
364
sym:: floorf32 => ( "floorf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
338
365
sym:: floorf64 => ( "floor" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
366
+ sym:: floorf128 => ( "floorf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
367
+ sym:: ceilf16 => ( "ceilf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
339
368
sym:: ceilf32 => ( "ceilf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
340
369
sym:: ceilf64 => ( "ceil" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
370
+ sym:: ceilf128 => ( "ceilf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
371
+ sym:: truncf16 => ( "truncf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
341
372
sym:: truncf32 => ( "truncf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
342
373
sym:: truncf64 => ( "trunc" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
374
+ sym:: truncf128 => ( "truncf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
375
+ sym:: round_ties_even_f16 => ( "rintf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
343
376
sym:: round_ties_even_f32 => ( "rintf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
344
377
sym:: round_ties_even_f64 => ( "rint" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
378
+ sym:: round_ties_even_f128 => ( "rintf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
379
+ sym:: roundf16 => ( "roundf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
345
380
sym:: roundf32 => ( "roundf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
346
381
sym:: roundf64 => ( "round" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
382
+ sym:: roundf128 => ( "roundf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
383
+ sym:: sinf16 => ( "sinf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
347
384
sym:: sinf32 => ( "sinf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
348
385
sym:: sinf64 => ( "sin" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
386
+ sym:: sinf128 => ( "sinf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
387
+ sym:: cosf16 => ( "cosf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
349
388
sym:: cosf32 => ( "cosf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
350
389
sym:: cosf64 => ( "cos" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
390
+ sym:: cosf128 => ( "cosf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
351
391
_ => return false ,
352
392
} ;
353
393
@@ -380,13 +420,26 @@ fn codegen_float_intrinsic_call<'tcx>(
380
420
} ;
381
421
382
422
let layout = fx. layout_of ( ty) ;
423
+ // FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift operations
424
+ // for `f16` and `f128` once the lowerings have been implemented in Cranelift.
383
425
let res = match intrinsic {
426
+ sym:: fmaf16 | sym:: fmuladdf16 => {
427
+ CValue :: by_val ( codegen_f16_f128:: fma_f16 ( fx, args[ 0 ] , args[ 1 ] , args[ 2 ] ) , layout)
428
+ }
384
429
sym:: fmaf32 | sym:: fmaf64 | sym:: fmuladdf32 | sym:: fmuladdf64 => {
385
430
CValue :: by_val ( fx. bcx . ins ( ) . fma ( args[ 0 ] , args[ 1 ] , args[ 2 ] ) , layout)
386
431
}
432
+ sym:: copysignf16 => {
433
+ CValue :: by_val ( codegen_f16_f128:: copysign_f16 ( fx, args[ 0 ] , args[ 1 ] ) , layout)
434
+ }
435
+ sym:: copysignf128 => {
436
+ CValue :: by_val ( codegen_f16_f128:: copysign_f128 ( fx, args[ 0 ] , args[ 1 ] ) , layout)
437
+ }
387
438
sym:: copysignf32 | sym:: copysignf64 => {
388
439
CValue :: by_val ( fx. bcx . ins ( ) . fcopysign ( args[ 0 ] , args[ 1 ] ) , layout)
389
440
}
441
+ sym:: fabsf16 => CValue :: by_val ( codegen_f16_f128:: abs_f16 ( fx, args[ 0 ] ) , layout) ,
442
+ sym:: fabsf128 => CValue :: by_val ( codegen_f16_f128:: abs_f128 ( fx, args[ 0 ] ) , layout) ,
390
443
sym:: fabsf32
391
444
| sym:: fabsf64
392
445
| sym:: floorf32
@@ -416,12 +469,36 @@ fn codegen_float_intrinsic_call<'tcx>(
416
469
417
470
// These intrinsics aren't supported natively by Cranelift.
418
471
// Lower them to a libcall.
419
- sym:: powif32 | sym:: powif64 => {
472
+ sym:: powif16 | sym:: powif32 | sym:: powif64 | sym:: powif128 => {
473
+ let temp;
474
+ let ( clif_ty, args) = if intrinsic == sym:: powif16 {
475
+ temp = [ codegen_f16_f128:: f16_to_f32 ( fx, args[ 0 ] ) , args[ 1 ] ] ;
476
+ ( types:: F32 , temp. as_slice ( ) )
477
+ } else {
478
+ ( clif_ty, args)
479
+ } ;
420
480
let input_tys: Vec < _ > =
421
481
vec ! [ AbiParam :: new( clif_ty) , lib_call_arg_param( fx. tcx, types:: I32 , true ) ] ;
422
482
let ret_val = fx. lib_call ( name, input_tys, vec ! [ AbiParam :: new( clif_ty) ] , & args) [ 0 ] ;
483
+ let ret_val = if intrinsic == sym:: powif16 {
484
+ codegen_f16_f128:: f32_to_f16 ( fx, ret_val)
485
+ } else {
486
+ ret_val
487
+ } ;
423
488
CValue :: by_val ( ret_val, fx. layout_of ( ty) )
424
489
}
490
+ sym:: powf16 => {
491
+ // FIXME(f16_f128): Rust `compiler-builtins` doesn't export `powf16` yet.
492
+ let x = codegen_f16_f128:: f16_to_f32 ( fx, args[ 0 ] ) ;
493
+ let y = codegen_f16_f128:: f16_to_f32 ( fx, args[ 1 ] ) ;
494
+ let ret_val = fx. lib_call (
495
+ "powf" ,
496
+ vec ! [ AbiParam :: new( types:: F32 ) , AbiParam :: new( types:: F32 ) ] ,
497
+ vec ! [ AbiParam :: new( types:: F32 ) ] ,
498
+ & [ x, y] ,
499
+ ) [ 0 ] ;
500
+ CValue :: by_val ( codegen_f16_f128:: f32_to_f16 ( fx, ret_val) , fx. layout_of ( ty) )
501
+ }
425
502
_ => {
426
503
let input_tys: Vec < _ > = args. iter ( ) . map ( |_| AbiParam :: new ( clif_ty) ) . collect ( ) ;
427
504
let ret_val = fx. lib_call ( name, input_tys, vec ! [ AbiParam :: new( clif_ty) ] , & args) [ 0 ] ;
0 commit comments