• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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