Skip to content

Commit 38a0227

Browse files
committed
Add compiler support for parsing f16 and f128
1 parent 1547c07 commit 38a0227

File tree

4 files changed

+71
-5
lines changed

4 files changed

+71
-5
lines changed

compiler/rustc_ast/src/util/literal.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,10 @@ fn filtered_float_lit(
276276
Some(suffix) => LitKind::Float(
277277
symbol,
278278
ast::LitFloatType::Suffixed(match suffix {
279+
sym::f16 => ast::FloatTy::F16,
279280
sym::f32 => ast::FloatTy::F32,
280281
sym::f64 => ast::FloatTy::F64,
282+
sym::f128 => ast::FloatTy::F128,
281283
_ => return Err(LitError::InvalidFloatSuffix(suffix)),
282284
}),
283285
),

compiler/rustc_middle/src/mir/interpret/value.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::fmt;
33
use either::{Either, Left, Right};
44

55
use rustc_apfloat::{
6-
ieee::{Double, Single},
6+
ieee::{Double, Half, Quad, Single},
77
Float,
88
};
99
use rustc_macros::HashStable;
@@ -201,6 +201,11 @@ impl<Prov> Scalar<Prov> {
201201
Self::from_int(i, cx.data_layout().pointer_size)
202202
}
203203

204+
#[inline]
205+
pub fn from_f16(f: Half) -> Self {
206+
Scalar::Int(f.into())
207+
}
208+
204209
#[inline]
205210
pub fn from_f32(f: Single) -> Self {
206211
Scalar::Int(f.into())
@@ -211,6 +216,11 @@ impl<Prov> Scalar<Prov> {
211216
Scalar::Int(f.into())
212217
}
213218

219+
#[inline]
220+
pub fn from_f128(f: Quad) -> Self {
221+
Scalar::Int(f.into())
222+
}
223+
214224
/// This is almost certainly not the method you want! You should dispatch on the type
215225
/// and use `to_{u8,u16,...}`/`scalar_to_ptr` to perform ptr-to-int / int-to-ptr casts as needed.
216226
///
@@ -422,6 +432,11 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
422432
Ok(F::from_bits(self.to_bits(Size::from_bits(F::BITS))?))
423433
}
424434

435+
#[inline]
436+
pub fn to_f16(self) -> InterpResult<'tcx, Half> {
437+
self.to_float()
438+
}
439+
425440
#[inline]
426441
pub fn to_f32(self) -> InterpResult<'tcx, Single> {
427442
self.to_float()
@@ -431,4 +446,9 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
431446
pub fn to_f64(self) -> InterpResult<'tcx, Double> {
432447
self.to_float()
433448
}
449+
450+
#[inline]
451+
pub fn to_f128(self) -> InterpResult<'tcx, Quad> {
452+
self.to_float()
453+
}
434454
}

compiler/rustc_middle/src/ty/consts/int.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_apfloat::ieee::{Double, Single};
1+
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
22
use rustc_apfloat::Float;
33
use rustc_errors::{DiagArgValue, IntoDiagnosticArg};
44
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -369,6 +369,11 @@ impl ScalarInt {
369369
Ok(F::from_bits(self.to_bits(Size::from_bits(F::BITS))?))
370370
}
371371

372+
#[inline]
373+
pub fn try_to_f16(self) -> Result<Half, Size> {
374+
self.try_to_float()
375+
}
376+
372377
#[inline]
373378
pub fn try_to_f32(self) -> Result<Single, Size> {
374379
self.try_to_float()
@@ -378,6 +383,11 @@ impl ScalarInt {
378383
pub fn try_to_f64(self) -> Result<Double, Size> {
379384
self.try_to_float()
380385
}
386+
387+
#[inline]
388+
pub fn try_to_f128(self) -> Result<Quad, Size> {
389+
self.try_to_float()
390+
}
381391
}
382392

383393
macro_rules! from {
@@ -450,6 +460,22 @@ impl TryFrom<ScalarInt> for char {
450460
}
451461
}
452462

463+
impl From<Half> for ScalarInt {
464+
#[inline]
465+
fn from(f: Half) -> Self {
466+
// We trust apfloat to give us properly truncated data.
467+
Self { data: f.to_bits(), size: NonZero::new((Half::BITS / 8) as u8).unwrap() }
468+
}
469+
}
470+
471+
impl TryFrom<ScalarInt> for Half {
472+
type Error = Size;
473+
#[inline]
474+
fn try_from(int: ScalarInt) -> Result<Self, Size> {
475+
int.to_bits(Size::from_bytes(2)).map(Self::from_bits)
476+
}
477+
}
478+
453479
impl From<Single> for ScalarInt {
454480
#[inline]
455481
fn from(f: Single) -> Self {
@@ -482,6 +508,22 @@ impl TryFrom<ScalarInt> for Double {
482508
}
483509
}
484510

511+
impl From<Quad> for ScalarInt {
512+
#[inline]
513+
fn from(f: Quad) -> Self {
514+
// We trust apfloat to give us properly truncated data.
515+
Self { data: f.to_bits(), size: NonZero::new((Quad::BITS / 8) as u8).unwrap() }
516+
}
517+
}
518+
519+
impl TryFrom<ScalarInt> for Quad {
520+
type Error = Size;
521+
#[inline]
522+
fn try_from(int: ScalarInt) -> Result<Self, Size> {
523+
int.to_bits(Size::from_bytes(16)).map(Self::from_bits)
524+
}
525+
}
526+
485527
impl fmt::Debug for ScalarInt {
486528
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
487529
// Dispatch to LowerHex below.

compiler/rustc_mir_build/src/build/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::build::expr::as_place::PlaceBuilder;
22
use crate::build::scope::DropKind;
33
use itertools::Itertools;
4-
use rustc_apfloat::ieee::{Double, Single};
4+
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
55
use rustc_apfloat::Float;
66
use rustc_ast::attr;
77
use rustc_data_structures::fx::FxHashMap;
@@ -1053,7 +1053,8 @@ pub(crate) fn parse_float_into_scalar(
10531053
) -> Option<Scalar> {
10541054
let num = num.as_str();
10551055
match float_ty {
1056-
ty::FloatTy::F16 => unimplemented!("f16_f128"),
1056+
// FIXME(f16_f128): When available, compare to the library parser as with `f32` and `f64`
1057+
ty::FloatTy::F16 => num.parse::<Half>().ok().map(Scalar::from_f16),
10571058
ty::FloatTy::F32 => {
10581059
let Ok(rust_f) = num.parse::<f32>() else { return None };
10591060
let mut f = num
@@ -1100,7 +1101,8 @@ pub(crate) fn parse_float_into_scalar(
11001101

11011102
Some(Scalar::from_f64(f))
11021103
}
1103-
ty::FloatTy::F128 => unimplemented!("f16_f128"),
1104+
// FIXME(f16_f128): When available, compare to the library parser as with `f32` and `f64`
1105+
ty::FloatTy::F128 => num.parse::<Quad>().ok().map(Scalar::from_f128),
11041106
}
11051107
}
11061108

0 commit comments

Comments
 (0)