Skip to main content

core/num/imp/
libm.rs

1//! Bindings to math functions provided by the system `libm` or by the `libm` crate, exposed
2//! via `compiler-builtins`.
3//!
4//! The functions in the root of this module are "guaranteed" to be available; see the
5//! `full_availability` module in compiler-builtins for details.
6
7// SAFETY: These symbols have standard interfaces in C and are defined by `libm`, or are
8// provided by `compiler-builtins` on unsupported platforms.
9#[allow(dead_code)] // This list reflects what is available rather than what is consumed.
10unsafe extern "C" {
11    pub(crate) safe fn __powidf2(a: f64, b: i32) -> f64;
12    pub(crate) safe fn __powisf2(a: f32, b: i32) -> f32;
13    // PowerPC uses `kf` rather than `tf` for `f128`.
14    #[cfg_attr(any(target_arch = "powerpc", target_arch = "powerpc64"), link_name = "__powikf2")]
15    pub(crate) safe fn __powitf2(a: f128, b: i32) -> f128;
16    pub(crate) safe fn cbrt(x: f64) -> f64;
17    pub(crate) safe fn cbrtf(n: f32) -> f32;
18    pub(crate) safe fn ceil(x: f64) -> f64;
19    pub(crate) safe fn ceilf(x: f32) -> f32;
20    pub(crate) safe fn ceilf128(x: f128) -> f128;
21    pub(crate) safe fn ceilf16(x: f16) -> f16;
22    pub(crate) safe fn copysign(x: f64, y: f64) -> f64;
23    pub(crate) safe fn copysignf(x: f32, y: f32) -> f32;
24    pub(crate) safe fn copysignf128(x: f128, y: f128) -> f128;
25    pub(crate) safe fn copysignf16(x: f16, y: f16) -> f16;
26    pub(crate) safe fn fabs(x: f64) -> f64;
27    pub(crate) safe fn fabsf(x: f32) -> f32;
28    pub(crate) safe fn fabsf128(x: f128) -> f128;
29    pub(crate) safe fn fabsf16(x: f16) -> f16;
30    pub(crate) safe fn fdim(a: f64, b: f64) -> f64;
31    pub(crate) safe fn fdimf(a: f32, b: f32) -> f32;
32    pub(crate) safe fn fdimf128(x: f128, y: f128) -> f128;
33    pub(crate) safe fn fdimf16(x: f16, y: f16) -> f16;
34    pub(crate) safe fn floor(x: f64) -> f64;
35    pub(crate) safe fn floorf(x: f32) -> f32;
36    pub(crate) safe fn floorf128(x: f128) -> f128;
37    pub(crate) safe fn floorf16(x: f16) -> f16;
38    pub(crate) safe fn fma(x: f64, y: f64, z: f64) -> f64;
39    pub(crate) safe fn fmaf(x: f32, y: f32, z: f32) -> f32;
40    pub(crate) safe fn fmaf128(x: f128, y: f128, z: f128) -> f128;
41    pub(crate) safe fn fmaf16(x: f16, y: f16, z: f16) -> f16;
42    pub(crate) safe fn fmax(x: f64, y: f64) -> f64;
43    pub(crate) safe fn fmaxf(x: f32, y: f32) -> f32;
44    pub(crate) safe fn fmaxf128(x: f128, y: f128) -> f128;
45    pub(crate) safe fn fmaxf16(x: f16, y: f16) -> f16;
46    pub(crate) safe fn fmaximum(x: f64, y: f64) -> f64;
47    pub(crate) safe fn fmaximumf(x: f32, y: f32) -> f32;
48    pub(crate) safe fn fmaximumf128(x: f128, y: f128) -> f128;
49    pub(crate) safe fn fmaximumf16(x: f16, y: f16) -> f16;
50    pub(crate) safe fn fmin(x: f64, y: f64) -> f64;
51    pub(crate) safe fn fminf(x: f32, y: f32) -> f32;
52    pub(crate) safe fn fminf128(x: f128, y: f128) -> f128;
53    pub(crate) safe fn fminf16(x: f16, y: f16) -> f16;
54    pub(crate) safe fn fminimum(x: f64, y: f64) -> f64;
55    pub(crate) safe fn fminimumf(x: f32, y: f32) -> f32;
56    pub(crate) safe fn fminimumf128(x: f128, y: f128) -> f128;
57    pub(crate) safe fn fminimumf16(x: f16, y: f16) -> f16;
58    pub(crate) safe fn fmod(x: f64, y: f64) -> f64;
59    pub(crate) safe fn fmodf(x: f32, y: f32) -> f32;
60    pub(crate) safe fn fmodf128(x: f128, y: f128) -> f128;
61    pub(crate) safe fn fmodf16(x: f16, y: f16) -> f16;
62    pub(crate) safe fn rint(x: f64) -> f64;
63    pub(crate) safe fn rintf(x: f32) -> f32;
64    pub(crate) safe fn rintf128(x: f128) -> f128;
65    pub(crate) safe fn rintf16(x: f16) -> f16;
66    pub(crate) safe fn round(x: f64) -> f64;
67    pub(crate) safe fn roundeven(x: f64) -> f64;
68    pub(crate) safe fn roundevenf(x: f32) -> f32;
69    pub(crate) safe fn roundevenf128(x: f128) -> f128;
70    pub(crate) safe fn roundevenf16(x: f16) -> f16;
71    pub(crate) safe fn roundf(x: f32) -> f32;
72    pub(crate) safe fn roundf128(x: f128) -> f128;
73    pub(crate) safe fn roundf16(x: f16) -> f16;
74    pub(crate) safe fn sqrt(x: f64) -> f64;
75    pub(crate) safe fn sqrtf(x: f32) -> f32;
76    pub(crate) safe fn sqrtf128(x: f128) -> f128;
77    pub(crate) safe fn sqrtf16(x: f16) -> f16;
78    pub(crate) safe fn trunc(x: f64) -> f64;
79    pub(crate) safe fn truncf(x: f32) -> f32;
80    pub(crate) safe fn truncf128(x: f128) -> f128;
81    pub(crate) safe fn truncf16(x: f16) -> f16;
82}
83
84/// These symbols are always provided by compiler-builtins.
85pub(crate) mod complex {
86    use crate::num::Complex;
87
88    unsafe extern "C" {
89        pub(crate) safe fn __mulsc3(a: f32, b: f32, c: f32, d: f32) -> Complex<f32>;
90        pub(crate) safe fn __muldc3(a: f64, b: f64, c: f64, d: f64) -> Complex<f64>;
91
92        pub(crate) safe fn __divsc3(a: f32, b: f32, c: f32, d: f32) -> Complex<f32>;
93        pub(crate) safe fn __divdc3(a: f64, b: f64, c: f64, d: f64) -> Complex<f64>;
94    }
95
96    unsafe extern "Rust" {
97        pub(crate) safe fn __rust_mulhc3(a: f16, b: f16, c: f16, d: f16) -> Complex<f16>;
98        pub(crate) safe fn __rust_multc3(a: f128, b: f128, c: f128, d: f128) -> Complex<f128>;
99
100        pub(crate) safe fn __rust_divhc3(a: f16, b: f16, c: f16, d: f16) -> Complex<f16>;
101        pub(crate) safe fn __rust_divtc3(a: f128, b: f128, c: f128, d: f128) -> Complex<f128>;
102    }
103}
104
105/// These symbols will be available when `std` is available, and on many no-std platforms. However,
106/// since this isn't a guarantee, we cannot rely on them for stable implementations.
107pub(crate) mod likely_available {
108    cfg_select! {
109        all(target_env = "msvc", target_arch = "x86") => {
110            /* these symbols are not available on x86 msvc */
111        }
112        _ => {
113            #[allow(dead_code)]
114            unsafe extern "C" {
115                pub(crate) safe fn acosf(n: f32) -> f32;
116                pub(crate) safe fn asinf(n: f32) -> f32;
117                pub(crate) safe fn atan2f(a: f32, b: f32) -> f32;
118                pub(crate) safe fn atanf(n: f32) -> f32;
119                pub(crate) safe fn cosf(x: f32) -> f32;
120                pub(crate) safe fn coshf(n: f32) -> f32;
121                pub(crate) safe fn erfcf(x: f32) -> f32;
122                pub(crate) safe fn erff(x: f32) -> f32;
123                pub(crate) safe fn exp2f(x: f32) -> f32;
124                pub(crate) safe fn expf(x: f32) -> f32;
125                pub(crate) safe fn expm1f(n: f32) -> f32;
126                pub(crate) safe fn hypotf(x: f32, y: f32) -> f32;
127                pub(crate) safe fn ldexpf(f: f32, n: i32) -> f32;
128                pub(crate) safe fn log10f(x: f32) -> f32;
129                pub(crate) safe fn log1pf(n: f32) -> f32;
130                pub(crate) safe fn log2f(x: f32) -> f32;
131                pub(crate) safe fn logf(x: f32) -> f32;
132                pub(crate) safe fn powf(x: f32, y: f32) -> f32;
133                pub(crate) safe fn sinf(x: f32) -> f32;
134                pub(crate) safe fn sinhf(n: f32) -> f32;
135                pub(crate) safe fn tanf(n: f32) -> f32;
136                pub(crate) safe fn tanhf(n: f32) -> f32;
137                pub(crate) safe fn tgammaf(x: f32) -> f32;
138            }
139        }
140    }
141
142    #[allow(dead_code)]
143    unsafe extern "C" {
144        pub(crate) safe fn acos(x: f64) -> f64;
145        pub(crate) safe fn asin(x: f64) -> f64;
146        pub(crate) safe fn atan(x: f64) -> f64;
147        pub(crate) safe fn atan2(x: f64, y: f64) -> f64;
148        pub(crate) safe fn cos(x: f64) -> f64;
149        pub(crate) safe fn cosh(x: f64) -> f64;
150        pub(crate) safe fn erf(x: f64) -> f64;
151        pub(crate) safe fn erfc(x: f64) -> f64;
152        pub(crate) safe fn exp(x: f64) -> f64;
153        pub(crate) safe fn exp2(x: f64) -> f64;
154        pub(crate) safe fn expm1(x: f64) -> f64;
155        pub(crate) safe fn hypot(x: f64, y: f64) -> f64;
156        pub(crate) safe fn ldexp(f: f64, n: i32) -> f64;
157        pub(crate) safe fn log(x: f64) -> f64;
158        pub(crate) safe fn log10(x: f64) -> f64;
159        pub(crate) safe fn log1p(x: f64) -> f64;
160        pub(crate) safe fn log2(x: f64) -> f64;
161        pub(crate) safe fn pow(x: f64, y: f64) -> f64;
162        pub(crate) safe fn sin(x: f64) -> f64;
163        pub(crate) safe fn sinh(x: f64) -> f64;
164        pub(crate) safe fn tan(x: f64) -> f64;
165        pub(crate) safe fn tanh(x: f64) -> f64;
166        pub(crate) safe fn tgamma(x: f64) -> f64;
167    }
168}
169
170/// These symbols exist on some platforms but do not have a compiler-builtins fallback.
171pub(crate) mod maybe_available {
172    #[allow(dead_code)]
173    unsafe extern "C" {
174        pub(crate) safe fn acosf128(x: f128) -> f128;
175        pub(crate) safe fn asinf128(x: f128) -> f128;
176        pub(crate) safe fn atanf128(x: f128) -> f128;
177        pub(crate) safe fn cbrtf128(x: f128) -> f128;
178        pub(crate) safe fn cosf128(x: f128) -> f128;
179        pub(crate) safe fn erff128(x: f128) -> f128;
180        pub(crate) safe fn expf128(x: f128) -> f128;
181        pub(crate) safe fn exp2f128(x: f128) -> f128;
182        pub(crate) safe fn expm1f128(x: f128) -> f128;
183        pub(crate) safe fn hypotf128(x: f128, y: f128) -> f128;
184        pub(crate) safe fn ldexpf128(f: f128, n: i32) -> f128;
185        pub(crate) safe fn log10f128(x: f128) -> f128;
186        pub(crate) safe fn log1pf128(x: f128) -> f128;
187        pub(crate) safe fn log2f128(x: f128) -> f128;
188        pub(crate) safe fn logf128(x: f128) -> f128;
189        pub(crate) safe fn powf128(x: f128, y: f128) -> f128;
190        pub(crate) safe fn sinf128(x: f128) -> f128;
191        pub(crate) safe fn tanf128(x: f128) -> f128;
192        pub(crate) safe fn tanhf128(x: f128) -> f128;
193        pub(crate) safe fn tgammaf128(x: f128) -> f128;
194    }
195}