1
Fork 0

Rollup merge of #122470 - tgross35:f16-f128-step4-libs-min, r=Amanieu

`f16` and `f128` step 4: basic library support

This is the next step after https://github.com/rust-lang/rust/pull/121926, another portion of https://github.com/rust-lang/rust/pull/114607

Tracking issue: https://github.com/rust-lang/rust/issues/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
This commit is contained in:
León Orell Valerian Liehr 2024-04-11 01:56:23 +02:00 committed by GitHub
commit aac3f24054
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 482 additions and 50 deletions

11
library/std/src/f128.rs Normal file
View file

@ -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;

View file

@ -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
library/std/src/f16.rs Normal file
View file

@ -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;

View file

@ -0,0 +1,46 @@
#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used
// We run out of precision pretty quickly with f16
const F16_APPROX_L1: f16 = 0.001;
const F16_APPROX_L2: f16 = 0.01;
const F16_APPROX_L3: f16 = 0.1;
const F16_APPROX_L4: f16 = 0.5;
/// Smallest number
const TINY_BITS: u16 = 0x1;
/// Next smallest number
const TINY_UP_BITS: u16 = 0x2;
/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
const MAX_DOWN_BITS: u16 = 0x7bfe;
/// Zeroed exponent, full significant
const LARGEST_SUBNORMAL_BITS: u16 = 0x03ff;
/// Exponent = 0b1, zeroed significand
const SMALLEST_NORMAL_BITS: u16 = 0x0400;
/// First pattern over the mantissa
const NAN_MASK1: u16 = 0x02aa;
/// Second pattern over the mantissa
const NAN_MASK2: u16 = 0x0155;
/// Compare by value
#[allow(unused_macros)]
macro_rules! assert_f16_eq {
($a:expr, $b:expr) => {
let (l, r): (&f16, &f16) = (&$a, &$b);
assert_eq!(*l, *r, "\na: {:#018x}\nb: {:#018x}", l.to_bits(), r.to_bits())
};
}
/// Compare by representation
#[allow(unused_macros)]
macro_rules! assert_f16_biteq {
($a:expr, $b:expr) => {
let (l, r): (&f16, &f16) = (&$a, &$b);
let lb = l.to_bits();
let rb = r.to_bits();
assert_eq!(
lb, rb,
"float {:?} is not bitequal to {:?}.\na: {:#018x}\nb: {:#018x}",
*l, *r, lb, rb
);
};
}

View file

@ -283,6 +283,8 @@
#![feature(doc_masked)]
#![feature(doc_notable_trait)]
#![feature(dropck_eyepatch)]
#![feature(f128)]
#![feature(f16)]
#![feature(if_let_guard)]
#![feature(intra_doc_pointers)]
#![feature(lang_items)]
@ -558,6 +560,10 @@ pub use core::u8;
#[allow(deprecated, deprecated_in_future)]
pub use core::usize;
#[unstable(feature = "f128", issue = "116909")]
pub mod f128;
#[unstable(feature = "f16", issue = "116909")]
pub mod f16;
pub mod f32;
pub mod f64;