Skip to content

Commit

Permalink
Rollup merge of #122470 - tgross35:f16-f128-step4-libs-min, r=Amanieu
Browse files Browse the repository at this point in the history
`f16` and `f128` step 4: basic library support

This is the next step after #121926, another portion of #114607

Tracking issue: #116909

This PR adds the most basic operations to `f16` and `f128` that get lowered as LLVM intrinsics. This is a very small step but it seemed reasonable enough to add unopinionated basic operations before the larger modules that are built on top of them.

r? ```@Amanieu``` since you were pretty involved in the RFC
cc ```@compiler-errors```
```@rustbot``` label +T-libs-api +S-blocked +F-f16_and_f128
  • Loading branch information
fmease authored Apr 10, 2024
2 parents aa067fb + 311ad55 commit aac3f24
Show file tree
Hide file tree
Showing 20 changed files with 482 additions and 50 deletions.
5 changes: 1 addition & 4 deletions library/core/src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,10 @@ mod impls {
impl_clone! {
usize u8 u16 u32 u64 u128
isize i8 i16 i32 i64 i128
f32 f64
f16 f32 f64 f128
bool char
}

#[cfg(not(bootstrap))]
impl_clone! { f16 f128 }

#[unstable(feature = "never_type", issue = "35121")]
impl Clone for ! {
#[inline]
Expand Down
10 changes: 2 additions & 8 deletions library/core/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1497,12 +1497,9 @@ mod impls {
}

partial_eq_impl! {
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
}

#[cfg(not(bootstrap))]
partial_eq_impl! { f16 f128 }

macro_rules! eq_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -1553,10 +1550,7 @@ mod impls {
}
}

partial_ord_impl! { f32 f64 }

#[cfg(not(bootstrap))]
partial_ord_impl! { f16 f128 }
partial_ord_impl! { f16 f32 f64 f128 }

macro_rules! ord_impl {
($($t:ty)*) => ($(
Expand Down
7 changes: 7 additions & 0 deletions library/core/src/convert/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ macro_rules! impl_float_to_int {
}
}

impl_float_to_int!(f16 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
impl_float_to_int!(f32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
impl_float_to_int!(f64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
impl_float_to_int!(f128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);

// Conversion traits for primitive integer and float types
// Conversions T -> T are covered by a blanket impl and therefore excluded
Expand Down Expand Up @@ -163,7 +165,12 @@ impl_from!(u16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);

// float -> float
impl_from!(f16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
impl_from!(f16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
impl_from!(f16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
impl_from!(f32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
impl_from!(f64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);

macro_rules! impl_float_from_bool {
($float:ty) => {
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/fmt/nofloat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ macro_rules! floating {
};
}

floating! { f16 }
floating! { f32 }
floating! { f64 }
floating! { f128 }
8 changes: 6 additions & 2 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,6 @@
//
// Language features:
// tidy-alphabetical-start
#![cfg_attr(not(bootstrap), feature(f128))]
#![cfg_attr(not(bootstrap), feature(f16))]
#![feature(abi_unadjusted)]
#![feature(adt_const_params)]
#![feature(allow_internal_unsafe)]
Expand All @@ -226,6 +224,8 @@
#![feature(doc_notable_trait)]
#![feature(effects)]
#![feature(extern_types)]
#![feature(f128)]
#![feature(f16)]
#![feature(freeze_impls)]
#![feature(fundamental)]
#![feature(generic_arg_infer)]
Expand Down Expand Up @@ -347,6 +347,10 @@ pub mod u8;
#[path = "num/shells/usize.rs"]
pub mod usize;

#[path = "num/f128.rs"]
pub mod f128;
#[path = "num/f16.rs"]
pub mod f16;
#[path = "num/f32.rs"]
pub mod f32;
#[path = "num/f64.rs"]
Expand Down
8 changes: 1 addition & 7 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,17 +422,11 @@ marker_impls! {
Copy for
usize, u8, u16, u32, u64, u128,
isize, i8, i16, i32, i64, i128,
f32, f64,
f16, f32, f64, f128,
bool, char,
{T: ?Sized} *const T,
{T: ?Sized} *mut T,
}

#[cfg(not(bootstrap))]
marker_impls! {
#[stable(feature = "rust1", since = "1.0.0")]
Copy for
f16, f128,
}

#[unstable(feature = "never_type", issue = "35121")]
Expand Down
16 changes: 16 additions & 0 deletions library/core/src/num/f128.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! Constants for the `f128` quadruple-precision floating point type.
//!
//! *[See also the `f128` primitive type][f128].*
//!
//! Mathematically significant numbers are provided in the `consts` sub-module.
//!
//! For the constants defined directly in this module
//! (as distinct from those defined in the `consts` sub-module),
//! new code should instead use the associated constants
//! defined directly on the `f128` type.
#![unstable(feature = "f128", issue = "116909")]

/// Basic mathematical constants.
#[unstable(feature = "f128", issue = "116909")]
pub mod consts {}
16 changes: 16 additions & 0 deletions library/core/src/num/f16.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! Constants for the `f16` half-precision floating point type.
//!
//! *[See also the `f16` primitive type][f16].*
//!
//! Mathematically significant numbers are provided in the `consts` sub-module.
//!
//! For the constants defined directly in this module
//! (as distinct from those defined in the `consts` sub-module),
//! new code should instead use the associated constants
//! defined directly on the `f16` type.
#![unstable(feature = "f16", issue = "116909")]

/// Basic mathematical constants.
#[unstable(feature = "f16", issue = "116909")]
pub mod consts {}
22 changes: 11 additions & 11 deletions library/core/src/ops/arith.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ macro_rules! add_impl {
)*)
}

add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }

/// The subtraction operator `-`.
///
Expand Down Expand Up @@ -218,7 +218,7 @@ macro_rules! sub_impl {
)*)
}

sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }

/// The multiplication operator `*`.
///
Expand Down Expand Up @@ -348,7 +348,7 @@ macro_rules! mul_impl {
)*)
}

mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }

/// The division operator `/`.
///
Expand Down Expand Up @@ -506,7 +506,7 @@ macro_rules! div_impl_float {
)*)
}

