Forráskód Böngészése

Auto merge of #142 - rust-lang-nursery:sub, r=alexcrichton

implement float subtraction

as a + (-b)

r? @alexcrichton
bors 8 éve
szülő
commit
1550b0d32f

+ 0 - 2
build.rs

@@ -170,8 +170,6 @@ fn main() {
                          "popcountdi2.c",
                          "popcountsi2.c",
                          "powixf2.c",
-                         "subdf3.c",
-                         "subsf3.c",
                          "subvdi3.c",
                          "subvsi3.c",
                          "truncdfhf2.c",

+ 2 - 0
compiler-rt/compiler-rt-cdylib/build.rs

@@ -60,6 +60,8 @@ fn main() {
         "addsf3.c",
         "powidf2.c",
         "powisf2.c",
+        "subdf3.c",
+        "subsf3.c",
         // 128 bit integers
         "lshrti3.c",
         "modti3.c",

+ 4 - 0
compiler-rt/compiler-rt-cdylib/src/lib.rs

@@ -24,6 +24,8 @@ extern {
     fn __adddf3();
     fn __powisf2();
     fn __powidf2();
+    fn __subsf3();
+    fn __subdf3();
 }
 
 macro_rules! declare {
@@ -57,6 +59,8 @@ declare!(___addsf3, __addsf3);
 declare!(___adddf3, __adddf3);
 declare!(___powisf2, __powisf2);
 declare!(___powidf2, __powidf2);
+declare!(___subsf3, __subsf3);
+declare!(___subdf3, __subdf3);
 
 #[cfg(all(not(windows),
           not(target_arch = "mips64"),

+ 11 - 1
src/arm.rs

@@ -60,7 +60,6 @@ pub unsafe fn __aeabi_ldivmod() {
     intrinsics::unreachable();
 }
 
-// TODO: These aeabi_* functions should be defined as aliases
 #[cfg_attr(not(test), no_mangle)]
 pub extern "aapcs" fn __aeabi_dadd(a: f64, b: f64) -> f64 {
     ::float::add::__adddf3(a, b)
@@ -71,6 +70,16 @@ pub extern "aapcs" fn __aeabi_fadd(a: f32, b: f32) -> f32 {
     ::float::add::__addsf3(a, b)
 }
 
+#[cfg_attr(not(test), no_mangle)]
+pub extern "aapcs" fn __aeabi_dsub(a: f64, b: f64) -> f64 {
+    ::float::sub::__subdf3(a, b)
+}
+
+#[cfg_attr(not(test), no_mangle)]
+pub extern "aapcs" fn __aeabi_fsub(a: f32, b: f32) -> f32 {
+    ::float::sub::__subsf3(a, b)
+}
+
 #[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
 #[cfg_attr(not(test), no_mangle)]
 pub extern "aapcs" fn __aeabi_idiv(a: i32, b: i32) -> i32 {
@@ -103,6 +112,7 @@ pub extern "aapcs" fn __aeabi_uidiv(a: u32, b: u32) -> u32 {
     ::int::udiv::__udivsi3(a, b)
 }
 
+// TODO: These aeabi_* functions should be defined as aliases
 #[cfg(not(feature = "mem"))]
 extern "C" {
     fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;

+ 1 - 0
src/float/mod.rs

@@ -2,6 +2,7 @@ use core::mem;
 
 pub mod add;
 pub mod pow;
+pub mod sub;
 
 /// Trait for some basic operations on floats
 pub trait Float: Sized + Copy {

+ 45 - 0
src/float/sub.rs

@@ -0,0 +1,45 @@
+use float::Float;
+
+macro_rules! sub {
+    ($(#[$attr:meta])*
+     | $intrinsic:ident: $ty:ty) => {
+        /// Returns `a - b`
+        $(#[$attr])*
+        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
+            a + <$ty>::from_repr(b.repr() ^ <$ty>::sign_mask())
+        }
+    }
+}
+
+sub!(#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
+     #[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
+     | __subsf3: f32);
+
+sub!(#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
+     #[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
+     | __subdf3: f64);
+
+// NOTE(cfg) for some reason, on arm*-unknown-linux-gnueabi*, our implementation doesn't
+// match the output of its gcc_s or compiler-rt counterpart. Until we investigate further, we'll
+// just avoid testing against them on those targets. Do note that our implementation gives the
+// correct answer; gcc_s and compiler-rt are incorrect in this case.
+#[cfg(all(test, not(arm_linux)))]
+mod tests {
+    use core::{f32, f64};
+    use qc::{F32, F64};
+
+    check! {
+        fn __subsf3(f: extern "C" fn(f32, f32) -> f32,
+                    a: F32,
+                    b: F32)
+                    -> Option<F32> {
+            Some(F32(f(a.0, b.0)))
+        }
+
+        fn __subdf3(f: extern "C" fn(f64, f64) -> f64,
+                    a: F64,
+                    b: F64) -> Option<F64> {
+            Some(F64(f(a.0, b.0)))
+        }
+    }
+}