compiler_builtins/int/
addsub.rs1use crate::int::{DInt, Int, MinInt};
2
3trait UAddSub: DInt + Int {
4 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 }
10 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 }
15 fn usub(self, other: Self) -> Self {
16 let uneg = (!other).uadd_one();
17 self.uadd(uneg)
18 }
19}
20
21impl UAddSub for u128 {}
22
23trait AddSub: Int
24where
25 <Self as MinInt>::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 MinInt>::UnsignedInt: UAddSub,
41{
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
48impl Addo for i128 {}
49impl Addo for u128 {}
50
51trait Subo: AddSub
52where
53 <Self as MinInt>::UnsignedInt: UAddSub,
54{
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
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, oflow: &mut i32) -> i128 {
70 let (add, o) = a.addo(b);
71 *oflow = o.into();
72 add
73 }
74
75 pub extern "C" fn __rust_u128_add(a: u128, b: u128) -> u128 {
76 AddSub::add(a,b)
77 }
78
79 pub extern "C" fn __rust_u128_addo(a: u128, b: u128, oflow: &mut i32) -> u128 {
80 let (add, o) = a.addo(b);
81 *oflow = o.into();
82 add
83 }
84
85 pub extern "C" fn __rust_i128_sub(a: i128, b: i128) -> i128 {
86 AddSub::sub(a,b)
87 }
88
89 pub extern "C" fn __rust_i128_subo(a: i128, b: i128, oflow: &mut i32) -> i128 {
90 let (sub, o) = a.subo(b);
91 *oflow = o.into();
92 sub
93 }
94
95 pub extern "C" fn __rust_u128_sub(a: u128, b: u128) -> u128 {
96 AddSub::sub(a,b)
97 }
98
99 pub extern "C" fn __rust_u128_subo(a: u128, b: u128, oflow: &mut i32) -> u128 {
100 let (sub, o) = a.subo(b);
101 *oflow = o.into();
102 sub
103 }
104}