From 5b8fe3e45a540e398094938697d5a1d46239f394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Cassiers?= Date: Tue, 24 Jan 2017 15:14:13 +0100 Subject: [PATCH 1/4] Move platform-specific implementation of libstd/path.rs This removes one exception in the tidy lint 'pal'. --- src/libstd/path.rs | 4 ++-- src/libstd/sys/redox/path.rs | 2 ++ src/libstd/sys/unix/path.rs | 1 + src/libstd/sys/windows/path.rs | 1 + src/tools/tidy/src/pal.rs | 1 - 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index eb0a6cd74d7bc..228c0fd773803 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -127,7 +127,7 @@ use ops::{self, Deref}; use ffi::{OsStr, OsString}; -use sys::path::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix}; +use sys::path::{ABSOLUTE_NEEDS_PREFIX, is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix}; //////////////////////////////////////////////////////////////////////////////// // GENERAL NOTES @@ -1509,7 +1509,7 @@ impl Path { #[allow(deprecated)] pub fn is_absolute(&self) -> bool { // FIXME: Remove target_os = "redox" and allow Redox prefixes - self.has_root() && (cfg!(unix) || cfg!(target_os = "redox") || self.prefix().is_some()) + self.has_root() && (!ABSOLUTE_NEEDS_PREFIX || self.prefix().is_some()) } /// A path is *relative* if it is not absolute. diff --git a/src/libstd/sys/redox/path.rs b/src/libstd/sys/redox/path.rs index e6a267dd5d913..8863937794bbe 100644 --- a/src/libstd/sys/redox/path.rs +++ b/src/libstd/sys/redox/path.rs @@ -37,3 +37,5 @@ pub fn parse_prefix(path: &OsStr) -> Option { pub const MAIN_SEP_STR: &'static str = "/"; pub const MAIN_SEP: char = '/'; +// FIXME: Change to 'true' and allow Redox prefixes +pub const ABSOLUTE_NEEDS_PREFIX: bool = false; diff --git a/src/libstd/sys/unix/path.rs b/src/libstd/sys/unix/path.rs index bf9af7a4353a8..5a06058534632 100644 --- a/src/libstd/sys/unix/path.rs +++ b/src/libstd/sys/unix/path.rs @@ -27,3 +27,4 @@ pub fn parse_prefix(_: &OsStr) -> Option { pub const MAIN_SEP_STR: &'static str = "/"; pub const MAIN_SEP: char = '/'; +pub const ABSOLUTE_NEEDS_PREFIX: bool = false; diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs index 2b47808451bc2..900946438d5d2 100644 --- a/src/libstd/sys/windows/path.rs +++ b/src/libstd/sys/windows/path.rs @@ -106,3 +106,4 @@ pub fn parse_prefix<'a>(path: &'a OsStr) -> Option { pub const MAIN_SEP_STR: &'static str = "\\"; pub const MAIN_SEP: char = '\\'; +pub const ABSOLUTE_NEEDS_PREFIX: bool = true; diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 3808c05c6b939..0a65de7468708 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -66,7 +66,6 @@ const EXCEPTION_PATHS: &'static [&'static str] = &[ // temporary exceptions "src/libstd/rtdeps.rs", // Until rustbuild replaces make - "src/libstd/path.rs", "src/libstd/f32.rs", "src/libstd/f64.rs", "src/libstd/sys_common/mod.rs", From 662fef63603a9600ff2e4a712373dea220d2e517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Cassiers?= Date: Thu, 26 Jan 2017 21:15:58 +0100 Subject: [PATCH 2/4] Move platform-specific implementation of libstd/f{32,64}.rs This removes exceptions in the tidy lint 'pal'. --- src/libstd/sys/redox/f32.rs | 78 ++++++++++++++ src/libstd/sys/redox/f64.rs | 33 ++++++ src/libstd/sys/unix/f32.rs | 81 +++++++++++++++ src/libstd/sys/unix/f64.rs | 66 ++++++++++++ src/libstd/sys/windows/f32.rs | 190 ++++++++++++++++++++++++++++++++++ src/libstd/sys/windows/f64.rs | 36 +++++++ 6 files changed, 484 insertions(+) create mode 100644 src/libstd/sys/redox/f32.rs create mode 100644 src/libstd/sys/redox/f64.rs create mode 100644 src/libstd/sys/unix/f32.rs create mode 100644 src/libstd/sys/unix/f64.rs create mode 100644 src/libstd/sys/windows/f32.rs create mode 100644 src/libstd/sys/windows/f64.rs diff --git a/src/libstd/sys/redox/f32.rs b/src/libstd/sys/redox/f32.rs new file mode 100644 index 0000000000000..6fd9ce3cc6bdb --- /dev/null +++ b/src/libstd/sys/redox/f32.rs @@ -0,0 +1,78 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +use intrinsics; + +pub mod cmath { + use libc::{c_float, c_int}; + + #[link_name = "m"] + extern { + pub fn lgammaf_r(n: c_float, sign: &mut c_int) -> c_float; + pub fn hypotf(x: c_float, y: c_float) -> c_float; + 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; + } +} + +#[inline] +pub fn floor(x: f32) -> f32 { + unsafe { intrinsics::floorf32(x) } +} + +#[inline] +pub fn ceil(x: f32) -> f32 { + unsafe { intrinsics::ceilf32(x) } +} + +#[inline] +pub fn powf(x: f32, n: f32) -> f32 { + unsafe { intrinsics::powf32(x, n) } +} + +#[inline] +pub fn exp(x: f32) -> f32 { + unsafe { intrinsics::expf32(x) } +} + +#[inline] +pub fn ln(x: f32) -> f32 { + unsafe { intrinsics::logf32(x) } +} + +#[inline] +pub fn log2(x: f32) -> f32 { + unsafe { intrinsics::log2f32(x) } +} + +#[inline] +pub fn log10(x: f32) -> f32 { + unsafe { intrinsics::log10f32(x) } +} + +#[inline] +pub fn sin(x: f32) -> f32 { + unsafe { intrinsics::sinf32(x) } +} + +#[inline] +pub fn cos(x: f32) -> f32 { + unsafe { intrinsics::cosf32(x) } +} diff --git a/src/libstd/sys/redox/f64.rs b/src/libstd/sys/redox/f64.rs new file mode 100644 index 0000000000000..4935a813f240e --- /dev/null +++ b/src/libstd/sys/redox/f64.rs @@ -0,0 +1,33 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +pub mod cmath { + use libc::{c_double, c_int}; + + #[link_name = "m"] + extern { + pub fn lgamma_r(n: c_double, sign: &mut c_int) -> c_double; + pub fn hypot(x: c_double, y: c_double) -> c_double; + } +} + +pub fn ln(x: f64) -> f64 { + unsafe { ::intrinsics::logf64(x) } +} + +pub fn log2(x: f64) -> f64 { + unsafe { ::intrinsics::log2f64(x) } +} + +pub fn log10(x: f64) -> f64 { + unsafe { ::intrinsics::log10f64(x) } +} diff --git a/src/libstd/sys/unix/f32.rs b/src/libstd/sys/unix/f32.rs new file mode 100644 index 0000000000000..23b73a84b4192 --- /dev/null +++ b/src/libstd/sys/unix/f32.rs @@ -0,0 +1,81 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +use intrinsics; + +pub mod cmath { + use libc::{c_float, c_int}; + + #[link_name = "m"] + extern { + pub fn lgammaf_r(n: c_float, sign: &mut c_int) -> c_float; + pub fn hypotf(x: c_float, y: c_float) -> c_float; + 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; + } +} + +#[inline] +pub fn floor(x: f32) -> f32 { + unsafe { intrinsics::floorf32(x) } +} + +#[inline] +pub fn ceil(x: f32) -> f32 { + unsafe { intrinsics::ceilf32(x) } +} + +#[inline] +pub fn powf(x: f32, n: f32) -> f32 { + unsafe { intrinsics::powf32(x, n) } +} + +#[inline] +pub fn exp(x: f32) -> f32 { + unsafe { intrinsics::expf32(x) } +} + +#[inline] +pub fn ln(x: f32) -> f32 { + unsafe { intrinsics::logf32(x) } +} + +#[inline] +pub fn log2(x: f32) -> f32 { + #[cfg(target_os = "android")] + return ::sys::android::log2f32(x); + #[cfg(not(target_os = "android"))] + return unsafe { intrinsics::log2f32(x) }; +} + +#[inline] +pub fn log10(x: f32) -> f32 { + unsafe { intrinsics::log10f32(x) } +} + +#[inline] +pub fn sin(x: f32) -> f32 { + unsafe { intrinsics::sinf32(x) } +} + +#[inline] +pub fn cos(x: f32) -> f32 { + unsafe { intrinsics::cosf32(x) } +} diff --git a/src/libstd/sys/unix/f64.rs b/src/libstd/sys/unix/f64.rs new file mode 100644 index 0000000000000..cce9d7a619f0e --- /dev/null +++ b/src/libstd/sys/unix/f64.rs @@ -0,0 +1,66 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +use core::f64::{NAN, NEG_INFINITY}; + +pub mod cmath { + use libc::{c_double, c_int}; + + #[link_name = "m"] + extern { + pub fn lgamma_r(n: c_double, sign: &mut c_int) -> c_double; + pub fn hypot(x: c_double, y: c_double) -> c_double; + } +} + +pub fn ln(x: f64) -> f64 { + log_wrapper(x, |n| { unsafe { ::intrinsics::logf64(n) } }) +} + +pub fn log2(x: f64) -> f64 { + log_wrapper(x, + |n| { + #[cfg(target_os = "android")] + return ::sys::android::log2f64(n); + #[cfg(not(target_os = "android"))] + return unsafe { ::intrinsics::log2f64(n) }; + }) +} + +pub fn log10(x: f64) -> f64 { + log_wrapper(x, |n| { unsafe { ::intrinsics::log10f64(n) } }) +} + +// 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 f64>(x: f64, log_fn: F) -> f64 { + if !cfg!(target_os = "solaris") { + log_fn(x) + } else { + if x.is_finite() { + if x > 0.0 { + log_fn(x) + } else if x == 0.0 { + NEG_INFINITY // log(0) = -Inf + } else { + NAN // log(-n) = NaN + } + } else if x.is_nan() { + x // log(NaN) = NaN + } else if x > 0.0 { + x // log(Inf) = Inf + } else { + NAN // log(-Inf) = NaN + } + } +} diff --git a/src/libstd/sys/windows/f32.rs b/src/libstd/sys/windows/f32.rs new file mode 100644 index 0000000000000..b57aaa4ecd25e --- /dev/null +++ b/src/libstd/sys/windows/f32.rs @@ -0,0 +1,190 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +use intrinsics; + +pub mod cmath { + use libc::{c_float, c_int}; + + extern { + #[cfg_attr(target_env = "msvc", link_name = "__lgamma_r")] + pub fn lgammaf_r(n: c_float, sign: &mut c_int) -> c_float; + + #[cfg_attr(target_env = "msvc", link_name = "_hypot")] + 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 + } + } +} + +pub fn floor(x: f32) -> f32 { + // On MSVC LLVM will lower many math intrinsics to a call to the + // corresponding function. On MSVC, however, many of these functions + // aren't actually available as symbols to call, but rather they are all + // `static inline` functions in header files. This means that from a C + // perspective it's "compatible", but not so much from an ABI + // perspective (which we're worried about). + // + // The inline header functions always just cast to a f64 and do their + // operation, so we do that here as well, but only for MSVC targets. + // + // 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 (x as f64).floor() as f32; + #[cfg(not(target_env = "msvc"))] + return unsafe { intrinsics::floorf32(x) }; +} + +#[inline] +pub fn ceil(x: f32) -> f32 { + // see notes above in `floor` + #[cfg(target_env = "msvc")] + return (x as f64).ceil() as f32; + #[cfg(not(target_env = "msvc"))] + return unsafe { intrinsics::ceilf32(x) }; +} + +#[inline] +pub fn powf(x: f32, n: f32) -> f32 { + // see notes above in `floor` + #[cfg(target_env = "msvc")] + return (x as f64).powf(n as f64) as f32; + #[cfg(not(target_env = "msvc"))] + return unsafe { intrinsics::powf32(x, n) }; +} + +#[inline] +pub fn exp(x: f32) -> f32 { + // see notes above in `floor` + #[cfg(target_env = "msvc")] + return (x as f64).exp() as f32; + #[cfg(not(target_env = "msvc"))] + return unsafe { intrinsics::expf32(x) }; +} + +#[inline] +pub fn ln(x: f32) -> f32 { + // see notes above in `floor` + #[cfg(target_env = "msvc")] + return (x as f64).ln() as f32; + #[cfg(not(target_env = "msvc"))] + return unsafe { intrinsics::logf32(x) }; +} + +#[inline] +pub fn log2(x: f32) -> f32 { + unsafe { intrinsics::log2f32(x) } +} + +#[inline] +pub fn log10(x: f32) -> f32 { + // see notes above in `floor` + #[cfg(target_env = "msvc")] + return (x as f64).log10() as f32; + #[cfg(not(target_env = "msvc"))] + return unsafe { intrinsics::log10f32(x) }; +} + +#[inline] +pub fn sin(x: f32) -> f32 { + // see notes in `core::f32::Float::floor` + #[cfg(target_env = "msvc")] + return (x as f64).sin() as f32; + #[cfg(not(target_env = "msvc"))] + return unsafe { intrinsics::sinf32(x) }; +} + +#[inline] +pub fn cos(x: f32) -> f32 { + // see notes in `core::f32::Float::floor` + #[cfg(target_env = "msvc")] + return (x as f64).cos() as f32; + #[cfg(not(target_env = "msvc"))] + return unsafe { intrinsics::cosf32(x) }; +} diff --git a/src/libstd/sys/windows/f64.rs b/src/libstd/sys/windows/f64.rs new file mode 100644 index 0000000000000..3e8504f86dc95 --- /dev/null +++ b/src/libstd/sys/windows/f64.rs @@ -0,0 +1,36 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +pub mod cmath { + use libc::{c_double, c_int}; + + #[link_name = "m"] + extern { + #[cfg_attr(target_env = "msvc", link_name = "__lgamma_r")] + pub fn lgamma_r(n: c_double, sign: &mut c_int) -> c_double; + + #[cfg_attr(target_env = "msvc", link_name = "_hypot")] + pub fn hypot(x: c_double, y: c_double) -> c_double; + } +} + +pub fn ln(x: f64) -> f64 { + unsafe { ::intrinsics::logf64(x) } +} + +pub fn log2(x: f64) -> f64 { + unsafe { ::intrinsics::log2f64(x) } +} + +pub fn log10(x: f64) -> f64 { + unsafe { ::intrinsics::log10f64(x) } +} From badd513e8c21f1c9d64931dab84eaa544720df88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Cassiers?= Date: Thu, 26 Jan 2017 23:35:49 +0100 Subject: [PATCH 3/4] Use platform-specific implementation for floats Also remove exceptions in tidy lint 'pal'. --- src/libstd/f32.rs | 132 ++++------------------------------ src/libstd/f64.rs | 47 +++--------- src/libstd/sys/redox/mod.rs | 2 + src/libstd/sys/unix/mod.rs | 2 + src/libstd/sys/windows/mod.rs | 2 + src/tools/tidy/src/pal.rs | 2 - 6 files changed, 28 insertions(+), 159 deletions(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 7a676c041ad89..9ae30a6d71768 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -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))] @@ -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; @@ -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 - } } } @@ -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. @@ -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 @@ -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. @@ -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)`. @@ -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. @@ -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. @@ -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. @@ -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). @@ -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). diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 67a1c302483d2..0b40358526224 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -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; @@ -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; } } @@ -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. @@ -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. @@ -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. @@ -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 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)] diff --git a/src/libstd/sys/redox/mod.rs b/src/libstd/sys/redox/mod.rs index 5982bdd6549ca..09880b74adfb5 100644 --- a/src/libstd/sys/redox/mod.rs +++ b/src/libstd/sys/redox/mod.rs @@ -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; diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index fd7dc17cccd8c..99a5b41048e66 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -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; diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index defc41c5f46a3..3d22d282bef5c 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -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; diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 0a65de7468708..82fd68652b2d6 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -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 From 729853539e94066ce9953f11db47ef7bae247c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Cassiers?= Date: Sun, 12 Feb 2017 23:35:50 +0100 Subject: [PATCH 4/4] Fix wrong link names on windows --- src/libstd/sys/windows/f32.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/windows/f32.rs b/src/libstd/sys/windows/f32.rs index b57aaa4ecd25e..4721858ab7bf5 100644 --- a/src/libstd/sys/windows/f32.rs +++ b/src/libstd/sys/windows/f32.rs @@ -16,10 +16,10 @@ pub mod cmath { use libc::{c_float, c_int}; extern { - #[cfg_attr(target_env = "msvc", link_name = "__lgamma_r")] + #[cfg_attr(target_env = "msvc", link_name = "__lgammaf_r")] pub fn lgammaf_r(n: c_float, sign: &mut c_int) -> c_float; - #[cfg_attr(target_env = "msvc", link_name = "_hypot")] + #[cfg_attr(target_env = "msvc", link_name = "_hypotf")] pub fn hypotf(x: c_float, y: c_float) -> c_float; }