diff options
Diffstat (limited to 'library/std/src/sys/cmath')
| -rw-r--r-- | library/std/src/sys/cmath/builtins.rs | 35 | ||||
| -rw-r--r-- | library/std/src/sys/cmath/mod.rs | 11 | ||||
| -rw-r--r-- | library/std/src/sys/cmath/windows.rs | 94 |
3 files changed, 140 insertions, 0 deletions
diff --git a/library/std/src/sys/cmath/builtins.rs b/library/std/src/sys/cmath/builtins.rs new file mode 100644 index 00000000000..c680132efa4 --- /dev/null +++ b/library/std/src/sys/cmath/builtins.rs @@ -0,0 +1,35 @@ +// These symbols are all defined by `libm`, +// or by `compiler-builtins` on unsupported platforms. + +extern "C" { + pub fn acos(n: f64) -> f64; + pub fn acosf(n: f32) -> f32; + pub fn asin(n: f64) -> f64; + pub fn asinf(n: f32) -> f32; + pub fn atan(n: f64) -> f64; + pub fn atan2(a: f64, b: f64) -> f64; + pub fn atan2f(a: f32, b: f32) -> f32; + pub fn atanf(n: f32) -> f32; + pub fn cbrt(n: f64) -> f64; + pub fn cbrtf(n: f32) -> f32; + pub fn cosh(n: f64) -> f64; + pub fn coshf(n: f32) -> f32; + pub fn expm1(n: f64) -> f64; + pub fn expm1f(n: f32) -> f32; + pub fn fdim(a: f64, b: f64) -> f64; + pub fn fdimf(a: f32, b: f32) -> f32; + pub fn hypot(x: f64, y: f64) -> f64; + pub fn hypotf(x: f32, y: f32) -> f32; + pub fn log1p(n: f64) -> f64; + pub fn log1pf(n: f32) -> f32; + pub fn sinh(n: f64) -> f64; + pub fn sinhf(n: f32) -> f32; + pub fn tan(n: f64) -> f64; + pub fn tanf(n: f32) -> f32; + pub fn tanh(n: f64) -> f64; + pub fn tanhf(n: f32) -> f32; + pub fn tgamma(n: f64) -> f64; + pub fn tgammaf(n: f32) -> f32; + pub fn lgamma_r(n: f64, s: &mut i32) -> f64; + pub fn lgammaf_r(n: f32, s: &mut i32) -> f32; +} diff --git a/library/std/src/sys/cmath/mod.rs b/library/std/src/sys/cmath/mod.rs new file mode 100644 index 00000000000..79d5021dd8d --- /dev/null +++ b/library/std/src/sys/cmath/mod.rs @@ -0,0 +1,11 @@ +#![cfg(not(test))] + +cfg_if::cfg_if! { + if #[cfg(target_os = "windows")] { + mod windows; + pub use windows::*; + } else { + mod builtins; + pub use builtins::*; + } +} diff --git a/library/std/src/sys/cmath/windows.rs b/library/std/src/sys/cmath/windows.rs new file mode 100644 index 00000000000..712097f06ff --- /dev/null +++ b/library/std/src/sys/cmath/windows.rs @@ -0,0 +1,94 @@ +use core::ffi::{c_double, c_float, c_int}; + +extern "C" { + pub fn acos(n: c_double) -> c_double; + pub fn asin(n: c_double) -> c_double; + pub fn atan(n: c_double) -> c_double; + pub fn atan2(a: c_double, b: c_double) -> c_double; + pub fn cbrt(n: c_double) -> c_double; + pub fn cbrtf(n: c_float) -> c_float; + pub fn cosh(n: c_double) -> c_double; + pub fn expm1(n: c_double) -> c_double; + pub fn expm1f(n: c_float) -> c_float; + pub fn fdim(a: c_double, b: c_double) -> c_double; + pub fn fdimf(a: c_float, b: c_float) -> c_float; + #[cfg_attr(target_env = "msvc", link_name = "_hypot")] + pub fn hypot(x: c_double, y: c_double) -> c_double; + #[cfg_attr(target_env = "msvc", link_name = "_hypotf")] + pub fn hypotf(x: c_float, y: c_float) -> c_float; + pub fn log1p(n: c_double) -> c_double; + pub fn log1pf(n: c_float) -> c_float; + pub fn sinh(n: c_double) -> c_double; + pub fn tan(n: c_double) -> c_double; + pub fn tanh(n: c_double) -> c_double; + pub fn tgamma(n: c_double) -> c_double; + pub fn tgammaf(n: c_float) -> c_float; + pub fn lgamma_r(n: c_double, s: &mut c_int) -> c_double; + pub fn lgammaf_r(n: c_float, s: &mut c_int) -> c_float; +} + +pub use self::shims::*; + +#[cfg(not(all(target_env = "msvc", target_arch = "x86")))] +mod shims { + use core::ffi::c_float; + + extern "C" { + pub fn acosf(n: c_float) -> c_float; + pub fn asinf(n: c_float) -> c_float; + pub fn atan2f(a: c_float, b: c_float) -> c_float; + pub fn atanf(n: c_float) -> c_float; + pub fn coshf(n: c_float) -> c_float; + pub fn sinhf(n: c_float) -> c_float; + pub fn tanf(n: c_float) -> c_float; + pub fn tanhf(n: c_float) -> c_float; + } +} + +// 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. +#[cfg(all(target_env = "msvc", target_arch = "x86"))] +mod shims { + use core::ffi::c_float; + + #[inline] + pub unsafe fn acosf(n: c_float) -> c_float { + f64::acos(n as f64) as c_float + } + + #[inline] + pub unsafe fn asinf(n: c_float) -> c_float { + f64::asin(n as f64) as c_float + } + + #[inline] + pub unsafe fn atan2f(n: c_float, b: c_float) -> c_float { + f64::atan2(n as f64, b as f64) as c_float + } + + #[inline] + pub unsafe fn atanf(n: c_float) -> c_float { + f64::atan(n as f64) as c_float + } + + #[inline] + pub unsafe fn coshf(n: c_float) -> c_float { + f64::cosh(n as f64) as c_float + } + + #[inline] + pub unsafe fn sinhf(n: c_float) -> c_float { + f64::sinh(n as f64) as c_float + } + + #[inline] + pub unsafe fn tanf(n: c_float) -> c_float { + f64::tan(n as f64) as c_float + } + + #[inline] + pub unsafe fn tanhf(n: c_float) -> c_float { + f64::tanh(n as f64) as c_float + } +} |
