|
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