Another attempt at making MIPS happy
(I really don't understand how arithmetic makes it segfault...)
This commit is contained in:
parent
bcc41a9b8d
commit
ba750103a3
28
build.rs
28
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))] = &[
|
||||
"
|
||||
|
@ -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 <Self as Int>::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 <Self as Int>::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)
|
||||
}
|
122
src/int/addsub.rs
Normal file
122
src/int/addsub.rs
Normal file
@ -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 <Self as Int>::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 <Self as Int>::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 <Self as Int>::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)
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user