@@ -466,124 +466,92 @@ fn trans_stmt<'a, 'tcx: 'a>(
466
466
Rvalue :: Cast ( CastKind :: Misc , operand, to_ty) => {
467
467
let operand = trans_operand ( fx, operand) ;
468
468
let from_ty = operand. layout ( ) . ty ;
469
- match ( & from_ty. sty , & to_ty. sty ) {
470
- ( ty:: Ref ( ..) , ty:: Ref ( ..) )
471
- | ( ty:: Ref ( ..) , ty:: RawPtr ( ..) )
472
- | ( ty:: RawPtr ( ..) , ty:: Ref ( ..) )
473
- | ( ty:: RawPtr ( ..) , ty:: RawPtr ( ..) )
474
- | ( ty:: FnPtr ( ..) , ty:: RawPtr ( ..) ) => {
475
- lval. write_cvalue ( fx, operand. unchecked_cast_to ( dest_layout) ) ;
476
- }
477
- ( ty:: RawPtr ( ..) , ty:: Uint ( _) )
478
- | ( ty:: RawPtr ( ..) , ty:: Int ( _) )
479
- | ( ty:: FnPtr ( ..) , ty:: Uint ( _) )
480
- if to_ty. sty == fx. tcx . types . usize . sty
481
- || to_ty. sty == fx. tcx . types . isize . sty
482
- || fx. clif_type ( to_ty) . unwrap ( ) == pointer_ty ( fx. tcx ) =>
483
- {
484
- lval. write_cvalue ( fx, operand. unchecked_cast_to ( dest_layout) ) ;
485
- }
486
- ( ty:: Uint ( _) , ty:: RawPtr ( ..) ) if from_ty. sty == fx. tcx . types . usize . sty => {
487
- lval. write_cvalue ( fx, operand. unchecked_cast_to ( dest_layout) ) ;
488
- }
489
- ( ty:: Int ( _) , ty:: RawPtr ( ..) ) if from_ty. sty == fx. tcx . types . isize . sty => {
469
+
470
+ fn is_fat_ptr < ' a , ' tcx : ' a > ( fx : & FunctionCx < ' a , ' tcx , impl Backend > , ty : Ty < ' tcx > ) -> bool {
471
+ ty
472
+ . builtin_deref ( true )
473
+ . map ( |ty:: TypeAndMut { ty : pointee_ty, mutbl : _ } | fx. layout_of ( pointee_ty) . is_unsized ( ) )
474
+ . unwrap_or ( false )
475
+ }
476
+
477
+ if is_fat_ptr ( fx, from_ty) {
478
+ if is_fat_ptr ( fx, to_ty) {
479
+ // fat-ptr -> fat-ptr
490
480
lval. write_cvalue ( fx, operand. unchecked_cast_to ( dest_layout) ) ;
481
+ } else {
482
+ // fat-ptr -> thin-ptr
483
+ let ( ptr, _extra) = operand. load_value_pair ( fx) ;
484
+ lval. write_cvalue ( fx, CValue :: ByVal ( ptr, dest_layout) )
491
485
}
492
- ( ty:: Char , ty:: Uint ( _) )
493
- | ( ty:: Uint ( _) , ty:: Char )
494
- | ( ty:: Uint ( _) , ty:: Int ( _) )
495
- | ( ty:: Uint ( _) , ty:: Uint ( _) ) => {
496
- let from = operand. load_scalar ( fx) ;
497
- let res = crate :: common:: clif_intcast (
498
- fx,
499
- from,
500
- fx. clif_type ( to_ty) . unwrap ( ) ,
501
- false ,
502
- ) ;
503
- lval. write_cvalue ( fx, CValue :: ByVal ( res, dest_layout) ) ;
486
+ } else if let ty:: Adt ( adt_def, _substs) = from_ty. sty {
487
+ // enum -> discriminant value
488
+ assert ! ( adt_def. is_enum( ) ) ;
489
+ match to_ty. sty {
490
+ ty:: Uint ( _) | ty:: Int ( _) => { } ,
491
+ _ => unreachable ! ( "cast adt {} -> {}" , from_ty, to_ty) ,
504
492
}
505
- ( ty:: Int ( _) , ty:: Int ( _) ) | ( ty:: Int ( _) , ty:: Uint ( _) ) => {
506
- let from = operand. load_scalar ( fx) ;
507
- let res = crate :: common:: clif_intcast (
493
+
494
+ // FIXME avoid forcing to stack
495
+ let place =
496
+ CPlace :: Addr ( operand. force_stack ( fx) , None , operand. layout ( ) ) ;
497
+ let discr = trans_get_discriminant ( fx, place, fx. layout_of ( to_ty) ) ;
498
+ lval. write_cvalue ( fx, discr) ;
499
+ } else {
500
+ let from_clif_ty = fx. clif_type ( from_ty) . unwrap ( ) ;
501
+ let to_clif_ty = fx. clif_type ( to_ty) . unwrap ( ) ;
502
+ let from = operand. load_scalar ( fx) ;
503
+
504
+ let signed = match from_ty. sty {
505
+ ty:: Ref ( ..) | ty:: RawPtr ( ..) | ty:: FnPtr ( ..) | ty:: Char | ty:: Uint ( ..) | ty:: Bool => false ,
506
+ ty:: Int ( ..) => true ,
507
+ ty:: Float ( ..) => false , // `signed` is unused for floats
508
+ _ => panic ! ( "{}" , from_ty) ,
509
+ } ;
510
+
511
+ let res = if from_clif_ty. is_int ( ) && to_clif_ty. is_int ( ) {
512
+ // int-like -> int-like
513
+ crate :: common:: clif_intcast (
508
514
fx,
509
515
from,
510
- fx. clif_type ( to_ty) . unwrap ( ) ,
511
- true ,
512
- ) ;
513
- lval. write_cvalue ( fx, CValue :: ByVal ( res, dest_layout) ) ;
514
- }
515
- ( ty:: Float ( from_flt) , ty:: Float ( to_flt) ) => {
516
- let from = operand. load_scalar ( fx) ;
517
- let res = match ( from_flt, to_flt) {
518
- ( FloatTy :: F32 , FloatTy :: F64 ) => {
519
- fx. bcx . ins ( ) . fpromote ( types:: F64 , from)
520
- }
521
- ( FloatTy :: F64 , FloatTy :: F32 ) => {
522
- fx. bcx . ins ( ) . fdemote ( types:: F32 , from)
523
- }
524
- _ => from,
525
- } ;
526
- lval. write_cvalue ( fx, CValue :: ByVal ( res, dest_layout) ) ;
527
- }
528
- ( ty:: Float ( _) , ty:: Int ( _) ) => {
529
- let from = operand. load_scalar ( fx) ;
530
- let i_type = fx. clif_type ( to_ty) . unwrap ( ) ;
531
- let res = fx. bcx . ins ( ) . fcvt_to_sint_sat ( i_type, from) ;
532
- lval. write_cvalue ( fx, CValue :: ByVal ( res, dest_layout) ) ;
533
- }
534
- ( ty:: Float ( _) , ty:: Uint ( _) ) => {
535
- let from = operand. load_scalar ( fx) ;
536
- let i_type = fx. clif_type ( to_ty) . unwrap ( ) ;
537
- let res = fx. bcx . ins ( ) . fcvt_to_uint_sat ( i_type, from) ;
538
- lval. write_cvalue ( fx, CValue :: ByVal ( res, dest_layout) ) ;
539
- }
540
- ( ty:: Int ( _) , ty:: Float ( _) ) => {
541
- let from_ty = fx. clif_type ( from_ty) . unwrap ( ) ;
542
- let from = operand. load_scalar ( fx) ;
516
+ to_clif_ty,
517
+ signed,
518
+ )
519
+ } else if from_clif_ty. is_int ( ) && to_clif_ty. is_float ( ) {
520
+ // int-like -> float
543
521
// FIXME missing encoding for fcvt_from_sint.f32.i8
544
- let from = if from_ty == types:: I8 || from_ty == types:: I16 {
545
- fx. bcx . ins ( ) . sextend ( types:: I32 , from)
546
- } else {
547
- from
548
- } ;
549
- let f_type = fx. clif_type ( to_ty) . unwrap ( ) ;
550
- let res = fx. bcx . ins ( ) . fcvt_from_sint ( f_type, from) ;
551
- lval. write_cvalue ( fx, CValue :: ByVal ( res, dest_layout) ) ;
552
- }
553
- ( ty:: Uint ( _) , ty:: Float ( _) ) => {
554
- let from_ty = fx. clif_type ( from_ty) . unwrap ( ) ;
555
- let from = operand. load_scalar ( fx) ;
556
- // FIXME missing encoding for fcvt_from_uint.f32.i8
557
- let from = if from_ty == types:: I8 || from_ty == types:: I16 {
522
+ let from = if from_clif_ty == types:: I8 || from_clif_ty == types:: I16 {
558
523
fx. bcx . ins ( ) . uextend ( types:: I32 , from)
559
524
} else {
560
525
from
561
526
} ;
562
- let f_type = fx. clif_type ( to_ty) . unwrap ( ) ;
563
- let res = fx. bcx . ins ( ) . fcvt_from_uint ( f_type, from) ;
564
- lval. write_cvalue ( fx, CValue :: ByVal ( res, dest_layout) ) ;
565
- }
566
- ( ty:: Bool , ty:: Uint ( _) ) | ( ty:: Bool , ty:: Int ( _) ) => {
567
- let to_ty = fx. clif_type ( to_ty) . unwrap ( ) ;
527
+ if signed {
528
+ fx. bcx . ins ( ) . fcvt_from_sint ( to_clif_ty, from)
529
+ } else {
530
+ fx. bcx . ins ( ) . fcvt_from_uint ( to_clif_ty, from)
531
+ }
532
+ } else if from_clif_ty. is_float ( ) && to_clif_ty. is_int ( ) {
533
+ // float -> int-like
568
534
let from = operand. load_scalar ( fx) ;
569
- let res = if to_ty != types :: I8 {
570
- fx. bcx . ins ( ) . uextend ( to_ty , from)
535
+ if signed {
536
+ fx. bcx . ins ( ) . fcvt_to_sint_sat ( to_clif_ty , from)
571
537
} else {
572
- from
573
- } ;
574
- lval. write_cvalue ( fx, CValue :: ByVal ( res, dest_layout) ) ;
575
- }
576
- ( ty:: Adt ( adt_def, _substs) , ty:: Uint ( _) )
577
- | ( ty:: Adt ( adt_def, _substs) , ty:: Int ( _) )
578
- if adt_def. is_enum ( ) =>
579
- {
580
- // FIXME avoid forcing to stack
581
- let place =
582
- CPlace :: Addr ( operand. force_stack ( fx) , None , operand. layout ( ) ) ;
583
- let discr = trans_get_discriminant ( fx, place, fx. layout_of ( to_ty) ) ;
584
- lval. write_cvalue ( fx, discr) ;
585
- }
586
- _ => unimpl ! ( "rval misc {:?} {:?}" , from_ty, to_ty) ,
538
+ fx. bcx . ins ( ) . fcvt_to_uint_sat ( to_clif_ty, from)
539
+ }
540
+ } else if from_clif_ty. is_float ( ) && to_clif_ty. is_float ( ) {
541
+ // float -> float
542
+ match ( from_clif_ty, to_clif_ty) {
543
+ ( types:: F32 , types:: F64 ) => {
544
+ fx. bcx . ins ( ) . fpromote ( types:: F64 , from)
545
+ }
546
+ ( types:: F64 , types:: F32 ) => {
547
+ fx. bcx . ins ( ) . fdemote ( types:: F32 , from)
548
+ }
549
+ _ => from,
550
+ }
551
+ } else {
552
+ unimpl ! ( "rval misc {:?} {:?}" , from_ty, to_ty)
553
+ } ;
554
+ lval. write_cvalue ( fx, CValue :: ByVal ( res, dest_layout) ) ;
587
555
}
588
556
}
589
557
Rvalue :: Cast ( CastKind :: ClosureFnPointer , operand, _ty) => {
0 commit comments