implement float subtraction

as a + (-b)
master
Jorge Aparicio 2017-02-08 10:10:40 -05:00
parent 9aa3a257d6
commit 5bb969d8f5
6 changed files with 63 additions and 3 deletions

View File

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

View File

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

View File

@ -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"),

View File

@ -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;

View File

@ -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
src/float/sub.rs Normal file
View File

@ -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)))
}
}
}