Skip to content

Commit 9493c37

Browse files
author
Jorge Aparicio
committed
test our implementations against gcc_s
if it exposes the same intrinsics that we implement -- gcc_s doesn't implement all the intrinsics for all the architectures. closes #65
1 parent 9d74cf0 commit 9493c37

File tree

9 files changed

+220
-22
lines changed

9 files changed

+220
-22
lines changed

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ version = "0.1.0"
77
rlibc = { git = "https://github.com/alexcrichton/rlibc", optional = true }
88

99
[dev-dependencies]
10+
gcc_s = { path = "gcc_s" }
1011
quickcheck = "0.3.1"
1112

1213
[features]
1314
default = ["rlibc/weak"]
15+
16+
[workspace]

gcc_s/Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
authors = ["Jorge Aparicio <[email protected]>"]
3+
name = "gcc_s"
4+
version = "0.1.0"
5+
6+
[dependencies]
7+
libloading = "0.3.0"

gcc_s/src/lib.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#![feature(drop_types_in_const)]
2+
3+
extern crate libloading;
4+
5+
use std::sync::{Once, ONCE_INIT};
6+
7+
use libloading::Library;
8+
9+
static mut GCC_S: Option<Library> = None;
10+
11+
fn gcc_s() -> &'static Library {
12+
unsafe {
13+
static INIT: Once = ONCE_INIT;
14+
15+
INIT.call_once(|| {
16+
GCC_S = Some(Library::new("libgcc_s.so.1").unwrap());
17+
});
18+
GCC_S.as_ref().unwrap()
19+
}
20+
}
21+
22+
macro_rules! declare {
23+
($symbol:ident: fn($($i:ty),+) -> $o:ty) => {
24+
pub fn $symbol() -> Option<unsafe extern fn($($i),+) -> $o> {
25+
unsafe {
26+
gcc_s().get(concat!("__", stringify!($symbol)).as_bytes()).ok().map(|s| *s)
27+
}
28+
}
29+
}
30+
}
31+
32+
declare!(ashldi3: fn(u64, u32) -> u64);
33+
declare!(ashrdi3: fn(i64, u32) -> i64);
34+
declare!(divdi3: fn(i64, i64) -> i64);
35+
declare!(divmoddi4: fn(i64, i64, &mut i64) -> i64);
36+
declare!(divmodsi4: fn(i32, i32, &mut i32) -> i32);
37+
declare!(divsi3: fn(i32, i32) -> i32);
38+
declare!(lshrdi3: fn(u64, u32) -> u64);
39+
declare!(moddi3: fn(i64, i64) -> i64);
40+
declare!(modsi3: fn(i32, i32) -> i32);
41+
declare!(muldi3: fn(u64, u64) -> u64);
42+
declare!(mulodi4: fn(i64, i64, &mut i32) -> i64);
43+
declare!(mulosi4: fn(i32, i32, &mut i32) -> i32);
44+
declare!(udivdi3: fn(u64, u64) -> u64);
45+
declare!(udivmoddi4: fn(u64, u64, Option<&mut u64>) -> u64);
46+
declare!(udivmodsi4: fn(u32, u32, Option<&mut u32>) -> u32);
47+
declare!(udivsi3: fn(u32, u32) -> u32);
48+
declare!(umoddi3: fn(u64, u64) -> u64);
49+
declare!(umodsi3: fn(u32, u32) -> u32);
50+
declare!(addsf3: fn(f32, f32) -> f32);
51+
declare!(adddf3: fn(f64, f64) -> f64);

