1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "mir_const.h"
17 #include "mir_function.h"
18 #include "global_tables.h"
19 #include "printing.h"
20 #if MIR_FEATURE_FULL
21
22 namespace maple {
Dump(const MIRSymbolTable *) const23 void MIRIntConst::Dump(const MIRSymbolTable *) const
24 {
25 LogInfo::MapleLogger() << value;
26 }
27
operator ==(const MIRConst & rhs) const28 bool MIRIntConst::operator==(const MIRConst &rhs) const
29 {
30 if (&rhs == this) {
31 return true;
32 }
33 if (GetKind() != rhs.GetKind()) {
34 return false;
35 }
36 const auto &intConst = static_cast<const MIRIntConst &>(rhs);
37 return ((&intConst.GetType() == &GetType()) && (intConst.value == value));
38 }
39
GetActualBitWidth() const40 uint8 MIRIntConst::GetActualBitWidth() const
41 {
42 if (value == 0) {
43 return 1;
44 }
45
46 int64 val = GetExtValue();
47 uint64 tmp = val < 0 ? -(val + 1) : val;
48
49 uint8 width = 0;
50 while (tmp != 0) {
51 ++width;
52 tmp = tmp >> 1u;
53 }
54
55 return width;
56 }
57
Dump(const MIRSymbolTable * localSymTab) const58 void MIRAddrofConst::Dump(const MIRSymbolTable *localSymTab) const
59 {
60 LogInfo::MapleLogger() << "addrof " << GetPrimTypeName(PTY_ptr);
61 const MIRSymbol *sym = stIdx.IsGlobal() ? GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx())
62 : localSymTab->GetSymbolFromStIdx(stIdx.Idx());
63 DEBUG_ASSERT(stIdx.IsGlobal() || sym->GetStorageClass() == kScPstatic || sym->GetStorageClass() == kScFstatic,
64 "MIRAddrofConst can only point to a global symbol");
65 LogInfo::MapleLogger() << (stIdx.IsGlobal() ? " $" : " %") << sym->GetName();
66 if (fldID > 0) {
67 LogInfo::MapleLogger() << " " << fldID;
68 }
69 if (offset != 0) {
70 LogInfo::MapleLogger() << " (" << offset << ")";
71 }
72 }
73
operator ==(const MIRConst & rhs) const74 bool MIRAddrofConst::operator==(const MIRConst &rhs) const
75 {
76 if (&rhs == this) {
77 return true;
78 }
79 if (GetKind() != rhs.GetKind()) {
80 return false;
81 }
82 const auto &rhsA = static_cast<const MIRAddrofConst &>(rhs);
83 if (&GetType() != &rhs.GetType()) {
84 return false;
85 }
86 return (stIdx == rhsA.stIdx) && (fldID == rhsA.fldID);
87 }
88
Dump(const MIRSymbolTable *) const89 void MIRAddroffuncConst::Dump(const MIRSymbolTable *) const
90 {
91 LogInfo::MapleLogger() << "addroffunc " << GetPrimTypeName(PTY_ptr);
92 MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
93 LogInfo::MapleLogger() << " &"
94 << GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx())->GetName();
95 }
96
operator ==(const MIRConst & rhs) const97 bool MIRAddroffuncConst::operator==(const MIRConst &rhs) const
98 {
99 if (&rhs == this) {
100 return true;
101 }
102 if (GetKind() != rhs.GetKind()) {
103 return false;
104 }
105 const auto &rhsAf = static_cast<const MIRAddroffuncConst &>(rhs);
106 return (&GetType() == &rhs.GetType()) && (puIdx == rhsAf.puIdx);
107 }
108
Dump(const MIRSymbolTable *) const109 void MIRLblConst::Dump(const MIRSymbolTable *) const
110 {
111 LogInfo::MapleLogger() << "addroflabel " << GetPrimTypeName(PTY_ptr);
112 MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
113 LogInfo::MapleLogger() << " @" << func->GetLabelName(value);
114 }
115
operator ==(const MIRConst & rhs) const116 bool MIRLblConst::operator==(const MIRConst &rhs) const
117 {
118 if (&rhs == this) {
119 return true;
120 }
121 if (GetKind() != rhs.GetKind()) {
122 return false;
123 }
124 const auto &lblConst = static_cast<const MIRLblConst &>(rhs);
125 return (lblConst.value == value);
126 }
127
operator ==(const MIRConst & rhs) const128 bool MIRFloatConst::operator==(const MIRConst &rhs) const
129 {
130 if (&rhs == this) {
131 return true;
132 }
133 if (GetKind() != rhs.GetKind()) {
134 return false;
135 }
136 const auto &floatConst = static_cast<const MIRFloatConst &>(rhs);
137 if (std::isnan(floatConst.value.floatValue)) {
138 return std::isnan(value.floatValue);
139 }
140 if (std::isnan(value.floatValue)) {
141 return std::isnan(floatConst.value.floatValue);
142 }
143 if (floatConst.value.floatValue == 0.0 && value.floatValue == 0.0) {
144 return floatConst.IsNeg() == IsNeg();
145 }
146 // Use bitwise comparison instead of approximate comparison for FP to avoid treating 0.0 and FLT_MIN as equal
147 return (floatConst.value.intValue == value.intValue);
148 }
149
operator ==(const MIRConst & rhs) const150 bool MIRDoubleConst::operator==(const MIRConst &rhs) const
151 {
152 if (&rhs == this) {
153 return true;
154 }
155 if (GetKind() != rhs.GetKind()) {
156 return false;
157 }
158 const auto &floatConst = static_cast<const MIRDoubleConst &>(rhs);
159 if (std::isnan(floatConst.value.dValue)) {
160 return std::isnan(value.dValue);
161 }
162 if (std::isnan(value.dValue)) {
163 return std::isnan(floatConst.value.dValue);
164 }
165 if (floatConst.value.dValue == 0.0 && value.dValue == 0.0) {
166 return floatConst.IsNeg() == IsNeg();
167 }
168 // Use bitwise comparison instead of approximate comparison for FP to avoid treating 0.0 and DBL_MIN as equal
169 return (floatConst.value.intValue == value.intValue);
170 }
171
operator ==(const MIRConst & rhs) const172 bool MIRFloat128Const::operator==(const MIRConst &rhs) const
173 {
174 if (&rhs == this) {
175 return true;
176 }
177 if (GetKind() != rhs.GetKind()) {
178 return false;
179 }
180 const auto &floatConst = static_cast<const MIRFloat128Const &>(rhs);
181 if ((value[0] == floatConst.value[0]) && (value[1] == floatConst.value[1])) {
182 return true;
183 }
184 return false;
185 }
186
operator ==(const MIRConst & rhs) const187 bool MIRAggConst::operator==(const MIRConst &rhs) const
188 {
189 if (&rhs == this) {
190 return true;
191 }
192 if (GetKind() != rhs.GetKind()) {
193 return false;
194 }
195 const auto &aggregateConst = static_cast<const MIRAggConst &>(rhs);
196 if (aggregateConst.constVec.size() != constVec.size()) {
197 return false;
198 }
199 for (size_t i = 0; i < constVec.size(); ++i) {
200 if (!(*aggregateConst.constVec[i] == *constVec[i])) {
201 return false;
202 }
203 }
204 return true;
205 }
206
Dump(const MIRSymbolTable *) const207 void MIRFloatConst::Dump(const MIRSymbolTable *) const
208 {
209 LogInfo::MapleLogger() << std::setprecision(std::numeric_limits<float>::max_digits10) << value.floatValue << "f";
210 }
211
Dump(const MIRSymbolTable *) const212 void MIRDoubleConst::Dump(const MIRSymbolTable *) const
213 {
214 LogInfo::MapleLogger() << std::setprecision(std::numeric_limits<double>::max_digits10) << value.dValue;
215 }
216
Dump(const MIRSymbolTable *) const217 void MIRFloat128Const::Dump(const MIRSymbolTable *) const
218 {
219 constexpr int fieldWidth = 16;
220 std::ios::fmtflags f(LogInfo::MapleLogger().flags());
221 LogInfo::MapleLogger().setf(std::ios::uppercase);
222 LogInfo::MapleLogger() << "0xL" << std::hex << std::setfill('0') << std::setw(fieldWidth) << value[0]
223 << std::setfill('0') << std::setw(fieldWidth) << value[1];
224 LogInfo::MapleLogger().flags(f);
225 }
226
Dump(const MIRSymbolTable * localSymTab) const227 void MIRAggConst::Dump(const MIRSymbolTable *localSymTab) const
228 {
229 LogInfo::MapleLogger() << "[";
230 size_t size = constVec.size();
231 for (size_t i = 0; i < size; ++i) {
232 if (fieldIdVec[i] != 0) {
233 LogInfo::MapleLogger() << fieldIdVec[i] << "= ";
234 }
235 constVec[i]->Dump(localSymTab);
236 if (i != size - 1) {
237 LogInfo::MapleLogger() << ", ";
238 }
239 }
240 LogInfo::MapleLogger() << "]";
241 }
242
MIRStrConst(const std::string & str,MIRType & type)243 MIRStrConst::MIRStrConst(const std::string &str, MIRType &type)
244 : MIRConst(type, kConstStrConst), value(GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(str))
245 {
246 }
247
Dump(const MIRSymbolTable *) const248 void MIRStrConst::Dump(const MIRSymbolTable *) const
249 {
250 LogInfo::MapleLogger() << "conststr " << GetPrimTypeName(GetType().GetPrimType());
251 const std::string &dumpStr = GlobalTables::GetUStrTable().GetStringFromStrIdx(value);
252 PrintString(dumpStr);
253 }
254
operator ==(const MIRConst & rhs) const255 bool MIRStrConst::operator==(const MIRConst &rhs) const
256 {
257 if (&rhs == this) {
258 return true;
259 }
260 if (GetKind() != rhs.GetKind()) {
261 return false;
262 }
263 const auto &rhsCs = static_cast<const MIRStrConst &>(rhs);
264 return (&rhs.GetType() == &GetType()) && (value == rhsCs.value);
265 }
266
MIRStr16Const(const std::u16string & str,MIRType & type)267 MIRStr16Const::MIRStr16Const(const std::u16string &str, MIRType &type)
268 : MIRConst(type, kConstStr16Const), value(GlobalTables::GetU16StrTable().GetOrCreateStrIdxFromName(str))
269 {
270 }
271
Dump(const MIRSymbolTable *) const272 void MIRStr16Const::Dump(const MIRSymbolTable *) const
273 {
274 LogInfo::MapleLogger() << "conststr16 " << GetPrimTypeName(GetType().GetPrimType());
275 std::u16string str16 = GlobalTables::GetU16StrTable().GetStringFromStrIdx(value);
276 // UTF-16 string are dumped as UTF-8 string in mpl to keep the printable chars in ascii form
277 std::string str;
278 (void)namemangler::UTF16ToUTF8(str, str16);
279 PrintString(str);
280 }
281
operator ==(const MIRConst & rhs) const282 bool MIRStr16Const::operator==(const MIRConst &rhs) const
283 {
284 if (&rhs == this) {
285 return true;
286 }
287 if (GetKind() != rhs.GetKind()) {
288 return false;
289 }
290 const auto &rhsCs = static_cast<const MIRStr16Const &>(rhs);
291 return (&GetType() == &rhs.GetType()) && (value == rhsCs.value);
292 }
293
IsDivSafe(const MIRIntConst & dividend,const MIRIntConst & divisor,PrimType pType)294 bool IsDivSafe(const MIRIntConst ÷nd, const MIRIntConst &divisor, PrimType pType)
295 {
296 if (IsUnsignedInteger(pType)) {
297 return divisor.GetValue() != 0;
298 }
299
300 return divisor.GetValue() != 0 && (!dividend.GetValue().IsMinValue() || !divisor.GetValue().AreAllBitsOne());
301 }
302
303 } // namespace maple
304 #endif // MIR_FEATURE_FULL
305