1 use int::{DInt, Int}; 2 3 trait UAddSub: DInt { uadd(self, other: Self) -> Self4 fn uadd(self, other: Self) -> Self { 5 let (lo, carry) = self.lo().overflowing_add(other.lo()); 6 let hi = self.hi().wrapping_add(other.hi()); 7 let carry = if carry { Self::H::ONE } else { Self::H::ZERO }; 8 Self::from_lo_hi(lo, hi.wrapping_add(carry)) 9 } uadd_one(self) -> Self10 fn uadd_one(self) -> Self { 11 let (lo, carry) = self.lo().overflowing_add(Self::H::ONE); 12 let carry = if carry { Self::H::ONE } else { Self::H::ZERO }; 13 Self::from_lo_hi(lo, self.hi().wrapping_add(carry)) 14 } usub(self, other: Self) -> Self15 fn usub(self, other: Self) -> Self { 16 let uneg = (!other).uadd_one(); 17 self.uadd(uneg) 18 } 19 } 20 21 impl UAddSub for u128 {} 22 23 trait AddSub: Int 24 where 25 <Self as Int>::UnsignedInt: UAddSub, 26 { add(self, other: Self) -> Self27 fn add(self, other: Self) -> Self { 28 Self::from_unsigned(self.unsigned().uadd(other.unsigned())) 29 } sub(self, other: Self) -> Self30 fn sub(self, other: Self) -> Self { 31 Self::from_unsigned(self.unsigned().usub(other.unsigned())) 32 } 33 } 34 35 impl AddSub for u128 {} 36 impl AddSub for i128 {} 37 38 trait Addo: AddSub 39 where 40 <Self as Int>::UnsignedInt: UAddSub, 41 { addo(self, other: Self) -> (Self, bool)42 fn addo(self, other: Self) -> (Self, bool) { 43 let sum = AddSub::add(self, other); 44 (sum, (other < Self::ZERO) != (sum < self)) 45 } 46 } 47 48 impl Addo for i128 {} 49 impl Addo for u128 {} 50 51 trait Subo: AddSub 52 where 53 <Self as Int>::UnsignedInt: UAddSub, 54 { subo(self, other: Self) -> (Self, bool)55 fn subo(self, other: Self) -> (Self, bool) { 56 let sum = AddSub::sub(self, other); 57 (sum, (other < Self::ZERO) != (self < sum)) 58 } 59 } 60 61 impl Subo for i128 {} 62 impl Subo for u128 {} 63 64 intrinsics! { 65 pub extern "C" fn __rust_i128_add(a: i128, b: i128) -> i128 { 66 AddSub::add(a,b) 67 } 68 69 pub extern "C" fn __rust_i128_addo(a: i128, b: i128) -> (i128, bool) { 70 a.addo(b) 71 } 72 73 pub extern "C" fn __rust_u128_add(a: u128, b: u128) -> u128 { 74 AddSub::add(a,b) 75 } 76 77 pub extern "C" fn __rust_u128_addo(a: u128, b: u128) -> (u128, bool) { 78 a.addo(b) 79 } 80 81 pub extern "C" fn __rust_i128_sub(a: i128, b: i128) -> i128 { 82 AddSub::sub(a,b) 83 } 84 85 pub extern "C" fn __rust_i128_subo(a: i128, b: i128) -> (i128, bool) { 86 a.subo(b) 87 } 88 89 pub extern "C" fn __rust_u128_sub(a: u128, b: u128) -> u128 { 90 AddSub::sub(a,b) 91 } 92 93 pub extern "C" fn __rust_u128_subo(a: u128, b: u128) -> (u128, bool) { 94 a.subo(b) 95 } 96 } 97