xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ADT/SlowDynamicAPInt.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- SlowDynamicAPInt.h - SlowDynamicAPInt Class --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This is a simple class to represent arbitrary precision signed integers.
10 // Unlike APInt, one does not have to specify a fixed maximum size, and the
11 // integer can take on any arbitrary values.
12 //
13 // This class is to be used as a fallback slow path for the DynamicAPInt class,
14 // and is not intended to be used directly.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_ADT_SLOWDYNAMICAPINT_H
19 #define LLVM_ADT_SLOWDYNAMICAPINT_H
20 
21 #include "llvm/ADT/APInt.h"
22 #include "llvm/Support/Compiler.h"
23 
24 namespace llvm {
25 class DynamicAPInt;
26 class raw_ostream;
27 } // namespace llvm
28 
29 namespace llvm::detail {
30 /// A simple class providing dynamic arbitrary-precision arithmetic. Internally,
31 /// it stores an APInt, whose width is doubled whenever an overflow occurs at a
32 /// certain width. The default constructor sets the initial width to 64.
33 /// SlowDynamicAPInt is primarily intended to be used as a slow fallback path
34 /// for the upcoming DynamicAPInt class.
35 class SlowDynamicAPInt {
36   APInt Val;
37 
38 public:
39   LLVM_ABI explicit SlowDynamicAPInt(int64_t Val);
40   LLVM_ABI SlowDynamicAPInt();
41   LLVM_ABI explicit SlowDynamicAPInt(const APInt &Val);
42   LLVM_ABI SlowDynamicAPInt &operator=(int64_t Val);
43   LLVM_ABI explicit operator int64_t() const;
44   LLVM_ABI SlowDynamicAPInt operator-() const;
45   LLVM_ABI bool operator==(const SlowDynamicAPInt &O) const;
46   LLVM_ABI bool operator!=(const SlowDynamicAPInt &O) const;
47   LLVM_ABI bool operator>(const SlowDynamicAPInt &O) const;
48   LLVM_ABI bool operator<(const SlowDynamicAPInt &O) const;
49   LLVM_ABI bool operator<=(const SlowDynamicAPInt &O) const;
50   LLVM_ABI bool operator>=(const SlowDynamicAPInt &O) const;
51   LLVM_ABI SlowDynamicAPInt operator+(const SlowDynamicAPInt &O) const;
52   LLVM_ABI SlowDynamicAPInt operator-(const SlowDynamicAPInt &O) const;
53   LLVM_ABI SlowDynamicAPInt operator*(const SlowDynamicAPInt &O) const;
54   LLVM_ABI SlowDynamicAPInt operator/(const SlowDynamicAPInt &O) const;
55   LLVM_ABI SlowDynamicAPInt operator%(const SlowDynamicAPInt &O) const;
56   LLVM_ABI SlowDynamicAPInt &operator+=(const SlowDynamicAPInt &O);
57   LLVM_ABI SlowDynamicAPInt &operator-=(const SlowDynamicAPInt &O);
58   LLVM_ABI SlowDynamicAPInt &operator*=(const SlowDynamicAPInt &O);
59   LLVM_ABI SlowDynamicAPInt &operator/=(const SlowDynamicAPInt &O);
60   LLVM_ABI SlowDynamicAPInt &operator%=(const SlowDynamicAPInt &O);
61 
62   LLVM_ABI SlowDynamicAPInt &operator++();
63   LLVM_ABI SlowDynamicAPInt &operator--();
64 
65   LLVM_ABI friend SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
66   LLVM_ABI friend SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
67                                            const SlowDynamicAPInt &RHS);
68   LLVM_ABI friend SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
69                                             const SlowDynamicAPInt &RHS);
70   /// The operands must be non-negative for gcd.
71   LLVM_ABI friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
72                                        const SlowDynamicAPInt &B);
73 
74   /// Overload to compute a hash_code for a SlowDynamicAPInt value.
75   LLVM_ABI friend hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT
76 
77   // Make DynamicAPInt a friend so it can access Val directly.
78   friend DynamicAPInt;
79 
getBitWidth()80   unsigned getBitWidth() const { return Val.getBitWidth(); }
81 
82   LLVM_ABI void print(raw_ostream &OS) const;
83 
84 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
85   LLVM_DUMP_METHOD void dump() const;
86 #endif
87 };
88 
89 inline raw_ostream &operator<<(raw_ostream &OS, const SlowDynamicAPInt &X) {
90   X.print(OS);
91   return OS;
92 }
93 
94 /// Returns the remainder of dividing LHS by RHS.
95 ///
96 /// The RHS is always expected to be positive, and the result
97 /// is always non-negative.
98 LLVM_ABI SlowDynamicAPInt mod(const SlowDynamicAPInt &LHS,
99                               const SlowDynamicAPInt &RHS);
100 
101 /// Returns the least common multiple of A and B.
102 LLVM_ABI SlowDynamicAPInt lcm(const SlowDynamicAPInt &A,
103                               const SlowDynamicAPInt &B);
104 
105 /// Redeclarations of friend declarations above to
106 /// make it discoverable by lookups.
107 LLVM_ABI SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
108 LLVM_ABI SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
109                                   const SlowDynamicAPInt &RHS);
110 LLVM_ABI SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
111                                    const SlowDynamicAPInt &RHS);
112 LLVM_ABI SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
113                               const SlowDynamicAPInt &B);
114 LLVM_ABI hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT
115 
116 /// ---------------------------------------------------------------------------
117 /// Convenience operator overloads for int64_t.
118 /// ---------------------------------------------------------------------------
119 LLVM_ABI SlowDynamicAPInt &operator+=(SlowDynamicAPInt &A, int64_t B);
120 LLVM_ABI SlowDynamicAPInt &operator-=(SlowDynamicAPInt &A, int64_t B);
121 LLVM_ABI SlowDynamicAPInt &operator*=(SlowDynamicAPInt &A, int64_t B);
122 LLVM_ABI SlowDynamicAPInt &operator/=(SlowDynamicAPInt &A, int64_t B);
123 LLVM_ABI SlowDynamicAPInt &operator%=(SlowDynamicAPInt &A, int64_t B);
124 
125 LLVM_ABI bool operator==(const SlowDynamicAPInt &A, int64_t B);
126 LLVM_ABI bool operator!=(const SlowDynamicAPInt &A, int64_t B);
127 LLVM_ABI bool operator>(const SlowDynamicAPInt &A, int64_t B);
128 LLVM_ABI bool operator<(const SlowDynamicAPInt &A, int64_t B);
129 LLVM_ABI bool operator<=(const SlowDynamicAPInt &A, int64_t B);
130 LLVM_ABI bool operator>=(const SlowDynamicAPInt &A, int64_t B);
131 LLVM_ABI SlowDynamicAPInt operator+(const SlowDynamicAPInt &A, int64_t B);
132 LLVM_ABI SlowDynamicAPInt operator-(const SlowDynamicAPInt &A, int64_t B);
133 LLVM_ABI SlowDynamicAPInt operator*(const SlowDynamicAPInt &A, int64_t B);
134 LLVM_ABI SlowDynamicAPInt operator/(const SlowDynamicAPInt &A, int64_t B);
135 LLVM_ABI SlowDynamicAPInt operator%(const SlowDynamicAPInt &A, int64_t B);
136 
137 LLVM_ABI bool operator==(int64_t A, const SlowDynamicAPInt &B);
138 LLVM_ABI bool operator!=(int64_t A, const SlowDynamicAPInt &B);
139 LLVM_ABI bool operator>(int64_t A, const SlowDynamicAPInt &B);
140 LLVM_ABI bool operator<(int64_t A, const SlowDynamicAPInt &B);
141 LLVM_ABI bool operator<=(int64_t A, const SlowDynamicAPInt &B);
142 LLVM_ABI bool operator>=(int64_t A, const SlowDynamicAPInt &B);
143 LLVM_ABI SlowDynamicAPInt operator+(int64_t A, const SlowDynamicAPInt &B);
144 LLVM_ABI SlowDynamicAPInt operator-(int64_t A, const SlowDynamicAPInt &B);
145 LLVM_ABI SlowDynamicAPInt operator*(int64_t A, const SlowDynamicAPInt &B);
146 LLVM_ABI SlowDynamicAPInt operator/(int64_t A, const SlowDynamicAPInt &B);
147 LLVM_ABI SlowDynamicAPInt operator%(int64_t A, const SlowDynamicAPInt &B);
148 } // namespace llvm::detail
149 
150 #endif // LLVM_ADT_SLOWDYNAMICAPINT_H
151