Implement 128bit checked add and sub

This commit is contained in:
bjorn3 2019-07-24 13:16:36 +02:00
parent 4d35be684d
commit 63b82238bb
3 changed files with 17 additions and 29 deletions

View File

@ -44,12 +44,10 @@ unsafe impl Copy for u8 {}
unsafe impl Copy for u16 {}
unsafe impl Copy for u32 {}
unsafe impl Copy for u64 {}
unsafe impl Copy for u128 {}
unsafe impl Copy for usize {}
unsafe impl Copy for i8 {}
unsafe impl Copy for i16 {}
unsafe impl Copy for i32 {}
unsafe impl Copy for i128 {}
unsafe impl Copy for isize {}
unsafe impl Copy for char {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
@ -146,22 +144,6 @@ impl Add for usize {
}
}
impl Add for u128 {
type Output = Self;
fn add(self, rhs: Self) -> Self {
self + rhs
}
}
impl Add for i128 {
type Output = Self;
fn add(self, rhs: Self) -> Self {
self + rhs
}
}
#[lang = "sub"]
pub trait Sub<RHS = Self> {
type Output;
@ -286,15 +268,6 @@ impl PartialEq for i32 {
}
}
impl PartialEq for i128 {
fn eq(&self, other: &i128) -> bool {
(*self) == (*other)
}
fn ne(&self, other: &i128) -> bool {
(*self) != (*other)
}
}
impl PartialEq for isize {
fn eq(&self, other: &isize) -> bool {
(*self) == (*other)

View File

@ -23,6 +23,9 @@ fn main() {
checked_div_u128(0u128, 2u128);
assert_eq!(1u128 + 2, 3);
// overflow panic
// 0xFEDCBA987654321123456789ABCDEFu128 + 0xFEDCBA987654321123456789ABCDEFu128;
println!("{}", 0b100010000000000000000000000000000u128 >> 10);
println!("{}", 0xFEDCBA987654321123456789ABCDEFu128 >> 64);
println!("{} >> 64 == {}", 0xFEDCBA987654321123456789ABCDEFu128 as i128, 0xFEDCBA987654321123456789ABCDEFu128 as i128 >> 64);

View File

@ -23,8 +23,20 @@ pub fn maybe_codegen<'a, 'tcx>(
assert!(!checked);
return None;
}
BinOp::Add | BinOp::Sub => {
return None; // FIXME implement checked versions
BinOp::Add | BinOp::Sub if !checked => return None,
BinOp::Add => {
return Some(if is_signed {
fx.easy_call("__rust_i128_addo", &[lhs, rhs], out_ty)
} else {
fx.easy_call("__rust_u128_addo", &[lhs, rhs], out_ty)
})
}
BinOp::Sub => {
return Some(if is_signed {
fx.easy_call("__rust_i128_subo", &[lhs, rhs], out_ty)
} else {
fx.easy_call("__rust_u128_subo", &[lhs, rhs], out_ty)
})
}
BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"),
BinOp::Mul => {