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,
|
Divsf3,
|
||||||
Divdf3,
|
Divdf3,
|
||||||
|
|
||||||
// int/add.rs
|
// int/addsub.rs
|
||||||
AddU128,
|
AddU128,
|
||||||
AddI128,
|
AddI128,
|
||||||
AddoU128,
|
AddoU128,
|
||||||
AddoI128,
|
AddoI128,
|
||||||
|
SubU128,
|
||||||
|
SubI128,
|
||||||
|
SuboU128,
|
||||||
|
SuboI128,
|
||||||
|
|
||||||
// int/mul.rs
|
// int/mul.rs
|
||||||
Muldi3,
|
Muldi3,
|
||||||
|
@ -160,12 +164,6 @@ mod tests {
|
||||||
Lshrdi3,
|
Lshrdi3,
|
||||||
Lshrti3,
|
Lshrti3,
|
||||||
|
|
||||||
// int/sub.rs
|
|
||||||
SubU128,
|
|
||||||
SubI128,
|
|
||||||
SuboU128,
|
|
||||||
SuboI128,
|
|
||||||
|
|
||||||
// int/udiv.rs
|
// int/udiv.rs
|
||||||
Udivdi3,
|
Udivdi3,
|
||||||
Udivmoddi4,
|
Udivmoddi4,
|
||||||
|
@ -390,7 +388,7 @@ fn addsf3() {
|
||||||
|
|
||||||
fn prologue() -> &'static str {
|
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)] = &[
|
static TEST_CASES: &[((u128, u128), u128)] = &[
|
||||||
"
|
"
|
||||||
|
@ -448,7 +446,7 @@ fn u128_add() {
|
||||||
|
|
||||||
fn prologue() -> &'static str {
|
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)] = &[
|
static TEST_CASES: &[((i128, i128), i128)] = &[
|
||||||
"
|
"
|
||||||
|
@ -508,7 +506,7 @@ fn i128_add() {
|
||||||
|
|
||||||
fn prologue() -> &'static str {
|
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))] = &[
|
static TEST_CASES: &[((u128, u128), (u128, bool))] = &[
|
||||||
"
|
"
|
||||||
|
@ -568,7 +566,7 @@ fn u128_addo() {
|
||||||
|
|
||||||
fn prologue() -> &'static str {
|
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))] = &[
|
static TEST_CASES: &[((i128, i128), (i128, bool))] = &[
|
||||||
"
|
"
|
||||||
|
@ -3514,7 +3512,7 @@ fn subsf3() {
|
||||||
|
|
||||||
fn prologue() -> &'static str {
|
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)] = &[
|
static TEST_CASES: &[((u128, u128), u128)] = &[
|
||||||
"
|
"
|
||||||
|
@ -3572,7 +3570,7 @@ fn u128_sub() {
|
||||||
|
|
||||||
fn prologue() -> &'static str {
|
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)] = &[
|
static TEST_CASES: &[((i128, i128), i128)] = &[
|
||||||
"
|
"
|
||||||
|
@ -3632,7 +3630,7 @@ fn i128_sub() {
|
||||||
|
|
||||||
fn prologue() -> &'static str {
|
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))] = &[
|
static TEST_CASES: &[((u128, u128), (u128, bool))] = &[
|
||||||
"
|
"
|
||||||
|
@ -3692,7 +3690,7 @@ fn u128_subo() {
|
||||||
|
|
||||||
fn prologue() -> &'static str {
|
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))] = &[
|
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)
|
|
||||||
}
|
|
|
@ -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 mul;
|
||||||
pub mod sdiv;
|
pub mod sdiv;
|
||||||
pub mod shift;
|
pub mod shift;
|
||||||
pub mod sub;
|
|
||||||
pub mod udiv;
|
pub mod udiv;
|
||||||
|
|
||||||
/// Trait for some basic operations on integers
|
/// 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