33use crate :: source:: { get_source_text, walk_span_to_context} ;
44use crate :: { clip, is_direct_expn_of, sext, unsext} ;
55
6+ use rustc_apfloat:: ieee:: { Half , Quad } ;
7+ use rustc_apfloat:: Float ;
68use rustc_ast:: ast:: { self , LitFloatType , LitKind } ;
79use rustc_data_structures:: sync:: Lrc ;
810use rustc_hir:: def:: { DefKind , Res } ;
@@ -33,10 +35,14 @@ pub enum Constant<'tcx> {
3335 Char ( char ) ,
3436 /// An integer's bit representation.
3537 Int ( u128 ) ,
38+ /// An `f16`.
39+ F16 ( f16 ) ,
3640 /// An `f32`.
3741 F32 ( f32 ) ,
3842 /// An `f64`.
3943 F64 ( f64 ) ,
44+ /// An `f128`.
45+ F128 ( f128 ) ,
4046 /// `true` or `false`.
4147 Bool ( bool ) ,
4248 /// An array of constants.
@@ -161,12 +167,19 @@ impl<'tcx> Hash for Constant<'tcx> {
161167 Self :: Int ( i) => {
162168 i. hash ( state) ;
163169 } ,
170+ Self :: F16 ( f) => {
171+ // FIXME(f16_f128): once conversions to/from `f128` are available on all platforms,
172+ f. to_bits ( ) . hash ( state) ;
173+ } ,
164174 Self :: F32 ( f) => {
165175 f64:: from ( f) . to_bits ( ) . hash ( state) ;
166176 } ,
167177 Self :: F64 ( f) => {
168178 f. to_bits ( ) . hash ( state) ;
169179 } ,
180+ Self :: F128 ( f) => {
181+ f. to_bits ( ) . hash ( state) ;
182+ } ,
170183 Self :: Bool ( b) => {
171184 b. hash ( state) ;
172185 } ,
@@ -268,6 +281,16 @@ impl<'tcx> Constant<'tcx> {
268281 }
269282 self
270283 }
284+
285+ fn parse_f16 ( s : & str ) -> Self {
286+ let f: Half = s. parse ( ) . unwrap ( ) ;
287+ Self :: F16 ( f16:: from_bits ( f. to_bits ( ) . try_into ( ) . unwrap ( ) ) )
288+ }
289+
290+ fn parse_f128 ( s : & str ) -> Self {
291+ let f: Quad = s. parse ( ) . unwrap ( ) ;
292+ Self :: F128 ( f128:: from_bits ( f. to_bits ( ) ) )
293+ }
271294}
272295
273296/// Parses a `LitKind` to a `Constant`.
@@ -279,16 +302,17 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option<Ty<'tcx>>) -> Constan
279302 LitKind :: Char ( c) => Constant :: Char ( c) ,
280303 LitKind :: Int ( n, _) => Constant :: Int ( n. get ( ) ) ,
281304 LitKind :: Float ( ref is, LitFloatType :: Suffixed ( fty) ) => match fty {
282- ast:: FloatTy :: F16 => unimplemented ! ( "f16_f128" ) ,
305+ // FIXME(f16_f128): just use `parse()` directly when available for `f16`/`f128`
306+ ast:: FloatTy :: F16 => Constant :: parse_f16 ( is. as_str ( ) ) ,
283307 ast:: FloatTy :: F32 => Constant :: F32 ( is. as_str ( ) . parse ( ) . unwrap ( ) ) ,
284308 ast:: FloatTy :: F64 => Constant :: F64 ( is. as_str ( ) . parse ( ) . unwrap ( ) ) ,
285- ast:: FloatTy :: F128 => unimplemented ! ( "f16_f128" ) ,
309+ ast:: FloatTy :: F128 => Constant :: parse_f128 ( is . as_str ( ) ) ,
286310 } ,
287311 LitKind :: Float ( ref is, LitFloatType :: Unsuffixed ) => match ty. expect ( "type of float is known" ) . kind ( ) {
288- ty:: Float ( FloatTy :: F16 ) => unimplemented ! ( "f16_f128" ) ,
312+ ty:: Float ( FloatTy :: F16 ) => Constant :: parse_f16 ( is . as_str ( ) ) ,
289313 ty:: Float ( FloatTy :: F32 ) => Constant :: F32 ( is. as_str ( ) . parse ( ) . unwrap ( ) ) ,
290314 ty:: Float ( FloatTy :: F64 ) => Constant :: F64 ( is. as_str ( ) . parse ( ) . unwrap ( ) ) ,
291- ty:: Float ( FloatTy :: F128 ) => unimplemented ! ( "f16_f128" ) ,
315+ ty:: Float ( FloatTy :: F128 ) => Constant :: parse_f128 ( is . as_str ( ) ) ,
292316 _ => bug ! ( ) ,
293317 } ,
294318 LitKind :: Bool ( b) => Constant :: Bool ( b) ,
@@ -625,15 +649,19 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
625649
626650 match ( lhs, index) {
627651 ( Some ( Constant :: Vec ( vec) ) , Some ( Constant :: Int ( index) ) ) => match vec. get ( index as usize ) {
652+ Some ( Constant :: F16 ( x) ) => Some ( Constant :: F16 ( * x) ) ,
628653 Some ( Constant :: F32 ( x) ) => Some ( Constant :: F32 ( * x) ) ,
629654 Some ( Constant :: F64 ( x) ) => Some ( Constant :: F64 ( * x) ) ,
655+ Some ( Constant :: F128 ( x) ) => Some ( Constant :: F128 ( * x) ) ,
630656 _ => None ,
631657 } ,
632658 ( Some ( Constant :: Vec ( vec) ) , _) => {
633659 if !vec. is_empty ( ) && vec. iter ( ) . all ( |x| * x == vec[ 0 ] ) {
634660 match vec. first ( ) {
661+ Some ( Constant :: F16 ( x) ) => Some ( Constant :: F16 ( * x) ) ,
635662 Some ( Constant :: F32 ( x) ) => Some ( Constant :: F32 ( * x) ) ,
636663 Some ( Constant :: F64 ( x) ) => Some ( Constant :: F64 ( * x) ) ,
664+ Some ( Constant :: F128 ( x) ) => Some ( Constant :: F128 ( * x) ) ,
637665 _ => None ,
638666 }
639667 } else {
@@ -760,6 +788,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
760788 } ,
761789 _ => None ,
762790 } ,
791+ // FIXME(f16_f128): add these types when binary operations are available on all platforms
763792 ( Constant :: F32 ( l) , Some ( Constant :: F32 ( r) ) ) => match op. node {
764793 BinOpKind :: Add => Some ( Constant :: F32 ( l + r) ) ,
765794 BinOpKind :: Sub => Some ( Constant :: F32 ( l - r) ) ,
@@ -813,8 +842,10 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) ->
813842 ty:: Adt ( adt_def, _) if adt_def. is_struct ( ) => Some ( Constant :: Adt ( result) ) ,
814843 ty:: Bool => Some ( Constant :: Bool ( int == ScalarInt :: TRUE ) ) ,
815844 ty:: Uint ( _) | ty:: Int ( _) => Some ( Constant :: Int ( int. to_bits ( int. size ( ) ) ) ) ,
845+ ty:: Float ( FloatTy :: F16 ) => Some ( Constant :: F16 ( f16:: from_bits ( int. into ( ) ) ) ) ,
816846 ty:: Float ( FloatTy :: F32 ) => Some ( Constant :: F32 ( f32:: from_bits ( int. into ( ) ) ) ) ,
817847 ty:: Float ( FloatTy :: F64 ) => Some ( Constant :: F64 ( f64:: from_bits ( int. into ( ) ) ) ) ,
848+ ty:: Float ( FloatTy :: F128 ) => Some ( Constant :: F128 ( f128:: from_bits ( int. into ( ) ) ) ) ,
818849 ty:: RawPtr ( _, _) => Some ( Constant :: RawPtr ( int. to_bits ( int. size ( ) ) ) ) ,
819850 _ => None ,
820851 } ,
@@ -835,10 +866,10 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) ->
835866 let range = alloc_range ( offset + size * idx, size) ;
836867 let val = alloc. read_scalar ( & lcx. tcx , range, /* read_provenance */ false ) . ok ( ) ?;
837868 res. push ( match flt {
838- FloatTy :: F16 => unimplemented ! ( "f16_f128" ) ,
869+ FloatTy :: F16 => Constant :: F16 ( f16 :: from_bits ( val . to_u16 ( ) . ok ( ) ? ) ) ,
839870 FloatTy :: F32 => Constant :: F32 ( f32:: from_bits ( val. to_u32 ( ) . ok ( ) ?) ) ,
840871 FloatTy :: F64 => Constant :: F64 ( f64:: from_bits ( val. to_u64 ( ) . ok ( ) ?) ) ,
841- FloatTy :: F128 => unimplemented ! ( "f16_f128" ) ,
872+ FloatTy :: F128 => Constant :: F128 ( f128 :: from_bits ( val . to_u128 ( ) . ok ( ) ? ) ) ,
842873 } ) ;
843874 }
844875 Some ( Constant :: Vec ( res) )
0 commit comments