|
1 | 1 | use crate::build::expr::as_place::PlaceBuilder; |
2 | 2 | use crate::build::scope::DropKind; |
3 | | -use rustc_apfloat::ieee::{Double, Single}; |
| 3 | +use rustc_apfloat::ieee::{Double, Half, Quad, Single}; |
4 | 4 | use rustc_apfloat::Float; |
5 | 5 | use rustc_ast::attr; |
6 | 6 | use rustc_data_structures::fx::FxHashMap; |
@@ -967,13 +967,60 @@ fn parse_float_into_constval<'tcx>( |
967 | 967 | parse_float_into_scalar(num, float_ty, neg).map(ConstValue::Scalar) |
968 | 968 | } |
969 | 969 |
|
| 970 | +// #[cfg(not(bootstrap))] |
| 971 | +// fn parse_f16(num: &str) -> Option<f16> { |
| 972 | +// num.parse().ok() |
| 973 | +// } |
| 974 | + |
| 975 | +// FIXME: bootstrap `f16` parsing via `f32` |
| 976 | +// #[cfg(bootstrap)] |
| 977 | +fn parse_f16(num: &str) -> Option<f32> { |
| 978 | + num.parse().ok() |
| 979 | +} |
| 980 | + |
| 981 | +// #[cfg(not(bootstrap))] |
| 982 | +// fn parse_f128(num: &str) -> Option<f128> { |
| 983 | +// num.parse().ok() |
| 984 | +// } |
| 985 | + |
| 986 | +// FIXME: bootstrap `f16` parsing via `f32` |
| 987 | +// #[cfg(bootstrap)] |
| 988 | +fn parse_f128(num: &str) -> Option<f64> { |
| 989 | + num.parse().ok() |
| 990 | +} |
| 991 | + |
970 | 992 | pub(crate) fn parse_float_into_scalar( |
971 | 993 | num: Symbol, |
972 | 994 | float_ty: ty::FloatTy, |
973 | 995 | neg: bool, |
974 | 996 | ) -> Option<Scalar> { |
975 | 997 | let num = num.as_str(); |
| 998 | + |
976 | 999 | match float_ty { |
| 1000 | + ty::FloatTy::F16 => { |
| 1001 | + let rust_f = parse_f16(num)?; |
| 1002 | + |
| 1003 | + let mut f = num |
| 1004 | + .parse::<Half>() |
| 1005 | + .unwrap_or_else(|e| panic!("apfloat::ieee::Half failed to parse `{num}`: {e:?}")); |
| 1006 | + |
| 1007 | + assert!( |
| 1008 | + u128::from(rust_f.to_bits()) == f.to_bits(), |
| 1009 | + "apfloat::ieee::Half gave different result for `{}`: \ |
| 1010 | + {}({:#x}) vs Rust's {}({:#x})", |
| 1011 | + rust_f, |
| 1012 | + f, |
| 1013 | + f.to_bits(), |
| 1014 | + Half::from_bits(rust_f.to_bits().into()), |
| 1015 | + rust_f.to_bits() |
| 1016 | + ); |
| 1017 | + |
| 1018 | + if neg { |
| 1019 | + f = -f; |
| 1020 | + } |
| 1021 | + |
| 1022 | + Some(Scalar::from_f16(f)) |
| 1023 | + } |
977 | 1024 | ty::FloatTy::F32 => { |
978 | 1025 | let Ok(rust_f) = num.parse::<f32>() else { return None }; |
979 | 1026 | let mut f = num |
@@ -1020,6 +1067,29 @@ pub(crate) fn parse_float_into_scalar( |
1020 | 1067 |
|
1021 | 1068 | Some(Scalar::from_f64(f)) |
1022 | 1069 | } |
| 1070 | + ty::FloatTy::F128 => { |
| 1071 | + let rust_f = parse_f128(num)?; |
| 1072 | + let mut f = num |
| 1073 | + .parse::<Quad>() |
| 1074 | + .unwrap_or_else(|e| panic!("apfloat::ieee::Quad failed to parse `{num}`: {e:?}")); |
| 1075 | + |
| 1076 | + assert!( |
| 1077 | + u128::from(rust_f.to_bits()) == f.to_bits(), |
| 1078 | + "apfloat::ieee::Quad gave different result for `{}`: \ |
| 1079 | + {}({:#x}) vs Rust's {}({:#x})", |
| 1080 | + rust_f, |
| 1081 | + f, |
| 1082 | + f.to_bits(), |
| 1083 | + Quad::from_bits(rust_f.to_bits().into()), |
| 1084 | + rust_f.to_bits() |
| 1085 | + ); |
| 1086 | + |
| 1087 | + if neg { |
| 1088 | + f = -f; |
| 1089 | + } |
| 1090 | + |
| 1091 | + Some(Scalar::from_f128(f)) |
| 1092 | + } |
1023 | 1093 | } |
1024 | 1094 | } |
1025 | 1095 |
|
|
0 commit comments