Skip to content

Commit 5bb969d

Browse files
author
Jorge Aparicio
committed
implement float subtraction
as a + (-b)
1 parent 9aa3a25 commit 5bb969d

File tree

6 files changed

+63
-3
lines changed

6 files changed

+63
-3
lines changed

build.rs

-2
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,6 @@ fn main() {
170170
"popcountdi2.c",
171171
"popcountsi2.c",
172172
"powixf2.c",
173-
"subdf3.c",
174-
"subsf3.c",
175173
"subvdi3.c",
176174
"subvsi3.c",
177175
"truncdfhf2.c",

compiler-rt/compiler-rt-cdylib/build.rs

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ fn main() {
6060
"addsf3.c",
6161
"powidf2.c",
6262
"powisf2.c",
63+
"subdf3.c",
64+
"subsf3.c",
6365
// 128 bit integers
6466
"lshrti3.c",
6567
"modti3.c",

compiler-rt/compiler-rt-cdylib/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ extern {
2424
fn __adddf3();
2525
fn __powisf2();
2626
fn __powidf2();
27+
fn __subsf3();
28+
fn __subdf3();
2729
}
2830

2931
macro_rules! declare {
@@ -57,6 +59,8 @@ declare!(___addsf3, __addsf3);
5759
declare!(___adddf3, __adddf3);
5860
declare!(___powisf2, __powisf2);
5961
declare!(___powidf2, __powidf2);
62+
declare!(___subsf3, __subsf3);
63+
declare!(___subdf3, __subdf3);
6064

6165
#[cfg(all(not(windows),
6266
not(target_arch = "mips64"),

src/arm.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ pub unsafe fn __aeabi_ldivmod() {
6060
intrinsics::unreachable();
6161
}
6262

63-
// TODO: These aeabi_* functions should be defined as aliases
6463
#[cfg_attr(not(test), no_mangle)]
6564
pub extern "aapcs" fn __aeabi_dadd(a: f64, b: f64) -> f64 {
6665
::float::add::__adddf3(a, b)
@@ -71,6 +70,16 @@ pub extern "aapcs" fn __aeabi_fadd(a: f32, b: f32) -> f32 {
7170
::float::add::__addsf3(a, b)
7271
}
7372

73+
#[cfg_attr(not(test), no_mangle)]
74+
pub extern "aapcs" fn __aeabi_dsub(a: f64, b: f64) -> f64 {
75+
::float::sub::__subdf3(a, b)
76+
}
77+
78+
#[cfg_attr(not(test), no_mangle)]
79+
pub extern "aapcs" fn __aeabi_fsub(a: f32, b: f32) -> f32 {
80+
::float::sub::__subsf3(a, b)
81+
}
82+
7483
#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
7584
#[cfg_attr(not(test), no_mangle)]
7685
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 {
103112
::int::udiv::__udivsi3(a, b)
104113
}
105114

115+
// TODO: These aeabi_* functions should be defined as aliases
106116
#[cfg(not(feature = "mem"))]
107117
extern "C" {
108118
fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;

src/float/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use core::mem;
22

33
pub mod add;
44
pub mod pow;
5+
pub mod sub;
56

67
/// Trait for some basic operations on floats
78
pub trait Float: Sized + Copy {

src/float/sub.rs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use float::Float;
2+
3+
macro_rules! sub {
4+
($(#[$attr:meta])*
5+
| $intrinsic:ident: $ty:ty) => {
6+
/// Returns `a - b`
7+
$(#[$attr])*
8+
pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
9+
a + <$ty>::from_repr(b.repr() ^ <$ty>::sign_mask())
10+
}
11+
}
12+
}
13+
14+
sub!(#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
15+
#[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
16+
| __subsf3: f32);
17+
18+
sub!(#[cfg_attr(all(not(test), not(target_arch = "arm")), no_mangle)]
19+
#[cfg_attr(all(not(test), target_arch = "arm"), inline(always))]
20+
| __subdf3: f64);
21+
22+
// NOTE(cfg) for some reason, on arm*-unknown-linux-gnueabi*, our implementation doesn't
23+
// match the output of its gcc_s or compiler-rt counterpart. Until we investigate further, we'll
24+
// just avoid testing against them on those targets. Do note that our implementation gives the
25+
// correct answer; gcc_s and compiler-rt are incorrect in this case.
26+
#[cfg(all(test, not(arm_linux)))]
27+
mod tests {
28+
use core::{f32, f64};
29+
use qc::{F32, F64};
30+
31+
check! {
32+
fn __subsf3(f: extern "C" fn(f32, f32) -> f32,
33+
a: F32,
34+
b: F32)
35+
-> Option<F32> {
36+
Some(F32(f(a.0, b.0)))
37+
}
38+
39+
fn __subdf3(f: extern "C" fn(f64, f64) -> f64,
40+
a: F64,
41+
b: F64) -> Option<F64> {
42+
Some(F64(f(a.0, b.0)))
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)