Skip to content

Commit 95d3b84

Browse files
committed
Add tests for ARM division builtins
1 parent 4939557 commit 95d3b84

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/arm.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,84 @@ pub unsafe extern "C" fn __aeabi_memclr4(dest: *mut u8, n: usize) {
127127
pub unsafe extern "C" fn __aeabi_memclr8(dest: *mut u8, n: usize) {
128128
memset(dest, 0, n);
129129
}
130+
131+
132+
#[cfg(test)]
133+
mod tests {
134+
use quickcheck::TestResult;
135+
use qc::{U32, U64};
136+
137+
quickcheck!{
138+
fn uldivmod(n: U64, d: U64) -> TestResult {
139+
let (n, d) = (n.0, d.0);
140+
if d == 0 {
141+
TestResult::discard()
142+
} else {
143+
let q: u64;
144+
let r: u64;
145+
unsafe {
146+
// The inline asm is a bit tricky here, LLVM will allocate
147+
// both r0 and r1 when we specify a 64-bit value for {r0}.
148+
asm!("bl __aeabi_uldivmod"
149+
: "={r0}" (q), "={r2}" (r)
150+
: "{r0}" (n), "{r2}" (d)
151+
: "r12", "lr", "flags");
152+
}
153+
TestResult::from_bool(q == n / d && r == n % d)
154+
}
155+
}
156+
157+
fn uidivmod(n: U32, d: U32) -> TestResult {
158+
let (n, d) = (n.0, d.0);
159+
if d == 0 {
160+
TestResult::discard()
161+
} else {
162+
let q: u32;
163+
let r: u32;
164+
unsafe {
165+
asm!("bl __aeabi_uidivmod"
166+
: "={r0}" (q), "={r1}" (r)
167+
: "{r0}" (n), "{r1}" (d)
168+
: "r2", "r3", "r12", "lr", "flags");
169+
}
170+
TestResult::from_bool(q == n / d && r == n % d)
171+
}
172+
}
173+
174+
fn ldivmod(n: U64, d: U64) -> TestResult {
175+
let (n, d) = (n.0 as i64, d.0 as i64);
176+
if d == 0 {
177+
TestResult::discard()
178+
} else {
179+
let q: i64;
180+
let r: i64;
181+
unsafe {
182+
// The inline asm is a bit tricky here, LLVM will allocate
183+
// both r0 and r1 when we specify a 64-bit value for {r0}.
184+
asm!("bl __aeabi_ldivmod"
185+
: "={r0}" (q), "={r2}" (r)
186+
: "{r0}" (n), "{r2}" (d)
187+
: "r12", "lr", "flags");
188+
}
189+
TestResult::from_bool(q == n / d && r == n % d)
190+
}
191+
}
192+
193+
fn idivmod(n: U32, d: U32) -> TestResult {
194+
let (n, d) = (n.0 as i32, d.0 as i32);
195+
if d == 0 {
196+
TestResult::discard()
197+
} else {
198+
let q: i32;
199+
let r: i32;
200+
unsafe {
201+
asm!("bl __aeabi_idivmod"
202+
: "={r0}" (q), "={r1}" (r)
203+
: "{r0}" (n), "{r1}" (d)
204+
: "r2", "r3", "r12", "lr", "flags");
205+
}
206+
TestResult::from_bool(q == n / d && r == n % d)
207+
}
208+
}
209+
}
210+
}

0 commit comments

Comments
 (0)