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 "aarch64_insn.h"
17 #include "aarch64_cg.h"
18
19 namespace maplebe {
20
21 #ifdef ARK_LITECG_DEBUG
EmitIntReg(const RegOperand & v,uint8 opndSz)22 void A64OpndEmitVisitor::EmitIntReg(const RegOperand &v, uint8 opndSz)
23 {
24 CHECK_FATAL(v.GetRegisterType() == kRegTyInt, "wrong Type");
25 uint8 opndSize = (opndSz == kMaxSimm32) ? v.GetSize() : opndSz;
26 DEBUG_ASSERT((opndSize == k32BitSize || opndSize == k64BitSize), "illegal register size");
27 #ifdef USE_32BIT_REF
28 bool r32 = (opndSize == k32BitSize) || isRefField;
29 #else
30 bool r32 = (opndSize == k32BitSize);
31 #endif /* USE_32BIT_REF */
32 (void)emitter.Emit(
33 AArch64CG::intRegNames[(r32 ? AArch64CG::kR32List : AArch64CG::kR64List)][v.GetRegisterNumber()]);
34 }
35
Visit(maplebe::RegOperand * v)36 void A64OpndEmitVisitor::Visit(maplebe::RegOperand *v)
37 {
38 DEBUG_ASSERT(opndProp == nullptr || opndProp->IsRegister(), "operand type doesn't match");
39 uint32 size = v->GetSize();
40 regno_t regNO = v->GetRegisterNumber();
41 uint8 opndSize = (opndProp != nullptr) ? opndProp->GetSize() : size;
42 switch (v->GetRegisterType()) {
43 case kRegTyInt: {
44 EmitIntReg(*v, opndSize);
45 break;
46 }
47 case kRegTyFloat: {
48 DEBUG_ASSERT((opndSize == k8BitSize || opndSize == k16BitSize || opndSize == k32BitSize ||
49 opndSize == k64BitSize || opndSize == k128BitSize),
50 "illegal register size");
51 /* FP reg cannot be reffield. 8~0, 16~1, 32~2, 64~3. 8 is 1000b, has 3 zero. */
52 uint32 regSet = static_cast<uint32>(__builtin_ctz(static_cast<uint32>(opndSize)) - 3);
53 (void)emitter.Emit(AArch64CG::intRegNames[regSet][regNO]);
54 break;
55 }
56 default:
57 DEBUG_ASSERT(false, "NYI");
58 break;
59 }
60 }
61
Visit(maplebe::ImmOperand * v)62 void A64OpndEmitVisitor::Visit(maplebe::ImmOperand *v)
63 {
64 if (v->IsOfstImmediate()) {
65 return Visit(static_cast<OfstOperand *>(v));
66 }
67
68 if (v->IsStImmediate()) {
69 Visit(*v->GetSymbol(), v->GetValue());
70 return;
71 }
72
73 int64 value = v->GetValue();
74 if (!v->IsFmov()) {
75 (void)emitter.Emit((opndProp != nullptr && opndProp->IsLoadLiteral()) ? "=" : "#")
76 .Emit((v->GetSize() == k64BitSize) ? value : static_cast<int64>(static_cast<int32>(value)));
77 return;
78 }
79 if (v->GetKind() == Operand::kOpdFPImmediate) {
80 CHECK_FATAL(value == 0, "NIY");
81 emitter.Emit("#0.0");
82 }
83 /*
84 * compute float value
85 * use top 4 bits expect MSB of value . then calculate its fourth power
86 */
87 int32 exp = static_cast<int32>((((static_cast<uint32>(value) & 0x70) >> 4) ^ 0x4) - 3);
88 /* use the lower four bits of value in this expression */
89 const float mantissa = 1.0 + (static_cast<float>(static_cast<uint64>(value) & 0xf) / 16.0);
90 float result = std::pow(2, exp) * mantissa;
91
92 std::stringstream ss;
93 ss << std::setprecision(10) << result; // float aligned with 10 characters
94 std::string res;
95 ss >> res;
96 size_t dot = res.find('.');
97 if (dot == std::string::npos) {
98 res += ".0";
99 dot = res.find('.');
100 CHECK_FATAL(dot != std::string::npos, "cannot find in string");
101 }
102 (void)res.erase(dot, 1);
103 std::string integer(res, 0, 1);
104 std::string fraction(res, 1);
105 DEBUG_ASSERT(fraction.size() >= 1, "fraction must not be empty");
106 while (fraction.size() != 1 && fraction[fraction.size() - 1] == '0') {
107 fraction.pop_back();
108 }
109 /* fetch the sign bit of this value */
110 std::string sign = static_cast<uint64>(value) & 0x80 ? "-" : "";
111 (void)emitter.Emit(sign + integer + "." + fraction + "e+").Emit(static_cast<int64>(dot) - 1);
112 }
113
Visit(maplebe::MemOperand * v)114 void A64OpndEmitVisitor::Visit(maplebe::MemOperand *v)
115 {
116 auto a64v = static_cast<MemOperand *>(v);
117 MemOperand::AArch64AddressingMode addressMode = a64v->GetAddrMode();
118 #if DEBUG
119 const InsnDesc *md = &AArch64CG::kMd[emitter.GetCurrentMOP()];
120 bool isLDSTpair = md->IsLoadStorePair();
121 DEBUG_ASSERT(md->Is64Bit() || md->GetOperandSize() <= k32BitSize || md->GetOperandSize() == k128BitSize,
122 "unexpected opnd size");
123 #endif
124 if (addressMode == MemOperand::kAddrModeBOi) {
125 (void)emitter.Emit("[");
126 auto *baseReg = v->GetBaseRegister();
127 DEBUG_ASSERT(baseReg != nullptr, "expect an RegOperand here");
128 uint32 baseSize = baseReg->GetSize();
129 if (baseSize != k64BitSize) {
130 baseReg->SetSize(k64BitSize);
131 }
132 EmitIntReg(*baseReg);
133 baseReg->SetSize(baseSize);
134 ImmOperand *offset = a64v->GetOffsetImmediate();
135 if (offset != nullptr) {
136 #ifndef USE_32BIT_REF /* can be load a ref here */
137 /*
138 * Cortex-A57 Software Optimization Guide:
139 * The ARMv8-A architecture allows many types of load and store accesses to be arbitrarily aligned
140 * The Cortex- A57 processor handles most unaligned accesses without performance penalties
141 */
142 #if DEBUG
143 if (a64v->IsOffsetMisaligned(md->GetOperandSize())) {
144 INFO(kLncInfo, "The Memory operand's offset is misaligned:", "");
145 }
146 #endif
147 #endif /* USE_32BIT_REF */
148 if (a64v->IsPostIndexed()) {
149 DEBUG_ASSERT(!a64v->IsSIMMOffsetOutOfRange(offset->GetValue(), md->Is64Bit(), isLDSTpair),
150 "should not be SIMMOffsetOutOfRange");
151 (void)emitter.Emit("]");
152 if (!offset->IsZero()) {
153 (void)emitter.Emit(", ");
154 Visit(offset);
155 }
156 } else if (a64v->IsPreIndexed()) {
157 DEBUG_ASSERT(!a64v->IsSIMMOffsetOutOfRange(offset->GetValue(), md->Is64Bit(), isLDSTpair),
158 "should not be SIMMOffsetOutOfRange");
159 if (!offset->IsZero()) {
160 (void)emitter.Emit(",");
161 Visit(offset);
162 }
163 (void)emitter.Emit("]!");
164 } else {
165 if (!offset->IsZero() || static_cast<OfstOperand *>(offset)->IsSymAndImmOffset() ||
166 static_cast<OfstOperand *>(offset)->IsSymOffset()) {
167 (void)emitter.Emit(",");
168 Visit(offset);
169 }
170 (void)emitter.Emit("]");
171 }
172 } else {
173 (void)emitter.Emit("]");
174 }
175 } else if (addressMode == MemOperand::kAddrModeBOrX) {
176 /*
177 * Base plus offset | [base{, #imm}] [base, Xm{, LSL #imm}] [base, Wm, (S|U)XTW {#imm}]
178 * offset_opnds=nullptr
179 * offset_opnds=64 offset_opnds=32
180 * imm=0 or 3 imm=0 or 2, s/u
181 */
182 (void)emitter.Emit("[");
183 auto *baseReg = v->GetBaseRegister();
184 // After ssa version support different size, the value is changed back
185 baseReg->SetSize(k64BitSize);
186
187 EmitIntReg(*baseReg);
188 (void)emitter.Emit(",");
189 EmitIntReg(*a64v->GetIndexRegister());
190 if (a64v->ShouldEmitExtend() || v->GetBaseRegister()->GetSize() > a64v->GetIndexRegister()->GetSize()) {
191 (void)emitter.Emit(",");
192 /* extend, #0, of #3/#2 */
193 (void)emitter.Emit(a64v->GetExtendAsString());
194 if (a64v->GetExtendAsString() == "LSL" || a64v->ShiftAmount() != 0) {
195 (void)emitter.Emit(" #");
196 (void)emitter.Emit(a64v->ShiftAmount());
197 }
198 }
199 (void)emitter.Emit("]");
200 } else if (addressMode == MemOperand::kAddrModeLiteral) {
201 CHECK_FATAL(opndProp != nullptr, "prop is nullptr in MemOperand::Emit");
202 if (opndProp->IsMemLow12()) {
203 (void)emitter.Emit("#:lo12:");
204 }
205 CHECK_NULL_FATAL(emitter.GetCG()->GetMIRModule()->CurFunction());
206 PUIdx pIdx = emitter.GetCG()->GetMIRModule()->CurFunction()->GetPuidx();
207 (void)emitter.Emit(v->GetSymbol()->GetName() + std::to_string(pIdx));
208 } else if (addressMode == MemOperand::kAddrModeLo12Li) {
209 (void)emitter.Emit("[");
210 EmitIntReg(*v->GetBaseRegister());
211
212 OfstOperand *offset = a64v->GetOffsetImmediate();
213 DEBUG_ASSERT(offset != nullptr, "nullptr check");
214
215 (void)emitter.Emit(", #:lo12:");
216 if (v->GetSymbol()->GetAsmAttr() != UStrIdx(0) &&
217 (v->GetSymbol()->GetStorageClass() == kScPstatic || v->GetSymbol()->GetStorageClass() == kScPstatic)) {
218 std::string asmSection = GlobalTables::GetUStrTable().GetStringFromStrIdx(v->GetSymbol()->GetAsmAttr());
219 (void)emitter.Emit(asmSection);
220 } else {
221 if (v->GetSymbol()->GetStorageClass() == kScPstatic && v->GetSymbol()->IsLocal()) {
222 CHECK_NULL_FATAL(emitter.GetCG()->GetMIRModule()->CurFunction());
223 PUIdx pIdx = emitter.GetCG()->GetMIRModule()->CurFunction()->GetPuidx();
224 (void)emitter.Emit(a64v->GetSymbolName() + std::to_string(pIdx));
225 } else {
226 (void)emitter.Emit(a64v->GetSymbolName());
227 }
228 }
229 if (!offset->IsZero()) {
230 (void)emitter.Emit("+");
231 (void)emitter.Emit(std::to_string(offset->GetOffsetValue()));
232 }
233 (void)emitter.Emit("]");
234 } else {
235 DEBUG_ASSERT(false, "nyi");
236 }
237 }
238
Visit(LabelOperand * v)239 void A64OpndEmitVisitor::Visit(LabelOperand *v)
240 {
241 emitter.EmitLabelRef(v->GetLabelIndex());
242 }
243
Visit(CondOperand * v)244 void A64OpndEmitVisitor::Visit(CondOperand *v)
245 {
246 (void)emitter.Emit(CondOperand::ccStrs[v->GetCode()]);
247 }
248
Visit(ExtendShiftOperand * v)249 void A64OpndEmitVisitor::Visit(ExtendShiftOperand *v)
250 {
251 DEBUG_ASSERT(v->GetShiftAmount() <= k4BitSize && v->GetShiftAmount() >= 0,
252 "shift amount out of range in ExtendShiftOperand");
253 auto emitExtendShift = [this, v](const std::string &extendKind) -> void {
254 (void)emitter.Emit(extendKind);
255 if (v->GetShiftAmount() != 0) {
256 (void)emitter.Emit(" #").Emit(v->GetShiftAmount());
257 }
258 };
259 switch (v->GetExtendOp()) {
260 case ExtendShiftOperand::kUXTB:
261 emitExtendShift("UXTB");
262 break;
263 case ExtendShiftOperand::kUXTH:
264 emitExtendShift("UXTH");
265 break;
266 case ExtendShiftOperand::kUXTW:
267 emitExtendShift("UXTW");
268 break;
269 case ExtendShiftOperand::kUXTX:
270 emitExtendShift("UXTX");
271 break;
272 case ExtendShiftOperand::kSXTB:
273 emitExtendShift("SXTB");
274 break;
275 case ExtendShiftOperand::kSXTH:
276 emitExtendShift("SXTH");
277 break;
278 case ExtendShiftOperand::kSXTW:
279 emitExtendShift("SXTW");
280 break;
281 case ExtendShiftOperand::kSXTX:
282 emitExtendShift("SXTX");
283 break;
284 default:
285 DEBUG_ASSERT(false, "should not be here");
286 break;
287 }
288 }
289
Visit(BitShiftOperand * v)290 void A64OpndEmitVisitor::Visit(BitShiftOperand *v)
291 {
292 (void)emitter
293 .Emit((v->GetShiftOp() == BitShiftOperand::kLSL)
294 ? "LSL #"
295 : ((v->GetShiftOp() == BitShiftOperand::kLSR) ? "LSR #" : "ASR #"))
296 .Emit(v->GetShiftAmount());
297 }
298
Visit(StImmOperand * v)299 void A64OpndEmitVisitor::Visit(StImmOperand *v)
300 {
301 CHECK_FATAL(opndProp != nullptr, "opndProp is nullptr in StImmOperand::Emit");
302 const MIRSymbol *symbol = v->GetSymbol();
303 const bool isThreadLocal = symbol->IsThreadLocal();
304 const bool isLiteralLow12 = opndProp->IsLiteralLow12();
305 const bool hasGotEntry = false;
306 bool hasPrefix = false;
307 if (isThreadLocal) {
308 (void)emitter.Emit(":tlsdesc");
309 hasPrefix = true;
310 }
311 if (!hasPrefix && hasGotEntry) {
312 (void)emitter.Emit(":got");
313 hasPrefix = true;
314 }
315 if (isLiteralLow12) {
316 std::string lo12String = hasPrefix ? "_lo12" : ":lo12";
317 (void)emitter.Emit(lo12String);
318 hasPrefix = true;
319 }
320 if (hasPrefix) {
321 (void)emitter.Emit(":");
322 }
323 if (symbol->GetAsmAttr() != UStrIdx(0) &&
324 (symbol->GetStorageClass() == kScPstatic || symbol->GetStorageClass() == kScPstatic)) {
325 std::string asmSection = GlobalTables::GetUStrTable().GetStringFromStrIdx(symbol->GetAsmAttr());
326 (void)emitter.Emit(asmSection);
327 } else {
328 if (symbol->GetStorageClass() == kScPstatic && symbol->GetSKind() != kStConst && symbol->IsLocal()) {
329 CHECK_NULL_FATAL(emitter.GetCG()->GetMIRModule()->CurFunction());
330 (void)emitter.Emit(symbol->GetName() +
331 std::to_string(emitter.GetCG()->GetMIRModule()->CurFunction()->GetPuidx()));
332 } else {
333 (void)emitter.Emit(v->GetName());
334 }
335 }
336 if (!hasGotEntry && v->GetOffset() != 0) {
337 (void)emitter.Emit("+" + std::to_string(v->GetOffset()));
338 }
339 }
340
Visit(FuncNameOperand * v)341 void A64OpndEmitVisitor::Visit(FuncNameOperand *v)
342 {
343 (void)emitter.Emit(v->GetName());
344 }
345
Visit(CommentOperand * v)346 void A64OpndEmitVisitor::Visit(CommentOperand *v)
347 {
348 (void)emitter.Emit(v->GetComment());
349 }
350
Visit(ListOperand * v)351 void A64OpndEmitVisitor::Visit(ListOperand *v)
352 {
353 (void)opndProp;
354 size_t nLeft = v->GetOperands().size();
355 if (nLeft == 0) {
356 return;
357 }
358
359 for (auto it = v->GetOperands().begin(); it != v->GetOperands().end(); ++it) {
360 Visit(*it);
361 if (--nLeft >= 1) {
362 (void)emitter.Emit(", ");
363 }
364 }
365 }
366
Visit(OfstOperand * v)367 void A64OpndEmitVisitor::Visit(OfstOperand *v)
368 {
369 int64 value = v->GetValue();
370 if (v->IsImmOffset()) {
371 (void)emitter.Emit((opndProp != nullptr && opndProp->IsLoadLiteral()) ? "=" : "#")
372 .Emit((v->GetSize() == k64BitSize) ? value : static_cast<int64>(static_cast<int32>(value)));
373 return;
374 }
375 const MIRSymbol *symbol = v->GetSymbol();
376 CHECK_NULL_FATAL(symbol);
377 if (symbol->GetStorageClass() == kScPstatic && symbol->GetSKind() != kStConst && symbol->IsLocal()) {
378 CHECK_NULL_FATAL(emitter.GetCG()->GetMIRModule()->CurFunction());
379 (void)emitter.Emit(symbol->GetName() +
380 std::to_string(emitter.GetCG()->GetMIRModule()->CurFunction()->GetPuidx()));
381 } else {
382 (void)emitter.Emit(symbol->GetName());
383 }
384 if (value != 0) {
385 (void)emitter.Emit("+" + std::to_string(value));
386 }
387 }
388 #endif
389
Visit(RegOperand * v)390 void A64OpndDumpVisitor::Visit(RegOperand *v)
391 {
392 #ifdef ARK_LITECG_DEBUG
393 std::array<const std::string, kRegTyLast> prims = {"U", "R", "V", "C", "X", "Vra"};
394 std::array<const std::string, kRegTyLast> classes = {"[U]", "[I]", "[F]", "[CC]", "[X87]", "[Vra]"};
395 uint32 regType = v->GetRegisterType();
396 DEBUG_ASSERT(regType < kRegTyLast, "unexpected regType");
397
398 regno_t reg = v->GetRegisterNumber();
399 reg = v->IsVirtualRegister() ? reg : (reg - 1);
400 uint32 vb = v->GetValidBitsNum();
401 LogInfo::MapleLogger() << (v->IsVirtualRegister() ? "vreg:" : " reg:") << prims[regType] << reg << " "
402 << classes[regType];
403 if (v->GetBaseRefOpnd()) {
404 LogInfo::MapleLogger() << " base ref:R" << v->GetBaseRefOpnd()->GetRegisterNumber() << " ";
405 }
406 if (v->GetValidBitsNum() != v->GetSize()) {
407 LogInfo::MapleLogger() << " Vb: [" << vb << "]";
408 }
409 LogInfo::MapleLogger() << " Sz: [" << v->GetSize() << "]";
410 #endif
411 }
412
Visit(ImmOperand * v)413 void A64OpndDumpVisitor::Visit(ImmOperand *v)
414 {
415 #ifdef ARK_LITECG_DEBUG
416 LogInfo::MapleLogger() << "imm:" << v->GetValue();
417 #endif
418 }
419
Visit(MemOperand * a64v)420 void A64OpndDumpVisitor::Visit(MemOperand *a64v)
421 {
422 #ifdef ARK_LITECG_DEBUG
423 LogInfo::MapleLogger() << "Mem:";
424 LogInfo::MapleLogger() << " size:" << a64v->GetSize() << " ";
425 LogInfo::MapleLogger() << " isStack:" << a64v->IsStackMem() << "-" << a64v->IsStackArgMem() << " ";
426 switch (a64v->GetAddrMode()) {
427 case MemOperand::kAddrModeBOi: {
428 LogInfo::MapleLogger() << "base:";
429 Visit(a64v->GetBaseRegister());
430 LogInfo::MapleLogger() << "offset:";
431 Visit(a64v->GetOffsetOperand());
432 switch (a64v->GetIndexOpt()) {
433 case MemOperand::kIntact:
434 LogInfo::MapleLogger() << " intact";
435 break;
436 case MemOperand::kPreIndex:
437 LogInfo::MapleLogger() << " pre-index";
438 break;
439 case MemOperand::kPostIndex:
440 LogInfo::MapleLogger() << " post-index";
441 break;
442 default:
443 break;
444 }
445 break;
446 }
447 case MemOperand::kAddrModeBOrX: {
448 LogInfo::MapleLogger() << "base:";
449 Visit(a64v->GetBaseRegister());
450 LogInfo::MapleLogger() << "offset:";
451 Visit(a64v->GetIndexRegister());
452 LogInfo::MapleLogger() << " " << a64v->GetExtendAsString();
453 LogInfo::MapleLogger() << " shift: " << a64v->ShiftAmount();
454 LogInfo::MapleLogger() << " extend: " << a64v->GetExtendAsString();
455 break;
456 }
457 case MemOperand::kAddrModeLiteral:
458 LogInfo::MapleLogger() << "literal: " << a64v->GetSymbolName();
459 break;
460 case MemOperand::kAddrModeLo12Li: {
461 LogInfo::MapleLogger() << "base:";
462 Visit(a64v->GetBaseRegister());
463 LogInfo::MapleLogger() << "offset:";
464 OfstOperand *offOpnd = a64v->GetOffsetImmediate();
465 LogInfo::MapleLogger() << "#:lo12:";
466 if (a64v->GetSymbol()->GetStorageClass() == kScPstatic && a64v->GetSymbol()->IsLocal()) {
467 CHECK_NULL_FATAL(CG::GetCurCGFunc()->GetMirModule().CurFunction());
468 PUIdx pIdx = CG::GetCurCGFunc()->GetMirModule().CurFunction()->GetPuidx();
469 LogInfo::MapleLogger() << a64v->GetSymbolName() << std::to_string(pIdx);
470 } else {
471 LogInfo::MapleLogger() << a64v->GetSymbolName();
472 }
473 LogInfo::MapleLogger() << "+" << std::to_string(offOpnd->GetOffsetValue());
474 break;
475 }
476 default:
477 DEBUG_ASSERT(false, "error memoperand dump");
478 break;
479 }
480 #endif
481 }
482
Visit(CondOperand * v)483 void A64OpndDumpVisitor::Visit(CondOperand *v)
484 {
485 #ifdef ARK_LITECG_DEBUG
486 LogInfo::MapleLogger() << "CC: " << CondOperand::ccStrs[v->GetCode()];
487 #endif
488 }
Visit(StImmOperand * v)489 void A64OpndDumpVisitor::Visit(StImmOperand *v)
490 {
491 #ifdef ARK_LITECG_DEBUG
492 LogInfo::MapleLogger() << v->GetName();
493 LogInfo::MapleLogger() << "+offset:" << v->GetOffset();
494 #endif
495 }
Visit(BitShiftOperand * v)496 void A64OpndDumpVisitor::Visit(BitShiftOperand *v)
497 {
498 #ifdef ARK_LITECG_DEBUG
499 BitShiftOperand::ShiftOp shiftOp = v->GetShiftOp();
500 uint32 shiftAmount = v->GetShiftAmount();
501 LogInfo::MapleLogger() << ((shiftOp == BitShiftOperand::kLSL)
502 ? "LSL: "
503 : ((shiftOp == BitShiftOperand::kLSR) ? "LSR: " : "ASR: "));
504 LogInfo::MapleLogger() << shiftAmount;
505 #endif
506 }
Visit(ExtendShiftOperand * v)507 void A64OpndDumpVisitor::Visit(ExtendShiftOperand *v)
508 {
509 #ifdef ARK_LITECG_DEBUG
510 auto dumpExtendShift = [v](const std::string &extendKind) -> void {
511 LogInfo::MapleLogger() << extendKind;
512 if (v->GetShiftAmount() != 0) {
513 LogInfo::MapleLogger() << " : " << v->GetShiftAmount();
514 }
515 };
516 switch (v->GetExtendOp()) {
517 case ExtendShiftOperand::kUXTB:
518 dumpExtendShift("UXTB");
519 break;
520 case ExtendShiftOperand::kUXTH:
521 dumpExtendShift("UXTH");
522 break;
523 case ExtendShiftOperand::kUXTW:
524 dumpExtendShift("UXTW");
525 break;
526 case ExtendShiftOperand::kUXTX:
527 dumpExtendShift("UXTX");
528 break;
529 case ExtendShiftOperand::kSXTB:
530 dumpExtendShift("SXTB");
531 break;
532 case ExtendShiftOperand::kSXTH:
533 dumpExtendShift("SXTH");
534 break;
535 case ExtendShiftOperand::kSXTW:
536 dumpExtendShift("SXTW");
537 break;
538 case ExtendShiftOperand::kSXTX:
539 dumpExtendShift("SXTX");
540 break;
541 default:
542 DEBUG_ASSERT(false, "should not be here");
543 break;
544 }
545 #endif
546 }
Visit(LabelOperand * v)547 void A64OpndDumpVisitor::Visit(LabelOperand *v)
548 {
549 #ifdef ARK_LITECG_DEBUG
550 LogInfo::MapleLogger() << "label:" << v->GetLabelIndex();
551 #endif
552 }
Visit(FuncNameOperand * v)553 void A64OpndDumpVisitor::Visit(FuncNameOperand *v)
554 {
555 #ifdef ARK_LITECG_DEBUG
556 LogInfo::MapleLogger() << "func :" << v->GetName();
557 #endif
558 }
Visit(CommentOperand * v)559 void A64OpndDumpVisitor::Visit(CommentOperand *v)
560 {
561 #ifdef ARK_LITECG_DEBUG
562 LogInfo::MapleLogger() << " #" << v->GetComment();
563 #endif
564 }
Visit(PhiOperand * v)565 void A64OpndDumpVisitor::Visit(PhiOperand *v)
566 {
567 #ifdef ARK_LITECG_DEBUG
568 auto &phiList = v->GetOperands();
569 for (auto it = phiList.begin(); it != phiList.end();) {
570 Visit(it->second);
571 LogInfo::MapleLogger() << " fBB<" << it->first << ">";
572 LogInfo::MapleLogger() << (++it == phiList.end() ? "" : " ,");
573 }
574 #endif
575 }
Visit(ListOperand * v)576 void A64OpndDumpVisitor::Visit(ListOperand *v)
577 {
578 #ifdef ARK_LITECG_DEBUG
579 auto &opndList = v->GetOperands();
580 for (auto it = opndList.begin(); it != opndList.end();) {
581 Visit(*it);
582 LogInfo::MapleLogger() << (++it == opndList.end() ? "" : " ,");
583 }
584 #endif
585 }
586
587 #ifdef ARK_LITECG_DEBUG
Visit(const MIRSymbol & symbol,int64 offset)588 void A64OpndEmitVisitor::Visit(const MIRSymbol &symbol, int64 offset)
589 {
590 CHECK_FATAL(opndProp != nullptr, "opndProp is nullptr in StImmOperand::Emit");
591 const bool isThreadLocal = symbol.IsThreadLocal();
592 const bool isLiteralLow12 = opndProp->IsLiteralLow12();
593 bool hasPrefix = false;
594 if (isThreadLocal) {
595 (void)emitter.Emit(":tlsdesc");
596 hasPrefix = true;
597 }
598 if (isLiteralLow12) {
599 std::string lo12String = hasPrefix ? "_lo12" : ":lo12";
600 (void)emitter.Emit(lo12String);
601 hasPrefix = true;
602 }
603 if (hasPrefix) {
604 (void)emitter.Emit(":");
605 }
606 if (symbol.GetAsmAttr() != UStrIdx(0) && symbol.GetStorageClass() == kScPstatic) {
607 std::string asmSection = GlobalTables::GetUStrTable().GetStringFromStrIdx(symbol.GetAsmAttr());
608 (void)emitter.Emit(asmSection);
609 } else {
610 if (symbol.GetStorageClass() == kScPstatic && symbol.GetSKind() != kStConst) {
611 CHECK_NULL_FATAL(emitter.GetCG()->GetMIRModule()->CurFunction());
612 (void)emitter.Emit(symbol.GetName() +
613 std::to_string(emitter.GetCG()->GetMIRModule()->CurFunction()->GetPuidx()));
614 } else {
615 (void)emitter.Emit(symbol.GetName());
616 }
617 }
618 if (offset != 0) {
619 (void)emitter.Emit("+" + std::to_string(offset));
620 }
621 }
622 #endif
623 } /* namespace maplebe */
624