src/float/add.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ pub extern fn __aeabi_fadd(a: f32, b: f32) -> f32 {
199199
#[cfg(test)]
200200
mod tests {
201201
use core::{f32, f64};
202+
203+
use gcc_s;
202204
use qc::{U32, U64};
203205
use float::Float;
204206

@@ -213,15 +215,23 @@ mod tests {
213215
fn addsf3(a: U32, b: U32) -> bool {
214216
let (a, b) = (f32::from_repr(a.0), f32::from_repr(b.0));
215217
let x = super::__addsf3(a, b);
216-
let y = a + b;
217-
x.eq_repr(y)
218+
219+
if let Some(addsf3) = gcc_s::addsf3() {
220+
x.eq_repr(unsafe { addsf3(a, b) })
221+
} else {
222+
x.eq_repr(a + b)
223+
}
218224
}
219225

220226
fn adddf3(a: U64, b: U64) -> bool {
221227
let (a, b) = (f64::from_repr(a.0), f64::from_repr(b.0));
222228
let x = super::__adddf3(a, b);
223-
let y = a + b;
224-
x.eq_repr(y)
229+
230+
if let Some(adddf3) = gcc_s::adddf3() {
231+
x.eq_repr(unsafe { adddf3(a, b) })
232+
} else {
233+
x.eq_repr(a + b)
234+
}
225235
}
226236
}
227237

src/int/mul.rs

+29-3
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,19 @@ mulo!(__mulodi4: i64);
7272

7373
#[cfg(test)]
7474
mod tests {
75+
use gcc_s;
7576
use qc::{I32, I64, U64};
7677

7778
quickcheck! {
7879
fn muldi(a: U64, b: U64) -> bool {
7980
let (a, b) = (a.0, b.0);
8081
let r = super::__muldi3(a, b);
81-
r == a.wrapping_mul(b)
82+
83+
if let Some(muldi3) = gcc_s::muldi3() {
84+
r == unsafe { muldi3(a, b) }
85+
} else {
86+
r == a.wrapping_mul(b)
87+
}
8288
}
8389

8490
fn mulosi(a: I32, b: I32) -> bool {
@@ -88,7 +94,17 @@ mod tests {
8894
if overflow != 0 && overflow != 1 {
8995
return false;
9096
}
91-
(r, overflow != 0) == a.overflowing_mul(b)
97+
98+
if let Some(mulosi4) = gcc_s::mulosi4() {
99+
let mut gcc_s_overflow = 2;
100+
let gcc_s_r = unsafe {
101+
mulosi4(a, b, &mut gcc_s_overflow)
102+
};
103+
104+
(r, overflow) == (gcc_s_r, gcc_s_overflow)
105+
} else {
106+
(r, overflow != 0) == a.overflowing_mul(b)
107+
}
92108
}
93109

94110
fn mulodi(a: I64, b: I64) -> bool {
@@ -98,7 +114,17 @@ mod tests {
98114
if overflow != 0 && overflow != 1 {
99115
return false;
100116
}
101-
(r, overflow != 0) == a.overflowing_mul(b)
117+
118+
if let Some(mulodi4) = gcc_s::mulodi4() {
119+
let mut gcc_s_overflow = 2;
120+
let gcc_s_r = unsafe {
121+
mulodi4(a, b, &mut gcc_s_overflow)
122+
};
123+
124+
(r, overflow) == (gcc_s_r, gcc_s_overflow)
125+
} else {
126+
(r, overflow != 0) == a.overflowing_mul(b)
127+
}
102128
}
103129
}
104130
}

src/int/sdiv.rs

+47-6
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ divmod!(__divmoddi4, __divdi3: i64);
5252

5353
#[cfg(test)]
5454
mod tests {
55+
use gcc_s;
5556
use quickcheck::TestResult;
5657
use qc::{U32, U64};
5758

@@ -62,7 +63,12 @@ mod tests {
6263
TestResult::discard()
6364
} else {
6465
let q = super::__divdi3(n, d);
65-
TestResult::from_bool(q == n / d)
66+
67+
if let Some(divdi3) = gcc_s::divdi3() {
68+
TestResult::from_bool(q == unsafe { divdi3(n, d) })
69+
} else {
70+
TestResult::from_bool(q == n / d)
71+
}
6672
}
6773
}
6874

@@ -72,7 +78,12 @@ mod tests {
7278
TestResult::discard()
7379
} else {
7480
let r = super::__moddi3(n, d);
75-
TestResult::from_bool(r == n % d)
81+
82+
if let Some(moddi3) = gcc_s::moddi3() {
83+
TestResult::from_bool(r == unsafe { moddi3(n, d) })
84+
} else {
85+
TestResult::from_bool(r == n % d)
86+
}
7687
}
7788
}
7889

@@ -83,7 +94,17 @@ mod tests {
8394
} else {
8495
let mut r = 0;
8596
let q = super::__divmoddi4(n, d, &mut r);
86-
TestResult::from_bool(q == n / d && r == n % d)
97+
98+
if let Some(divmoddi4) = gcc_s::divmoddi4() {
99+
let mut gcc_s_r = 0;
100+
let gcc_s_q = unsafe {
101+
divmoddi4(n, d, &mut gcc_s_r)
102+
};
103+
104+
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
105+
} else {
106+
TestResult::from_bool(q == n / d && r == n % d)
107+
}
87108
}
88109
}
89110

@@ -93,7 +114,12 @@ mod tests {
93114
TestResult::discard()
94115
} else {
95116
let q = super::__divsi3(n, d);
96-
TestResult::from_bool(q == n / d)
117+
118+
if let Some(divsi3) = gcc_s::divsi3() {
119+
TestResult::from_bool(q == unsafe { divsi3(n, d)})
120+
} else {
121+
TestResult::from_bool(q == n / d)
122+
}
97123
}
98124
}
99125

@@ -103,7 +129,12 @@ mod tests {
103129
TestResult::discard()
104130
} else {
105131
let r = super::__modsi3(n, d);
106-
TestResult::from_bool(r == n % d)
132+
133+
if let Some(modsi3) = gcc_s::modsi3() {
134+
TestResult::from_bool(r == unsafe { modsi3(n, d) })
135+
} else {
136+
TestResult::from_bool(r == n % d)
137+
}
107138
}
108139
}
109140

