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