From ba750103a3348080035c7140c416f82e0dbae7fb Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 25 Nov 2017 07:00:26 -0800 Subject: [PATCH] Another attempt at making MIPS happy (I really don't understand how arithmetic makes it segfault...) --- build.rs | 28 +++++------ src/int/add.rs | 67 ------------------------- src/int/addsub.rs | 122 ++++++++++++++++++++++++++++++++++++++++++++++ src/int/mod.rs | 3 +- src/int/sub.rs | 52 -------------------- 5 files changed, 136 insertions(+), 136 deletions(-) delete mode 100644 src/int/add.rs create mode 100644 src/int/addsub.rs delete mode 100644 src/int/sub.rs diff --git a/build.rs b/build.rs index d7f6c01..753978d 100644 --- a/build.rs +++ b/build.rs @@ -129,11 +129,15 @@ mod tests { Divsf3, Divdf3, - // int/add.rs + // int/addsub.rs AddU128, AddI128, AddoU128, AddoI128, + SubU128, + SubI128, + SuboU128, + SuboI128, // int/mul.rs Muldi3, @@ -160,12 +164,6 @@ mod tests { Lshrdi3, Lshrti3, - // int/sub.rs - SubU128, - SubI128, - SuboU128, - SuboI128, - // int/udiv.rs Udivdi3, Udivmoddi4, @@ -390,7 +388,7 @@ fn addsf3() { fn prologue() -> &'static str { " -use compiler_builtins::int::add::rust_u128_add; +use compiler_builtins::int::addsub::rust_u128_add; static TEST_CASES: &[((u128, u128), u128)] = &[ " @@ -448,7 +446,7 @@ fn u128_add() { fn prologue() -> &'static str { " -use compiler_builtins::int::add::rust_i128_add; +use compiler_builtins::int::addsub::rust_i128_add; static TEST_CASES: &[((i128, i128), i128)] = &[ " @@ -508,7 +506,7 @@ fn i128_add() { fn prologue() -> &'static str { " -use compiler_builtins::int::add::rust_u128_addo; +use compiler_builtins::int::addsub::rust_u128_addo; static TEST_CASES: &[((u128, u128), (u128, bool))] = &[ " @@ -568,7 +566,7 @@ fn u128_addo() { fn prologue() -> &'static str { " -use compiler_builtins::int::add::rust_i128_addo; +use compiler_builtins::int::addsub::rust_i128_addo; static TEST_CASES: &[((i128, i128), (i128, bool))] = &[ " @@ -3514,7 +3512,7 @@ fn subsf3() { fn prologue() -> &'static str { " -use compiler_builtins::int::sub::rust_u128_sub; +use compiler_builtins::int::addsub::rust_u128_sub; static TEST_CASES: &[((u128, u128), u128)] = &[ " @@ -3572,7 +3570,7 @@ fn u128_sub() { fn prologue() -> &'static str { " -use compiler_builtins::int::sub::rust_i128_sub; +use compiler_builtins::int::addsub::rust_i128_sub; static TEST_CASES: &[((i128, i128), i128)] = &[ " @@ -3632,7 +3630,7 @@ fn i128_sub() { fn prologue() -> &'static str { " -use compiler_builtins::int::sub::rust_u128_subo; +use compiler_builtins::int::addsub::rust_u128_subo; static TEST_CASES: &[((u128, u128), (u128, bool))] = &[ " @@ -3692,7 +3690,7 @@ fn u128_subo() { fn prologue() -> &'static str { " -use compiler_builtins::int::sub::rust_i128_subo; +use compiler_builtins::int::addsub::rust_i128_subo; static TEST_CASES: &[((i128, i128), (i128, bool))] = &[ " diff --git a/src/int/add.rs b/src/int/add.rs deleted file mode 100644 index 5c746c2..0000000 --- a/src/int/add.rs +++ /dev/null @@ -1,67 +0,0 @@ -use int::LargeInt; -use int::Int; - -trait UAdd: LargeInt { - fn uadd(self, other: Self) -> Self { - let (low, carry) = self.low().overflowing_add(other.low()); - let high = self.high().wrapping_add(other.high()); - let carry = if carry { Self::HighHalf::ONE } else { Self::HighHalf::ZERO }; - Self::from_parts(low, high.wrapping_add(carry)) - } -} - -impl UAdd for u128 {} - -trait Add: Int - where ::UnsignedInt: UAdd -{ - fn add(self, other: Self) -> Self { - Self::from_unsigned(self.unsigned().uadd(other.unsigned())) - } -} - -impl Add for u128 {} -impl Add for i128 {} - -trait Addo: Add - where ::UnsignedInt: UAdd -{ - fn addo(self, other: Self, overflow: &mut i32) -> Self { - *overflow = 0; - let result = Add::add(self, other); - if other >= Self::ZERO { - if result < self { - *overflow = 1; - } - } else { - if result >= self { - *overflow = 1; - } - } - result - } -} - -impl Addo for i128 {} -impl Addo for u128 {} - -#[cfg_attr(not(stage0), lang = "i128_add")] -pub fn rust_i128_add(a: i128, b: i128) -> i128 { - rust_u128_add(a as _, b as _) as _ -} -#[cfg_attr(not(stage0), lang = "i128_addo")] -pub fn rust_i128_addo(a: i128, b: i128) -> (i128, bool) { - let mut oflow = 0; - let r = a.addo(b, &mut oflow); - (r, oflow != 0) -} -#[cfg_attr(not(stage0), lang = "u128_add")] -pub fn rust_u128_add(a: u128, b: u128) -> u128 { - a.add(b) -} -#[cfg_attr(not(stage0), lang = "u128_addo")] -pub fn rust_u128_addo(a: u128, b: u128) -> (u128, bool) { - let mut oflow = 0; - let r = a.addo(b, &mut oflow); - (r, oflow != 0) -} diff --git a/src/int/addsub.rs b/src/int/addsub.rs new file mode 100644 index 0000000..7564d89 --- /dev/null +++ b/src/int/addsub.rs @@ -0,0 +1,122 @@ +use int::LargeInt; +use int::Int; + +trait UAddSub: LargeInt { + fn uadd(self, other: Self) -> Self { + let (low, carry) = self.low().overflowing_add(other.low()); + let high = self.high().wrapping_add(other.high()); + let carry = if carry { Self::HighHalf::ONE } else { Self::HighHalf::ZERO }; + Self::from_parts(low, high.wrapping_add(carry)) + } + fn uadd_one(self) -> Self { + let (low, carry) = self.low().overflowing_add(Self::LowHalf::ONE); + let carry = if carry { Self::HighHalf::ONE } else { Self::HighHalf::ZERO }; + Self::from_parts(low, self.high().wrapping_add(carry)) + } + fn usub(self, other: Self) -> Self { + let uneg = (!other).uadd_one(); + self.uadd(uneg) + } +} + +impl UAddSub for u128 {} + +trait AddSub: Int + where ::UnsignedInt: UAddSub +{ + fn add(self, other: Self) -> Self { + Self::from_unsigned(self.unsigned().uadd(other.unsigned())) + } + fn sub(self, other: Self) -> Self { + Self::from_unsigned(self.unsigned().usub(other.unsigned())) + } +} + +impl AddSub for u128 {} +impl AddSub for i128 {} + +trait Addo: AddSub + where ::UnsignedInt: UAddSub +{ + fn addo(self, other: Self, overflow: &mut i32) -> Self { + *overflow = 0; + let result = AddSub::add(self, other); + if other >= Self::ZERO { + if result < self { + *overflow = 1; + } + } else { + if result >= self { + *overflow = 1; + } + } + result + } +} + +impl Addo for i128 {} +impl Addo for u128 {} + +trait Subo: AddSub + where ::UnsignedInt: UAddSub +{ + fn subo(self, other: Self, overflow: &mut i32) -> Self { + *overflow = 0; + let result = AddSub::sub(self, other); + if other >= Self::ZERO { + if result > self { + *overflow = 1; + } + } else { + if result <= self { + *overflow = 1; + } + } + result + } +} + +impl Subo for i128 {} +impl Subo for u128 {} + +#[cfg_attr(not(stage0), lang = "i128_add")] +pub fn rust_i128_add(a: i128, b: i128) -> i128 { + rust_u128_add(a as _, b as _) as _ +} +#[cfg_attr(not(stage0), lang = "i128_addo")] +pub fn rust_i128_addo(a: i128, b: i128) -> (i128, bool) { + let mut oflow = 0; + let r = a.addo(b, &mut oflow); + (r, oflow != 0) +} +#[cfg_attr(not(stage0), lang = "u128_add")] +pub fn rust_u128_add(a: u128, b: u128) -> u128 { + a.add(b) +} +#[cfg_attr(not(stage0), lang = "u128_addo")] +pub fn rust_u128_addo(a: u128, b: u128) -> (u128, bool) { + let mut oflow = 0; + let r = a.addo(b, &mut oflow); + (r, oflow != 0) +} + +#[cfg_attr(not(stage0), lang = "i128_sub")] +pub fn rust_i128_sub(a: i128, b: i128) -> i128 { + rust_u128_sub(a as _, b as _) as _ +} +#[cfg_attr(not(stage0), lang = "i128_subo")] +pub fn rust_i128_subo(a: i128, b: i128) -> (i128, bool) { + let mut oflow = 0; + let r = a.subo(b, &mut oflow); + (r, oflow != 0) +} +#[cfg_attr(not(stage0), lang = "u128_sub")] +pub fn rust_u128_sub(a: u128, b: u128) -> u128 { + a.sub(b) +} +#[cfg_attr(not(stage0), lang = "u128_subo")] +pub fn rust_u128_subo(a: u128, b: u128) -> (u128, bool) { + let mut oflow = 0; + let r = a.subo(b, &mut oflow); + (r, oflow != 0) +} diff --git a/src/int/mod.rs b/src/int/mod.rs index c5490cb..b645b21 100644 --- a/src/int/mod.rs +++ b/src/int/mod.rs @@ -12,11 +12,10 @@ macro_rules! os_ty { } } -pub mod add; +pub mod addsub; pub mod mul; pub mod sdiv; pub mod shift; -pub mod sub; pub mod udiv; /// Trait for some basic operations on integers diff --git a/src/int/sub.rs b/src/int/sub.rs deleted file mode 100644 index abcb45a..0000000 --- a/src/int/sub.rs +++ /dev/null @@ -1,52 +0,0 @@ -use int::LargeInt; - -trait Sub: LargeInt { - fn sub(self, other: Self) -> Self { - let neg_other = (!other).wrapping_add(Self::ONE); - self.wrapping_add(neg_other) - } -} - -impl Sub for i128 {} -impl Sub for u128 {} - -trait Subo: Sub { - fn subo(self, other: Self, overflow: &mut i32) -> Self { - *overflow = 0; - let result = Sub::sub(self, other); - if other >= Self::ZERO { - if result > self { - *overflow = 1; - } - } else { - if result <= self { - *overflow = 1; - } - } - result - } -} - -impl Subo for i128 {} -impl Subo for u128 {} - -#[cfg_attr(not(stage0), lang = "i128_sub")] -pub fn rust_i128_sub(a: i128, b: i128) -> i128 { - rust_u128_sub(a as _, b as _) as _ -} -#[cfg_attr(not(stage0), lang = "i128_subo")] -pub fn rust_i128_subo(a: i128, b: i128) -> (i128, bool) { - let mut oflow = 0; - let r = a.subo(b, &mut oflow); - (r, oflow != 0) -} -#[cfg_attr(not(stage0), lang = "u128_sub")] -pub fn rust_u128_sub(a: u128, b: u128) -> u128 { - a.sub(b) -} -#[cfg_attr(not(stage0), lang = "u128_subo")] -pub fn rust_u128_subo(a: u128, b: u128) -> (u128, bool) { - let mut oflow = 0; - let r = a.subo(b, &mut oflow); - (r, oflow != 0) -}