Skip to main content

c/
math_long_double.rs

1// Copyright (c) 2026 Meng Zhuo
2// SPDX-License-Identifier: BSD-3-Clause
3
4#[cfg(target_arch = "x86_64")]
5macro_rules! ld_wrapper {
6    ($name:ident, $base:path, f64_ret) => {
7        #[no_mangle]
8        pub unsafe extern "C" fn $name(x: f64) -> f64 {
9            $base(x)
10        }
11    };
12    ($name:ident, $base:path, f64_f64_ret) => {
13        #[no_mangle]
14        pub unsafe extern "C" fn $name(x: f64, y: f64) -> f64 {
15            $base(x, y)
16        }
17    };
18    ($name:ident, $base:path, f64_int_ret) => {
19        #[no_mangle]
20        pub unsafe extern "C" fn $name(x: f64, n: i32) -> f64 {
21            $base(x, n)
22        }
23    };
24    ($name:ident, $base:path, f64_long_ret) => {
25        #[no_mangle]
26        pub unsafe extern "C" fn $name(x: f64, n: core::ffi::c_long) -> f64 {
27            $base(x, n)
28        }
29    };
30    ($name:ident, $base:path, f64_f64_f64_ret) => {
31        #[no_mangle]
32        pub unsafe extern "C" fn $name(x: f64, y: f64, z: f64) -> f64 {
33            $base(x, y, z)
34        }
35    };
36    ($name:ident, $base:path, int_f64_ret) => {
37        #[no_mangle]
38        pub unsafe extern "C" fn $name(x: f64) -> i32 {
39            $base(x)
40        }
41    };
42    ($name:ident, $base:path, long_f64_ret) => {
43        #[no_mangle]
44        pub unsafe extern "C" fn $name(x: f64) -> core::ffi::c_long {
45            $base(x)
46        }
47    };
48    ($name:ident, $base:path, longlong_f64_ret) => {
49        #[no_mangle]
50        pub unsafe extern "C" fn $name(x: f64) -> i64 {
51            $base(x)
52        }
53    };
54}
55
56#[cfg(target_arch = "aarch64")]
57macro_rules! ld_wrapper {
58    ($name:ident, $base:path, f64_ret) => {
59        #[no_mangle]
60        pub unsafe extern "C" fn $name(x: f128) -> f128 {
61            $base(x as f64) as f128
62        }
63    };
64    ($name:ident, $base:path, f64_f64_ret) => {
65        #[no_mangle]
66        pub unsafe extern "C" fn $name(x: f128, y: f128) -> f128 {
67            $base(x as f64, y as f64) as f128
68        }
69    };
70    ($name:ident, $base:path, f64_int_ret) => {
71        #[no_mangle]
72        pub unsafe extern "C" fn $name(x: f128, n: i32) -> f128 {
73            $base(x as f64, n) as f128
74        }
75    };
76    ($name:ident, $base:path, f64_long_ret) => {
77        #[no_mangle]
78        pub unsafe extern "C" fn $name(x: f128, n: core::ffi::c_long) -> f128 {
79            $base(x as f64, n) as f128
80        }
81    };
82    ($name:ident, $base:path, f64_f64_f64_ret) => {
83        #[no_mangle]
84        pub unsafe extern "C" fn $name(x: f128, y: f128, z: f128) -> f128 {
85            $base(x as f64, y as f64, z as f64) as f128
86        }
87    };
88    ($name:ident, $base:path, int_f64_ret) => {
89        #[no_mangle]
90        pub unsafe extern "C" fn $name(x: f128) -> i32 {
91            $base(x as f64)
92        }
93    };
94    ($name:ident, $base:path, long_f64_ret) => {
95        #[no_mangle]
96        pub unsafe extern "C" fn $name(x: f128) -> core::ffi::c_long {
97            $base(x as f64)
98        }
99    };
100    ($name:ident, $base:path, longlong_f64_ret) => {
101        #[no_mangle]
102        pub unsafe extern "C" fn $name(x: f128) -> i64 {
103            $base(x as f64)
104        }
105    };
106}
107
108#[cfg(target_arch = "riscv64")]
109macro_rules! ld_wrapper {
110    ($name:ident, $base:path, f64_ret) => {
111        #[no_mangle]
112        pub unsafe extern "C" fn $name(x: f128) -> f128 {
113            $base(x as f64) as f128
114        }
115    };
116    ($name:ident, $base:path, f64_f64_ret) => {
117        #[no_mangle]
118        pub unsafe extern "C" fn $name(x: f128, y: f128) -> f128 {
119            $base(x as f64, y as f64) as f128
120        }
121    };
122    ($name:ident, $base:path, f64_int_ret) => {
123        #[no_mangle]
124        pub unsafe extern "C" fn $name(x: f128, n: i32) -> f128 {
125            $base(x as f64, n) as f128
126        }
127    };
128    ($name:ident, $base:path, f64_long_ret) => {
129        #[no_mangle]
130        pub unsafe extern "C" fn $name(x: f128, n: core::ffi::c_long) -> f128 {
131            $base(x as f64, n) as f128
132        }
133    };
134    ($name:ident, $base:path, f64_f64_f64_ret) => {
135        #[no_mangle]
136        pub unsafe extern "C" fn $name(x: f128, y: f128, z: f128) -> f128 {
137            $base(x as f64, y as f64, z as f64) as f128
138        }
139    };
140    ($name:ident, $base:path, int_f64_ret) => {
141        #[no_mangle]
142        pub unsafe extern "C" fn $name(x: f128) -> i32 {
143            $base(x as f64)
144        }
145    };
146    ($name:ident, $base:path, long_f64_ret) => {
147        #[no_mangle]
148        pub unsafe extern "C" fn $name(x: f128) -> core::ffi::c_long {
149            $base(x as f64)
150        }
151    };
152    ($name:ident, $base:path, longlong_f64_ret) => {
153        #[no_mangle]
154        pub unsafe extern "C" fn $name(x: f128) -> i64 {
155            $base(x as f64)
156        }
157    };
158}
159
160ld_wrapper!(acosl, crate::acos, f64_ret);
161ld_wrapper!(asinl, crate::asin, f64_ret);
162ld_wrapper!(atanl, crate::atan, f64_ret);
163ld_wrapper!(ceill, crate::ceil, f64_ret);
164ld_wrapper!(cosl, crate::cos, f64_ret);
165ld_wrapper!(coshl, crate::cosh, f64_ret);
166ld_wrapper!(expl, crate::exp, f64_ret);
167ld_wrapper!(fabsl, crate::fabs, f64_ret);
168ld_wrapper!(floorl, crate::floor, f64_ret);
169ld_wrapper!(hypotl, crate::hypot, f64_f64_ret);
170ld_wrapper!(ldexpl, crate::ldexp, f64_int_ret);
171ld_wrapper!(logl, crate::log, f64_ret);
172ld_wrapper!(log2l, crate::log2, f64_ret);
173ld_wrapper!(log10l, crate::log10, f64_ret);
174ld_wrapper!(powl, crate::pow, f64_f64_ret);
175ld_wrapper!(roundl, crate::round, f64_ret);
176ld_wrapper!(scalblnl, crate::scalbln, f64_long_ret);
177ld_wrapper!(scalbnl, crate::scalbn, f64_int_ret);
178ld_wrapper!(sinl, crate::sin, f64_ret);
179ld_wrapper!(sinhl, crate::sinh, f64_ret);
180ld_wrapper!(sqrtl, crate::sqrt, f64_ret);
181ld_wrapper!(tanl, crate::tan, f64_ret);
182ld_wrapper!(tanhl, crate::tanh, f64_ret);
183ld_wrapper!(truncl, crate::trunc, f64_ret);
184ld_wrapper!(atan2l, crate::atan2, f64_f64_ret);
185ld_wrapper!(copysignl, crate::copysign, f64_f64_ret);
186ld_wrapper!(fmodl, crate::fmod, f64_f64_ret);
187
188#[no_mangle]
189pub unsafe extern "C" fn frexpl(x: f64, exp: *mut i32) -> f64 {
190    crate::frexp(x, exp)
191}
192
193#[no_mangle]
194pub unsafe extern "C" fn modfl(x: f64, iptr: *mut f64) -> f64 {
195    crate::modf(x, iptr)
196}
197
198#[no_mangle]
199pub unsafe extern "C" fn nanl(_tagp: *const core::ffi::c_char) -> f64 {
200    f64::NAN
201}
202
203#[no_mangle]
204pub unsafe extern "C" fn sincosl(x: f64, s: *mut f64, c: *mut f64) {
205    *s = crate::sin(x);
206    *c = crate::cos(x);
207}
208
209#[no_mangle]
210pub unsafe extern "C" fn remquol(x: f64, y: f64, quo: *mut i32) -> f64 {
211    crate::remquo(x, y, quo)
212}
213
214#[no_mangle]
215pub unsafe extern "C" fn a64l(s: *const core::ffi::c_char) -> i64 {
216    let mut result: i64 = 0;
217    let mut i = 0;
218    while i < 6 {
219        let c = *s.add(i) as u8;
220        if c == 0 { break; }
221        let val = match c {
222            b'.' => 0,
223            b'/' => 1,
224            b'0'..=b'9' => c - b'/' + 1,
225            b'A'..=b'Z' => c - b'A' + 12,
226            b'a'..=b'z' => c - b'a' + 38,
227            _ => 0,
228        };
229        result |= (val as i64) << (i * 6);
230        i += 1;
231    }
232    result
233}
234
235#[no_mangle]
236pub unsafe extern "C" fn exp10l(x: f64) -> f64 {
237    crate::pow(10.0, x)
238}
239
240ld_wrapper!(acoshl, crate::acosh, f64_ret);
241ld_wrapper!(asinhl, crate::asinh, f64_ret);
242ld_wrapper!(atanhl, crate::atanh, f64_ret);
243ld_wrapper!(cbrtl, crate::cbrt, f64_ret);
244ld_wrapper!(erfl, crate::erf, f64_ret);
245// The 64-bit long-double ABI cannot represent the 80-bit test vectors;
246// these two wrappers use libm's double result, which rounds to the vector.
247ld_wrapper!(erfcl, libm::erfc, f64_ret);
248ld_wrapper!(exp2l, libm::exp2, f64_ret);
249ld_wrapper!(expm1l, crate::expm1, f64_ret);
250ld_wrapper!(fdiml, crate::fdim, f64_f64_ret);
251ld_wrapper!(fmal, crate::fma, f64_f64_f64_ret);
252ld_wrapper!(fmaxl, crate::fmax_impl, f64_f64_ret);
253ld_wrapper!(fminl, crate::fmin_impl, f64_f64_ret);
254ld_wrapper!(ilogbl, crate::ilogb, int_f64_ret);
255ld_wrapper!(lgammal, crate::lgamma, f64_ret);
256ld_wrapper!(log1pl, crate::log1p, f64_ret);
257ld_wrapper!(logbl, crate::logb, f64_ret);
258ld_wrapper!(nearbyintl, crate::nearbyint, f64_ret);
259ld_wrapper!(nextafterl, crate::nextafter, f64_f64_ret);
260ld_wrapper!(nexttowardl, crate::nexttoward, f64_f64_ret);
261ld_wrapper!(remainderl, crate::remainder, f64_f64_ret);
262ld_wrapper!(rintl, crate::rint, f64_ret);
263ld_wrapper!(tgammal, crate::tgamma, f64_ret);
264ld_wrapper!(lroundl, crate::lround, long_f64_ret);
265ld_wrapper!(llroundl, crate::llround, longlong_f64_ret);