diff options
| author | bors <bors@rust-lang.org> | 2015-08-18 04:23:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-08-18 04:23:25 +0000 |
| commit | 4c0ffc0e38f1a00925935dce859262cb4e4d6f55 (patch) | |
| tree | 0a6b813b76397ec1d6acba8e8d7c9a3d7514d119 /src/libstd | |
| parent | de67d62c6b7e76ca53b66b3796258238348b3c96 (diff) | |
| parent | 1ddee8070d3cb83609b1f71c29e3deda3d30fd51 (diff) | |
| download | rust-4c0ffc0e38f1a00925935dce859262cb4e4d6f55.tar.gz rust-4c0ffc0e38f1a00925935dce859262cb4e4d6f55.zip | |
Auto merge of #27823 - eefriedman:float-dep-core, r=alexcrichton
There wasn't any particular reason the functions needed to be there anyway, so just get rid of them, and adjust libstd to compensate. With this change, libcore depends on exactly two floating-point functions: fmod and fmodf. They are implicitly referenced because they are used to implement "%". Dependencies of libcore on Linux x86-x64 with this patch: ``` 0000000000000000 *UND* 0000000000000000 __powidf2 0000000000000000 *UND* 0000000000000000 __powisf2 0000000000000000 *UND* 0000000000000000 fmod 0000000000000000 *UND* 0000000000000000 fmodf 0000000000000000 *UND* 0000000000000000 memcmp 0000000000000000 *UND* 0000000000000000 memcpy 0000000000000000 *UND* 0000000000000000 memset 0000000000000000 *UND* 0000000000000000 rust_begin_unwind 0000000000000000 *UND* 0000000000000000 rust_eh_personality ```
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/num/f32.rs | 109 | ||||
| -rw-r--r-- | src/libstd/num/f64.rs | 56 |
2 files changed, 132 insertions, 33 deletions
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index bcbd1a80e8b..62f6cfcb36f 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -16,7 +16,6 @@ #![allow(missing_docs)] use core::num; -#[cfg(not(target_env = "msvc"))] use intrinsics; use libc::c_int; use num::{FpCategory, ParseFloatError}; @@ -40,11 +39,11 @@ mod cmath { pub fn fmaxf(a: c_float, b: c_float) -> c_float; pub fn fminf(a: c_float, b: c_float) -> c_float; pub fn fmodf(a: c_float, b: c_float) -> c_float; - pub fn nextafterf(x: c_float, y: c_float) -> c_float; + pub fn ilogbf(n: c_float) -> c_int; pub fn logbf(n: c_float) -> c_float; pub fn log1pf(n: c_float) -> c_float; - pub fn ilogbf(n: c_float) -> c_int; 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")] @@ -270,7 +269,27 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn floor(self) -> f32 { num::Float::floor(self) } + pub fn floor(self) -> f32 { + return floorf(self); + + // 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")] + fn floorf(f: f32) -> f32 { (f as f64).floor() as f32 } + #[cfg(not(target_env = "msvc"))] + fn floorf(f: f32) -> f32 { unsafe { intrinsics::floorf32(f) } } + } /// Returns the smallest integer greater than or equal to a number. /// @@ -283,7 +302,15 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn ceil(self) -> f32 { num::Float::ceil(self) } + pub fn ceil(self) -> f32 { + return ceilf(self); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn ceilf(f: f32) -> f32 { (f as f64).ceil() as f32 } + #[cfg(not(target_env = "msvc"))] + fn ceilf(f: f32) -> f32 { unsafe { intrinsics::ceilf32(f) } } + } /// Returns the nearest integer to a number. Round half-way cases away from /// `0.0`. @@ -297,7 +324,9 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn round(self) -> f32 { num::Float::round(self) } + pub fn round(self) -> f32 { + unsafe { intrinsics::roundf32(self) } + } /// Returns the integer part of a number. /// @@ -310,7 +339,9 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn trunc(self) -> f32 { num::Float::trunc(self) } + pub fn trunc(self) -> f32 { + unsafe { intrinsics::truncf32(self) } + } /// Returns the fractional part of a number. /// @@ -327,7 +358,7 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn fract(self) -> f32 { num::Float::fract(self) } + pub fn fract(self) -> f32 { self - self.trunc() } /// Computes the absolute value of `self`. Returns `NAN` if the /// number is `NAN`. @@ -426,7 +457,9 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn mul_add(self, a: f32, b: f32) -> f32 { num::Float::mul_add(self, a, b) } + pub fn mul_add(self, a: f32, b: f32) -> f32 { + unsafe { intrinsics::fmaf32(self, a, b) } + } /// Takes the reciprocal (inverse) of a number, `1/x`. /// @@ -470,7 +503,15 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn powf(self, n: f32) -> f32 { num::Float::powf(self, n) } + pub fn powf(self, n: f32) -> f32 { + return powf(self, n); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn powf(f: f32, n: f32) -> f32 { (f as f64).powf(n as f64) as f32 } + #[cfg(not(target_env = "msvc"))] + fn powf(f: f32, n: f32) -> f32 { unsafe { intrinsics::powf32(f, n) } } + } /// Takes the square root of a number. /// @@ -489,7 +530,13 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn sqrt(self) -> f32 { num::Float::sqrt(self) } + pub fn sqrt(self) -> f32 { + if self < 0.0 { + NAN + } else { + unsafe { intrinsics::sqrtf32(self) } + } + } /// Returns `e^(self)`, (the exponential function). /// @@ -507,7 +554,15 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn exp(self) -> f32 { num::Float::exp(self) } + pub fn exp(self) -> f32 { + return expf(self); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn expf(f: f32) -> f32 { (f as f64).exp() as f32 } + #[cfg(not(target_env = "msvc"))] + fn expf(f: f32) -> f32 { unsafe { intrinsics::expf32(f) } } + } /// Returns `2^(self)`. /// @@ -523,7 +578,9 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn exp2(self) -> f32 { num::Float::exp2(self) } + pub fn exp2(self) -> f32 { + unsafe { intrinsics::exp2f32(self) } + } /// Returns the natural logarithm of the number. /// @@ -541,7 +598,15 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn ln(self) -> f32 { num::Float::ln(self) } + pub fn ln(self) -> f32 { + return logf(self); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn logf(f: f32) -> f32 { (f as f64).ln() as f32 } + #[cfg(not(target_env = "msvc"))] + fn logf(f: f32) -> f32 { unsafe { intrinsics::logf32(f) } } + } /// Returns the logarithm of the number with respect to an arbitrary base. /// @@ -562,7 +627,7 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn log(self, base: f32) -> f32 { num::Float::log(self, base) } + pub fn log(self, base: f32) -> f32 { self.ln() / base.ln() } /// Returns the base 2 logarithm of the number. /// @@ -578,7 +643,9 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn log2(self) -> f32 { num::Float::log2(self) } + pub fn log2(self) -> f32 { + unsafe { intrinsics::log2f32(self) } + } /// Returns the base 10 logarithm of the number. /// @@ -594,7 +661,15 @@ impl f32 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn log10(self) -> f32 { num::Float::log10(self) } + pub fn log10(self) -> f32 { + return log10f(self); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn log10f(f: f32) -> f32 { (f as f64).log10() as f32 } + #[cfg(not(target_env = "msvc"))] + fn log10f(f: f32) -> f32 { unsafe { intrinsics::log10f32(f) } } + } /// Converts radians to degrees. /// diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index ea48c46b611..14c540e819e 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -45,12 +45,12 @@ mod cmath { pub fn fmax(a: c_double, b: c_double) -> c_double; pub fn fmin(a: c_double, b: c_double) -> c_double; pub fn fmod(a: c_double, b: c_double) -> c_double; - pub fn nextafter(x: c_double, y: c_double) -> c_double; pub fn frexp(n: c_double, value: &mut c_int) -> c_double; + pub fn ilogb(n: c_double) -> c_int; pub fn ldexp(x: c_double, n: c_int) -> c_double; pub fn logb(n: c_double) -> c_double; pub fn log1p(n: c_double) -> c_double; - pub fn ilogb(n: c_double) -> c_int; + pub fn nextafter(x: c_double, y: c_double) -> c_double; pub fn modf(n: c_double, iptr: &mut c_double) -> c_double; pub fn sinh(n: c_double) -> c_double; pub fn tan(n: c_double) -> c_double; @@ -222,7 +222,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn floor(self) -> f64 { num::Float::floor(self) } + pub fn floor(self) -> f64 { + unsafe { intrinsics::floorf64(self) } + } /// Returns the smallest integer greater than or equal to a number. /// @@ -235,7 +237,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn ceil(self) -> f64 { num::Float::ceil(self) } + pub fn ceil(self) -> f64 { + unsafe { intrinsics::ceilf64(self) } + } /// Returns the nearest integer to a number. Round half-way cases away from /// `0.0`. @@ -249,7 +253,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn round(self) -> f64 { num::Float::round(self) } + pub fn round(self) -> f64 { + unsafe { intrinsics::roundf64(self) } + } /// Returns the integer part of a number. /// @@ -262,7 +268,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn trunc(self) -> f64 { num::Float::trunc(self) } + pub fn trunc(self) -> f64 { + unsafe { intrinsics::truncf64(self) } + } /// Returns the fractional part of a number. /// @@ -277,7 +285,7 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn fract(self) -> f64 { num::Float::fract(self) } + pub fn fract(self) -> f64 { self - self.trunc() } /// Computes the absolute value of `self`. Returns `NAN` if the /// number is `NAN`. @@ -386,7 +394,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn mul_add(self, a: f64, b: f64) -> f64 { num::Float::mul_add(self, a, b) } + pub fn mul_add(self, a: f64, b: f64) -> f64 { + unsafe { intrinsics::fmaf64(self, a, b) } + } /// Takes the reciprocal (inverse) of a number, `1/x`. /// @@ -424,7 +434,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn powf(self, n: f64) -> f64 { num::Float::powf(self, n) } + pub fn powf(self, n: f64) -> f64 { + unsafe { intrinsics::powf64(self, n) } + } /// Takes the square root of a number. /// @@ -441,7 +453,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn sqrt(self) -> f64 { num::Float::sqrt(self) } + pub fn sqrt(self) -> f64 { + unsafe { intrinsics::sqrtf64(self) } + } /// Returns `e^(self)`, (the exponential function). /// @@ -457,7 +471,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn exp(self) -> f64 { num::Float::exp(self) } + pub fn exp(self) -> f64 { + unsafe { intrinsics::expf64(self) } + } /// Returns `2^(self)`. /// @@ -471,7 +487,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn exp2(self) -> f64 { num::Float::exp2(self) } + pub fn exp2(self) -> f64 { + unsafe { intrinsics::exp2f64(self) } + } /// Returns the natural logarithm of the number. /// @@ -487,7 +505,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn ln(self) -> f64 { num::Float::ln(self) } + pub fn ln(self) -> f64 { + unsafe { intrinsics::logf64(self) } + } /// Returns the logarithm of the number with respect to an arbitrary base. /// @@ -506,7 +526,7 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn log(self, base: f64) -> f64 { num::Float::log(self, base) } + pub fn log(self, base: f64) -> f64 { self.ln() / base.ln() } /// Returns the base 2 logarithm of the number. /// @@ -520,7 +540,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn log2(self) -> f64 { num::Float::log2(self) } + pub fn log2(self) -> f64 { + unsafe { intrinsics::log2f64(self) } + } /// Returns the base 10 logarithm of the number. /// @@ -534,7 +556,9 @@ impl f64 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn log10(self) -> f64 { num::Float::log10(self) } + pub fn log10(self) -> f64 { + unsafe { intrinsics::log10f64(self) } + } /// Converts radians to degrees. /// |
