From b78e956f0834d224f98473003494436856f14490 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 3 Feb 2017 22:06:36 +0100 Subject: [PATCH] Add quickcheck tests --- compiler-rt/compiler-rt-cdylib/build.rs | 11 ++++++ compiler-rt/compiler-rt-cdylib/src/lib.rs | 27 ++++++++++++++ src/int/mul.rs | 24 ++++++++++++ src/int/sdiv.rs | 26 +++++++++++++ src/int/shift.rs | 36 ++++++++++++++++++ src/int/udiv.rs | 45 +++++++++++++++++++++++ src/qc.rs | 2 + 7 files changed, 171 insertions(+) diff --git a/compiler-rt/compiler-rt-cdylib/build.rs b/compiler-rt/compiler-rt-cdylib/build.rs index 4eb7638..5fc18f1 100644 --- a/compiler-rt/compiler-rt-cdylib/build.rs +++ b/compiler-rt/compiler-rt-cdylib/build.rs @@ -60,6 +60,17 @@ fn main() { "addsf3.c", "powidf2.c", "powisf2.c", + // 128 bit integers + "lshrti3.c", + "modti3.c", + "muloti4.c", + "multi3.c", + "udivmodti4.c", + "udivti3.c", + "umodti3.c", + "ashlti3.c", + "ashrti3.c", + "divti3.c", ]); for src in sources.files.iter() { diff --git a/compiler-rt/compiler-rt-cdylib/src/lib.rs b/compiler-rt/compiler-rt-cdylib/src/lib.rs index 81affa2..268da50 100644 --- a/compiler-rt/compiler-rt-cdylib/src/lib.rs +++ b/compiler-rt/compiler-rt-cdylib/src/lib.rs @@ -58,6 +58,33 @@ declare!(___adddf3, __adddf3); declare!(___powisf2, __powisf2); declare!(___powidf2, __powidf2); +#[cfg(all(not(windows), target_pointer_width="64"))] +pub mod int_128 { + extern { + fn __lshrti3(); + fn __modti3(); + fn __muloti4(); + fn __multi3(); + fn __udivmodti4(); + fn __udivti3(); + fn __umodti3(); + fn __ashlti3(); + fn __ashrti3(); + fn __divti3(); + } + + declare!(___lshrti3, __lshrti3); + declare!(___modti3, __modti3); + declare!(___muloti4, __muloti4); + declare!(___multi3, __multi3); + declare!(___udivmodti4, __udivmodti4); + declare!(___udivti3, __udivti3); + declare!(___umodti3, __umodti3); + declare!(___ashlti3, __ashlti3); + declare!(___ashrti3, __ashrti3); + declare!(___divti3, __divti3); +} + #[lang = "eh_personality"] fn eh_personality() {} #[lang = "panic_fmt"] diff --git a/src/int/mul.rs b/src/int/mul.rs index 45a7128..c2aece0 100644 --- a/src/int/mul.rs +++ b/src/int/mul.rs @@ -120,3 +120,27 @@ mod tests { } } } + +#[cfg(test)] +#[cfg(all(not(windows), target_pointer_width="64"))] +mod tests_i128 { + use qc::I128; + + check! { + fn __multi3(f: extern fn(i128, i128) -> i128, a: I128, b: I128) + -> Option { + Some(f(a.0, b.0)) + } + fn __muloti4(f: extern fn(i128, i128, &mut i32) -> i128, + a: I128, + b: I128) -> Option<(i128, i32)> { + let (a, b) = (a.0, b.0); + let mut overflow = 2; + let r = f(a, b, &mut overflow); + if overflow != 0 && overflow != 1 { + return None + } + Some((r, overflow)) + } + } +} diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index 84f72f1..97e1939 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -162,3 +162,29 @@ mod tests { } } } + +#[cfg(test)] +#[cfg(all(not(windows), target_pointer_width="64"))] +mod tests_i128 { + use qc::U128; + + check! { + fn __divti3(f: extern fn(i128, i128) -> i128, n: U128, d: U128) -> Option { + let (n, d) = (n.0 as i128, d.0 as i128); + if d == 0 { + None + } else { + Some(f(n, d)) + } + } + + fn __modti3(f: extern fn(i128, i128) -> i128, n: U128, d: U128) -> Option { + let (n, d) = (n.0 as i128, d.0 as i128); + if d == 0 { + None + } else { + Some(f(n, d)) + } + } + } +} diff --git a/src/int/shift.rs b/src/int/shift.rs index 5c8dd5c..2993d92 100644 --- a/src/int/shift.rs +++ b/src/int/shift.rs @@ -103,3 +103,39 @@ mod tests { } } } + +#[cfg(test)] +#[cfg(all(not(windows), target_pointer_width="64"))] +mod tests_i128 { + use qc::{I128, U128}; + + // NOTE We purposefully stick to `u32` for `b` here because we want "small" values (b < 64) + check! { + fn __ashlti3(f: extern fn(u128, u32) -> u128, a: U128, b: u32) -> Option { + let a = a.0; + if b >= 64 { + None + } else { + Some(f(a, b)) + } + } + + fn __ashrti3(f: extern fn(i128, u32) -> i128, a: I128, b: u32) -> Option { + let a = a.0; + if b >= 64 { + None + } else { + Some(f(a, b)) + } + } + + fn __lshrti3(f: extern fn(u128, u32) -> u128, a: U128, b: u32) -> Option { + let a = a.0; + if b >= 128 { + None + } else { + Some(f(a, b)) + } + } + } +} diff --git a/src/int/udiv.rs b/src/int/udiv.rs index 44a1149..735d388 100644 --- a/src/int/udiv.rs +++ b/src/int/udiv.rs @@ -380,3 +380,48 @@ mod tests { } } } + +#[cfg(test)] +#[cfg(all(not(windows), target_pointer_width="64"))] +mod tests_i128 { + use qc::U128; + + check! { + fn __udivti3(f: extern fn(u128, u128) -> u128, + n: U128, + d: U128) -> Option { + let (n, d) = (n.0, d.0); + if d == 0 { + None + } else { + Some(f(n, d)) + } + } + + fn __umodti3(f: extern fn(u128, u128) -> u128, + n: U128, + d: U128) -> Option { + let (n, d) = (n.0, d.0); + if d == 0 { + None + } else { + Some(f(n, d)) + } + } + + fn __udivmodti4(f: extern fn(u128, u128, Option<&mut u128>) -> u128, + n: U128, + d: U128) -> Option { + let (n, d) = (n.0, d.0); + if d == 0 { + None + } else { + // FIXME fix the segfault when the remainder is requested + /*let mut r = 0; + let q = f(n, d, Some(&mut r)); + Some((q, r))*/ + Some(f(n, d, None)) + } + } + } +} diff --git a/src/qc.rs b/src/qc.rs index 5dbc56f..ea0faac 100644 --- a/src/qc.rs +++ b/src/qc.rs @@ -144,6 +144,8 @@ macro_rules! arbitrary_large { arbitrary_large!(I64: i64); arbitrary_large!(U64: u64); +arbitrary_large!(I128: i128); +arbitrary_large!(U128: u128); macro_rules! arbitrary_float { ($TY:ident : $ty:ident) => {