@@ -248,8 +248,10 @@ fn bool_to_zero_or_max_uint<'tcx>(
248
248
let ty = fx. clif_type ( ty) . unwrap ( ) ;
249
249
250
250
let int_ty = match ty {
251
+ types:: F16 => types:: I16 ,
251
252
types:: F32 => types:: I32 ,
252
253
types:: F64 => types:: I64 ,
254
+ types:: F128 => types:: I128 ,
253
255
ty => ty,
254
256
} ;
255
257
@@ -308,45 +310,83 @@ fn codegen_float_intrinsic_call<'tcx>(
308
310
ret : CPlace < ' tcx > ,
309
311
) -> bool {
310
312
let ( name, arg_count, ty, clif_ty) = match intrinsic {
313
+ sym:: expf16 => ( "expf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
311
314
sym:: expf32 => ( "expf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
312
315
sym:: expf64 => ( "exp" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
316
+ sym:: expf128 => ( "expf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
317
+ sym:: exp2f16 => ( "exp2f16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
313
318
sym:: exp2f32 => ( "exp2f" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
314
319
sym:: exp2f64 => ( "exp2" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
320
+ sym:: exp2f128 => ( "exp2f128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
321
+ sym:: sqrtf16 => ( "sqrtf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
315
322
sym:: sqrtf32 => ( "sqrtf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
316
323
sym:: sqrtf64 => ( "sqrt" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
324
+ sym:: sqrtf128 => ( "sqrtf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
325
+ sym:: powif16 => ( "__powisf2" , 2 , fx. tcx . types . f16 , types:: F16 ) , // compiler-builtins
317
326
sym:: powif32 => ( "__powisf2" , 2 , fx. tcx . types . f32 , types:: F32 ) , // compiler-builtins
318
327
sym:: powif64 => ( "__powidf2" , 2 , fx. tcx . types . f64 , types:: F64 ) , // compiler-builtins
328
+ sym:: powif128 => ( "__powitf2" , 2 , fx. tcx . types . f128 , types:: F128 ) , // compiler-builtins
329
+ sym:: powf16 => ( "powf16" , 2 , fx. tcx . types . f16 , types:: F16 ) ,
319
330
sym:: powf32 => ( "powf" , 2 , fx. tcx . types . f32 , types:: F32 ) ,
320
331
sym:: powf64 => ( "pow" , 2 , fx. tcx . types . f64 , types:: F64 ) ,
332
+ sym:: powf128 => ( "powf128" , 2 , fx. tcx . types . f128 , types:: F128 ) ,
333
+ sym:: logf16 => ( "logf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
321
334
sym:: logf32 => ( "logf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
322
335
sym:: logf64 => ( "log" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
336
+ sym:: logf128 => ( "logf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
337
+ sym:: log2f16 => ( "log2f16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
323
338
sym:: log2f32 => ( "log2f" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
324
339
sym:: log2f64 => ( "log2" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
340
+ sym:: log2f128 => ( "log2f16" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
341
+ sym:: log10f16 => ( "log10f16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
325
342
sym:: log10f32 => ( "log10f" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
326
343
sym:: log10f64 => ( "log10" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
344
+ sym:: log10f128 => ( "log10f128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
345
+ sym:: fabsf16 => ( "fabsf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
327
346
sym:: fabsf32 => ( "fabsf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
328
347
sym:: fabsf64 => ( "fabs" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
348
+ sym:: fabsf128 => ( "fabsf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
349
+ sym:: fmaf16 => ( "fmaf16" , 3 , fx. tcx . types . f16 , types:: F16 ) ,
329
350
sym:: fmaf32 => ( "fmaf" , 3 , fx. tcx . types . f32 , types:: F32 ) ,
330
351
sym:: fmaf64 => ( "fma" , 3 , fx. tcx . types . f64 , types:: F64 ) ,
352
+ sym:: fmaf128 => ( "fmaf128" , 3 , fx. tcx . types . f128 , types:: F128 ) ,
331
353
// FIXME: calling `fma` from libc without FMA target feature uses expensive sofware emulation
354
+ sym:: fmuladdf16 => ( "fmaf16" , 3 , fx. tcx . types . f16 , types:: F16 ) , // TODO: use cranelift intrinsic analogous to llvm.fmuladd.f16
332
355
sym:: fmuladdf32 => ( "fmaf" , 3 , fx. tcx . types . f32 , types:: F32 ) , // TODO: use cranelift intrinsic analogous to llvm.fmuladd.f32
333
356
sym:: fmuladdf64 => ( "fma" , 3 , fx. tcx . types . f64 , types:: F64 ) , // TODO: use cranelift intrinsic analogous to llvm.fmuladd.f64
357
+ sym:: fmuladdf128 => ( "fmaf128" , 3 , fx. tcx . types . f128 , types:: F128 ) , // TODO: use cranelift intrinsic analogous to llvm.fmuladd.f128
358
+ sym:: copysignf16 => ( "copysignf16" , 2 , fx. tcx . types . f16 , types:: F16 ) ,
334
359
sym:: copysignf32 => ( "copysignf" , 2 , fx. tcx . types . f32 , types:: F32 ) ,
335
360
sym:: copysignf64 => ( "copysign" , 2 , fx. tcx . types . f64 , types:: F64 ) ,
361
+ sym:: copysignf128 => ( "copysignf128" , 2 , fx. tcx . types . f128 , types:: F128 ) ,
362
+ sym:: floorf16 => ( "floorf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
336
363
sym:: floorf32 => ( "floorf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
337
364
sym:: floorf64 => ( "floor" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
365
+ sym:: floorf128 => ( "floorf128" , 1 , fx. tcx . types . f16 , types:: F128 ) ,
366
+ sym:: ceilf16 => ( "ceilf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
338
367
sym:: ceilf32 => ( "ceilf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
339
368
sym:: ceilf64 => ( "ceil" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
369
+ sym:: ceilf128 => ( "ceilf128" , 1 , fx. tcx . types . f16 , types:: F128 ) ,
370
+ sym:: truncf16 => ( "truncf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
340
371
sym:: truncf32 => ( "truncf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
341
372
sym:: truncf64 => ( "trunc" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
373
+ sym:: truncf128 => ( "truncf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
374
+ sym:: round_ties_even_f16 => ( "rintf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
342
375
sym:: round_ties_even_f32 => ( "rintf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
343
376
sym:: round_ties_even_f64 => ( "rint" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
377
+ sym:: round_ties_even_f128 => ( "rintf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
378
+ sym:: roundf16 => ( "roundf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
344
379
sym:: roundf32 => ( "roundf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
345
380
sym:: roundf64 => ( "round" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
381
+ sym:: roundf128 => ( "roundf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
382
+ sym:: sinf16 => ( "sinf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
346
383
sym:: sinf32 => ( "sinf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
347
384
sym:: sinf64 => ( "sin" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
385
+ sym:: sinf128 => ( "sinf128" , 1 , fx. tcx . types . f16 , types:: F128 ) ,
386
+ sym:: cosf16 => ( "cosf16" , 1 , fx. tcx . types . f16 , types:: F16 ) ,
348
387
sym:: cosf32 => ( "cosf" , 1 , fx. tcx . types . f32 , types:: F32 ) ,
349
388
sym:: cosf64 => ( "cos" , 1 , fx. tcx . types . f64 , types:: F64 ) ,
389
+ sym:: cosf128 => ( "cosf128" , 1 , fx. tcx . types . f128 , types:: F128 ) ,
350
390
_ => return false ,
351
391
} ;
352
392
@@ -380,33 +420,61 @@ fn codegen_float_intrinsic_call<'tcx>(
380
420
381
421
let layout = fx. layout_of ( ty) ;
382
422
let res = match intrinsic {
383
- sym:: fmaf32 | sym:: fmaf64 | sym:: fmuladdf32 | sym:: fmuladdf64 => {
384
- CValue :: by_val ( fx. bcx . ins ( ) . fma ( args[ 0 ] , args[ 1 ] , args[ 2 ] ) , layout)
385
- }
386
- sym:: copysignf32 | sym:: copysignf64 => {
423
+ sym:: fmaf16
424
+ | sym:: fmaf32
425
+ | sym:: fmaf64
426
+ | sym:: fmaf128
427
+ | sym:: fmuladdf16
428
+ | sym:: fmuladdf32
429
+ | sym:: fmuladdf64
430
+ | sym:: fmuladdf128 => CValue :: by_val ( fx. bcx . ins ( ) . fma ( args[ 0 ] , args[ 1 ] , args[ 2 ] ) , layout) ,
431
+ sym:: copysignf16 | sym:: copysignf32 | sym:: copysignf64 | sym:: copysignf128 => {
387
432
CValue :: by_val ( fx. bcx . ins ( ) . fcopysign ( args[ 0 ] , args[ 1 ] ) , layout)
388
433
}
389
- sym:: fabsf32
434
+ sym:: fabsf16
435
+ | sym:: fabsf32
390
436
| sym:: fabsf64
437
+ | sym:: fabsf128
438
+ | sym:: floorf16
391
439
| sym:: floorf32
392
440
| sym:: floorf64
441
+ | sym:: floorf128
442
+ | sym:: ceilf16
393
443
| sym:: ceilf32
394
444
| sym:: ceilf64
445
+ | sym:: ceilf128
446
+ | sym:: truncf16
395
447
| sym:: truncf32
396
448
| sym:: truncf64
449
+ | sym:: truncf128
450
+ | sym:: round_ties_even_f16
397
451
| sym:: round_ties_even_f32
398
452
| sym:: round_ties_even_f64
453
+ | sym:: round_ties_even_f128
454
+ | sym:: sqrtf16
399
455
| sym:: sqrtf32
400
- | sym:: sqrtf64 => {
456
+ | sym:: sqrtf64
457
+ | sym:: sqrtf128 => {
401
458
let val = match intrinsic {
402
- sym:: fabsf32 | sym:: fabsf64 => fx. bcx . ins ( ) . fabs ( args[ 0 ] ) ,
403
- sym:: floorf32 | sym:: floorf64 => fx. bcx . ins ( ) . floor ( args[ 0 ] ) ,
404
- sym:: ceilf32 | sym:: ceilf64 => fx. bcx . ins ( ) . ceil ( args[ 0 ] ) ,
405
- sym:: truncf32 | sym:: truncf64 => fx. bcx . ins ( ) . trunc ( args[ 0 ] ) ,
406
- sym:: round_ties_even_f32 | sym:: round_ties_even_f64 => {
407
- fx. bcx . ins ( ) . nearest ( args[ 0 ] )
459
+ sym:: fabsf16 | sym:: fabsf32 | sym:: fabsf64 | sym:: fabsf128 => {
460
+ fx. bcx . ins ( ) . fabs ( args[ 0 ] )
461
+ }
462
+ sym:: floorf16 | sym:: floorf32 | sym:: floorf64 | sym:: floorf128 => {
463
+ fx. bcx . ins ( ) . floor ( args[ 0 ] )
464
+ }
465
+ sym:: ceilf16 | sym:: ceilf32 | sym:: ceilf64 | sym:: ceilf128 => {
466
+ fx. bcx . ins ( ) . ceil ( args[ 0 ] )
467
+ }
468
+ sym:: truncf16 | sym:: truncf32 | sym:: truncf64 | sym:: truncf128 => {
469
+ fx. bcx . ins ( ) . trunc ( args[ 0 ] )
470
+ }
471
+ sym:: round_ties_even_f16
472
+ | sym:: round_ties_even_f32
473
+ | sym:: round_ties_even_f64
474
+ | sym:: round_ties_even_f128 => fx. bcx . ins ( ) . nearest ( args[ 0 ] ) ,
475
+ sym:: sqrtf16 | sym:: sqrtf32 | sym:: sqrtf64 | sym:: sqrtf128 => {
476
+ fx. bcx . ins ( ) . sqrt ( args[ 0 ] )
408
477
}
409
- sym:: sqrtf32 | sym:: sqrtf64 => fx. bcx . ins ( ) . sqrt ( args[ 0 ] ) ,
410
478
_ => unreachable ! ( ) ,
411
479
} ;
412
480
@@ -415,9 +483,21 @@ fn codegen_float_intrinsic_call<'tcx>(
415
483
416
484
// These intrinsics aren't supported natively by Cranelift.
417
485
// Lower them to a libcall.
418
- sym:: powif32 | sym:: powif64 => {
486
+ sym:: powif16 | sym:: powif32 | sym:: powif64 | sym:: powif128 => {
487
+ let temp;
488
+ let ( clif_ty, args) = if intrinsic == sym:: powif16 {
489
+ temp = [ fx. bcx . ins ( ) . fpromote ( types:: F32 , args[ 0 ] ) , args[ 1 ] ] ;
490
+ ( types:: F32 , temp. as_slice ( ) )
491
+ } else {
492
+ ( clif_ty, args)
493
+ } ;
419
494
let input_tys: Vec < _ > = vec ! [ AbiParam :: new( clif_ty) , AbiParam :: new( types:: I32 ) ] ;
420
495
let ret_val = fx. lib_call ( name, input_tys, vec ! [ AbiParam :: new( clif_ty) ] , & args) [ 0 ] ;
496
+ let ret_val = if intrinsic == sym:: powif16 {
497
+ fx. bcx . ins ( ) . fdemote ( types:: F16 , ret_val)
498
+ } else {
499
+ ret_val
500
+ } ;
421
501
CValue :: by_val ( ret_val, fx. layout_of ( ty) )
422
502
}
423
503
_ => {
@@ -1117,40 +1197,24 @@ fn codegen_regular_intrinsic_call<'tcx>(
1117
1197
ret. write_cvalue ( fx, old) ;
1118
1198
}
1119
1199
1120
- sym:: minnumf32 => {
1200
+ sym:: minnumf16 | sym :: minnumf32 | sym :: minnumf64 | sym :: minnumf128 => {
1121
1201
intrinsic_args ! ( fx, args => ( a, b) ; intrinsic) ;
1202
+ let layout = a. layout ( ) ;
1122
1203
let a = a. load_scalar ( fx) ;
1123
1204
let b = b. load_scalar ( fx) ;
1124
1205
1125
1206
let val = crate :: num:: codegen_float_min ( fx, a, b) ;
1126
- let val = CValue :: by_val ( val, fx. layout_of ( fx. tcx . types . f32 ) ) ;
1127
- ret. write_cvalue ( fx, val) ;
1128
- }
1129
- sym:: minnumf64 => {
1130
- intrinsic_args ! ( fx, args => ( a, b) ; intrinsic) ;
1131
- let a = a. load_scalar ( fx) ;
1132
- let b = b. load_scalar ( fx) ;
1133
-
1134
- let val = crate :: num:: codegen_float_min ( fx, a, b) ;
1135
- let val = CValue :: by_val ( val, fx. layout_of ( fx. tcx . types . f64 ) ) ;
1136
- ret. write_cvalue ( fx, val) ;
1137
- }
1138
- sym:: maxnumf32 => {
1139
- intrinsic_args ! ( fx, args => ( a, b) ; intrinsic) ;
1140
- let a = a. load_scalar ( fx) ;
1141
- let b = b. load_scalar ( fx) ;
1142
-
1143
- let val = crate :: num:: codegen_float_max ( fx, a, b) ;
1144
- let val = CValue :: by_val ( val, fx. layout_of ( fx. tcx . types . f32 ) ) ;
1207
+ let val = CValue :: by_val ( val, layout) ;
1145
1208
ret. write_cvalue ( fx, val) ;
1146
1209
}
1147
- sym:: maxnumf64 => {
1210
+ sym:: maxnumf16 | sym :: maxnumf32 | sym :: maxnumf64 | sym :: maxnumf128 => {
1148
1211
intrinsic_args ! ( fx, args => ( a, b) ; intrinsic) ;
1212
+ let layout = a. layout ( ) ;
1149
1213
let a = a. load_scalar ( fx) ;
1150
1214
let b = b. load_scalar ( fx) ;
1151
1215
1152
1216
let val = crate :: num:: codegen_float_max ( fx, a, b) ;
1153
- let val = CValue :: by_val ( val, fx . layout_of ( fx . tcx . types . f64 ) ) ;
1217
+ let val = CValue :: by_val ( val, layout ) ;
1154
1218
ret. write_cvalue ( fx, val) ;
1155
1219
}
1156
1220
0 commit comments