Skip to content

Commit 5dfe588

Browse files
committed
u128 udiv intrinsics
1 parent d053642 commit 5dfe588

File tree

4 files changed

+76
-20
lines changed

4 files changed

+76
-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: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,46 @@ 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(not(stage0))]
133+
#[cfg(not(all(windows, target_pointer_width="64")))]
134+
div_mod_intrinsics!(__udivti3, __umodti3: u128, u128_div_mod);
135+
136+
#[cfg(not(stage0))]
137+
#[cfg(all(windows, target_pointer_width="64"))]
138+
div_mod_intrinsics!(__udivti3, __umodti3: u128, u128_div_mod, ::U64x2, ::conv);
116139

117140
macro_rules! udivmod_inner {
118141
($n:expr, $d:expr, $rem:expr, $ty:ty) => {{
@@ -269,6 +292,31 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
269292
udivmod_inner!(n, d, rem, u64)
270293
}
271294

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