Skip to content

Commit 2f3c534

Browse files
committed
u128 udiv intrinsics
1 parent 8fe50d8 commit 2f3c534

File tree

4 files changed

+71
-20
lines changed

4 files changed

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

117138
macro_rules! udivmod_inner {
118139
($n:expr, $d:expr, $rem:expr, $ty:ty) => {{
@@ -269,6 +290,28 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
269290
udivmod_inner!(n, d, rem, u64)
270291
}
271292

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

src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,17 @@ macro_rules! srem {
8989
}
9090
}
9191

92+
// Hack for LLVM expectations for ABI on windows
93+
#[cfg(all(windows, target_pointer_width="64"))]
94+
#[repr(simd)]
95+
pub struct U64x2(u64, u64);
96+
97+
#[cfg(all(windows, target_pointer_width="64"))]
98+
fn conv(i: u128) -> U64x2 {
99+
use int::LargeInt;
100+
U64x2(i.low(), i.high())
101+
}
102+
92103
#[cfg(test)]
93104
#[cfg_attr(target_arch = "arm", macro_use)]
94105
extern crate quickcheck;

0 commit comments

Comments
 (0)