Skip to content

Commit 211d602

Browse files
committed
u128 udiv intrinsics
1 parent d053642 commit 211d602

File tree

4 files changed

+77
-20
lines changed

4 files changed

+77
-20
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,9 @@ These builtins are needed to support 128-bit integers, which are in the process
208208
- [ ] modti3.c
209209
- [x] muloti4.c
210210
- [x] multi3.c
211-
- [ ] udivmodti4.c
212-
- [ ] udivti3.c
213-
- [ ] umodti3.c
211+
- [x] udivmodti4.c
212+
- [x] udivti3.c
213+
- [x] umodti3.c
214214

215215
## Unimplemented functions
216216

build.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,7 @@ fn main() {
207207
"subtf3.c",
208208
"subvti3.c",
209209
"trampoline_setup.c",
210-
"ucmpti2.c",
211-
"udivmodti4.c",
212-
"udivti3.c",
213-
"umodti3.c"]);
210+
"ucmpti2.c"]);
214211
}
215212

216213
if target_vendor == "apple" {

src/int/udiv.rs

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,49 @@ pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 {
9696
q
9797
}
9898

99-
/// Returns `n / d`
100-
#[cfg_attr(not(test), no_mangle)]
101-
#[cfg(not(all(feature = "c", target_arch = "x86")))]
102-
pub extern "C" fn __udivdi3(n: u64, d: u64) -> u64 {
103-
__udivmoddi4(n, d, None)
99+
macro_rules! div_mod_intrinsics {
100+
($udiv_intr:ident, $umod_intr:ident : $ty:ty) => {
101+
div_mod_intrinsics!($udiv_intr, $umod_intr : $ty,
102+
__udivmoddi4);
103+
};
104+
($udiv_intr:ident, $umod_intr:ident : $ty:ty, $divmod_intr:expr) => {
105+
div_mod_intrinsics!($udiv_intr, $umod_intr : $ty,
106+
$divmod_intr, $ty, |i|{ i });
107+
};
108+
($udiv_intr:ident, $umod_intr:ident : $ty:ty, $divmod_intr:expr,
109+
$tyret:ty, $conv:expr) => {
110+
/// Returns `n / d`
111+
#[cfg_attr(not(test), no_mangle)]
112+
pub extern "C" fn $udiv_intr(n: $ty, d: $ty) -> $tyret {
113+
let r = $divmod_intr(n, d, None);
114+
($conv)(r)
115+
}
116+
117+
/// Returns `n % d`
118+
#[cfg_attr(not(test), no_mangle)]
119+
pub extern "C" fn $umod_intr(a: $ty, b: $ty) -> $tyret {
120+
use core::mem;
121+
122+
let mut rem = unsafe { mem::uninitialized() };
123+
$divmod_intr(a, b, Some(&mut rem));
124+
($conv)(rem)
125+
}
126+
}
104127
}
105128

106-
/// Returns `n % d`
107129
#[cfg(not(all(feature = "c", target_arch = "x86")))]
108-
#[cfg_attr(not(test), no_mangle)]
109-
pub extern "C" fn __umoddi3(a: u64, b: u64) -> u64 {
110-
use core::mem;
130+
div_mod_intrinsics!(__udivdi3, __umoddi3: u64);
111131

112-
let mut rem = unsafe { mem::uninitialized() };
113-
__udivmoddi4(a, b, Some(&mut rem));
114-
rem
115-
}
132+
#[cfg(stage0)]
133+
div_mod_intrinsics!(__udivti3, __umodti3: u64);
134+
135+
#[cfg(not(stage0))]
136+
#[cfg(not(all(windows, target_pointer_width="64")))]
137+
div_mod_intrinsics!(__udivti3, __umodti3: u128, u128_div_mod);
138+
139+
#[cfg(not(stage0))]
140+
#[cfg(all(windows, target_pointer_width="64"))]
141+
div_mod_intrinsics!(__udivti3, __umodti3: u128, u128_div_mod, ::U64x2, ::conv);
116142

117143
macro_rules! udivmod_inner {
118144
($n:expr, $d:expr, $rem:expr, $ty:ty) => {{
@@ -269,6 +295,29 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
269295
udivmod_inner!(n, d, rem, u64)
270296
}
271297

298+
macro_rules! udivmodti4 {
299+
($tyret:ty, $conv:expr) => {
300+
/// Returns `n / d` and sets `*rem = n % d`
301+
#[cfg_attr(not(test), no_mangle)]
302+
pub extern "C" fn __udivmodti4(n: u128, d: u128, rem: Option<&mut u128>) -> $tyret {
303+
let r = u128_div_mod(n, d, rem);
304+
($conv)(r)
305+
}
306+
}
307+
}
308+
309+
/// Returns `n / d` and sets `*rem = n % d`
310+
#[cfg(not(stage0))]
311+
fn u128_div_mod(n: u128, d: u128, rem: Option<&mut u128>) -> u128 {
312+
udivmod_inner!(n, d, rem, u128)
313+
}
314+
315+
#[cfg(all(windows, target_pointer_width="64", not(stage0)))]
316+
udivmodti4!(::U64x2, ::conv);
317+
318+
#[cfg(not(all(windows, target_pointer_width="64", not(stage0))))]
319+
udivmodti4!(::U128_, |i|{ i });
320+
272321
#[cfg(test)]
273322
mod tests {
274323
use qc::{U32, U64};

src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ type U128_ = u128;
100100
#[cfg(not(stage0))]
101101
type I128_ = i128;
102102

103+
// Hack for LLVM expectations for ABI on windows
104+
#[cfg(all(windows, target_pointer_width="64"))]
105+
#[repr(simd)]
106+
pub struct U64x2(u64, u64);
107+
108+
#[cfg(all(windows, target_pointer_width="64"))]
109+
fn conv(i: u128) -> U64x2 {
110+
use int::LargeInt;
111+
U64x2(i.low(), i.high())
112+
}
113+
103114
#[cfg(test)]
104115
#[macro_use]
105116
extern crate quickcheck;

0 commit comments

Comments
 (0)