Skip to content

Commit edf40ed

Browse files
committed
Next stage of f16 and f128
1 parent 8cb4195 commit edf40ed

File tree

6 files changed

+86
-6
lines changed

6 files changed

+86
-6
lines changed

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -303,15 +303,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
303303
self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
304304

305305
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
306-
(Int(..) | F32 | F64, Int(..) | F32 | F64) => bx.bitcast(imm, to_backend_ty),
306+
(Int(..) | F16 | F32 | F64 | F128, Int(..) | F16 | F32 | F64 | F128) => {
307+
bx.bitcast(imm, to_backend_ty)
308+
}
307309
(Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
308310
(Int(..), Pointer(..)) => bx.inttoptr(imm, to_backend_ty),
309311
(Pointer(..), Int(..)) => bx.ptrtoint(imm, to_backend_ty),
310-
(F32 | F64, Pointer(..)) => {
312+
(F16 | F32 | F64 | F128, Pointer(..)) => {
311313
let int_imm = bx.bitcast(imm, bx.cx().type_isize());
312314
bx.inttoptr(int_imm, to_backend_ty)
313315
}
314-
(Pointer(..), F32 | F64) => {
316+
(Pointer(..), F16 | F32 | F64 | F128) => {
315317
let int_imm = bx.ptrtoint(imm, bx.cx().type_isize());
316318
bx.bitcast(int_imm, to_backend_ty)
317319
}

compiler/rustc_const_eval/src/interpret/operator.rs

+6
Original file line numberDiff line numberDiff line change
@@ -380,12 +380,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
380380
let left = left.to_scalar();
381381
let right = right.to_scalar();
382382
Ok(match fty {
383+
FloatTy::F16 => {
384+
self.binary_float_op(bin_op, ty, left.to_f16()?, right.to_f16()?)
385+
}
383386
FloatTy::F32 => {
384387
self.binary_float_op(bin_op, ty, left.to_f32()?, right.to_f32()?)
385388
}
386389
FloatTy::F64 => {
387390
self.binary_float_op(bin_op, ty, left.to_f64()?, right.to_f64()?)
388391
}
392+
FloatTy::F128 => {
393+
self.binary_float_op(bin_op, ty, left.to_f128()?, right.to_f128()?)
394+
}
389395
})
390396
}
391397
_ if left.layout.ty.is_integral() => {

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

+37-1
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;
@@ -159,6 +159,13 @@ impl<Prov: Provenance> fmt::LowerHex for Scalar<Prov> {
159159
}
160160
}
161161

162+
impl<Prov> From<Half> for Scalar<Prov> {
163+
#[inline(always)]
164+
fn from(f: Half) -> Self {
165+
Scalar::from_f16(f)
166+
}
167+
}
168+
162169
impl<Prov> From<Single> for Scalar<Prov> {
163170
#[inline(always)]
164171
fn from(f: Single) -> Self {
@@ -173,6 +180,13 @@ impl<Prov> From<Double> for Scalar<Prov> {
173180
}
174181
}
175182

183+
impl<Prov> From<Quad> for Scalar<Prov> {
184+
#[inline(always)]
185+
fn from(f: Quad) -> Self {
186+
Scalar::from_f128(f)
187+
}
188+
}
189+
176190
impl<Prov> From<ScalarInt> for Scalar<Prov> {
177191
#[inline(always)]
178192
fn from(ptr: ScalarInt) -> Self {
@@ -281,6 +295,11 @@ impl<Prov> Scalar<Prov> {
281295
Self::from_int(i, cx.data_layout().pointer_size)
282296
}
283297

298+
#[inline]
299+
pub fn from_f16(f: Half) -> Self {
300+
Scalar::Int(f.into())
301+
}
302+
284303
#[inline]
285304
pub fn from_f32(f: Single) -> Self {
286305
Scalar::Int(f.into())
@@ -291,6 +310,11 @@ impl<Prov> Scalar<Prov> {
291310
Scalar::Int(f.into())
292311
}
293312

313+
#[inline]
314+
pub fn from_f128(f: Quad) -> Self {
315+
Scalar::Int(f.into())
316+
}
317+
294318
/// This is almost certainly not the method you want! You should dispatch on the type
295319
/// and use `to_{u8,u16,...}`/`scalar_to_ptr` to perform ptr-to-int / int-to-ptr casts as needed.
296320
///
@@ -493,6 +517,12 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
493517
Ok(i64::try_from(b).unwrap())
494518
}
495519

520+
#[inline]
521+
pub fn to_f16(self) -> InterpResult<'tcx, Half> {
522+
// Going through `u16` to check size and truncation.
523+
Ok(Half::from_bits(self.to_u16()?.into()))
524+
}
525+
496526
#[inline]
497527
pub fn to_f32(self) -> InterpResult<'tcx, Single> {
498528
// Going through `u32` to check size and truncation.
@@ -504,6 +534,12 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
504534
// Going through `u64` to check size and truncation.
505535
Ok(Double::from_bits(self.to_u64()?.into()))
506536
}
537+
538+
#[inline]
539+
pub fn to_f128(self) -> InterpResult<'tcx, Quad> {
540+
// Going through `u128` to check size and truncation.
541+
Ok(Quad::from_bits(self.to_u128()?.into()))
542+
}
507543
}
508544

509545
/// Gets the bytes of a constant slice value.

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

+33-1
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::{DiagnosticArgValue, IntoDiagnosticArg};
44
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -428,6 +428,22 @@ impl TryFrom<ScalarInt> for char {
428428
}
429429
}
430430