@@ -114,7 +145,17 @@ mod tests {
114145
} else {
115146
let mut r = 0;
116147
let q = super::__divmodsi4(n, d, &mut r);
117-
TestResult::from_bool(q == n / d && r == n % d)
148+
149+
if let Some(divmodsi4) = gcc_s::divmodsi4() {
150+
let mut gcc_s_r = 0;
151+
let gcc_s_q = unsafe {
152+
divmodsi4(n, d, &mut gcc_s_r)
153+
};
154+
155+
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
156+
} else {
157+
TestResult::from_bool(q == n / d && r == n % d)
158+
}
118159
}
119160
}
120161
}

src/int/shift.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ lshr!(__lshrdi3: u64);
6060

6161
#[cfg(test)]
6262
mod tests {
63+
use gcc_s;
6364
use quickcheck::TestResult;
6465
use qc::{I64, U64};
6566

@@ -71,7 +72,12 @@ mod tests {
7172
TestResult::discard()
7273
} else {
7374
let r = super::__ashldi3(a, b);
74-
TestResult::from_bool(r == a << b)
75+
76+
if let Some(ashldi3) = gcc_s::ashldi3() {
77+
TestResult::from_bool(r == unsafe { ashldi3(a, b) })
78+
} else {
79+
TestResult::from_bool(r == a << b)
80+
}
7581
}
7682
}
7783

@@ -81,7 +87,12 @@ mod tests {
8187
TestResult::discard()
8288
} else {
8389
let r = super::__ashrdi3(a, b);
84-
TestResult::from_bool(r == a >> b)
90+
91+
if let Some(ashrdi3) = gcc_s::ashrdi3() {
92+
TestResult::from_bool(r == unsafe { ashrdi3(a, b) })
93+
} else {
94+
TestResult::from_bool(r == a >> b)
95+
}
8596
}
8697
}
8798

@@ -91,7 +102,12 @@ mod tests {
91102
TestResult::discard()
92103
} else {
93104
let r = super::__lshrdi3(a, b);
94-
TestResult::from_bool(r == a >> b)
105+
106+
if let Some(lshrdi3) = gcc_s::lshrdi3() {
107+
TestResult::from_bool(r == unsafe { lshrdi3(a, b) })
108+
} else {
109+
TestResult::from_bool(r == a >> b)
110+
}
95111
}
96112
}
97113
}

0 commit comments

Comments
 (0)