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