1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | #ifndef LLVM_CLANG_BASIC_FIXEDPOINT_H |
17 | #define LLVM_CLANG_BASIC_FIXEDPOINT_H |
18 | |
19 | #include "llvm/ADT/APSInt.h" |
20 | #include "llvm/ADT/SmallString.h" |
21 | #include "llvm/Support/raw_ostream.h" |
22 | |
23 | namespace clang { |
24 | |
25 | class ASTContext; |
26 | class QualType; |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | class FixedPointSemantics { |
34 | public: |
35 | FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned, |
36 | bool IsSaturated, bool HasUnsignedPadding) |
37 | : Width(Width), Scale(Scale), IsSigned(IsSigned), |
38 | IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) { |
39 | (0) . __assert_fail ("Width >= Scale && \"Not enough room for the scale\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/FixedPoint.h", 39, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Width >= Scale && "Not enough room for the scale"); |
40 | (0) . __assert_fail ("!(IsSigned && HasUnsignedPadding) && \"Cannot have unsigned padding on a signed type.\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/FixedPoint.h", 41, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!(IsSigned && HasUnsignedPadding) && |
41 | (0) . __assert_fail ("!(IsSigned && HasUnsignedPadding) && \"Cannot have unsigned padding on a signed type.\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/FixedPoint.h", 41, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "Cannot have unsigned padding on a signed type."); |
42 | } |
43 | |
44 | unsigned getWidth() const { return Width; } |
45 | unsigned getScale() const { return Scale; } |
46 | bool isSigned() const { return IsSigned; } |
47 | bool isSaturated() const { return IsSaturated; } |
48 | bool hasUnsignedPadding() const { return HasUnsignedPadding; } |
49 | |
50 | void setSaturated(bool Saturated) { IsSaturated = Saturated; } |
51 | |
52 | |
53 | |
54 | |
55 | unsigned getIntegralBits() const { |
56 | if (IsSigned || (!IsSigned && HasUnsignedPadding)) |
57 | return Width - Scale - 1; |
58 | else |
59 | return Width - Scale; |
60 | } |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | FixedPointSemantics |
67 | getCommonSemantics(const FixedPointSemantics &Other) const; |
68 | |
69 | |
70 | static FixedPointSemantics GetIntegerSemantics(unsigned Width, |
71 | bool IsSigned) { |
72 | return FixedPointSemantics(Width, , IsSigned, |
73 | , |
74 | ); |
75 | } |
76 | |
77 | private: |
78 | unsigned Width; |
79 | unsigned Scale; |
80 | bool IsSigned; |
81 | bool IsSaturated; |
82 | bool HasUnsignedPadding; |
83 | }; |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | class APFixedPoint { |
96 | public: |
97 | APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema) |
98 | : Val(Val, !Sema.isSigned()), Sema(Sema) { |
99 | (0) . __assert_fail ("Val.getBitWidth() == Sema.getWidth() && \"The value should have a bit width that matches the Sema width\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/FixedPoint.h", 100, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Val.getBitWidth() == Sema.getWidth() && |
100 | (0) . __assert_fail ("Val.getBitWidth() == Sema.getWidth() && \"The value should have a bit width that matches the Sema width\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Basic/FixedPoint.h", 100, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> "The value should have a bit width that matches the Sema width"); |
101 | } |
102 | |
103 | APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema) |
104 | : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()), |
105 | Sema) {} |
106 | |
107 | |
108 | APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {} |
109 | |
110 | llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); } |
111 | inline unsigned getWidth() const { return Sema.getWidth(); } |
112 | inline unsigned getScale() const { return Sema.getScale(); } |
113 | inline bool isSaturated() const { return Sema.isSaturated(); } |
114 | inline bool isSigned() const { return Sema.isSigned(); } |
115 | inline bool hasPadding() const { return Sema.hasUnsignedPadding(); } |
116 | FixedPointSemantics getSemantics() const { return Sema; } |
117 | |
118 | bool getBoolValue() const { return Val.getBoolValue(); } |
119 | |
120 | |
121 | |
122 | |
123 | APFixedPoint convert(const FixedPointSemantics &DstSema, |
124 | bool *Overflow = nullptr) const; |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const; |
131 | |
132 | |
133 | |
134 | APFixedPoint negate(bool *Overflow = nullptr) const; |
135 | |
136 | APFixedPoint shr(unsigned Amt) const { |
137 | return APFixedPoint(Val >> Amt, Sema); |
138 | } |
139 | |
140 | APFixedPoint shl(unsigned Amt) const { |
141 | return APFixedPoint(Val << Amt, Sema); |
142 | } |
143 | |
144 | |
145 | |
146 | llvm::APSInt getIntPart() const { |
147 | if (Val < 0 && Val != -Val) |
148 | return -(-Val >> getScale()); |
149 | else |
150 | return Val >> getScale(); |
151 | } |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | llvm::APSInt convertToInt(unsigned DstWidth, bool DstSign, |
162 | bool *Overflow = nullptr) const; |
163 | |
164 | void toString(llvm::SmallVectorImpl<char> &Str) const; |
165 | std::string toString() const { |
166 | llvm::SmallString<40> S; |
167 | toString(S); |
168 | return S.str(); |
169 | } |
170 | |
171 | |
172 | int compare(const APFixedPoint &Other) const; |
173 | bool operator==(const APFixedPoint &Other) const { |
174 | return compare(Other) == 0; |
175 | } |
176 | bool operator!=(const APFixedPoint &Other) const { |
177 | return compare(Other) != 0; |
178 | } |
179 | bool operator>(const APFixedPoint &Other) const { return compare(Other) > 0; } |
180 | bool operator<(const APFixedPoint &Other) const { return compare(Other) < 0; } |
181 | bool operator>=(const APFixedPoint &Other) const { |
182 | return compare(Other) >= 0; |
183 | } |
184 | bool operator<=(const APFixedPoint &Other) const { |
185 | return compare(Other) <= 0; |
186 | } |
187 | |
188 | static APFixedPoint getMax(const FixedPointSemantics &Sema); |
189 | static APFixedPoint getMin(const FixedPointSemantics &Sema); |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | static APFixedPoint getFromIntValue(const llvm::APSInt &Value, |
196 | const FixedPointSemantics &DstFXSema, |
197 | bool *Overflow = nullptr); |
198 | |
199 | private: |
200 | llvm::APSInt Val; |
201 | FixedPointSemantics Sema; |
202 | }; |
203 | |
204 | inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, |
205 | const APFixedPoint &FX) { |
206 | OS << FX.toString(); |
207 | return OS; |
208 | } |
209 | |
210 | } |
211 | |
212 | #endif |
213 | |