1use crate::int::{DInt, Int};
2
3trait UAddSub: DInt {
4 fn uadd(self, other: Self) -> Self {
5 let (lo: ::H, carry: bool) = self.lo().overflowing_add(other.lo());
6 let hi: ::H = self.hi().wrapping_add(other.hi());
7 let carry: ::H = if carry { Self::H::ONE } else { Self::H::ZERO };
8 Self::from_lo_hi(lo, hi:hi.wrapping_add(carry))
9 }
10 fn uadd_one(self) -> Self {
11 let (lo: ::H, carry: bool) = self.lo().overflowing_add(Self::H::ONE);
12 let carry: ::H = if carry { Self::H::ONE } else { Self::H::ZERO };
13 Self::from_lo_hi(lo, self.hi().wrapping_add(carry))
14 }
15 fn usub(self, other: Self) -> Self {
16 let uneg: Self = (!other).uadd_one();
17 self.uadd(uneg)
18 }
19}
20
21impl UAddSub for u128 {}
22
23trait AddSub: Int
24where
25 <Self as Int>::UnsignedInt: UAddSub,
26{
27 fn add(self, other: Self) -> Self {
28 Self::from_unsigned(self.unsigned().uadd(other.unsigned()))
29 }
30 fn sub(self, other: Self) -> Self {
31 Self::from_unsigned(self.unsigned().usub(other.unsigned()))
32 }
33}
34
35impl AddSub for u128 {}
36impl AddSub for i128 {}
37
38trait Addo: AddSub
39where
40 <Self as Int>::UnsignedInt: UAddSub,
41{
42 fn addo(self, other: Self) -> (Self, bool) {
43 let sum: Self = AddSub::add(self, other);
44 (sum, (other < Self::ZERO) != (sum < self))
45 }
46}
47
48impl Addo for i128 {}
49impl Addo for u128 {}
50
51trait Subo: AddSub
52where
53 <Self as Int>::UnsignedInt: UAddSub,
54{
55 fn subo(self, other: Self) -> (Self, bool) {
56 let sum: Self = AddSub::sub(self, other);
57 (sum, (other < Self::ZERO) != (self < sum))
58 }
59}
60
61impl Subo for i128 {}
62impl Subo for u128 {}
63
64intrinsics! {
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