div_impl_float! { f32 f64 }
div_impl_float! { f16 f32 f64 f128 }

/// The remainder operator `%`.
///
Expand Down Expand Up @@ -623,7 +623,7 @@ macro_rules! rem_impl_float {
)*)
}

rem_impl_float! { f32 f64 }
rem_impl_float! { f16 f32 f64 f128 }

/// The unary negation operator `-`.
///
Expand Down Expand Up @@ -698,7 +698,7 @@ macro_rules! neg_impl {
)*)
}

neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
neg_impl! { isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }

/// The addition assignment operator `+=`.
///
Expand Down Expand Up @@ -765,7 +765,7 @@ macro_rules! add_assign_impl {
)+)
}

add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }

/// The subtraction assignment operator `-=`.
///
Expand Down Expand Up @@ -832,7 +832,7 @@ macro_rules! sub_assign_impl {
)+)
}

sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }

/// The multiplication assignment operator `*=`.
///
Expand Down Expand Up @@ -890,7 +890,7 @@ macro_rules! mul_assign_impl {
)+)
}

mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }

/// The division assignment operator `/=`.
///
Expand Down Expand Up @@ -947,7 +947,7 @@ macro_rules! div_assign_impl {
)+)
}

div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }

/// The remainder assignment operator `%=`.
///
Expand Down Expand Up @@ -1008,4 +1008,4 @@ macro_rules! rem_assign_impl {
)+)
}

rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
30 changes: 30 additions & 0 deletions library/core/src/primitive_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,22 @@ mod prim_tuple {}
#[doc(hidden)]
impl<T> (T,) {}

