diff --git a/README.md b/README.md index 7397810..0810edf 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ These builtins are needed to support 128-bit integers, which are in the process - [x] ashlti3.c - [x] ashrti3.c -- [ ] divti3.c +- [x] divti3.c - [ ] fixdfti.c - [ ] fixsfti.c - [ ] fixunsdfti.c @@ -205,7 +205,7 @@ These builtins are needed to support 128-bit integers, which are in the process - [ ] floatuntidf.c - [ ] floatuntisf.c - [x] lshrti3.c -- [ ] modti3.c +- [x] modti3.c - [x] muloti4.c - [x] multi3.c - [x] udivmodti4.c diff --git a/build.rs b/build.rs index 5219a04..ca58b67 100644 --- a/build.rs +++ b/build.rs @@ -182,7 +182,6 @@ fn main() { "cmpti2.c", "ctzti2.c", "divtf3.c", - "divti3.c", "ffsti2.c", "fixdfti.c", "fixsfti.c", @@ -196,7 +195,6 @@ fn main() { "floatuntidf.c", "floatuntisf.c", "floatuntixf.c", - "modti3.c", "multf3.c", "mulvti3.c", "negti2.c", diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index b541322..84f72f1 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -2,9 +2,12 @@ use int::Int; macro_rules! div { ($intrinsic:ident: $ty:ty, $uty:ty) => { + div!($intrinsic: $ty, $uty, $ty, |i| {i}); + }; + ($intrinsic:ident: $ty:ty, $uty:ty, $tyret:ty, $conv:expr) => { /// Returns `a / b` #[cfg_attr(not(test), no_mangle)] - pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty { + pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $tyret { let s_a = a >> (<$ty>::bits() - 1); let s_b = b >> (<$ty>::bits() - 1); let a = (a ^ s_a) - s_a; @@ -12,23 +15,26 @@ macro_rules! div { let s = s_a ^ s_b; let r = udiv!(a as $uty, b as $uty); - (r as $ty ^ s) - s + ($conv)((r as $ty ^ s) - s) } } } macro_rules! mod_ { ($intrinsic:ident: $ty:ty, $uty:ty) => { + mod_!($intrinsic: $ty, $uty, $ty, |i| {i}); + }; + ($intrinsic:ident: $ty:ty, $uty:ty, $tyret:ty, $conv:expr) => { /// Returns `a % b` #[cfg_attr(not(test), no_mangle)] - pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty { + pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $tyret { let s = b >> (<$ty>::bits() - 1); let b = (b ^ s) - s; let s = a >> (<$ty>::bits() - 1); let a = (a ^ s) - s; let r = urem!(a as $uty, b as $uty); - (r as $ty ^ s) - s + ($conv)((r as $ty ^ s) - s) } } } @@ -61,12 +67,24 @@ div!(__divsi3: i32, u32); #[cfg(not(all(feature = "c", target_arch = "x86")))] div!(__divdi3: i64, u64); +#[cfg(not(all(windows, target_pointer_width="64")))] +div!(__divti3: i128, u128); + +#[cfg(all(windows, target_pointer_width="64"))] +div!(__divti3: i128, u128, ::U64x2, ::sconv); + #[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))] mod_!(__modsi3: i32, u32); #[cfg(not(all(feature = "c", target_arch = "x86")))] mod_!(__moddi3: i64, u64); +#[cfg(not(all(windows, target_pointer_width="64")))] +mod_!(__modti3: i128, u128); + +#[cfg(all(windows, target_pointer_width="64"))] +mod_!(__modti3: i128, u128, ::U64x2, ::sconv); + #[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))] divmod!(__divmodsi4, __divsi3: i32); diff --git a/src/lib.rs b/src/lib.rs index 559e1a7..0a80ad2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,13 @@ fn conv(i: u128) -> U64x2 { U64x2(i.low(), i.high()) } +#[cfg(all(windows, target_pointer_width="64"))] +fn sconv(i: i128) -> U64x2 { + use int::LargeInt; + let j = i as u128; + U64x2(j.low(), j.high()) +} + #[cfg(test)] #[cfg_attr(target_arch = "arm", macro_use)] extern crate quickcheck;