3
3
use crate :: source:: { get_source_text, walk_span_to_context} ;
4
4
use crate :: { clip, is_direct_expn_of, sext, unsext} ;
5
5
6
+ use rustc_apfloat:: ieee:: { Half , Quad } ;
7
+ use rustc_apfloat:: Float ;
6
8
use rustc_ast:: ast:: { self , LitFloatType , LitKind } ;
7
9
use rustc_data_structures:: sync:: Lrc ;
8
10
use rustc_hir:: def:: { DefKind , Res } ;
@@ -33,10 +35,14 @@ pub enum Constant<'tcx> {
33
35
Char ( char ) ,
34
36
/// An integer's bit representation.
35
37
Int ( u128 ) ,
38
+ /// An `f16`.
39
+ F16 ( f16 ) ,
36
40
/// An `f32`.
37
41
F32 ( f32 ) ,
38
42
/// An `f64`.
39
43
F64 ( f64 ) ,
44
+ /// An `f128`.
45
+ F128 ( f128 ) ,
40
46
/// `true` or `false`.
41
47
Bool ( bool ) ,
42
48
/// An array of constants.
@@ -161,12 +167,19 @@ impl<'tcx> Hash for Constant<'tcx> {
161
167
Self :: Int ( i) => {
162
168
i. hash ( state) ;
163
169
} ,
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
+ } ,
164
174
Self :: F32 ( f) => {
165
175
f64:: from ( f) . to_bits ( ) . hash ( state) ;
166
176
} ,
167
177
Self :: F64 ( f) => {
168
178
f. to_bits ( ) . hash ( state) ;
169
179
} ,
180
+ Self :: F128 ( f) => {
181
+ f. to_bits ( ) . hash ( state) ;
182
+ } ,
170
183
Self :: Bool ( b) => {
171
184
b. hash ( state) ;
172
185
} ,
@@ -268,6 +281,16 @@ impl<'tcx> Constant<'tcx> {
268
281
}
269
282
self
270
283
}
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
+ }
271
294
}
272
295
273
296
/// Parses a `LitKind` to a `Constant`.
@@ -279,16 +302,17 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option<Ty<'tcx>>) -> Constan
279
302
LitKind :: Char ( c) => Constant :: Char ( c) ,
280
303
LitKind :: Int ( n, _) => Constant :: Int ( n. get ( ) ) ,
281
304
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 ( ) ) ,
283
307
ast:: FloatTy :: F32 => Constant :: F32 ( is. as_str ( ) . parse ( ) . unwrap ( ) ) ,
284
308
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 ( ) ) ,
286
310
} ,
287
311
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 ( ) ) ,
289
313
ty:: Float ( FloatTy :: F32 ) => Constant :: F32 ( is. as_str ( ) . parse ( ) . unwrap ( ) ) ,
290
314
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 ( ) ) ,
292
316
_ => bug ! ( ) ,
293
317
} ,
294
318
LitKind :: Bool ( b) => Constant :: Bool ( b) ,
@@ -625,15 +649,19 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
625
649
626
650
match ( lhs, index) {
627
651
( Some ( Constant :: Vec ( vec) ) , Some ( Constant :: Int ( index) ) ) => match vec. get ( index as usize ) {
652
+ Some ( Constant :: F16 ( x) ) => Some ( Constant :: F16 ( * x) ) ,
628
653
Some ( Constant :: F32 ( x) ) => Some ( Constant :: F32 ( * x) ) ,
629
654
Some ( Constant :: F64 ( x) ) => Some ( Constant :: F64 ( * x) ) ,
655
+ Some ( Constant :: F128 ( x) ) => Some ( Constant :: F128 ( * x) ) ,
630
656
_ => None ,
631
657
} ,
632
658
( Some ( Constant :: Vec ( vec) ) , _) => {
633
659
if !vec. is_empty ( ) && vec. iter ( ) . all ( |x| * x == vec[ 0 ] ) {
634
660
match vec. first ( ) {
661
+ Some ( Constant :: F16 ( x) ) => Some ( Constant :: F16 ( * x) ) ,
635
662
Some ( Constant :: F32 ( x) ) => Some ( Constant :: F32 ( * x) ) ,
636
663
Some ( Constant :: F64 ( x) ) => Some ( Constant :: F64 ( * x) ) ,
664
+ Some ( Constant :: F128 ( x) ) => Some ( Constant :: F128 ( * x) ) ,
637
665
_ => None ,
638
666
}
639
667
} else {
@@ -760,6 +788,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
760
788
} ,
761
789
_ => None ,
762
790
} ,
791
+ // FIXME(f16_f128): add these types when binary operations are available on all platforms
763
792
( Constant :: F32 ( l) , Some ( Constant :: F32 ( r) ) ) => match op. node {
764
793
BinOpKind :: Add => Some ( Constant :: F32 ( l + r) ) ,
765
794
BinOpKind :: Sub => Some ( Constant :: F32 ( l - r) ) ,
@@ -813,8 +842,10 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) ->
813
842
ty:: Adt ( adt_def, _) if adt_def. is_struct ( ) => Some ( Constant :: Adt ( result) ) ,
814
843
ty:: Bool => Some ( Constant :: Bool ( int == ScalarInt :: TRUE ) ) ,
815
844
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 ( ) ) ) ) ,
816
846
ty:: Float ( FloatTy :: F32 ) => Some ( Constant :: F32 ( f32:: from_bits ( int. into ( ) ) ) ) ,
817
847
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 ( ) ) ) ) ,
818
849
ty:: RawPtr ( _, _) => Some ( Constant :: RawPtr ( int. to_bits ( int. size ( ) ) ) ) ,
819
850
_ => None ,
820
851
} ,
@@ -835,10 +866,10 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) ->
835
866
let range = alloc_range ( offset + size * idx, size) ;
836
867
let val = alloc. read_scalar ( & lcx. tcx , range, /* read_provenance */ false ) . ok ( ) ?;
837
868
res. push ( match flt {
838
- FloatTy :: F16 => unimplemented ! ( "f16_f128" ) ,
869
+ FloatTy :: F16 => Constant :: F16 ( f16 :: from_bits ( val . to_u16 ( ) . ok ( ) ? ) ) ,
839
870
FloatTy :: F32 => Constant :: F32 ( f32:: from_bits ( val. to_u32 ( ) . ok ( ) ?) ) ,
840
871
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 ( ) ? ) ) ,
842
873
} ) ;
843
874
}
844
875
Some ( Constant :: Vec ( res) )
0 commit comments