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