diff --git a/src/int/mod.rs b/src/int/mod.rs index d52e208c..c6909c78 100644 --- a/src/int/mod.rs +++ b/src/int/mod.rs @@ -1,3 +1,14 @@ +macro_rules! hty { + ($ty:ty) => { + <$ty as LargeInt>::HighHalf + } +} + +macro_rules! os_ty { + ($ty:ty) => { + <$ty as Int>::OtherSign + } +} pub mod mul; pub mod sdiv; @@ -6,6 +17,8 @@ pub mod udiv; /// Trait for some basic operations on integers pub trait Int { + /// Type with the same width but other signedness + type OtherSign; /// Returns the bitwidth of the int type fn bits() -> u32; } @@ -13,11 +26,13 @@ pub trait Int { macro_rules! int_impl { ($ity:ty, $sty:ty, $bits:expr) => { impl Int for $ity { + type OtherSign = $sty; fn bits() -> u32 { $bits } } impl Int for $sty { + type OtherSign = $ity; fn bits() -> u32 { $bits } diff --git a/src/int/mul.rs b/src/int/mul.rs index 881e923f..571f621e 100644 --- a/src/int/mul.rs +++ b/src/int/mul.rs @@ -2,7 +2,7 @@ use int::LargeInt; use int::Int; macro_rules! mul { - ($intrinsic:ident: $ty:ty, $tyh:ty) => { + ($intrinsic:ident: $ty:ty) => { /// Returns `a * b` #[cfg_attr(not(test), no_mangle)] pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty { @@ -13,15 +13,15 @@ macro_rules! mul { low &= lower_mask; t += (a.low() >> half_bits).wrapping_mul(b.low() & lower_mask); low += (t & lower_mask) << half_bits; - let mut high = (t >> half_bits) as $tyh; + let mut high = (t >> half_bits) as hty!($ty); t = low >> half_bits; low &= lower_mask; t += (b.low() >> half_bits).wrapping_mul(a.low() & lower_mask); low += (t & lower_mask) << half_bits; - high += (t >> half_bits) as $tyh; - high += (a.low() >> half_bits).wrapping_mul(b.low() >> half_bits) as $tyh; - high = high.wrapping_add(a.high().wrapping_mul(b.low() as $tyh)) - .wrapping_add((a.low() as $tyh).wrapping_mul(b.high())); + high += (t >> half_bits) as hty!($ty); + high += (a.low() >> half_bits).wrapping_mul(b.low() >> half_bits) as hty!($ty); + high = high.wrapping_add(a.high().wrapping_mul(b.low() as hty!($ty))) + .wrapping_add((a.low() as hty!($ty)).wrapping_mul(b.high())); <$ty>::from_parts(low, high) } } @@ -73,12 +73,12 @@ macro_rules! mulo { } #[cfg(not(all(feature = "c", target_arch = "x86")))] -mul!(__muldi3: u64, u32); +mul!(__muldi3: u64); #[cfg(stage0)] -mul!(__multi3: u64, u32); +mul!(__multi3: u64); #[cfg(not(stage0))] -mul!(__multi3: i128, i64); +mul!(__multi3: i128); mulo!(__mulosi4: i32); mulo!(__mulodi4: i64); diff --git a/src/int/udiv.rs b/src/int/udiv.rs index b6fe6718..a1a9503a 100644 --- a/src/int/udiv.rs +++ b/src/int/udiv.rs @@ -115,7 +115,7 @@ pub extern "C" fn __umoddi3(a: u64, b: u64) -> u64 { } macro_rules! udivmod_inner { - ($n:expr, $d:expr, $rem:expr, $ty:ty, $tys:ty, $tyh:ty) => {{ + ($n:expr, $d:expr, $rem:expr, $ty:ty) => {{ let (n, d, rem) = ($n, $d, $rem); // NOTE X is unknown, K != 0 if n.high() == 0 { @@ -179,7 +179,7 @@ macro_rules! udivmod_inner { sr = d.high().leading_zeros().wrapping_sub(n.high().leading_zeros()); // D > N - if sr > <$tyh>::bits() - 2 { + if sr > ::bits() - 2 { if let Some(rem) = rem { *rem = n; } @@ -188,7 +188,7 @@ macro_rules! udivmod_inner { sr += 1; - // 1 <= sr <= <$tyh>::bits() - 1 + // 1 <= sr <= ::bits() - 1 q = n << (<$ty>::bits() - sr); r = n >> sr; } else if d.high() == 0 { @@ -208,7 +208,7 @@ macro_rules! udivmod_inner { }; } - sr = 1 + <$tyh>::bits() + d.low().leading_zeros() - n.high().leading_zeros(); + sr = 1 + ::bits() + d.low().leading_zeros() - n.high().leading_zeros(); // 2 <= sr <= u64::bits() - 1 q = n << (<$ty>::bits() - sr); @@ -220,7 +220,7 @@ macro_rules! udivmod_inner { sr = d.high().leading_zeros().wrapping_sub(n.high().leading_zeros()); // D > N - if sr > <$tyh>::bits() - 1 { + if sr > ::bits() - 1 { if let Some(rem) = rem { *rem = n; } @@ -229,7 +229,7 @@ macro_rules! udivmod_inner { sr += 1; - // 1 <= sr <= <$tyh>::bits() + // 1 <= sr <= ::bits() q = n << (<$ty>::bits() - sr); r = n >> sr; } @@ -251,8 +251,8 @@ macro_rules! udivmod_inner { // r -= d; // carry = 1; // } - let s = (d.wrapping_sub(r).wrapping_sub(1)) as $tys >> (<$ty>::bits() - 1); - carry = (s & 1) as $tyh; + let s = (d.wrapping_sub(r).wrapping_sub(1)) as os_ty!($ty) >> (<$ty>::bits() - 1); + carry = (s & 1) as hty!($ty); r -= d & s as $ty; } @@ -266,7 +266,7 @@ macro_rules! udivmod_inner { /// Returns `n / d` and sets `*rem = n % d` #[cfg_attr(not(test), no_mangle)] pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 { - udivmod_inner!(n, d, rem, u64, i64, u32) + udivmod_inner!(n, d, rem, u64) } #[cfg(test)]