Skip to content

Commit b9e916c

Browse files
committed
Add tests for ARM division builtins
1 parent f919660 commit b9e916c

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/arm.rs

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

0 commit comments

Comments
 (0)