diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 769faedf46e8e..e8bc95fad8cc2 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -82,7 +82,9 @@ clone_impl! { u16 } clone_impl! { u32 } clone_impl! { u64 } +#[cfg_attr(not(stage0), cfg(target_float))] clone_impl! { f32 } +#[cfg_attr(not(stage0), cfg(target_float))] clone_impl! { f64 } clone_impl! { () } diff --git a/src/libcore/default.rs b/src/libcore/default.rs index 12c4a5ca200ad..a0f463aeb2981 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -160,5 +160,7 @@ default_impl! { i16, 0 } default_impl! { i32, 0 } default_impl! { i64, 0 } +#[cfg_attr(not(stage0), cfg(target_float))] default_impl! { f32, 0.0f32 } +#[cfg_attr(not(stage0), cfg(target_float))] default_impl! { f64, 0.0f64 } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index a3b09e9db42d1..4ff041373eb9d 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -17,6 +17,7 @@ use prelude::v1::*; use cell::{Cell, RefCell, Ref, RefMut, BorrowState}; use marker::PhantomData; use mem; +#[cfg_attr(not(stage0), cfg(target_float))] use num::flt2dec; use ops::Deref; use result; @@ -1018,6 +1019,7 @@ impl<'a> Formatter<'a> { /// Takes the formatted parts and applies the padding. /// Assumes that the caller already has rendered the parts with required precision, /// so that `self.precision` can be ignored. + #[cfg_attr(not(stage0), cfg(target_float))] fn pad_formatted_parts(&mut self, formatted: &flt2dec::Formatted) -> Result { if let Some(mut width) = self.width { // for the sign-aware zero padding, we render the sign first and @@ -1054,6 +1056,7 @@ impl<'a> Formatter<'a> { } } + #[cfg_attr(not(stage0), cfg(target_float))] fn write_formatted_parts(&mut self, formatted: &flt2dec::Formatted) -> Result { fn write_bytes(buf: &mut Write, s: &[u8]) -> Result { buf.write_str(unsafe { str::from_utf8_unchecked(s) }) @@ -1436,6 +1439,7 @@ impl<'a, T: ?Sized> Pointer for &'a mut T { } } +#[cfg_attr(not(stage0), cfg(target_float))] // Common code of floating point Debug and Display. fn float_to_decimal_common(fmt: &mut Formatter, num: &T, negative_zero: bool) -> Result where T: flt2dec::DecodableFloat @@ -1460,6 +1464,7 @@ fn float_to_decimal_common(fmt: &mut Formatter, num: &T, negative_zero: bool) fmt.pad_formatted_parts(&formatted) } +#[cfg_attr(not(stage0), cfg(target_float))] // Common code of floating point LowerExp and UpperExp. fn float_to_exponential_common(fmt: &mut Formatter, num: &T, upper: bool) -> Result where T: flt2dec::DecodableFloat @@ -1513,7 +1518,9 @@ macro_rules! floating { ($ty:ident) => { } } } } +#[cfg_attr(not(stage0), cfg(target_float))] floating! { f32 } +#[cfg_attr(not(stage0), cfg(target_float))] floating! { f64 } // Implementation of Display/Debug for various core types diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 2e2292d63f4c6..e5b0f01d1b2ff 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -414,7 +414,10 @@ extern "rust-intrinsic" { pub fn volatile_load(src: *const T) -> T; /// Perform a volatile store to the `dst` pointer. pub fn volatile_store(dst: *mut T, val: T); +} +#[cfg_attr(not(stage0), cfg(target_float))] +extern "rust-intrinsic" { /// Returns the square root of an `f32` pub fn sqrtf32(x: f32) -> f32; /// Returns the square root of an `f64` @@ -511,7 +514,9 @@ extern "rust-intrinsic" { pub fn roundf32(x: f32) -> f32; /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. pub fn roundf64(x: f64) -> f64; +} +extern "rust-intrinsic" { /// Returns the number of bits set in an integer type `T` pub fn ctpop(x: T) -> T; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index f76b8655ad1ed..b832b7b7ce89a 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -102,7 +102,9 @@ mod uint_macros; #[path = "num/u32.rs"] pub mod u32; #[path = "num/u64.rs"] pub mod u64; +#[cfg_attr(not(stage0), cfg(target_float))] #[path = "num/f32.rs"] pub mod f32; +#[cfg_attr(not(stage0), cfg(target_float))] #[path = "num/f64.rs"] pub mod f64; #[macro_use] diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs index 6265691bde9e9..deceab53cd48d 100644 --- a/src/libcore/num/flt2dec/decoder.rs +++ b/src/libcore/num/flt2dec/decoder.rs @@ -12,6 +12,7 @@ use prelude::v1::*; +#[cfg_attr(not(stage0), cfg(target_float))] use {f32, f64}; use num::{Float, FpCategory}; @@ -57,10 +58,12 @@ pub trait DecodableFloat: Float + Copy { fn min_pos_norm_value() -> Self; } +#[cfg_attr(not(stage0), cfg(target_float))] impl DecodableFloat for f32 { fn min_pos_norm_value() -> Self { f32::MIN_POSITIVE } } +#[cfg_attr(not(stage0), cfg(target_float))] impl DecodableFloat for f64 { fn min_pos_norm_value() -> Self { f64::MIN_POSITIVE } } diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index ed370bb91648f..40d4e3f619258 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -44,7 +44,9 @@ pub struct Wrapping(#[stable(feature = "rust1", since = "1.0.0")] pub T); pub mod wrapping; // All these modules are technically private and only exposed for libcoretest: +#[cfg_attr(not(stage0), cfg(target_float))] pub mod flt2dec; +#[cfg_attr(not(stage0), cfg(target_float))] pub mod dec2flt; pub mod bignum; pub mod diy_float; @@ -111,6 +113,7 @@ macro_rules! zero_one_impl_float { } )*) } +#[cfg_attr(not(stage0), cfg(target_float))] zero_one_impl_float! { f32 f64 } macro_rules! checked_op { @@ -2210,6 +2213,7 @@ pub enum FpCategory { #[unstable(feature = "core_float", reason = "stable interface is via `impl f{32,64}` in later crates", issue = "27702")] +#[cfg_attr(not(stage0), cfg(target_float))] pub trait Float: Sized { /// Returns the NaN value. #[unstable(feature = "float_extras", reason = "needs removal", @@ -2448,6 +2452,7 @@ impl fmt::Display for ParseIntError { } #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(stage0), cfg(target_float))] pub use num::dec2flt::ParseFloatError; // Conversion traits for primitive integer and float types @@ -2495,19 +2500,23 @@ impl_from! { u32, i64 } // they fit in the significand, which is 24 bits in f32 and 53 bits in f64. // Lossy float conversions are not implemented at this time. -// Signed -> Float -impl_from! { i8, f32 } -impl_from! { i8, f64 } -impl_from! { i16, f32 } -impl_from! { i16, f64 } -impl_from! { i32, f64 } - -// Unsigned -> Float -impl_from! { u8, f32 } -impl_from! { u8, f64 } -impl_from! { u16, f32 } -impl_from! { u16, f64 } -impl_from! { u32, f64 } - -// Float -> Float -impl_from! { f32, f64 } +#[cfg_attr(not(stage0), cfg(target_float))] +mod int_flot_conv { + use convert::From; + // Signed -> Float + impl_from! { i8, f32 } + impl_from! { i8, f64 } + impl_from! { i16, f32 } + impl_from! { i16, f64 } + impl_from! { i32, f64 } + + // Unsigned -> Float + impl_from! { u8, f32 } + impl_from! { u8, f64 } + impl_from! { u16, f32 } + impl_from! { u16, f64 } + impl_from! { u32, f64 } + + // Float -> Float + impl_from! { f32, f64 } +} diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index d1c5b175bb034..13a7202ddb100 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -212,7 +212,9 @@ macro_rules! add_impl { )*) } -add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } +add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +#[cfg_attr(not(stage0), cfg(target_float))] +add_impl! { f32 f64 } /// The `Sub` trait is used to specify the functionality of `-`. /// @@ -265,7 +267,9 @@ macro_rules! sub_impl { )*) } -sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } +sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +#[cfg_attr(not(stage0), cfg(target_float))] +sub_impl! { f32 f64 } /// The `Mul` trait is used to specify the functionality of `*`. /// @@ -318,7 +322,9 @@ macro_rules! mul_impl { )*) } -mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } +mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +#[cfg_attr(not(stage0), cfg(target_float))] +mul_impl! { f32 f64 } /// The `Div` trait is used to specify the functionality of `/`. /// @@ -389,6 +395,7 @@ macro_rules! div_impl_float { )*) } +#[cfg_attr(not(stage0), cfg(target_float))] div_impl_float! { f32 f64 } /// The `Rem` trait is used to specify the functionality of `%`. @@ -460,6 +467,7 @@ macro_rules! rem_impl_float { )*) } +#[cfg_attr(not(stage0), cfg(target_float))] rem_impl_float! { f32 f64 } /// The `Neg` trait is used to specify the functionality of unary `-`. @@ -527,7 +535,9 @@ macro_rules! neg_impl_unsigned { } // neg_impl_unsigned! { usize u8 u16 u32 u64 } -neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 } +neg_impl_numeric! { isize i8 i16 i32 i64 } +#[cfg_attr(not(stage0), cfg(target_float))] +neg_impl_numeric! { f32 f64 } /// The `Not` trait is used to specify the functionality of unary `!`. /// @@ -927,7 +937,9 @@ macro_rules! add_assign_impl { )+) } -add_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } +add_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +#[cfg_attr(not(stage0), cfg(target_float))] +add_assign_impl! { f32 f64 } /// The `SubAssign` trait is used to specify the functionality of `-=`. /// @@ -973,7 +985,9 @@ macro_rules! sub_assign_impl { )+) } -sub_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } +sub_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +#[cfg_attr(not(stage0), cfg(target_float))] +sub_assign_impl! { f32 f64 } /// The `MulAssign` trait is used to specify the functionality of `*=`. /// @@ -1019,7 +1033,9 @@ macro_rules! mul_assign_impl { )+) } -mul_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } +mul_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +#[cfg_attr(not(stage0), cfg(target_float))] +mul_assign_impl! { f32 f64 } /// The `DivAssign` trait is used to specify the functionality of `/=`. /// @@ -1065,7 +1081,9 @@ macro_rules! div_assign_impl { )+) } -div_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } +div_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +#[cfg_attr(not(stage0), cfg(target_float))] +div_assign_impl! { f32 f64 } /// The `RemAssign` trait is used to specify the functionality of `%=`. /// @@ -1111,7 +1129,9 @@ macro_rules! rem_assign_impl { )+) } -rem_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } +rem_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } +#[cfg_attr(not(stage0), cfg(target_float))] +rem_assign_impl! { f32 f64 } /// The `BitAndAssign` trait is used to specify the functionality of `&=`. /// diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index f835613cfcbb9..8f8b600b8d4e6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -697,6 +697,9 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { "windows" | "unix" => ret.push(attr::mk_word_item(fam)), _ => (), } + if sess.target.target.options.has_floating_point { + ret.push(attr::mk_word_item(InternedString::new("target_float"))); + } if sess.target.target.options.has_elf_tls { ret.push(attr::mk_word_item(InternedString::new("target_thread_local"))); } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index e0743c339ce9d..b40ac1cebdb5c 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -279,6 +279,10 @@ pub struct TargetOptions { pub lib_allocation_crate: String, pub exe_allocation_crate: String, + /// Flag indicating whether hardware floating point support is available for + /// this target. + pub has_floating_point: bool, + /// Flag indicating whether ELF TLS (e.g. #[thread_local]) is available for /// this target. pub has_elf_tls: bool, @@ -332,6 +336,7 @@ impl Default for TargetOptions { lib_allocation_crate: "alloc_system".to_string(), exe_allocation_crate: "alloc_system".to_string(), allow_asm: true, + has_floating_point: true, has_elf_tls: false, obj_is_bitcode: false, } @@ -437,6 +442,7 @@ impl Target { key!(is_like_windows, bool); key!(linker_is_gnu, bool); key!(has_rpath, bool); + key!(has_floating_point, bool); key!(no_compiler_rt, bool); key!(no_default_libraries, bool); key!(pre_link_args, list);