1 | use crate::int::{DInt, Int}; |
2 | |
3 | trait 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 | |
21 | impl UAddSub for u128 {} |
22 | |
23 | trait AddSub: Int |
24 | where |
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 | |
35 | impl AddSub for u128 {} |
36 | impl AddSub for i128 {} |
37 | |
38 | trait Addo: AddSub |
39 | where |
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 | |
48 | impl Addo for i128 {} |
49 | impl Addo for u128 {} |
50 | |
51 | trait Subo: AddSub |
52 | where |
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 | |
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 | |