Enable const casting for f16
and f128
· rust-lang/rust@648cb16 (original) (raw)
1
1
`use std::assert_matches::assert_matches;
`
2
2
``
3
``
`-
use rustc_apfloat::ieee::{Double, Single};
`
``
3
`+
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
`
4
4
`use rustc_apfloat::{Float, FloatConvert};
`
5
5
`use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
`
6
6
`use rustc_middle::mir::CastKind;
`
`@@ -187,10 +187,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
`
187
187
`bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty)
`
188
188
`};
`
189
189
`let val = match fty {
`
190
``
`-
FloatTy::F16 => unimplemented!("f16_f128"),
`
``
190
`+
FloatTy::F16 => self.cast_from_float(src.to_scalar().to_f16()?, cast_to.ty),
`
191
191
`FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty),
`
192
192
`FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty),
`
193
``
`-
FloatTy::F128 => unimplemented!("f16_f128"),
`
``
193
`+
FloatTy::F128 => self.cast_from_float(src.to_scalar().to_f128()?, cast_to.ty),
`
194
194
`};
`
195
195
`Ok(ImmTy::from_scalar(val, cast_to))
`
196
196
`}
`
`@@ -296,18 +296,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
`
296
296
`Float(fty) if signed => {
`
297
297
`let v = v as i128;
`
298
298
`match fty {
`
299
``
`-
FloatTy::F16 => unimplemented!("f16_f128"),
`
``
299
`+
FloatTy::F16 => Scalar::from_f16(Half::from_i128(v).value),
`
300
300
`FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value),
`
301
301
`FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value),
`
302
``
`-
FloatTy::F128 => unimplemented!("f16_f128"),
`
``
302
`+
FloatTy::F128 => Scalar::from_f128(Quad::from_i128(v).value),
`
303
303
`}
`
304
304
`}
`
305
305
`// unsigned int -> float
`
306
306
`Float(fty) => match fty {
`
307
``
`-
FloatTy::F16 => unimplemented!("f16_f128"),
`
``
307
`+
FloatTy::F16 => Scalar::from_f16(Half::from_u128(v).value),
`
308
308
`FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value),
`
309
309
`FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value),
`
310
``
`-
FloatTy::F128 => unimplemented!("f16_f128"),
`
``
310
`+
FloatTy::F128 => Scalar::from_f128(Quad::from_u128(v).value),
`
311
311
`},
`
312
312
``
313
313
`// u8 -> char
`
`@@ -321,7 +321,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
`
321
321
`` /// Low-level cast helper function. Converts an apfloat f
into int or float types.
``
322
322
`fn cast_from_float(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar<M::Provenance>
`
323
323
`where
`
324
``
`-
F: Float + Into<Scalar<M::Provenance>> + FloatConvert + FloatConvert,
`
``
324
`+
F: Float
`
``
325
`+
- Into<Scalar<M::Provenance>>
`
``
326
`+
- FloatConvert
`
``
327
`+
- FloatConvert
`
``
328
`+
- FloatConvert
`
``
329
`+
- FloatConvert,
`
325
330
`{
`
326
331
`use rustc_type_ir::TyKind::*;
`
327
332
``
`@@ -358,10 +363,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
`
358
363
`}
`
359
364
`// float -> float
`
360
365
`Float(fty) => match fty {
`
361
``
`-
FloatTy::F16 => unimplemented!("f16_f128"),
`
``
366
`+
FloatTy::F16 => Scalar::from_f16(adjust_nan(self, f, f.convert(&mut false).value)),
`
362
367
`FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)),
`
363
368
`FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)),
`
364
``
`-
FloatTy::F128 => unimplemented!("f16_f128"),
`
``
369
`+
FloatTy::F128 => {
`
``
370
`+
Scalar::from_f128(adjust_nan(self, f, f.convert(&mut false).value))
`
``
371
`+
}
`
365
372
`},
`
366
373
`// That's it.
`
367
374
` _ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty),
`