The f128 math functions (acosf128, cbrtf128 etc.) require IEEE 754 binary128 support in the C library. These are not available on PowerPC which uses IBM double-double format rather than IEEE binary128. This patch gates the f128 math extern declarations and the corresponding f128 math methods to exclude PowerPC Apple targets. Also handles lgammaf_r which is not available on legacy macOS, using the same fallback approach as AIX (promote to f64, compute, demote). diff --git a/library/std/src/sys/cmath.rs b/library/std/src/sys/cmath.rs --- a/library/std/src/sys/cmath.rs +++ b/library/std/src/sys/cmath.rs @@ -22,28 +22,49 @@ pub safe fn tgamma(n: f64) -> f64; pub safe fn tgammaf(n: f32) -> f32; pub safe fn lgamma_r(n: f64, s: &mut i32) -> f64; - #[cfg(not(target_os = "aix"))] + #[cfg(not(any( + target_os = "aix", + all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64")) + )))] pub safe fn lgammaf_r(n: f32, s: &mut i32) -> f32; pub safe fn erf(n: f64) -> f64; pub safe fn erff(n: f32) -> f32; pub safe fn erfc(n: f64) -> f64; pub safe fn erfcf(n: f32) -> f32; + // f128 math functions require IEEE binary128 support in libm. + // Not available on PowerPC macOS (uses IBM double-double, not IEEE binary128). + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn acosf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn asinf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn atanf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn atan2f128(a: f128, b: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn cbrtf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn coshf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn expm1f128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn hypotf128(x: f128, y: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn log1pf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn sinhf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn tanf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn tanhf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn tgammaf128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn lgammaf128_r(n: f128, s: &mut i32) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn erff128(n: f128) -> f128; + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub safe fn erfcf128(n: f128) -> f128; cfg_if::cfg_if! { @@ -66,6 +87,12 @@ lgamma_r(n.into(), s) as f32 } +// On macOS PowerPC use lgamma_r (f64) as a fallback, like AIX +#[cfg(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64")))] +pub fn lgammaf_r(n: f32, s: &mut i32) -> f32 { + lgamma_r(n.into(), s) as f32 +} + // On 32-bit x86 MSVC these functions aren't defined, so we just define shims // which promote everything to f64, perform the calculation, and then demote // back to f32. While not precisely correct should be "correct enough" for now. diff --git a/library/std/src/num/f128.rs b/library/std/src/num/f128.rs --- a/library/std/src/num/f128.rs +++ b/library/std/src/num/f128.rs @@ -317,6 +317,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn cbrt(self) -> f128 { cmath::cbrtf128(self) } @@ -355,6 +356,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn hypot(self, other: f128) -> f128 { cmath::hypotf128(self, other) } @@ -384,6 +386,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn sin(self) -> f128 { unsafe { intrinsics::sinf128(self) } } @@ -413,6 +416,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn cos(self) -> f128 { unsafe { intrinsics::cosf128(self) } } @@ -444,6 +448,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn tan(self) -> f128 { cmath::tanf128(self) } @@ -480,6 +485,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn asin(self) -> f128 { cmath::asinf128(self) } @@ -516,6 +522,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn acos(self) -> f128 { cmath::acosf128(self) } @@ -551,6 +558,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn atan(self) -> f128 { cmath::atanf128(self) } @@ -598,6 +606,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn atan2(self, other: f128) -> f128 { cmath::atan2f128(self, other) } @@ -634,6 +643,7 @@ #[doc(alias = "sincos")] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn sin_cos(self) -> (f128, f128) { (self.sin(), self.cos()) } @@ -669,6 +679,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn exp_m1(self) -> f128 { cmath::expm1f128(self) } @@ -718,6 +729,7 @@ #[must_use = "method returns a new number and does not mutate the original value"] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn ln_1p(self) -> f128 { cmath::log1pf128(self) } @@ -754,6 +766,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn sinh(self) -> f128 { cmath::sinhf128(self) } @@ -790,6 +803,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn cosh(self) -> f128 { cmath::coshf128(self) } @@ -826,6 +840,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn tanh(self) -> f128 { cmath::tanhf128(self) } @@ -857,6 +872,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn asinh(self) -> f128 { let ax = self.abs(); let ix = 1.0 / ax; @@ -890,6 +906,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn acosh(self) -> f128 { if self < 1.0 { Self::NAN @@ -925,6 +942,7 @@ #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn atanh(self) -> f128 { 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() } @@ -959,6 +977,7 @@ #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_gamma", issue = "99842")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn gamma(self) -> f128 { cmath::tgammaf128(self) } @@ -995,6 +1014,7 @@ #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_gamma", issue = "99842")] #[must_use = "method returns a new number and does not mutate the original value"] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn ln_gamma(self) -> (f128, i32) { let mut signgamp: i32 = 0; let x = cmath::lgammaf128_r(self, &mut signgamp); @@ -1037,6 +1057,7 @@ #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_erf", issue = "136321")] #[inline] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn erf(self) -> f128 { cmath::erff128(self) } @@ -1071,6 +1092,7 @@ #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_erf", issue = "136321")] #[inline] + #[cfg(not(all(target_vendor = "apple", any(target_arch = "powerpc", target_arch = "powerpc64"))))] pub fn erfc(self) -> f128 { cmath::erfcf128(self) }