implement float subtraction
as a + (-b)
This commit is contained in:
parent
9aa3a257d6
commit
5bb969d8f5
2
build.rs
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",
|
||||
|
@ -60,6 +60,8 @@ fn main() {
|
||||
"addsf3.c",
|
||||
"powidf2.c",
|
||||
"powisf2.c",
|
||||
"subdf3.c",
|
||||
"subsf3.c",
|
||||
// 128 bit integers
|
||||
"lshrti3.c",
|
||||
"modti3.c",
|
||||
|
@ -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"),
|
||||
|
12
src/arm.rs
12
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;
|
||||
|
@ -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
45
src/float/sub.rs
Normal 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)))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user