compiler_builtins/math/
mod.rs

1#[rustfmt::skip]
2#[allow(dead_code)]
3#[allow(unused_imports)]
4#[allow(clippy::all)]
5#[path = "../../../libm/src/math/mod.rs"]
6pub(crate) mod libm_math;
7
8macro_rules! libm_intrinsics {
9    ($(fn $fun:ident($($iid:ident : $ity:ty),+) -> $oty:ty;)+) => {
10        intrinsics! {
11            $(
12                pub extern "C" fn $fun($($iid: $ity),+) -> $oty {
13                    $crate::math::libm_math::$fun($($iid),+)
14                }
15            )+
16        }
17    }
18}
19
20/// This set of functions is well tested in `libm` and known to provide similar performance to
21/// system `libm`, as well as the same or better accuracy.
22pub mod full_availability {
23    #[cfg(f16_enabled)]
24    libm_intrinsics! {
25        fn ceilf16(x: f16) -> f16;
26        fn copysignf16(x: f16, y: f16) -> f16;
27        fn fabsf16(x: f16) -> f16;
28        fn fdimf16(x: f16, y: f16) -> f16;
29        fn floorf16(x: f16) -> f16;
30        fn fmaxf16(x: f16, y: f16) -> f16;
31        fn fmaximumf16(x: f16, y: f16) -> f16;
32        fn fminf16(x: f16, y: f16) -> f16;
33        fn fminimumf16(x: f16, y: f16) -> f16;
34        fn fmodf16(x: f16, y: f16) -> f16;
35        fn rintf16(x: f16) -> f16;
36        fn roundevenf16(x: f16) -> f16;
37        fn roundf16(x: f16) -> f16;
38        fn sqrtf16(x: f16) -> f16;
39        fn truncf16(x: f16) -> f16;
40    }
41
42    /* Weak linkage is unreliable on Windows and Apple, so we don't expose symbols that we know
43     * the system libc provides in order to avoid conflicts. */
44
45    #[cfg(all(not(windows), not(target_vendor = "apple")))]
46    libm_intrinsics! {
47        /* f32 */
48        fn cbrtf(n: f32) -> f32;
49        fn ceilf(x: f32) -> f32;
50        fn copysignf(x: f32, y: f32) -> f32;
51        fn fabsf(x: f32) -> f32;
52        fn fdimf(a: f32, b: f32) -> f32;
53        fn floorf(x: f32) -> f32;
54        fn fmaf(x: f32, y: f32, z: f32) -> f32;
55        fn fmaxf(x: f32, y: f32) -> f32;
56        fn fminf(x: f32, y: f32) -> f32;
57        fn fmodf(x: f32, y: f32) -> f32;
58        fn rintf(x: f32) -> f32;
59        fn roundf(x: f32) -> f32;
60        fn sqrtf(x: f32) -> f32;
61        fn truncf(x: f32) -> f32;
62
63        /* f64 */
64        fn cbrt(x: f64) -> f64;
65        fn ceil(x: f64) -> f64;
66        fn copysign(x: f64, y: f64) -> f64;
67        fn fabs(x: f64) -> f64;
68        fn fdim(a: f64, b: f64) -> f64;
69        fn floor(x: f64) -> f64;
70        fn fma(x: f64, y: f64, z: f64) -> f64;
71        fn fmax(x: f64, y: f64) -> f64;
72        fn fmin(x: f64, y: f64) -> f64;
73        fn fmod(x: f64, y: f64) -> f64;
74        fn rint(x: f64) -> f64;
75        fn round(x: f64) -> f64;
76        fn sqrt(x: f64) -> f64;
77        fn trunc(x: f64) -> f64;
78    }
79
80    // Windows and MacOS do not yet expose roundeven and IEEE 754-2019 `maximum` / `minimum`,
81    // however, so we still provide a fallback.
82    libm_intrinsics! {
83        fn fmaximum(x: f64, y: f64) -> f64;
84        fn fmaximumf(x: f32, y: f32) -> f32;
85        fn fminimum(x: f64, y: f64) -> f64;
86        fn fminimumf(x: f32, y: f32) -> f32;
87        fn roundeven(x: f64) -> f64;
88        fn roundevenf(x: f32) -> f32;
89    }
90
91    #[cfg(f128_enabled)]
92    libm_intrinsics! {
93        fn ceilf128(x: f128) -> f128;
94        fn copysignf128(x: f128, y: f128) -> f128;
95        fn fabsf128(x: f128) -> f128;
96        fn fdimf128(x: f128, y: f128) -> f128;
97        fn floorf128(x: f128) -> f128;
98        fn fmaf128(x: f128, y: f128, z: f128) -> f128;
99        fn fmaxf128(x: f128, y: f128) -> f128;
100        fn fmaximumf128(x: f128, y: f128) -> f128;
101        fn fminf128(x: f128, y: f128) -> f128;
102        fn fminimumf128(x: f128, y: f128) -> f128;
103        fn fmodf128(x: f128, y: f128) -> f128;
104        fn rintf128(x: f128) -> f128;
105        fn roundevenf128(x: f128) -> f128;
106        fn roundf128(x: f128) -> f128;
107        fn sqrtf128(x: f128) -> f128;
108        fn truncf128(x: f128) -> f128;
109    }
110}
111
112/// This group of functions has more performance or precision issues than system versions, or
113/// are otherwise less well tested. Provide them only on platforms that have problems with the
114/// system `libm`.
115///
116/// As `libm` improves, more functions will be moved from this group to the first group.
117///
118/// Do not supply for any of the following:
119/// - x86 without sse2 due to ABI issues
120///   - <https://github.com/rust-lang/rust/issues/114479>
121///   - but exclude UEFI since it is a soft-float target
122///     - <https://github.com/rust-lang/rust/issues/128533>
123/// - All unix targets (linux, macos, freebsd, android, etc)
124/// - wasm with known target_os
125#[cfg(not(any(
126    all(
127        target_arch = "x86",
128        not(target_feature = "sse2"),
129        not(target_os = "uefi"),
130    ),
131    unix,
132    all(target_family = "wasm", not(target_os = "unknown"))
133)))]
134pub mod partial_availability {
135    #[cfg(not(windows))]
136    libm_intrinsics! {
137        fn acos(x: f64) -> f64;
138        fn acosf(n: f32) -> f32;
139        fn asin(x: f64) -> f64;
140        fn asinf(n: f32) -> f32;
141        fn atan(x: f64) -> f64;
142        fn atan2(x: f64, y: f64) -> f64;
143        fn atan2f(a: f32, b: f32) -> f32;
144        fn atanf(n: f32) -> f32;
145        fn cos(x: f64) -> f64;
146        fn cosf(x: f32) -> f32;
147        fn cosh(x: f64) -> f64;
148        fn coshf(n: f32) -> f32;
149        fn erf(x: f64) -> f64;
150        fn erfc(x: f64) -> f64;
151        fn erfcf(x: f32) -> f32;
152        fn erff(x: f32) -> f32;
153        fn exp(x: f64) -> f64;
154        fn exp2(x: f64) -> f64;
155        fn exp2f(x: f32) -> f32;
156        fn expf(x: f32) -> f32;
157        fn expm1(x: f64) -> f64;
158        fn expm1f(n: f32) -> f32;
159        fn hypot(x: f64, y: f64) -> f64;
160        fn hypotf(x: f32, y: f32) -> f32;
161        fn ldexp(f: f64, n: i32) -> f64;
162        fn ldexpf(f: f32, n: i32) -> f32;
163        fn log(x: f64) -> f64;
164        fn log10(x: f64) -> f64;
165        fn log10f(x: f32) -> f32;
166        fn log1p(x: f64) -> f64;
167        fn log1pf(n: f32) -> f32;
168        fn log2(x: f64) -> f64;
169        fn log2f(x: f32) -> f32;
170        fn logf(x: f32) -> f32;
171        fn pow(x: f64, y: f64) -> f64;
172        fn powf(x: f32, y: f32) -> f32;
173        fn sin(x: f64) -> f64;
174        fn sinf(x: f32) -> f32;
175        fn sinh(x: f64) -> f64;
176        fn sinhf(n: f32) -> f32;
177        fn tan(x: f64) -> f64;
178        fn tanf(n: f32) -> f32;
179        fn tanh(x: f64) -> f64;
180        fn tanhf(n: f32) -> f32;
181        fn tgamma(x: f64) -> f64;
182        fn tgammaf(x: f32) -> f32;
183    }
184
185    // allow for windows (and other targets)
186    intrinsics! {
187        pub extern "C" fn lgamma_r(x: f64, s: &mut i32) -> f64 {
188            let r = super::libm_math::lgamma_r(x);
189            *s = r.1;
190            r.0
191        }
192
193        pub extern "C" fn lgammaf_r(x: f32, s: &mut i32) -> f32 {
194            let r = super::libm_math::lgammaf_r(x);
195            *s = r.1;
196            r.0
197        }
198    }
199}