From 3b7e69a7e606c05964a002f098c76189b6ad571a Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 18 Jun 2024 21:39:00 -0500 Subject: [PATCH] Add math intrinsics for `f16` and `f128` These already exist in the compiler. Expose them in core so we can add their library functions. --- library/core/src/intrinsics.rs | 289 +++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 720da0feecee6..017b20c122431 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1580,6 +1580,12 @@ extern "rust-intrinsic" { #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"] pub fn unaligned_volatile_store(dst: *mut T, val: T); + /// Returns the square root of an `f16` + /// + /// The stabilized version of this intrinsic is + /// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt) + #[rustc_nounwind] + pub fn sqrtf16(x: f16) -> f16; /// Returns the square root of an `f32` /// /// The stabilized version of this intrinsic is @@ -1592,6 +1598,12 @@ extern "rust-intrinsic" { /// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt) #[rustc_nounwind] pub fn sqrtf64(x: f64) -> f64; + /// Returns the square root of an `f128` + /// + /// The stabilized version of this intrinsic is + /// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt) + #[rustc_nounwind] + pub fn sqrtf128(x: f128) -> f128; /// Raises an `f16` to an integer power. /// @@ -1618,6 +1630,12 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn powif128(a: f128, x: i32) -> f128; + /// Returns the sine of an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::sin`](../../std/primitive.f16.html#method.sin) + #[rustc_nounwind] + pub fn sinf16(x: f16) -> f16; /// Returns the sine of an `f32`. /// /// The stabilized version of this intrinsic is @@ -1630,7 +1648,19 @@ extern "rust-intrinsic" { /// [`f64::sin`](../../std/primitive.f64.html#method.sin) #[rustc_nounwind] pub fn sinf64(x: f64) -> f64; + /// Returns the sine of an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::sin`](../../std/primitive.f128.html#method.sin) + #[rustc_nounwind] + pub fn sinf128(x: f128) -> f128; + /// Returns the cosine of an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::cos`](../../std/primitive.f16.html#method.cos) + #[rustc_nounwind] + pub fn cosf16(x: f16) -> f16; /// Returns the cosine of an `f32`. /// /// The stabilized version of this intrinsic is @@ -1643,7 +1673,19 @@ extern "rust-intrinsic" { /// [`f64::cos`](../../std/primitive.f64.html#method.cos) #[rustc_nounwind] pub fn cosf64(x: f64) -> f64; + /// Returns the cosine of an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::cos`](../../std/primitive.f128.html#method.cos) + #[rustc_nounwind] + pub fn cosf128(x: f128) -> f128; + /// Raises an `f16` to an `f16` power. + /// + /// The stabilized version of this intrinsic is + /// [`f16::powf`](../../std/primitive.f16.html#method.powf) + #[rustc_nounwind] + pub fn powf16(a: f16, x: f16) -> f16; /// Raises an `f32` to an `f32` power. /// /// The stabilized version of this intrinsic is @@ -1656,7 +1698,19 @@ extern "rust-intrinsic" { /// [`f64::powf`](../../std/primitive.f64.html#method.powf) #[rustc_nounwind] pub fn powf64(a: f64, x: f64) -> f64; + /// Raises an `f128` to an `f128` power. + /// + /// The stabilized version of this intrinsic is + /// [`f128::powf`](../../std/primitive.f128.html#method.powf) + #[rustc_nounwind] + pub fn powf128(a: f128, x: f128) -> f128; + /// Returns the exponential of an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::exp`](../../std/primitive.f16.html#method.exp) + #[rustc_nounwind] + pub fn expf16(x: f16) -> f16; /// Returns the exponential of an `f32`. /// /// The stabilized version of this intrinsic is @@ -1669,7 +1723,19 @@ extern "rust-intrinsic" { /// [`f64::exp`](../../std/primitive.f64.html#method.exp) #[rustc_nounwind] pub fn expf64(x: f64) -> f64; + /// Returns the exponential of an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::exp`](../../std/primitive.f128.html#method.exp) + #[rustc_nounwind] + pub fn expf128(x: f128) -> f128; + /// Returns 2 raised to the power of an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::exp2`](../../std/primitive.f16.html#method.exp2) + #[rustc_nounwind] + pub fn exp2f16(x: f16) -> f16; /// Returns 2 raised to the power of an `f32`. /// /// The stabilized version of this intrinsic is @@ -1682,7 +1748,19 @@ extern "rust-intrinsic" { /// [`f64::exp2`](../../std/primitive.f64.html#method.exp2) #[rustc_nounwind] pub fn exp2f64(x: f64) -> f64; + /// Returns 2 raised to the power of an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::exp2`](../../std/primitive.f128.html#method.exp2) + #[rustc_nounwind] + pub fn exp2f128(x: f128) -> f128; + /// Returns the natural logarithm of an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::ln`](../../std/primitive.f16.html#method.ln) + #[rustc_nounwind] + pub fn logf16(x: f16) -> f16; /// Returns the natural logarithm of an `f32`. /// /// The stabilized version of this intrinsic is @@ -1695,7 +1773,19 @@ extern "rust-intrinsic" { /// [`f64::ln`](../../std/primitive.f64.html#method.ln) #[rustc_nounwind] pub fn logf64(x: f64) -> f64; + /// Returns the natural logarithm of an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::ln`](../../std/primitive.f128.html#method.ln) + #[rustc_nounwind] + pub fn logf128(x: f128) -> f128; + /// Returns the base 10 logarithm of an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::log10`](../../std/primitive.f16.html#method.log10) + #[rustc_nounwind] + pub fn log10f16(x: f16) -> f16; /// Returns the base 10 logarithm of an `f32`. /// /// The stabilized version of this intrinsic is @@ -1708,7 +1798,19 @@ extern "rust-intrinsic" { /// [`f64::log10`](../../std/primitive.f64.html#method.log10) #[rustc_nounwind] pub fn log10f64(x: f64) -> f64; + /// Returns the base 10 logarithm of an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::log10`](../../std/primitive.f128.html#method.log10) + #[rustc_nounwind] + pub fn log10f128(x: f128) -> f128; + /// Returns the base 2 logarithm of an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::log2`](../../std/primitive.f16.html#method.log2) + #[rustc_nounwind] + pub fn log2f16(x: f16) -> f16; /// Returns the base 2 logarithm of an `f32`. /// /// The stabilized version of this intrinsic is @@ -1721,7 +1823,19 @@ extern "rust-intrinsic" { /// [`f64::log2`](../../std/primitive.f64.html#method.log2) #[rustc_nounwind] pub fn log2f64(x: f64) -> f64; + /// Returns the base 2 logarithm of an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::log2`](../../std/primitive.f128.html#method.log2) + #[rustc_nounwind] + pub fn log2f128(x: f128) -> f128; + /// Returns `a * b + c` for `f16` values. + /// + /// The stabilized version of this intrinsic is + /// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) + #[rustc_nounwind] + pub fn fmaf16(a: f16, b: f16, c: f16) -> f16; /// Returns `a * b + c` for `f32` values. /// /// The stabilized version of this intrinsic is @@ -1734,7 +1848,19 @@ extern "rust-intrinsic" { /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) #[rustc_nounwind] pub fn fmaf64(a: f64, b: f64, c: f64) -> f64; + /// Returns `a * b + c` for `f128` values. + /// + /// The stabilized version of this intrinsic is + /// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) + #[rustc_nounwind] + pub fn fmaf128(a: f128, b: f128, c: f128) -> f128; + /// Returns the absolute value of an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::abs`](../../std/primitive.f16.html#method.abs) + #[rustc_nounwind] + pub fn fabsf16(x: f16) -> f16; /// Returns the absolute value of an `f32`. /// /// The stabilized version of this intrinsic is @@ -1747,7 +1873,25 @@ extern "rust-intrinsic" { /// [`f64::abs`](../../std/primitive.f64.html#method.abs) #[rustc_nounwind] pub fn fabsf64(x: f64) -> f64; + /// Returns the absolute value of an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::abs`](../../std/primitive.f128.html#method.abs) + #[rustc_nounwind] + pub fn fabsf128(x: f128) -> f128; + /// Returns the minimum of two `f16` values. + /// + /// Note that, unlike most intrinsics, this is safe to call; + /// it does not require an `unsafe` block. + /// Therefore, implementations must not require the user to uphold + /// any safety invariants. + /// + /// The stabilized version of this intrinsic is + /// [`f16::min`] + #[rustc_safe_intrinsic] + #[rustc_nounwind] + pub fn minnumf16(x: f16, y: f16) -> f16; /// Returns the minimum of two `f32` values. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -1772,6 +1916,31 @@ extern "rust-intrinsic" { #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn minnumf64(x: f64, y: f64) -> f64; + /// Returns the minimum of two `f128` values. + /// + /// Note that, unlike most intrinsics, this is safe to call; + /// it does not require an `unsafe` block. + /// Therefore, implementations must not require the user to uphold + /// any safety invariants. + /// + /// The stabilized version of this intrinsic is + /// [`f128::min`] + #[rustc_safe_intrinsic] + #[rustc_nounwind] + pub fn minnumf128(x: f128, y: f128) -> f128; + + /// Returns the maximum of two `f16` values. + /// + /// Note that, unlike most intrinsics, this is safe to call; + /// it does not require an `unsafe` block. + /// Therefore, implementations must not require the user to uphold + /// any safety invariants. + /// + /// The stabilized version of this intrinsic is + /// [`f16::max`] + #[rustc_safe_intrinsic] + #[rustc_nounwind] + pub fn maxnumf16(x: f16, y: f16) -> f16; /// Returns the maximum of two `f32` values. /// /// Note that, unlike most intrinsics, this is safe to call; @@ -1796,7 +1965,25 @@ extern "rust-intrinsic" { #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn maxnumf64(x: f64, y: f64) -> f64; + /// Returns the maximum of two `f128` values. + /// + /// Note that, unlike most intrinsics, this is safe to call; + /// it does not require an `unsafe` block. + /// Therefore, implementations must not require the user to uphold + /// any safety invariants. + /// + /// The stabilized version of this intrinsic is + /// [`f128::max`] + #[rustc_safe_intrinsic] + #[rustc_nounwind] + pub fn maxnumf128(x: f128, y: f128) -> f128; + /// Copies the sign from `y` to `x` for `f16` values. + /// + /// The stabilized version of this intrinsic is + /// [`f16::copysign`](../../std/primitive.f16.html#method.copysign) + #[rustc_nounwind] + pub fn copysignf16(x: f16, y: f16) -> f16; /// Copies the sign from `y` to `x` for `f32` values. /// /// The stabilized version of this intrinsic is @@ -1809,7 +1996,19 @@ extern "rust-intrinsic" { /// [`f64::copysign`](../../std/primitive.f64.html#method.copysign) #[rustc_nounwind] pub fn copysignf64(x: f64, y: f64) -> f64; + /// Copies the sign from `y` to `x` for `f128` values. + /// + /// The stabilized version of this intrinsic is + /// [`f128::copysign`](../../std/primitive.f128.html#method.copysign) + #[rustc_nounwind] + pub fn copysignf128(x: f128, y: f128) -> f128; + /// Returns the largest integer less than or equal to an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::floor`](../../std/primitive.f16.html#method.floor) + #[rustc_nounwind] + pub fn floorf16(x: f16) -> f16; /// Returns the largest integer less than or equal to an `f32`. /// /// The stabilized version of this intrinsic is @@ -1822,7 +2021,19 @@ extern "rust-intrinsic" { /// [`f64::floor`](../../std/primitive.f64.html#method.floor) #[rustc_nounwind] pub fn floorf64(x: f64) -> f64; + /// Returns the largest integer less than or equal to an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::floor`](../../std/primitive.f128.html#method.floor) + #[rustc_nounwind] + pub fn floorf128(x: f128) -> f128; + /// Returns the smallest integer greater than or equal to an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) + #[rustc_nounwind] + pub fn ceilf16(x: f16) -> f16; /// Returns the smallest integer greater than or equal to an `f32`. /// /// The stabilized version of this intrinsic is @@ -1835,7 +2046,19 @@ extern "rust-intrinsic" { /// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) #[rustc_nounwind] pub fn ceilf64(x: f64) -> f64; + /// Returns the smallest integer greater than or equal to an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) + #[rustc_nounwind] + pub fn ceilf128(x: f128) -> f128; + /// Returns the integer part of an `f16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) + #[rustc_nounwind] + pub fn truncf16(x: f16) -> f16; /// Returns the integer part of an `f32`. /// /// The stabilized version of this intrinsic is @@ -1848,7 +2071,25 @@ extern "rust-intrinsic" { /// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) #[rustc_nounwind] pub fn truncf64(x: f64) -> f64; + /// Returns the integer part of an `f128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) + #[rustc_nounwind] + pub fn truncf128(x: f128) -> f128; + /// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, + /// so this rounds half-way cases to the number with an even least significant digit. + /// + /// May raise an inexact floating-point exception if the argument is not an integer. + /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions + /// cannot actually be utilized from Rust code. + /// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`. + /// + /// The stabilized version of this intrinsic is + /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) + #[rustc_nounwind] + pub fn rintf16(x: f16) -> f16; /// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, /// so this rounds half-way cases to the number with an even least significant digit. /// @@ -1873,7 +2114,25 @@ extern "rust-intrinsic" { /// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) #[rustc_nounwind] pub fn rintf64(x: f64) -> f64; + /// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, + /// so this rounds half-way cases to the number with an even least significant digit. + /// + /// May raise an inexact floating-point exception if the argument is not an integer. + /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions + /// cannot actually be utilized from Rust code. + /// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`. + /// + /// The stabilized version of this intrinsic is + /// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) + #[rustc_nounwind] + pub fn rintf128(x: f128) -> f128; + /// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, + /// so this rounds half-way cases to the number with an even least significant digit. + /// + /// This intrinsic does not have a stable counterpart. + #[rustc_nounwind] + pub fn nearbyintf16(x: f16) -> f16; /// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, /// so this rounds half-way cases to the number with an even least significant digit. /// @@ -1886,7 +2145,19 @@ extern "rust-intrinsic" { /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] pub fn nearbyintf64(x: f64) -> f64; + /// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, + /// so this rounds half-way cases to the number with an even least significant digit. + /// + /// This intrinsic does not have a stable counterpart. + #[rustc_nounwind] + pub fn nearbyintf128(x: f128) -> f128; + /// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. + /// + /// The stabilized version of this intrinsic is + /// [`f16::round`](../../std/primitive.f16.html#method.round) + #[rustc_nounwind] + pub fn roundf16(x: f16) -> f16; /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. /// /// The stabilized version of this intrinsic is @@ -1899,7 +2170,19 @@ extern "rust-intrinsic" { /// [`f64::round`](../../std/primitive.f64.html#method.round) #[rustc_nounwind] pub fn roundf64(x: f64) -> f64; + /// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. + /// + /// The stabilized version of this intrinsic is + /// [`f128::round`](../../std/primitive.f128.html#method.round) + #[rustc_nounwind] + pub fn roundf128(x: f128) -> f128; + /// Returns the nearest integer to an `f16`. Rounds half-way cases to the number + /// with an even least significant digit. + /// + /// This intrinsic does not have a stable counterpart. + #[rustc_nounwind] + pub fn roundevenf16(x: f16) -> f16; /// Returns the nearest integer to an `f32`. Rounds half-way cases to the number /// with an even least significant digit. /// @@ -1912,6 +2195,12 @@ extern "rust-intrinsic" { /// This intrinsic does not have a stable counterpart. #[rustc_nounwind] pub fn roundevenf64(x: f64) -> f64; + /// Returns the nearest integer to an `f128`. Rounds half-way cases to the number + /// with an even least significant digit. + /// + /// This intrinsic does not have a stable counterpart. + #[rustc_nounwind] + pub fn roundevenf128(x: f128) -> f128; /// Float addition that allows optimizations based on algebraic rules. /// May assume inputs are finite.