431+
impl From<Half> for ScalarInt {
432+
#[inline]
433+
fn from(f: Half) -> Self {
434+
// We trust apfloat to give us properly truncated data.
435+
Self { data: f.to_bits(), size: NonZeroU8::new((Half::BITS / 8) as u8).unwrap() }
436+
}
437+
}
438+
439+
impl TryFrom<ScalarInt> for Half {
440+
type Error = Size;
441+
#[inline]
442+
fn try_from(int: ScalarInt) -> Result<Self, Size> {
443+
int.to_bits(Size::from_bytes(2)).map(Self::from_bits)
444+
}
445+
}
446+
431447
impl From<Single> for ScalarInt {
432448
#[inline]
433449
fn from(f: Single) -> Self {
@@ -460,6 +476,22 @@ impl TryFrom<ScalarInt> for Double {
460476
}
461477
}
462478

479+
impl From<Quad> for ScalarInt {
480+
#[inline]
481+
fn from(f: Quad) -> Self {
482+
// We trust apfloat to give us properly truncated data.
483+
Self { data: f.to_bits(), size: NonZeroU8::new((Quad::BITS / 8) as u8).unwrap() }
484+
}
485+
}
486+
487+
impl TryFrom<ScalarInt> for Quad {
488+
type Error = Size;
489+
#[inline]
490+
fn try_from(int: ScalarInt) -> Result<Self, Size> {
491+
int.to_bits(Size::from_bytes(16)).map(Self::from_bits)
492+
}
493+
}
494+
463495
impl fmt::Debug for ScalarInt {
464496
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
465497
// Dispatch to LowerHex below.

compiler/rustc_middle/src/ty/layout.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,10 @@ impl PrimitiveExt for Primitive {
130130
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
131131
match *self {
132132
Int(i, signed) => i.to_ty(tcx, signed),
133+
F16 => tcx.types.f16,
133134
F32 => tcx.types.f32,
134135
F64 => tcx.types.f64,
136+
F128 => tcx.types.f128,
135137
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
136138
Pointer(_) => Ty::new_mut_ptr(tcx, Ty::new_unit(tcx)),
137139
}
@@ -148,7 +150,7 @@ impl PrimitiveExt for Primitive {
148150
let signed = false;
149151
tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed)
150152
}
151-
F32 | F64 => bug!("floats do not have an int type"),
153+
F16 | F32 | F64 | F128 => bug!("floats do not have an int type"),
152154
}
153155
}
154156
}

compiler/rustc_ty_utils/src/layout.rs

+2
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,10 @@ fn layout_of_uncached<'tcx>(
137137
ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)),
138138
ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)),
139139
ty::Float(fty) => scalar(match fty {
140+
ty::FloatTy::F16 => F16,
140141
ty::FloatTy::F32 => F32,
141142
ty::FloatTy::F64 => F64,
143+
ty::FloatTy::F128 => F128,
142144
}),
143145
ty::FnPtr(_) => {
144146
let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));

0 commit comments

Comments
 (0)