#[rustc_doc_primitive = "f16"]
#[doc(alias = "half")]
/// A 16-bit floating point type (specifically, the "binary16" type defined in IEEE 754-2008).
///
/// This type is very similar to [`prim@f32`] but has decreased precision because it uses half as many
/// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on
/// half-precision values][wikipedia] for more information.
///
/// *[See also the `std::f16::consts` module](crate::f16::consts).*
///
/// [wikipedia]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
#[unstable(feature = "f16", issue = "116909")]
mod prim_f16 {}

#[rustc_doc_primitive = "f32"]
#[doc(alias = "single")]
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
///
/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
Expand Down Expand Up @@ -1143,6 +1158,7 @@ impl<T> (T,) {}
mod prim_f32 {}

#[rustc_doc_primitive = "f64"]
#[doc(alias = "double")]
/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
///
/// This type is very similar to [`f32`], but has increased
Expand All @@ -1157,6 +1173,20 @@ mod prim_f32 {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_f64 {}

#[rustc_doc_primitive = "f128"]
#[doc(alias = "quad")]
/// A 128-bit floating point type (specifically, the "binary128" type defined in IEEE 754-2008).
///
/// This type is very similar to [`prim@f32`] and [`prim@f64`], but has increased precision by using twice
/// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on
/// quad-precision values][wikipedia] for more information.
///
/// *[See also the `std::f128::consts` module](crate::f128::consts).*
///
/// [wikipedia]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
#[unstable(feature = "f128", issue = "116909")]
mod prim_f128 {}

#[rustc_doc_primitive = "i8"]
//
/// The 8-bit signed integer type.
Expand Down
11 changes: 11 additions & 0 deletions library/std/src/f128.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! Constants for the `f128` double-precision floating point type.
//!
//! *[See also the `f128` primitive type](primitive@f128).*
//!
//! Mathematically significant numbers are provided in the `consts` sub-module.
#[cfg(test)]
mod tests;

#[unstable(feature = "f128", issue = "116909")]
pub use core::f128::consts;
40 changes: 40 additions & 0 deletions library/std/src/f128/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used

/// Smallest number
const TINY_BITS: u128 = 0x1;
/// Next smallest number
const TINY_UP_BITS: u128 = 0x2;
/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
const MAX_DOWN_BITS: u128 = 0x7ffeffffffffffffffffffffffffffff;
/// Zeroed exponent, full significant
const LARGEST_SUBNORMAL_BITS: u128 = 0x0000ffffffffffffffffffffffffffff;
/// Exponent = 0b1, zeroed significand
const SMALLEST_NORMAL_BITS: u128 = 0x00010000000000000000000000000000;
/// First pattern over the mantissa
const NAN_MASK1: u128 = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa;
/// Second pattern over the mantissa
const NAN_MASK2: u128 = 0x00005555555555555555555555555555;

/// Compare by value
#[allow(unused_macros)]
macro_rules! assert_f128_eq {
($a:expr, $b:expr) => {
let (l, r): (&f128, &f128) = (&$a, &$b);
assert_eq!(*l, *r, "\na: {:#0130x}\nb: {:#0130x}", l.to_bits(), r.to_bits())
};
}

/// Compare by representation
#[allow(unused_macros)]
macro_rules! assert_f128_biteq {
($a:expr, $b:expr) => {
let (l, r): (&f128, &f128) = (&$a, &$b);
let lb = l.to_bits();
let rb = r.to_bits();
assert_eq!(
lb, rb,
"float {:?} is not bitequal to {:?}.\na: {:#0130x}\nb: {:#0130x}",
*l, *r, lb, rb
);
};
}
11 changes: 11 additions & 0 deletions library/std/src/f16.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! Constants for the `f16` double-precision floating point type.
//!
//! *[See also the `f16` primitive type](primitive@f16).*
//!
//! Mathematically significant numbers are provided in the `consts` sub-module.
#[cfg(test)]
mod tests;

#[unstable(feature = "f16", issue = "116909")]
pub use core::f16::consts;
Loading

0 comments on commit aac3f24

Please sign in to comment.