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