@@ -1518,9 +1518,97 @@ impl Evaluator<'_> {
1518
1518
self . size_of_sized ( target_ty, locals, "destination of int to int cast" ) ?;
1519
1519
Owned ( current[ 0 ..dest_size] . to_vec ( ) )
1520
1520
}
1521
- CastKind :: FloatToInt => not_supported ! ( "float to int cast" ) ,
1522
- CastKind :: FloatToFloat => not_supported ! ( "float to float cast" ) ,
1523
- CastKind :: IntToFloat => not_supported ! ( "float to int cast" ) ,
1521
+ CastKind :: FloatToInt => {
1522
+ let ty = self . operand_ty ( operand, locals) ?;
1523
+ let TyKind :: Scalar ( chalk_ir:: Scalar :: Float ( ty) ) = ty. kind ( Interner ) else {
1524
+ not_supported ! ( "invalid float to int cast" ) ;
1525
+ } ;
1526
+ let value = self . eval_operand ( operand, locals) ?. get ( self ) ?;
1527
+ let value = match ty {
1528
+ chalk_ir:: FloatTy :: F32 => {
1529
+ let value = value. try_into ( ) . unwrap ( ) ;
1530
+ f32:: from_le_bytes ( value) as f64
1531
+ }
1532
+ chalk_ir:: FloatTy :: F64 => {
1533
+ let value = value. try_into ( ) . unwrap ( ) ;
1534
+ f64:: from_le_bytes ( value)
1535
+ }
1536
+ chalk_ir:: FloatTy :: F16 | chalk_ir:: FloatTy :: F128 => {
1537
+ not_supported ! ( "unstable floating point type f16 and f128" ) ;
1538
+ }
1539
+ } ;
1540
+ let is_signed = matches ! (
1541
+ target_ty. kind( Interner ) ,
1542
+ TyKind :: Scalar ( chalk_ir:: Scalar :: Int ( _) )
1543
+ ) ;
1544
+ let dest_size =
1545
+ self . size_of_sized ( target_ty, locals, "destination of float to int cast" ) ?;
1546
+ let dest_bits = dest_size * 8 ;
1547
+ let ( max, min) = if dest_bits == 128 {
1548
+ ( i128:: MAX , i128:: MIN )
1549
+ } else if is_signed {
1550
+ let max = 1i128 << ( dest_bits - 1 ) ;
1551
+ ( max - 1 , -max)
1552
+ } else {
1553
+ ( 1i128 << dest_bits, 0 )
1554
+ } ;
1555
+ let value = ( value as i128 ) . min ( max) . max ( min) ;
1556
+ let result = value. to_le_bytes ( ) ;
1557
+ Owned ( result[ 0 ..dest_size] . to_vec ( ) )
1558
+ }
1559
+ CastKind :: FloatToFloat => {
1560
+ let ty = self . operand_ty ( operand, locals) ?;
1561
+ let TyKind :: Scalar ( chalk_ir:: Scalar :: Float ( ty) ) = ty. kind ( Interner ) else {
1562
+ not_supported ! ( "invalid float to int cast" ) ;
1563
+ } ;
1564
+ let value = self . eval_operand ( operand, locals) ?. get ( self ) ?;
1565
+ let value = match ty {
1566
+ chalk_ir:: FloatTy :: F32 => {
1567
+ let value = value. try_into ( ) . unwrap ( ) ;
1568
+ f32:: from_le_bytes ( value) as f64
1569
+ }
1570
+ chalk_ir:: FloatTy :: F64 => {
1571
+ let value = value. try_into ( ) . unwrap ( ) ;
1572
+ f64:: from_le_bytes ( value)
1573
+ }
1574
+ chalk_ir:: FloatTy :: F16 | chalk_ir:: FloatTy :: F128 => {
1575
+ not_supported ! ( "unstable floating point type f16 and f128" ) ;
1576
+ }
1577
+ } ;
1578
+ let TyKind :: Scalar ( chalk_ir:: Scalar :: Float ( target_ty) ) =
1579
+ target_ty. kind ( Interner )
1580
+ else {
1581
+ not_supported ! ( "invalid float to float cast" ) ;
1582
+ } ;
1583
+ match target_ty {
1584
+ chalk_ir:: FloatTy :: F32 => Owned ( ( value as f32 ) . to_le_bytes ( ) . to_vec ( ) ) ,
1585
+ chalk_ir:: FloatTy :: F64 => Owned ( ( value as f64 ) . to_le_bytes ( ) . to_vec ( ) ) ,
1586
+ chalk_ir:: FloatTy :: F16 | chalk_ir:: FloatTy :: F128 => {
1587
+ not_supported ! ( "unstable floating point type f16 and f128" ) ;
1588
+ }
1589
+ }
1590
+ }
1591
+ CastKind :: IntToFloat => {
1592
+ let current_ty = self . operand_ty ( operand, locals) ?;
1593
+ let is_signed = matches ! (
1594
+ current_ty. kind( Interner ) ,
1595
+ TyKind :: Scalar ( chalk_ir:: Scalar :: Int ( _) )
1596
+ ) ;
1597
+ let value = pad16 ( self . eval_operand ( operand, locals) ?. get ( self ) ?, is_signed) ;
1598
+ let value = i128:: from_le_bytes ( value) ;
1599
+ let TyKind :: Scalar ( chalk_ir:: Scalar :: Float ( target_ty) ) =
1600
+ target_ty. kind ( Interner )
1601
+ else {
1602
+ not_supported ! ( "invalid int to float cast" ) ;
1603
+ } ;
1604
+ match target_ty {
1605
+ chalk_ir:: FloatTy :: F32 => Owned ( ( value as f32 ) . to_le_bytes ( ) . to_vec ( ) ) ,
1606
+ chalk_ir:: FloatTy :: F64 => Owned ( ( value as f64 ) . to_le_bytes ( ) . to_vec ( ) ) ,
1607
+ chalk_ir:: FloatTy :: F16 | chalk_ir:: FloatTy :: F128 => {
1608
+ not_supported ! ( "unstable floating point type f16 and f128" ) ;
1609
+ }
1610
+ }
1611
+ }
1524
1612
CastKind :: FnPtrToPtr => not_supported ! ( "fn ptr to ptr cast" ) ,
1525
1613
} ,
1526
1614
} )
0 commit comments