@@ -1873,32 +1873,31 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
18731873 // On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because
18741874 // we're rounding towards zero, we just get float_ty::MAX (which is always an integer).
18751875 // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX.
1876- let int_max = | signed : bool , int_width : u64 | -> u128 {
1876+ fn int_max ( signed : bool , int_width : u64 ) -> u128 {
18771877 let shift_amount = 128 - int_width;
18781878 if signed { i128:: MAX as u128 >> shift_amount } else { u128:: MAX >> shift_amount }
1879- } ;
1880- let int_min = | signed : bool , int_width : u64 | -> i128 {
1879+ }
1880+ fn int_min ( signed : bool , int_width : u64 ) -> i128 {
18811881 if signed { i128:: MIN >> ( 128 - int_width) } else { 0 }
1882- } ;
1882+ }
18831883
1884- let compute_clamp_bounds_single = |signed : bool , int_width : u64 | -> ( u128 , u128 ) {
1884+ // TODO: rewrite using a generic function with <F: Float>.
1885+ let compute_clamp_bounds_half = |signed : bool , int_width : u64 | -> ( u128 , u128 ) {
18851886 let rounded_min =
1886- ieee:: Single :: from_i128_r ( int_min ( signed, int_width) , Round :: TowardZero ) ;
1887- assert_eq ! ( rounded_min. status, Status :: OK ) ;
1887+ ieee:: Half :: from_i128_r ( int_min ( signed, int_width) , Round :: TowardZero ) ;
1888+ // assert_eq!(rounded_min.status, Status::OK);
18881889 let rounded_max =
1889- ieee:: Single :: from_u128_r ( int_max ( signed, int_width) , Round :: TowardZero ) ;
1890+ ieee:: Half :: from_u128_r ( int_max ( signed, int_width) , Round :: TowardZero ) ;
18901891 assert ! ( rounded_max. value. is_finite( ) ) ;
18911892 ( rounded_min. value . to_bits ( ) , rounded_max. value . to_bits ( ) )
18921893 } ;
1893- let compute_clamp_bounds_double = |signed : bool , int_width : u64 | -> ( u128 , u128 ) {
1894- let rounded_min =
1895- ieee:: Double :: from_i128_r ( int_min ( signed, int_width) , Round :: TowardZero ) ;
1894+ fn compute_clamp_bounds < F : Float > ( signed : bool , int_width : u64 ) -> ( u128 , u128 ) {
1895+ let rounded_min = F :: from_i128_r ( int_min ( signed, int_width) , Round :: TowardZero ) ;
18961896 assert_eq ! ( rounded_min. status, Status :: OK ) ;
1897- let rounded_max =
1898- ieee:: Double :: from_u128_r ( int_max ( signed, int_width) , Round :: TowardZero ) ;
1897+ let rounded_max = F :: from_u128_r ( int_max ( signed, int_width) , Round :: TowardZero ) ;
18991898 assert ! ( rounded_max. value. is_finite( ) ) ;
19001899 ( rounded_min. value . to_bits ( ) , rounded_max. value . to_bits ( ) )
1901- } ;
1900+ }
19021901 // To implement saturation, we perform the following steps:
19031902 //
19041903 // 1. Cast val to an integer with fpto[su]i. This may result in undef.
@@ -1928,15 +1927,19 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
19281927
19291928 let float_bits_to_llval = |bx : & mut Self , bits| {
19301929 let bits_llval = match float_width {
1930+ 16 => bx. cx ( ) . const_u16 ( bits as u16 ) ,
19311931 32 => bx. cx ( ) . const_u32 ( bits as u32 ) ,
19321932 64 => bx. cx ( ) . const_u64 ( bits as u64 ) ,
1933+ 128 => bx. cx ( ) . const_u128 ( bits) ,
19331934 n => bug ! ( "unsupported float width {}" , n) ,
19341935 } ;
19351936 bx. bitcast ( bits_llval, float_ty)
19361937 } ;
19371938 let ( f_min, f_max) = match float_width {
1938- 32 => compute_clamp_bounds_single ( signed, int_width) ,
1939- 64 => compute_clamp_bounds_double ( signed, int_width) ,
1939+ 16 => compute_clamp_bounds_half ( signed, int_width) ,
1940+ 32 => compute_clamp_bounds :: < ieee:: Single > ( signed, int_width) ,
1941+ 64 => compute_clamp_bounds :: < ieee:: Double > ( signed, int_width) ,
1942+ 128 => compute_clamp_bounds :: < ieee:: Quad > ( signed, int_width) ,
19401943 n => bug ! ( "unsupported float width {}" , n) ,
19411944 } ;
19421945 let f_min = float_bits_to_llval ( self , f_min) ;
0 commit comments