• 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 "x64_cgfunc.h"
17 #include "assembler/operand.h"
18 
19 namespace maplebe {
MergeReturn()20 void X64CGFunc::MergeReturn()
21 {
22     CHECK_FATAL(false, "NIY");
23 }
SelectDassign(DassignNode & stmt,Operand & opnd0)24 void X64CGFunc::SelectDassign(DassignNode &stmt, Operand &opnd0)
25 {
26     CHECK_FATAL(false, "NIY");
27 }
SelectRegassign(RegassignNode & stmt,Operand & opnd0)28 void X64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0)
29 {
30     CHECK_FATAL(false, "NIY");
31 }
SelectIassign(IassignNode & stmt)32 void X64CGFunc::SelectIassign(IassignNode &stmt)
33 {
34     CHECK_FATAL(false, "NIY");
35 }
SelectReturn(Operand * opnd)36 void X64CGFunc::SelectReturn(Operand *opnd)
37 {
38     CHECK_FATAL(false, "NIY");
39 }
SelectCondGoto(CondGotoNode & stmt,Operand & opnd0,Operand & opnd1)40 void X64CGFunc::SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1)
41 {
42     CHECK_FATAL(false, "NIY");
43 }
SelectCondSpecialCase1(CondGotoNode & stmt,BaseNode & opnd0)44 void X64CGFunc::SelectCondSpecialCase1(CondGotoNode &stmt, BaseNode &opnd0)
45 {
46     CHECK_FATAL(false, "NIY");
47 }
SelectCondSpecialCase2(const CondGotoNode & stmt,BaseNode & opnd0)48 void X64CGFunc::SelectCondSpecialCase2(const CondGotoNode &stmt, BaseNode &opnd0)
49 {
50     CHECK_FATAL(false, "NIY");
51 }
SelectGoto(GotoNode & stmt)52 void X64CGFunc::SelectGoto(GotoNode &stmt)
53 {
54     CHECK_FATAL(false, "NIY");
55 }
SelectCall(CallNode & callNode)56 void X64CGFunc::SelectCall(CallNode &callNode)
57 {
58     CHECK_FATAL(false, "NIY");
59 }
SelectIcall(IcallNode & icallNode)60 void X64CGFunc::SelectIcall(IcallNode &icallNode)
61 {
62     CHECK_FATAL(false, "NIY");
63 }
SelectIntrinsicCall(IntrinsiccallNode & intrinsiccallNode)64 void X64CGFunc::SelectIntrinsicCall(IntrinsiccallNode &intrinsiccallNode)
65 {
66     CHECK_FATAL(false, "NIY");
67 }
SelectCclz(IntrinsicopNode & intrinopNode)68 Operand *X64CGFunc::SelectCclz(IntrinsicopNode &intrinopNode)
69 {
70     CHECK_FATAL(false, "NIY");
71     return nullptr;
72 }
SelectComment(CommentNode & comment)73 void X64CGFunc::SelectComment(CommentNode &comment)
74 {
75     CHECK_FATAL(false, "NIY");
76 }
SelectDread(const BaseNode & parent,AddrofNode & expr)77 Operand *X64CGFunc::SelectDread(const BaseNode &parent, AddrofNode &expr)
78 {
79     CHECK_FATAL(false, "NIY");
80     return nullptr;
81 }
SelectRegread(RegreadNode & expr)82 RegOperand *X64CGFunc::SelectRegread(RegreadNode &expr)
83 {
84     CHECK_FATAL(false, "NIY");
85     return nullptr;
86 }
SelectIread(const BaseNode & parent,IreadNode & expr,int extraOffset,PrimType finalBitFieldDestType)87 Operand *X64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr, int extraOffset,
88                                 PrimType finalBitFieldDestType)
89 {
90     CHECK_FATAL(false, "NIY");
91     return nullptr;
92 }
SelectIntConst(const MIRIntConst & intConst,const BaseNode & parent)93 Operand *X64CGFunc::SelectIntConst(const MIRIntConst &intConst, const BaseNode &parent)
94 {
95     CHECK_FATAL(false, "NIY");
96     return nullptr;
97 }
SelectFloatConst(MIRFloatConst & floatConst,const BaseNode & parent)98 Operand *X64CGFunc::SelectFloatConst(MIRFloatConst &floatConst, const BaseNode &parent)
99 {
100     CHECK_FATAL(false, "NIY");
101     return nullptr;
102 }
SelectDoubleConst(MIRDoubleConst & doubleConst,const BaseNode & parent)103 Operand *X64CGFunc::SelectDoubleConst(MIRDoubleConst &doubleConst, const BaseNode &parent)
104 {
105     CHECK_FATAL(false, "NIY");
106     return nullptr;
107 }
SelectAdd(Operand & resOpnd,Operand & opnd0,Operand & opnd1,PrimType primType)108 void X64CGFunc::SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType)
109 {
110     CHECK_FATAL(false, "NIY");
111 }
SelectAdd(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)112 Operand *X64CGFunc::SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
113 {
114     CHECK_FATAL(false, "NIY");
115     return nullptr;
116 }
SelectShift(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)117 Operand *X64CGFunc::SelectShift(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
118 {
119     CHECK_FATAL(false, "NIY");
120     return nullptr;
121 }
SelectMpy(Operand & resOpnd,Operand & opnd0,Operand & opnd1,PrimType primType)122 void X64CGFunc::SelectMpy(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType)
123 {
124     CHECK_FATAL(false, "NIY");
125 }
SelectMpy(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)126 Operand *X64CGFunc::SelectMpy(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
127 {
128     CHECK_FATAL(false, "NIY");
129     return nullptr;
130 }
SelectRem(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)131 Operand *X64CGFunc::SelectRem(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
132 {
133     CHECK_FATAL(false, "NIY");
134     return nullptr;
135 }
SelectDiv(Operand & resOpnd,Operand & opnd0,Operand & opnd1,PrimType primType)136 void X64CGFunc::SelectDiv(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType)
137 {
138     CHECK_FATAL(false, "NIY");
139 }
SelectDiv(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)140 Operand *X64CGFunc::SelectDiv(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
141 {
142     CHECK_FATAL(false, "NIY");
143     return nullptr;
144 }
SelectSub(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)145 Operand *X64CGFunc::SelectSub(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
146 {
147     CHECK_FATAL(false, "NIY");
148     return nullptr;
149 }
SelectSub(Operand & resOpnd,Operand & opnd0,Operand & opnd1,PrimType primType)150 void X64CGFunc::SelectSub(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType)
151 {
152     CHECK_FATAL(false, "NIY");
153 }
SelectBand(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)154 Operand *X64CGFunc::SelectBand(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
155 {
156     CHECK_FATAL(false, "NIY");
157     return nullptr;
158 }
SelectBand(Operand & resOpnd,Operand & opnd0,Operand & opnd1,PrimType primType)159 void X64CGFunc::SelectBand(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType)
160 {
161     CHECK_FATAL(false, "NIY");
162 }
SelectMin(Operand & resOpnd,Operand & opnd0,Operand & opnd1,PrimType primType)163 void X64CGFunc::SelectMin(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType)
164 {
165     CHECK_FATAL(false, "NIY");
166 }
SelectMin(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)167 Operand *X64CGFunc::SelectMin(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
168 {
169     CHECK_FATAL(false, "NIY");
170     return nullptr;
171 }
SelectMax(Operand & resOpnd,Operand & opnd0,Operand & opnd1,PrimType primType)172 void X64CGFunc::SelectMax(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType)
173 {
174     CHECK_FATAL(false, "NIY");
175 }
SelectMax(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)176 Operand *X64CGFunc::SelectMax(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
177 {
178     CHECK_FATAL(false, "NIY");
179     return nullptr;
180 }
SelectCmpOp(CompareNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)181 Operand *X64CGFunc::SelectCmpOp(CompareNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
182 {
183     CHECK_FATAL(false, "NIY");
184     return nullptr;
185 }
SelectBior(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)186 Operand *X64CGFunc::SelectBior(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
187 {
188     CHECK_FATAL(false, "NIY");
189     return nullptr;
190 }
SelectBior(Operand & resOpnd,Operand & opnd0,Operand & opnd1,PrimType primType)191 void X64CGFunc::SelectBior(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType)
192 {
193     CHECK_FATAL(false, "NIY");
194 }
SelectBxor(BinaryNode & node,Operand & opnd0,Operand & opnd1,const BaseNode & parent)195 Operand *X64CGFunc::SelectBxor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent)
196 {
197     CHECK_FATAL(false, "NIY");
198     return nullptr;
199 }
SelectBxor(Operand & resOpnd,Operand & opnd0,Operand & opnd1,PrimType primType)200 void X64CGFunc::SelectBxor(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType)
201 {
202     CHECK_FATAL(false, "NIY");
203 }
SelectAbs(UnaryNode & node,Operand & opnd0)204 Operand *X64CGFunc::SelectAbs(UnaryNode &node, Operand &opnd0)
205 {
206     CHECK_FATAL(false, "NIY");
207     return nullptr;
208 }
SelectBnot(UnaryNode & node,Operand & opnd0,const BaseNode & parent)209 Operand *X64CGFunc::SelectBnot(UnaryNode &node, Operand &opnd0, const BaseNode &parent)
210 {
211     CHECK_FATAL(false, "NIY");
212     return nullptr;
213 }
SelectExtractbits(ExtractbitsNode & node,Operand & opnd0,const BaseNode & parent)214 Operand *X64CGFunc::SelectExtractbits(ExtractbitsNode &node, Operand &opnd0, const BaseNode &parent)
215 {
216     CHECK_FATAL(false, "NIY");
217     return nullptr;
218 }
SelectRegularBitFieldLoad(ExtractbitsNode & node,const BaseNode & parent)219 Operand *X64CGFunc::SelectRegularBitFieldLoad(ExtractbitsNode &node, const BaseNode &parent)
220 {
221     CHECK_FATAL(false, "NIY");
222     return nullptr;
223 }
SelectLnot(UnaryNode & node,Operand & opnd0,const BaseNode & parent)224 Operand *X64CGFunc::SelectLnot(UnaryNode &node, Operand &opnd0, const BaseNode &parent)
225 {
226     CHECK_FATAL(false, "NIY");
227     return nullptr;
228 }
SelectNeg(UnaryNode & node,Operand & opnd0,const BaseNode & parent)229 Operand *X64CGFunc::SelectNeg(UnaryNode &node, Operand &opnd0, const BaseNode &parent)
230 {
231     CHECK_FATAL(false, "NIY");
232     return nullptr;
233 }
SelectSqrt(UnaryNode & node,Operand & opnd0,const BaseNode & parent)234 Operand *X64CGFunc::SelectSqrt(UnaryNode &node, Operand &opnd0, const BaseNode &parent)
235 {
236     CHECK_FATAL(false, "NIY");
237     return nullptr;
238 }
SelectCeil(TypeCvtNode & node,Operand & opnd0,const BaseNode & parent)239 Operand *X64CGFunc::SelectCeil(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent)
240 {
241     CHECK_FATAL(false, "NIY");
242     return nullptr;
243 }
SelectFloor(TypeCvtNode & node,Operand & opnd0,const BaseNode & parent)244 Operand *X64CGFunc::SelectFloor(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent)
245 {
246     CHECK_FATAL(false, "NIY");
247     return nullptr;
248 }
SelectRetype(TypeCvtNode & node,Operand & opnd0)249 Operand *X64CGFunc::SelectRetype(TypeCvtNode &node, Operand &opnd0)
250 {
251     CHECK_FATAL(false, "NIY");
252     return nullptr;
253 }
SelectCvt(const BaseNode & parent,TypeCvtNode & node,Operand & opnd0)254 Operand *X64CGFunc::SelectCvt(const BaseNode &parent, TypeCvtNode &node, Operand &opnd0)
255 {
256     CHECK_FATAL(false, "NIY");
257     return nullptr;
258 }
SelectTrunc(TypeCvtNode & node,Operand & opnd0,const BaseNode & parent)259 Operand *X64CGFunc::SelectTrunc(TypeCvtNode &node, Operand &opnd0, const BaseNode &parent)
260 {
261     CHECK_FATAL(false, "NIY");
262     return nullptr;
263 }
SelectCopy(Operand & src,PrimType srcType,PrimType dstType)264 RegOperand &X64CGFunc::SelectCopy(Operand &src, PrimType srcType, PrimType dstType)
265 {
266     CHECK_FATAL(false, "NIY");
267     RegOperand *a;
268     return *a;
269 }
SelectRangeGoto(RangeGotoNode & rangeGotoNode,Operand & opnd0)270 void X64CGFunc::SelectRangeGoto(RangeGotoNode &rangeGotoNode, Operand &opnd0)
271 {
272     CHECK_FATAL(false, "NIY");
273 }
GetOrCreateRflag()274 Operand &X64CGFunc::GetOrCreateRflag()
275 {
276     CHECK_FATAL(false, "NIY");
277     Operand *a;
278     return *a;
279 }
GetRflag() const280 const Operand *X64CGFunc::GetRflag() const
281 {
282     CHECK_FATAL(false, "NIY");
283     return nullptr;
284 }
GetLabelOperand(LabelIdx labIdx) const285 const LabelOperand *X64CGFunc::GetLabelOperand(LabelIdx labIdx) const
286 {
287     CHECK_FATAL(false, "NIY");
288     return nullptr;
289 }
GetOrCreateLabelOperand(LabelIdx labIdx)290 LabelOperand &X64CGFunc::GetOrCreateLabelOperand(LabelIdx labIdx)
291 {
292     std::string lableName = ".L." + std::to_string(GetUniqueID()) + "__" + std::to_string(labIdx);
293     return GetOpndBuilder()->CreateLabel(lableName.c_str(), labIdx);
294 }
GetOrCreateLabelOperand(BB & bb)295 LabelOperand &X64CGFunc::GetOrCreateLabelOperand(BB &bb)
296 {
297     CHECK_FATAL(false, "NIY");
298     LabelOperand *a;
299     return *a;
300 }
CreateVirtualRegisterOperand(regno_t vRegNO)301 RegOperand &X64CGFunc::CreateVirtualRegisterOperand(regno_t vRegNO)
302 {
303     CHECK_FATAL(false, "NIY");
304     RegOperand *a;
305     return *a;
306 }
GetOrCreateVirtualRegisterOperand(regno_t vRegNO)307 RegOperand &X64CGFunc::GetOrCreateVirtualRegisterOperand(regno_t vRegNO)
308 {
309     CHECK_FATAL(false, "NIY");
310     RegOperand *a;
311     return *a;
312 }
GetOrCreateFramePointerRegOperand()313 RegOperand &X64CGFunc::GetOrCreateFramePointerRegOperand()
314 {
315     CHECK_FATAL(false, "NIY");
316     RegOperand *a;
317     return *a;
318 }
GetOrCreateStackBaseRegOperand()319 RegOperand &X64CGFunc::GetOrCreateStackBaseRegOperand()
320 {
321     return GetOpndBuilder()->CreatePReg(x64::RBP, GetPointerSize() * kBitsPerByte, kRegTyInt);
322 }
GetZeroOpnd(uint32 size)323 RegOperand &X64CGFunc::GetZeroOpnd(uint32 size)
324 {
325     CHECK_FATAL(false, "NIY");
326     RegOperand *a;
327     return *a;
328 }
CreateCfiRegOperand(uint32 reg,uint32 size)329 Operand &X64CGFunc::CreateCfiRegOperand(uint32 reg, uint32 size)
330 {
331     CHECK_FATAL(false, "NIY");
332     Operand *a;
333     return *a;
334 }
CreateImmOperand(PrimType primType,int64 val)335 Operand &X64CGFunc::CreateImmOperand(PrimType primType, int64 val)
336 {
337     CHECK_FATAL(false, "NIY");
338     Operand *a;
339     return *a;
340 }
GetPseudoRegisterSpillMemoryOperand(PregIdx idx)341 MemOperand *X64CGFunc::GetPseudoRegisterSpillMemoryOperand(PregIdx idx)
342 {
343     CHECK_FATAL(false, "NIY");
344     return nullptr;
345 }
GetBaseOffset(const SymbolAlloc & symbolAlloc)346 int32 X64CGFunc::GetBaseOffset(const SymbolAlloc &symbolAlloc)
347 {
348     const auto *symAlloc = static_cast<const X64SymbolAlloc *>(&symbolAlloc);
349     /* Call Frame layout of X64
350      * Refer to layout in x64_memlayout.h.
351      * Do Not change this unless you know what you do
352      * memlayout like this
353      * rbp position
354      * prologue slots --
355      * ArgsReg          |
356      * Locals           | -- FrameSize
357      * Spill            |
358      * ArgsStk        --
359      */
360     constexpr const int32 sizeofFplr = 2 * kX64IntregBytelen;
361     // baseOffset is the offset of this symbol based on the rbp position.
362     int32 baseOffset = symAlloc->GetOffset();
363     MemSegmentKind sgKind = symAlloc->GetMemSegment()->GetMemSegmentKind();
364     auto *memLayout = static_cast<X64MemLayout *>(this->GetMemlayout());
365     if (sgKind == kMsSpillReg) {
366         /* spill = -(Locals + ArgsReg + baseOffset + ReseverdSlot + kSizeOfPtr) */
367         return -(static_cast<int32>(memLayout->GetSizeOfLocals()) +
368             static_cast<int32>(memLayout->SizeOfArgsRegisterPassed()) + baseOffset +
369             GetFunction().GetFrameReseverdSlot() + static_cast<int32>(GetPointerSize()));
370     } else if (sgKind == kMsLocals) {
371         /* Locals = baseOffset - (ReseverdSlot + Locals + ArgsReg) */
372         return baseOffset - (GetFunction().GetFrameReseverdSlot() + static_cast<int32>(memLayout->GetSizeOfLocals()) +
373             static_cast<int32>(memLayout->SizeOfArgsRegisterPassed()));
374     } else if (sgKind == kMsArgsRegPassed) {
375         /* ArgsReg = baseOffset - ReseverdSlot  - ArgsReg */
376         return baseOffset - static_cast<int32_t>(GetFunction().GetFrameReseverdSlot()) -
377             static_cast<int32_t>(memLayout->SizeOfArgsRegisterPassed());
378     } else if (sgKind == kMsArgsStkPassed) {
379         return baseOffset + sizeofFplr;
380     } else {
381         CHECK_FATAL(false, "sgKind check");
382     }
383     return 0;
384 }
385 
GetBaseReg(const maplebe::SymbolAlloc & symAlloc)386 RegOperand *X64CGFunc::GetBaseReg(const maplebe::SymbolAlloc &symAlloc)
387 {
388     MemSegmentKind sgKind = symAlloc.GetMemSegment()->GetMemSegmentKind();
389     DEBUG_ASSERT(((sgKind == kMsArgsRegPassed) || (sgKind == kMsLocals) || (sgKind == kMsRefLocals) ||
390                   (sgKind == kMsArgsToStkPass) || (sgKind == kMsArgsStkPassed)),
391                  "NIY");
392     if (sgKind == kMsLocals || sgKind == kMsArgsRegPassed || sgKind == kMsArgsStkPassed) {
393         return &GetOpndBuilder()->CreatePReg(x64::RBP, GetPointerSize() * kBitsPerByte, kRegTyInt);
394     } else {
395         CHECK_FATAL(false, "NIY sgKind");
396     }
397     return nullptr;
398 }
399 
FreeSpillRegMem(regno_t vrNum)400 void X64CGFunc::FreeSpillRegMem(regno_t vrNum)
401 {
402     MemOperand *memOpnd = nullptr;
403 
404     auto p = spillRegMemOperands.find(vrNum);
405     if (p != spillRegMemOperands.end()) {
406         memOpnd = p->second;
407     }
408 
409     if ((memOpnd == nullptr) && IsVRegNOForPseudoRegister(vrNum)) {
410         auto pSecond = pRegSpillMemOperands.find(GetPseudoRegIdxFromVirtualRegNO(vrNum));
411         if (pSecond != pRegSpillMemOperands.end()) {
412             memOpnd = pSecond->second;
413         }
414     }
415 
416     if (memOpnd == nullptr) {
417         DEBUG_ASSERT(false, "free spillreg have no mem");
418         return;
419     }
420 
421     uint32 size = memOpnd->GetSize();
422     MapleUnorderedMap<uint32, SpillMemOperandSet *>::iterator iter;
423     if ((iter = reuseSpillLocMem.find(size)) != reuseSpillLocMem.end()) {
424         iter->second->Add(*memOpnd);
425     } else {
426         reuseSpillLocMem[size] = memPool->New<SpillMemOperandSet>(*GetFuncScopeAllocator());
427         reuseSpillLocMem[size]->Add(*memOpnd);
428     }
429 }
430 
GetOrCreatSpillMem(regno_t vrNum,uint32 memSize)431 MemOperand *X64CGFunc::GetOrCreatSpillMem(regno_t vrNum, uint32 memSize)
432 {
433     /* NOTES: must used in RA, not used in other place. */
434     if (IsVRegNOForPseudoRegister(vrNum)) {
435         auto p = pRegSpillMemOperands.find(GetPseudoRegIdxFromVirtualRegNO(vrNum));
436         if (p != pRegSpillMemOperands.end()) {
437             return p->second;
438         }
439     }
440 
441     auto p = spillRegMemOperands.find(vrNum);
442     if (p == spillRegMemOperands.end()) {
443         uint32 memBitSize = k64BitSize;
444         auto it = reuseSpillLocMem.find(memBitSize);
445         if (it != reuseSpillLocMem.end()) {
446             MemOperand *memOpnd = it->second->GetOne();
447             if (memOpnd != nullptr) {
448                 spillRegMemOperands.emplace(std::pair<regno_t, MemOperand *>(vrNum, memOpnd));
449                 return memOpnd;
450             }
451         }
452 
453         RegOperand &baseOpnd = GetOrCreateStackBaseRegOperand();
454         int32 offset = GetOrCreatSpillRegLocation(vrNum, memBitSize / kBitsPerByte);
455         MemOperand *memOpnd = &GetOpndBuilder()->CreateMem(baseOpnd, offset, memBitSize);
456         spillRegMemOperands.emplace(std::pair<regno_t, MemOperand *>(vrNum, memOpnd));
457         return memOpnd;
458     } else {
459         return p->second;
460     }
461 }
462 
Visit(maplebe::RegOperand * v)463 void X64OpndDumpVisitor::Visit(maplebe::RegOperand *v)
464 {
465     DumpOpndPrefix();
466     LogInfo::MapleLogger() << "reg ";
467     DumpRegInfo(*v);
468     DumpSize(*v);
469     DumpReferenceInfo(*v);
470     const OpndDesc *regDesc = GetOpndDesc();
471     LogInfo::MapleLogger() << " [";
472     if (regDesc->IsRegDef()) {
473         LogInfo::MapleLogger() << "DEF ";
474     }
475     if (regDesc->IsRegUse()) {
476         LogInfo::MapleLogger() << "USE ";
477     }
478     LogInfo::MapleLogger() << "]";
479     DumpOpndSuffix();
480 }
481 
Visit(CommentOperand * v)482 void X64OpndDumpVisitor::Visit(CommentOperand *v)
483 {
484     LogInfo::MapleLogger() << ":#" << v->GetComment();
485 }
486 
Visit(maplebe::ImmOperand * v)487 void X64OpndDumpVisitor::Visit(maplebe::ImmOperand *v)
488 {
489     DumpOpndPrefix();
490     LogInfo::MapleLogger() << "imm ";
491     LogInfo::MapleLogger() << v->GetValue();
492     DumpSize(*v);
493     DumpReferenceInfo(*v);
494     DumpOpndSuffix();
495 }
496 
Visit(maplebe::MemOperand * v)497 void X64OpndDumpVisitor::Visit(maplebe::MemOperand *v)
498 {
499     DumpOpndPrefix();
500     LogInfo::MapleLogger() << "mem ";
501     if (v->GetBaseRegister() != nullptr) {
502         DumpRegInfo(*v->GetBaseRegister());
503         if (v->GetOffsetOperand() != nullptr) {
504             LogInfo::MapleLogger() << " + " << v->GetOffsetOperand()->GetValue();
505         }
506     }
507     DumpSize(*v);
508     DumpReferenceInfo(*v);
509     DumpOpndSuffix();
510 }
DumpRegInfo(maplebe::RegOperand & v)511 void X64OpndDumpVisitor::DumpRegInfo(maplebe::RegOperand &v)
512 {
513     if (v.GetRegisterNumber() > baseVirtualRegNO) {
514         LogInfo::MapleLogger() << "V" << v.GetRegisterNumber();
515     } else {
516         uint8 regType = -1;
517         switch (v.GetSize()) {
518             case k8BitSize:
519                 /* use lower 8-bits */
520                 regType = X64CG::kR8LowList;
521                 break;
522             case k16BitSize:
523                 regType = X64CG::kR16List;
524                 break;
525             case k32BitSize:
526                 regType = X64CG::kR32List;
527                 break;
528             case k64BitSize:
529                 regType = X64CG::kR64List;
530                 break;
531             default:
532                 CHECK_FATAL(false, "unkown reg size");
533                 break;
534         }
535         assembler::Reg reg = assembler::kRegArray[regType][v.GetRegisterNumber()];
536         LogInfo::MapleLogger() << "%" << assembler::kRegStrMap.at(reg);
537     }
538 }
539 
Visit(maplebe::FuncNameOperand * v)540 void X64OpndDumpVisitor::Visit(maplebe::FuncNameOperand *v)
541 {
542     DumpOpndPrefix();
543     LogInfo::MapleLogger() << "funcname ";
544     LogInfo::MapleLogger() << v->GetName();
545     DumpSize(*v);
546     DumpReferenceInfo(*v);
547     DumpOpndSuffix();
548 }
549 
Visit(maplebe::ListOperand * v)550 void X64OpndDumpVisitor::Visit(maplebe::ListOperand *v)
551 {
552     DumpOpndPrefix();
553     LogInfo::MapleLogger() << "list ";
554 
555     MapleList<RegOperand *> opndList = v->GetOperands();
556     for (auto it = opndList.begin(); it != opndList.end();) {
557         (*it)->Dump();
558         LogInfo::MapleLogger() << (++it == opndList.end() ? "" : " ,");
559     }
560     DumpSize(*v);
561     DumpOpndSuffix();
562 }
563 
Visit(maplebe::LabelOperand * v)564 void X64OpndDumpVisitor::Visit(maplebe::LabelOperand *v)
565 {
566     DumpOpndPrefix();
567     LogInfo::MapleLogger() << "label ";
568     LogInfo::MapleLogger() << v->GetLabelIndex();
569     DumpSize(*v);
570     DumpOpndSuffix();
571 }
572 
Visit(PhiOperand * v)573 void X64OpndDumpVisitor::Visit(PhiOperand *v)
574 {
575     CHECK_FATAL(false, "NIY");
576 }
577 
Visit(CondOperand * v)578 void X64OpndDumpVisitor::Visit(CondOperand *v)
579 {
580     CHECK_FATAL(false, "do not use this operand, it will be eliminated soon");
581 }
Visit(StImmOperand * v)582 void X64OpndDumpVisitor::Visit(StImmOperand *v)
583 {
584     CHECK_FATAL(false, "do not use this operand, it will be eliminated soon");
585 }
Visit(BitShiftOperand * v)586 void X64OpndDumpVisitor::Visit(BitShiftOperand *v)
587 {
588     CHECK_FATAL(false, "do not use this operand, it will be eliminated soon");
589 }
Visit(ExtendShiftOperand * v)590 void X64OpndDumpVisitor::Visit(ExtendShiftOperand *v)
591 {
592     CHECK_FATAL(false, "do not use this operand, it will be eliminated soon");
593 }
594 }  // namespace maplebe
595