root / int128.h @ b3ce604e
History | View | Annotate | Download (1.9 kB)
1 | b7cd3db6 | Avi Kivity | #ifndef INT128_H
|
---|---|---|---|
2 | b7cd3db6 | Avi Kivity | #define INT128_H
|
3 | b7cd3db6 | Avi Kivity | |
4 | b7cd3db6 | Avi Kivity | typedef struct Int128 Int128; |
5 | b7cd3db6 | Avi Kivity | |
6 | b7cd3db6 | Avi Kivity | struct Int128 {
|
7 | b7cd3db6 | Avi Kivity | uint64_t lo; |
8 | b7cd3db6 | Avi Kivity | int64_t hi; |
9 | b7cd3db6 | Avi Kivity | }; |
10 | b7cd3db6 | Avi Kivity | |
11 | b7cd3db6 | Avi Kivity | static inline Int128 int128_make64(uint64_t a) |
12 | b7cd3db6 | Avi Kivity | { |
13 | b7cd3db6 | Avi Kivity | return (Int128) { a, 0 }; |
14 | b7cd3db6 | Avi Kivity | } |
15 | b7cd3db6 | Avi Kivity | |
16 | b7cd3db6 | Avi Kivity | static inline uint64_t int128_get64(Int128 a) |
17 | b7cd3db6 | Avi Kivity | { |
18 | b7cd3db6 | Avi Kivity | assert(!a.hi); |
19 | b7cd3db6 | Avi Kivity | return a.lo;
|
20 | b7cd3db6 | Avi Kivity | } |
21 | b7cd3db6 | Avi Kivity | |
22 | b7cd3db6 | Avi Kivity | static inline Int128 int128_zero(void) |
23 | b7cd3db6 | Avi Kivity | { |
24 | b7cd3db6 | Avi Kivity | return int128_make64(0); |
25 | b7cd3db6 | Avi Kivity | } |
26 | b7cd3db6 | Avi Kivity | |
27 | b7cd3db6 | Avi Kivity | static inline Int128 int128_one(void) |
28 | b7cd3db6 | Avi Kivity | { |
29 | b7cd3db6 | Avi Kivity | return int128_make64(1); |
30 | b7cd3db6 | Avi Kivity | } |
31 | b7cd3db6 | Avi Kivity | |
32 | b7cd3db6 | Avi Kivity | static inline Int128 int128_2_64(void) |
33 | b7cd3db6 | Avi Kivity | { |
34 | b7cd3db6 | Avi Kivity | return (Int128) { 0, 1 }; |
35 | b7cd3db6 | Avi Kivity | } |
36 | b7cd3db6 | Avi Kivity | |
37 | b7cd3db6 | Avi Kivity | static inline Int128 int128_add(Int128 a, Int128 b) |
38 | b7cd3db6 | Avi Kivity | { |
39 | b7cd3db6 | Avi Kivity | Int128 r = { a.lo + b.lo, a.hi + b.hi }; |
40 | b7cd3db6 | Avi Kivity | r.hi += (r.lo < a.lo) || (r.lo < b.lo); |
41 | b7cd3db6 | Avi Kivity | return r;
|
42 | b7cd3db6 | Avi Kivity | } |
43 | b7cd3db6 | Avi Kivity | |
44 | b7cd3db6 | Avi Kivity | static inline Int128 int128_neg(Int128 a) |
45 | b7cd3db6 | Avi Kivity | { |
46 | b7cd3db6 | Avi Kivity | a.lo = ~a.lo; |
47 | b7cd3db6 | Avi Kivity | a.hi = ~a.hi; |
48 | b7cd3db6 | Avi Kivity | return int128_add(a, int128_one());
|
49 | b7cd3db6 | Avi Kivity | } |
50 | b7cd3db6 | Avi Kivity | |
51 | b7cd3db6 | Avi Kivity | static inline Int128 int128_sub(Int128 a, Int128 b) |
52 | b7cd3db6 | Avi Kivity | { |
53 | b7cd3db6 | Avi Kivity | return int128_add(a, int128_neg(b));
|
54 | b7cd3db6 | Avi Kivity | } |
55 | b7cd3db6 | Avi Kivity | |
56 | b7cd3db6 | Avi Kivity | static inline bool int128_nonneg(Int128 a) |
57 | b7cd3db6 | Avi Kivity | { |
58 | b7cd3db6 | Avi Kivity | return a.hi >= 0; |
59 | b7cd3db6 | Avi Kivity | } |
60 | b7cd3db6 | Avi Kivity | |
61 | b7cd3db6 | Avi Kivity | static inline bool int128_eq(Int128 a, Int128 b) |
62 | b7cd3db6 | Avi Kivity | { |
63 | b7cd3db6 | Avi Kivity | return a.lo == b.lo && a.hi == b.hi;
|
64 | b7cd3db6 | Avi Kivity | } |
65 | b7cd3db6 | Avi Kivity | |
66 | b7cd3db6 | Avi Kivity | static inline bool int128_ne(Int128 a, Int128 b) |
67 | b7cd3db6 | Avi Kivity | { |
68 | b7cd3db6 | Avi Kivity | return !int128_eq(a, b);
|
69 | b7cd3db6 | Avi Kivity | } |
70 | b7cd3db6 | Avi Kivity | |
71 | b7cd3db6 | Avi Kivity | static inline bool int128_ge(Int128 a, Int128 b) |
72 | b7cd3db6 | Avi Kivity | { |
73 | b7cd3db6 | Avi Kivity | return int128_nonneg(int128_sub(a, b));
|
74 | b7cd3db6 | Avi Kivity | } |
75 | b7cd3db6 | Avi Kivity | |
76 | b7cd3db6 | Avi Kivity | static inline bool int128_lt(Int128 a, Int128 b) |
77 | b7cd3db6 | Avi Kivity | { |
78 | b7cd3db6 | Avi Kivity | return !int128_ge(a, b);
|
79 | b7cd3db6 | Avi Kivity | } |
80 | b7cd3db6 | Avi Kivity | |
81 | b7cd3db6 | Avi Kivity | static inline bool int128_le(Int128 a, Int128 b) |
82 | b7cd3db6 | Avi Kivity | { |
83 | b7cd3db6 | Avi Kivity | return int128_ge(b, a);
|
84 | b7cd3db6 | Avi Kivity | } |
85 | b7cd3db6 | Avi Kivity | |
86 | b7cd3db6 | Avi Kivity | static inline bool int128_gt(Int128 a, Int128 b) |
87 | b7cd3db6 | Avi Kivity | { |
88 | b7cd3db6 | Avi Kivity | return !int128_le(a, b);
|
89 | b7cd3db6 | Avi Kivity | } |
90 | b7cd3db6 | Avi Kivity | |
91 | b7cd3db6 | Avi Kivity | static inline bool int128_nz(Int128 a) |
92 | b7cd3db6 | Avi Kivity | { |
93 | b7cd3db6 | Avi Kivity | return a.lo || a.hi;
|
94 | b7cd3db6 | Avi Kivity | } |
95 | b7cd3db6 | Avi Kivity | |
96 | b7cd3db6 | Avi Kivity | static inline Int128 int128_min(Int128 a, Int128 b) |
97 | b7cd3db6 | Avi Kivity | { |
98 | b7cd3db6 | Avi Kivity | return int128_le(a, b) ? a : b;
|
99 | b7cd3db6 | Avi Kivity | } |
100 | b7cd3db6 | Avi Kivity | |
101 | b7cd3db6 | Avi Kivity | static inline Int128 int128_max(Int128 a, Int128 b) |
102 | b7cd3db6 | Avi Kivity | { |
103 | b7cd3db6 | Avi Kivity | return int128_ge(a, b) ? a : b;
|
104 | b7cd3db6 | Avi Kivity | } |
105 | b7cd3db6 | Avi Kivity | |
106 | b7cd3db6 | Avi Kivity | static inline void int128_addto(Int128 *a, Int128 b) |
107 | b7cd3db6 | Avi Kivity | { |
108 | b7cd3db6 | Avi Kivity | *a = int128_add(*a, b); |
109 | b7cd3db6 | Avi Kivity | } |
110 | b7cd3db6 | Avi Kivity | |
111 | b7cd3db6 | Avi Kivity | static inline void int128_subfrom(Int128 *a, Int128 b) |
112 | b7cd3db6 | Avi Kivity | { |
113 | b7cd3db6 | Avi Kivity | *a = int128_sub(*a, b); |
114 | b7cd3db6 | Avi Kivity | } |
115 | b7cd3db6 | Avi Kivity | |
116 | b7cd3db6 | Avi Kivity | #endif |