Skip to content

Commit

Permalink
Introduce hty and os_ty macros and use them
Browse files Browse the repository at this point in the history
  • Loading branch information
est31 committed Jan 5, 2017
1 parent 2a89d0e commit ae515d0
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 18 deletions.
15 changes: 15 additions & 0 deletions src/int/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -6,18 +17,22 @@ 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;
}

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
}
Expand Down
18 changes: 9 additions & 9 deletions src/int/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
}
}
Expand Down Expand Up @@ -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);
Expand Down
18 changes: 9 additions & 9 deletions src/int/udiv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 > <hty!($ty)>::bits() - 2 {
if let Some(rem) = rem {
*rem = n;
}
Expand All @@ -188,7 +188,7 @@ macro_rules! udivmod_inner {

sr += 1;

// 1 <= sr <= <$tyh>::bits() - 1
// 1 <= sr <= <hty!($ty)>::bits() - 1
q = n << (<$ty>::bits() - sr);
r = n >> sr;
} else if d.high() == 0 {
Expand All @@ -208,7 +208,7 @@ macro_rules! udivmod_inner {
};
}

sr = 1 + <$tyh>::bits() + d.low().leading_zeros() - n.high().leading_zeros();
sr = 1 + <hty!($ty)>::bits() + d.low().leading_zeros() - n.high().leading_zeros();

// 2 <= sr <= u64::bits() - 1
q = n << (<$ty>::bits() - sr);
Expand All @@ -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 > <hty!($ty)>::bits() - 1 {
if let Some(rem) = rem {
*rem = n;
}
Expand All @@ -229,7 +229,7 @@ macro_rules! udivmod_inner {

sr += 1;

// 1 <= sr <= <$tyh>::bits()
// 1 <= sr <= <hty!($ty)>::bits()
q = n << (<$ty>::bits() - sr);
r = n >> sr;
}
Expand All @@ -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;
}

Expand All @@ -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)]
Expand Down

0 comments on commit ae515d0

Please sign in to comment.