Skip to content

Commit

Permalink
Use platform-specific implementation for floats
Browse files Browse the repository at this point in the history
Also remove exceptions in tidy lint 'pal'.
  • Loading branch information
cassiersg committed Jan 26, 2017
1 parent 662fef6 commit badd513
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 159 deletions.
132 changes: 14 additions & 118 deletions src/libstd/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]

#[allow(unused_imports)]
use sys;

#[cfg(not(test))]
use core::num;
#[cfg(not(test))]
Expand All @@ -40,6 +43,8 @@ pub use core::f32::consts;
mod cmath {
use libc::{c_float, c_int};

pub use sys::f32::cmath::*;

extern {
pub fn cbrtf(n: c_float) -> c_float;
pub fn erff(n: c_float) -> c_float;
Expand All @@ -55,88 +60,6 @@ mod cmath {
pub fn modff(n: c_float, iptr: &mut c_float) -> c_float;
pub fn nextafterf(x: c_float, y: c_float) -> c_float;
pub fn tgammaf(n: c_float) -> c_float;

#[cfg_attr(all(windows, target_env = "msvc"), link_name = "__lgammaf_r")]
pub fn lgammaf_r(n: c_float, sign: &mut c_int) -> c_float;
#[cfg_attr(all(windows, target_env = "msvc"), link_name = "_hypotf")]
pub fn hypotf(x: c_float, y: c_float) -> c_float;
}

// See the comments in the `floor` function for why MSVC is special
// here.
#[cfg(not(target_env = "msvc"))]
extern {
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 frexpf(n: c_float, value: &mut c_int) -> c_float;
pub fn ldexpf(x: c_float, n: c_int) -> 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;
}

#[cfg(target_env = "msvc")]
pub use self::shims::*;
#[cfg(target_env = "msvc")]
mod shims {
use libc::{c_float, c_int};

#[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]
#[allow(deprecated)]
pub unsafe fn frexpf(x: c_float, value: &mut c_int) -> c_float {
let (a, b) = f64::frexp(x as f64);
*value = b as c_int;
a as c_float
}

#[inline]
#[allow(deprecated)]
pub unsafe fn ldexpf(x: c_float, n: c_int) -> c_float {
f64::ldexp(x as f64, n as isize) 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
}
}
}

Expand Down Expand Up @@ -301,10 +224,7 @@ impl f32 {
// Note that there are many MSVC-specific float operations which
// redirect to this comment, so `floorf` is just one case of a missing
// function on MSVC, but there are many others elsewhere.
#[cfg(target_env = "msvc")]
return (self as f64).floor() as f32;
#[cfg(not(target_env = "msvc"))]
return unsafe { intrinsics::floorf32(self) };
sys::f32::floor(self)
}

/// Returns the smallest integer greater than or equal to a number.
Expand All @@ -320,10 +240,7 @@ impl f32 {
#[inline]
pub fn ceil(self) -> f32 {
// see notes above in `floor`
#[cfg(target_env = "msvc")]
return (self as f64).ceil() as f32;
#[cfg(not(target_env = "msvc"))]
return unsafe { intrinsics::ceilf32(self) };
sys::f32::ceil(self)
}

/// Returns the nearest integer to a number. Round half-way cases away from
Expand Down Expand Up @@ -519,10 +436,7 @@ impl f32 {
#[inline]
pub fn powf(self, n: f32) -> f32 {
// see notes above in `floor`
#[cfg(target_env = "msvc")]
return (self as f64).powf(n as f64) as f32;
#[cfg(not(target_env = "msvc"))]
return unsafe { intrinsics::powf32(self, n) };
sys::f32::powf(self, n)
}

/// Takes the square root of a number.
Expand Down Expand Up @@ -568,10 +482,7 @@ impl f32 {
#[inline]
pub fn exp(self) -> f32 {
// see notes above in `floor`
#[cfg(target_env = "msvc")]
return (self as f64).exp() as f32;
#[cfg(not(target_env = "msvc"))]
return unsafe { intrinsics::expf32(self) };
sys::f32::exp(self)
}

/// Returns `2^(self)`.
Expand Down Expand Up @@ -610,10 +521,7 @@ impl f32 {
#[inline]
pub fn ln(self) -> f32 {
// see notes above in `floor`
#[cfg(target_env = "msvc")]
return (self as f64).ln() as f32;
#[cfg(not(target_env = "msvc"))]
return unsafe { intrinsics::logf32(self) };
sys::f32::ln(self)
}

/// Returns the logarithm of the number with respect to an arbitrary base.
Expand Down Expand Up @@ -652,10 +560,7 @@ impl f32 {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn log2(self) -> f32 {
#[cfg(target_os = "android")]
return ::sys::android::log2f32(self);
#[cfg(not(target_os = "android"))]
return unsafe { intrinsics::log2f32(self) };
sys::f32::log2(self)
}

/// Returns the base 10 logarithm of the number.
Expand All @@ -674,10 +579,7 @@ impl f32 {
#[inline]
pub fn log10(self) -> f32 {
// see notes above in `floor`
#[cfg(target_env = "msvc")]
return (self as f64).log10() as f32;
#[cfg(not(target_env = "msvc"))]
return unsafe { intrinsics::log10f32(self) };
sys::f32::log10(self)
}

/// Converts radians to degrees.
Expand Down Expand Up @@ -908,10 +810,7 @@ impl f32 {
#[inline]
pub fn sin(self) -> f32 {
// see notes in `core::f32::Float::floor`
#[cfg(target_env = "msvc")]
return (self as f64).sin() as f32;
#[cfg(not(target_env = "msvc"))]
return unsafe { intrinsics::sinf32(self) };
sys::f32::sin(self)
}

/// Computes the cosine of a number (in radians).
Expand All @@ -929,10 +828,7 @@ impl f32 {
#[inline]
pub fn cos(self) -> f32 {
// see notes in `core::f32::Float::floor`
#[cfg(target_env = "msvc")]
return (self as f64).cos() as f32;
#[cfg(not(target_env = "msvc"))]
return unsafe { intrinsics::cosf32(self) };
sys::f32::cos(self)
}

/// Computes the tangent of a number (in radians).
Expand Down
47 changes: 8 additions & 39 deletions src/libstd/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,15 @@ pub use core::f64::{MIN, MIN_POSITIVE, MAX};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::f64::consts;

#[allow(unused_imports)]
use sys;

#[allow(dead_code)]
mod cmath {
use libc::{c_double, c_int};

pub use sys::f64::cmath::*;

#[link_name = "m"]
extern {
pub fn acos(n: c_double) -> c_double;
Expand Down Expand Up @@ -75,12 +80,6 @@ mod cmath {
pub fn y0(n: c_double) -> c_double;
pub fn y1(n: c_double) -> c_double;
pub fn yn(i: c_int, n: c_double) -> c_double;

#[cfg_attr(all(windows, target_env = "msvc"), link_name = "__lgamma_r")]
pub fn lgamma_r(n: c_double, sign: &mut c_int) -> c_double;

#[cfg_attr(all(windows, target_env = "msvc"), link_name = "_hypot")]
pub fn hypot(x: c_double, y: c_double) -> c_double;
}
}

Expand Down Expand Up @@ -515,7 +514,7 @@ impl f64 {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn ln(self) -> f64 {
self.log_wrapper(|n| { unsafe { intrinsics::logf64(n) } })
sys::f64::ln(self)
}

/// Returns the logarithm of the number with respect to an arbitrary base.
Expand Down Expand Up @@ -550,12 +549,7 @@ impl f64 {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn log2(self) -> f64 {
self.log_wrapper(|n| {
#[cfg(target_os = "android")]
return ::sys::android::log2f64(n);
#[cfg(not(target_os = "android"))]
return unsafe { intrinsics::log2f64(n) };
})
sys::f64::log2(self)
}

/// Returns the base 10 logarithm of the number.
Expand All @@ -571,7 +565,7 @@ impl f64 {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn log10(self) -> f64 {
self.log_wrapper(|n| { unsafe { intrinsics::log10f64(n) } })
sys::f64::log10(self)
}

/// Converts radians to degrees.
Expand Down Expand Up @@ -1091,31 +1085,6 @@ impl f64 {
pub fn atanh(self) -> f64 {
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
}

// Solaris/Illumos requires a wrapper around log, log2, and log10 functions
// because of their non-standard behavior (e.g. log(-n) returns -Inf instead
// of expected NaN).
fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
if !cfg!(target_os = "solaris") {
log_fn(self)
} else {
if self.is_finite() {
if self > 0.0 {
log_fn(self)
} else if self == 0.0 {
NEG_INFINITY // log(0) = -Inf
} else {
NAN // log(-n) = NaN
}
} else if self.is_nan() {
self // log(NaN) = NaN
} else if self > 0.0 {
self // log(Inf) = Inf
} else {
NAN // log(-Inf) = NaN
}
}
}
}

#[cfg(test)]
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/sys/redox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub mod backtrace;
pub mod condvar;
pub mod env;
pub mod ext;
pub mod f32;
pub mod f64;
pub mod fast_thread_local;
pub mod fd;
pub mod fs;
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ pub mod backtrace;
pub mod condvar;
pub mod env;
pub mod ext;
pub mod f32;
pub mod f64;
pub mod fast_thread_local;
pub mod fd;
pub mod fs;
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/sys/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub mod condvar;
pub mod dynamic_lib;
pub mod env;
pub mod ext;
pub mod f32;
pub mod f64;
pub mod fs;
pub mod handle;
pub mod memchr;
Expand Down
2 changes: 0 additions & 2 deletions src/tools/tidy/src/pal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ const EXCEPTION_PATHS: &'static [&'static str] = &[

// temporary exceptions
"src/libstd/rtdeps.rs", // Until rustbuild replaces make
"src/libstd/f32.rs",
"src/libstd/f64.rs",
"src/libstd/sys_common/mod.rs",
"src/libstd/sys_common/net.rs",
"src/libterm", // Not sure how to make this crate portable, but test needs it
Expand Down

0 comments on commit badd513

Please sign in to comment.