@@ -434,8 +434,36 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
434
434
} ) ;
435
435
}
436
436
437
- sym:: simd_round => {
438
- intrinsic_args ! ( fx, args => ( a) ; intrinsic) ;
437
+ sym:: simd_fpow => {
438
+ intrinsic_args ! ( fx, args => ( a, b) ; intrinsic) ;
439
+
440
+ if !a. layout ( ) . ty . is_simd ( ) {
441
+ report_simd_type_validation_error ( fx, intrinsic, span, a. layout ( ) . ty ) ;
442
+ return ;
443
+ }
444
+
445
+ simd_pair_for_each_lane ( fx, a, b, ret, & |fx, lane_ty, _ret_lane_ty, a_lane, b_lane| {
446
+ match lane_ty. kind ( ) {
447
+ ty:: Float ( FloatTy :: F32 ) => fx. lib_call (
448
+ "powf" ,
449
+ vec ! [ AbiParam :: new( types:: F32 ) , AbiParam :: new( types:: F32 ) ] ,
450
+ vec ! [ AbiParam :: new( types:: F32 ) ] ,
451
+ & [ a_lane, b_lane] ,
452
+ ) [ 0 ] ,
453
+ ty:: Float ( FloatTy :: F64 ) => fx. lib_call (
454
+ "pow" ,
455
+ vec ! [ AbiParam :: new( types:: F64 ) , AbiParam :: new( types:: F64 ) ] ,
456
+ vec ! [ AbiParam :: new( types:: F64 ) ] ,
457
+ & [ a_lane, b_lane] ,
458
+ ) [ 0 ] ,
459
+ _ => unreachable ! ( "{:?}" , lane_ty) ,
460
+ }
461
+ } ) ;
462
+ }
463
+
464
+ sym:: simd_fpowi => {
465
+ intrinsic_args ! ( fx, args => ( a, exp) ; intrinsic) ;
466
+ let exp = exp. load_scalar ( fx) ;
439
467
440
468
if !a. layout ( ) . ty . is_simd ( ) {
441
469
report_simd_type_validation_error ( fx, intrinsic, span, a. layout ( ) . ty ) ;
@@ -448,22 +476,71 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
448
476
ret,
449
477
& |fx, lane_ty, _ret_lane_ty, lane| match lane_ty. kind ( ) {
450
478
ty:: Float ( FloatTy :: F32 ) => fx. lib_call (
451
- "roundf" ,
452
- vec ! [ AbiParam :: new( types:: F32 ) ] ,
479
+ "__powisf2" , // compiler-builtins
480
+ vec ! [ AbiParam :: new( types:: F32 ) , AbiParam :: new ( types :: I32 ) ] ,
453
481
vec ! [ AbiParam :: new( types:: F32 ) ] ,
454
- & [ lane] ,
482
+ & [ lane, exp ] ,
455
483
) [ 0 ] ,
456
484
ty:: Float ( FloatTy :: F64 ) => fx. lib_call (
457
- "round" ,
485
+ "__powidf2" , // compiler-builtins
486
+ vec ! [ AbiParam :: new( types:: F64 ) , AbiParam :: new( types:: I32 ) ] ,
458
487
vec ! [ AbiParam :: new( types:: F64 ) ] ,
459
- vec ! [ AbiParam :: new( types:: F64 ) ] ,
460
- & [ lane] ,
488
+ & [ lane, exp] ,
461
489
) [ 0 ] ,
462
490
_ => unreachable ! ( "{:?}" , lane_ty) ,
463
491
} ,
464
492
) ;
465
493
}
466
494
495
+ sym:: simd_fsin
496
+ | sym:: simd_fcos
497
+ | sym:: simd_fexp
498
+ | sym:: simd_fexp2
499
+ | sym:: simd_flog
500
+ | sym:: simd_flog10
501
+ | sym:: simd_flog2
502
+ | sym:: simd_round => {
503
+ intrinsic_args ! ( fx, args => ( a) ; intrinsic) ;
504
+
505
+ if !a. layout ( ) . ty . is_simd ( ) {
506
+ report_simd_type_validation_error ( fx, intrinsic, span, a. layout ( ) . ty ) ;
507
+ return ;
508
+ }
509
+
510
+ simd_for_each_lane ( fx, a, ret, & |fx, lane_ty, _ret_lane_ty, lane| {
511
+ let lane_ty = match lane_ty. kind ( ) {
512
+ ty:: Float ( FloatTy :: F32 ) => types:: F32 ,
513
+ ty:: Float ( FloatTy :: F64 ) => types:: F64 ,
514
+ _ => unreachable ! ( "{:?}" , lane_ty) ,
515
+ } ;
516
+ let name = match ( intrinsic, lane_ty) {
517
+ ( sym:: simd_fsin, types:: F32 ) => "sinf" ,
518
+ ( sym:: simd_fsin, types:: F64 ) => "sin" ,
519
+ ( sym:: simd_fcos, types:: F32 ) => "cosf" ,
520
+ ( sym:: simd_fcos, types:: F64 ) => "cos" ,
521
+ ( sym:: simd_fexp, types:: F32 ) => "expf" ,
522
+ ( sym:: simd_fexp, types:: F64 ) => "exp" ,
523
+ ( sym:: simd_fexp2, types:: F32 ) => "exp2f" ,
524
+ ( sym:: simd_fexp2, types:: F64 ) => "exp2" ,
525
+ ( sym:: simd_flog, types:: F32 ) => "logf" ,
526
+ ( sym:: simd_flog, types:: F64 ) => "log" ,
527
+ ( sym:: simd_flog10, types:: F32 ) => "log10f" ,
528
+ ( sym:: simd_flog10, types:: F64 ) => "log10" ,
529
+ ( sym:: simd_flog2, types:: F32 ) => "log2f" ,
530
+ ( sym:: simd_flog2, types:: F64 ) => "log2" ,
531
+ ( sym:: simd_round, types:: F32 ) => "roundf" ,
532
+ ( sym:: simd_round, types:: F64 ) => "round" ,
533
+ _ => unreachable ! ( "{:?}" , intrinsic) ,
534
+ } ;
535
+ fx. lib_call (
536
+ name,
537
+ vec ! [ AbiParam :: new( lane_ty) ] ,
538
+ vec ! [ AbiParam :: new( lane_ty) ] ,
539
+ & [ lane] ,
540
+ ) [ 0 ]
541
+ } ) ;
542
+ }
543
+
467
544
sym:: simd_fabs | sym:: simd_fsqrt | sym:: simd_ceil | sym:: simd_floor | sym:: simd_trunc => {
468
545
intrinsic_args ! ( fx, args => ( a) ; intrinsic) ;
469
546
0 commit comments