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