• 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_emitter.h"
17 #include "x64_cgfunc.h"
18 #include "x64_cg.h"
19 #include "insn.h"
20 
21 namespace {
22 using namespace maple;
23 
LFindAttribute(MapleVector<DBGDieAttr * > & vec,DwAt key)24 DBGDieAttr *LFindAttribute(MapleVector<DBGDieAttr *> &vec, DwAt key)
25 {
26     for (DBGDieAttr *at : vec) {
27         if (at->GetDwAt() == key) {
28             return at;
29         }
30     }
31     return nullptr;
32 }
33 
LFindAbbrevEntry(MapleVector<DBGAbbrevEntry * > & abbvec,unsigned int key)34 DBGAbbrevEntry *LFindAbbrevEntry(MapleVector<DBGAbbrevEntry *> &abbvec, unsigned int key)
35 {
36     for (DBGAbbrevEntry *daie : abbvec) {
37         if (!daie) {
38             continue;
39         }
40         if (daie->GetAbbrevId() == key) {
41             return daie;
42         }
43     }
44     DEBUG_ASSERT(0, "");
45     return nullptr;
46 }
47 
LShouldEmit(unsigned int dwform)48 bool LShouldEmit(unsigned int dwform)
49 {
50     return dwform != static_cast<uint32>(DW_FORM_flag_present);
51 }
52 
LFindChildDieWithName(DBGDie & die,DwTag tag,const GStrIdx key)53 DBGDie *LFindChildDieWithName(DBGDie &die, DwTag tag, const GStrIdx key)
54 {
55     for (DBGDie *c : die.GetSubDieVec()) {
56         if (c->GetTag() != tag) {
57             continue;
58         }
59         for (DBGDieAttr *a : c->GetAttrVec()) {
60             if ((a->GetDwAt() == static_cast<uint32>(DW_AT_name)) &&
61                 ((a->GetDwForm() == static_cast<uint32>(DW_FORM_string) ||
62                   a->GetDwForm() == static_cast<uint32>(DW_FORM_strp)) &&
63                  a->GetId() == key.GetIdx())) {
64                 return c;
65             }
66             if ((a->GetDwAt() == static_cast<uint32>(DW_AT_name)) &&
67                 (!((a->GetDwForm() == static_cast<uint32>(DW_FORM_string) ||
68                     a->GetDwForm() == static_cast<uint32>(DW_FORM_strp)) &&
69                     a->GetId() == key.GetIdx()))) {
70                 break;
71             }
72         }
73     }
74     return nullptr;
75 }
76 
77 /* GetDwOpName(unsigned n) */
78 #define TOSTR(s) #s
GetDwOpName(unsigned n)79 const std::string GetDwOpName(unsigned n)
80 {
81     switch (n) {
82 #define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
83     case DW_OP_##NAME:                          \
84         return TOSTR(DW_OP_##NAME)
85         case DW_OP_hi_user:
86             return "DW_OP_hi_user";
87         default:
88             return nullptr;
89     }
90 }
91 }  // namespace
92 
93 using namespace std;
94 using namespace assembler;
95 
96 namespace maplebe {
GetSymbolAlign(const MIRSymbol & mirSymbol,bool isComm)97 uint8 X64Emitter::GetSymbolAlign(const MIRSymbol &mirSymbol, bool isComm)
98 {
99     uint8 alignInByte = mirSymbol.GetAttrs().GetAlignValue();
100     MIRTypeKind kind = mirSymbol.GetType()->GetKind();
101     if (isComm) {
102         MIRStorageClass storage = mirSymbol.GetStorageClass();
103         if (((kind == kTypeStruct) || (kind == kTypeClass) || (kind == kTypeArray) || (kind == kTypeUnion)) &&
104             ((storage == kScGlobal) || (storage == kScPstatic) || (storage == kScFstatic)) &&
105             alignInByte < kSizeOfPTR) {
106             alignInByte = kQ;
107             return alignInByte;
108         }
109     }
110     if (alignInByte == 0) {
111         if (kind == kTypeStruct || kind == kTypeClass || kind == kTypeArray || kind == kTypeUnion) {
112             return alignInByte;
113         } else {
114             alignInByte = Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirSymbol.GetType()->GetTypeIndex());
115         }
116     }
117     return alignInByte;
118 }
119 
GetSymbolSize(const TyIdx typeIndex)120 uint64 X64Emitter::GetSymbolSize(const TyIdx typeIndex)
121 {
122     uint64 sizeInByte = Globals::GetInstance()->GetBECommon()->GetTypeSize(typeIndex);
123     return sizeInByte;
124 }
125 
TransferReg(Operand * opnd) const126 Reg X64Emitter::TransferReg(Operand *opnd) const
127 {
128     RegOperand *v = static_cast<RegOperand *>(opnd);
129     /* check whether this reg is still virtual */
130     CHECK_FATAL(v->IsPhysicalRegister(), "register is still virtual or reg num is 0");
131 
132     uint8 regType = -1;
133     switch (v->GetSize()) {
134         case k8BitSize:
135             regType = v->IsHigh8Bit() ? X64CG::kR8HighList : X64CG::kR8LowList;
136             break;
137         case k16BitSize:
138             regType = X64CG::kR16List;
139             break;
140         case k32BitSize:
141             regType = X64CG::kR32List;
142             break;
143         case k64BitSize:
144             regType = X64CG::kR64List;
145             break;
146         case k128BitSize:
147             regType = X64CG::kR128List;
148             break;
149         default:
150             FATAL(kLncFatal, "unkown reg size");
151             break;
152     }
153     CHECK_FATAL(v->GetRegisterNumber() < kRegArray[regType].size(), "NIY, reg out of range");
154     Reg reg = kRegArray[regType][v->GetRegisterNumber()];
155     CHECK_FATAL(reg != Reg::ERR, "error reg");
156     return reg;
157 }
158 
TransferImm(Operand * opnd)159 pair<int64, bool> X64Emitter::TransferImm(Operand *opnd)
160 {
161     ImmOperand *v = static_cast<ImmOperand *>(opnd);
162     if (v->GetKind() == Operand::kOpdStImmediate) {
163         uint32 symIdx = v->GetSymbol()->GetNameStrIdx().get();
164         const string &symName = v->GetName();
165         assmbler.StoreNameIntoSymMap(symIdx, symName);
166         return pair<int64, bool>(symIdx, true);
167     } else {
168         return pair<int64, bool>(v->GetValue(), false);
169     }
170 }
171 
TransferMem(Operand * opnd,uint32 funcUniqueId)172 Mem X64Emitter::TransferMem(Operand *opnd, uint32 funcUniqueId)
173 {
174     MemOperand *v = static_cast<MemOperand *>(opnd);
175     Mem mem;
176     mem.size = v->GetSize();
177     if (v->GetOffsetOperand() != nullptr) {
178         ImmOperand *ofset = v->GetOffsetOperand();
179         if (ofset->GetKind() == Operand::kOpdStImmediate) {
180             string symbolName = ofset->GetName();
181             const MIRSymbol *symbol = ofset->GetSymbol();
182 
183             MIRStorageClass storageClass = symbol->GetStorageClass();
184             bool isLocalVar = ofset->GetSymbol()->IsLocal();
185             if (storageClass == kScPstatic && isLocalVar) {
186                 symbolName.append(to_string(funcUniqueId));
187             }
188 
189             int64 symIdx;
190             /* 2 : if it is a bb label, the second position in symbolName is '.' */
191             if (symbolName.size() > 2 && symbolName[2] == '.') {
192                 string delimiter = "__";
193                 size_t pos = symbolName.find(delimiter);
194                 uint32 itsFuncUniqueId =
195                     pos > 3 ? stoi(symbolName.substr(3, pos)) : 0; /* 3: index starts after ".L." */
196                 uint32 labelIdx = stoi(symbolName.substr(pos + 2, symbolName.length())); /* 2: delimiter.length() */
197                 symIdx = CalculateLabelSymIdx(itsFuncUniqueId, labelIdx);
198             } else {
199                 symIdx = symbol->GetNameStrIdx().get();
200             }
201             assmbler.StoreNameIntoSymMap(symIdx, symbolName);
202             mem.disp.first = symIdx;
203         }
204         if (ofset->GetValue() != 0) {
205             mem.disp.second = ofset->GetValue();
206         }
207     }
208     if (v->GetBaseRegister() != nullptr) {
209         if (v->GetIndexRegister() != nullptr && v->GetBaseRegister()->GetRegisterNumber() == x64::RBP) {
210             mem.base = ERR;
211         } else {
212             mem.base = TransferReg(v->GetBaseRegister());
213         }
214     }
215     if (v->GetIndexRegister() != nullptr) {
216         mem.index = TransferReg(v->GetIndexRegister());
217         uint8 s = static_cast<uint8>(v->GetScaleOperand()->GetValue());
218         /* 1, 2, 4, 8: allowed range for s */
219         CHECK_FATAL(s == 1 || s == 2 || s == 4 || s == 8, "mem.s is not 1, 2, 4, or 8");
220         mem.s = s;
221     }
222     mem.SetMemType();
223     return mem;
224 }
225 
TransferLabel(Operand * opnd,uint32 funcUniqueId)226 int64 X64Emitter::TransferLabel(Operand *opnd, uint32 funcUniqueId)
227 {
228     LabelOperand *v = static_cast<LabelOperand *>(opnd);
229     int64 labelSymIdx = CalculateLabelSymIdx(funcUniqueId, v->GetLabelIndex());
230     assmbler.StoreNameIntoSymMap(labelSymIdx, v->GetParentFunc());
231     return labelSymIdx;
232 }
233 
TransferFuncName(Operand * opnd)234 uint32 X64Emitter::TransferFuncName(Operand *opnd)
235 {
236     FuncNameOperand *v = static_cast<FuncNameOperand *>(opnd);
237     uint32 funcSymIdx = v->GetFunctionSymbol()->GetNameStrIdx().get();
238     assmbler.StoreNameIntoSymMap(funcSymIdx, v->GetName());
239     return funcSymIdx;
240 }
241 
EmitInsn(Insn & insn,uint32 funcUniqueId)242 void X64Emitter::EmitInsn(Insn &insn, uint32 funcUniqueId)
243 {
244 #if DEBUG
245     insn.Check();
246 #endif
247 
248     MOperator mop = insn.GetMachineOpcode();
249     const InsnDesc &curMd = X64CG::kMd[mop];
250     uint32 opndNum = curMd.GetOpndMDLength(); /* Get operands Number */
251 
252     /* Get operand(s) */
253     Operand *opnd0 = nullptr;
254     Operand *opnd1 = nullptr;
255     if (opndNum > 0) {
256         opnd0 = &insn.GetOperand(0);
257         if (opndNum > 1) {
258             opnd1 = &insn.GetOperand(1);
259         }
260     }
261 
262     switch (mop) {
263         /* mov */
264         case x64::MOP_movb_r_r:
265             assmbler.Mov(kB, TransferReg(opnd0), TransferReg(opnd1));
266             break;
267         case x64::MOP_movw_r_r:
268             assmbler.Mov(kW, TransferReg(opnd0), TransferReg(opnd1));
269             break;
270         case x64::MOP_movl_r_r:
271             assmbler.Mov(kL, TransferReg(opnd0), TransferReg(opnd1));
272             break;
273         case x64::MOP_movq_r_r:
274             assmbler.Mov(kQ, TransferReg(opnd0), TransferReg(opnd1));
275             break;
276         case x64::MOP_movb_m_r:
277             assmbler.Mov(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
278             break;
279         case x64::MOP_movw_m_r:
280             assmbler.Mov(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
281             break;
282         case x64::MOP_movl_m_r:
283             assmbler.Mov(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
284             break;
285         case x64::MOP_movq_m_r:
286             assmbler.Mov(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
287             break;
288         case x64::MOP_movb_i_r:
289             assmbler.Mov(kB, TransferImm(opnd0), TransferReg(opnd1));
290             break;
291         case x64::MOP_movw_i_r:
292             assmbler.Mov(kW, TransferImm(opnd0), TransferReg(opnd1));
293             break;
294         case x64::MOP_movl_i_r:
295             assmbler.Mov(kL, TransferImm(opnd0), TransferReg(opnd1));
296             break;
297         case x64::MOP_movq_i_r:
298             assmbler.Mov(kQ, TransferImm(opnd0), TransferReg(opnd1));
299             break;
300         case x64::MOP_movb_i_m:
301             assmbler.Mov(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
302             break;
303         case x64::MOP_movw_i_m:
304             assmbler.Mov(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
305             break;
306         case x64::MOP_movl_i_m:
307             assmbler.Mov(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
308             break;
309         case x64::MOP_movb_r_m:
310             assmbler.Mov(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
311             break;
312         case x64::MOP_movw_r_m:
313             assmbler.Mov(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
314             break;
315         case x64::MOP_movl_r_m:
316             assmbler.Mov(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
317             break;
318         case x64::MOP_movq_r_m:
319             assmbler.Mov(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
320             break;
321         /* floating point mov */
322         case x64::MOP_movd_fr_r:
323             assmbler.Mov(TransferReg(opnd0), TransferReg(opnd1));
324             break;
325         case x64::MOP_movq_fr_r:
326         case x64::MOP_movq_r_fr:
327             assmbler.Mov(TransferReg(opnd0), TransferReg(opnd1), false);
328             break;
329         case x64::MOP_movfs_r_r:
330             assmbler.MovF(TransferReg(opnd0), TransferReg(opnd1));
331             break;
332         case x64::MOP_movfd_r_r:
333             assmbler.MovF(TransferReg(opnd0), TransferReg(opnd1), false);
334             break;
335         case x64::MOP_movfs_m_r:
336             assmbler.MovF(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
337             break;
338         case x64::MOP_movfs_r_m:
339             assmbler.MovF(TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
340             break;
341         case x64::MOP_movfd_m_r:
342             assmbler.MovF(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1), false);
343             break;
344         case x64::MOP_movfd_r_m:
345             assmbler.MovF(TransferReg(opnd0), TransferMem(opnd1, funcUniqueId), false);
346             break;
347         /* movzx */
348         case x64::MOP_movzbw_r_r:
349             assmbler.MovZx(kB, kW, TransferReg(opnd0), TransferReg(opnd1));
350             break;
351         case x64::MOP_movzbl_r_r:
352             assmbler.MovZx(kB, kL, TransferReg(opnd0), TransferReg(opnd1));
353             break;
354         case x64::MOP_movzbq_r_r:
355             assmbler.MovZx(kB, kQ, TransferReg(opnd0), TransferReg(opnd1));
356             break;
357         case x64::MOP_movzwl_r_r:
358             assmbler.MovZx(kW, kL, TransferReg(opnd0), TransferReg(opnd1));
359             break;
360         case x64::MOP_movzwq_r_r:
361             assmbler.MovZx(kW, kQ, TransferReg(opnd0), TransferReg(opnd1));
362             break;
363         case x64::MOP_movzbw_m_r:
364             assmbler.MovZx(kB, kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
365             break;
366         case x64::MOP_movzbl_m_r:
367             assmbler.MovZx(kB, kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
368             break;
369         case x64::MOP_movzbq_m_r:
370             assmbler.MovZx(kB, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
371             break;
372         case x64::MOP_movzwl_m_r:
373             assmbler.MovZx(kW, kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
374             break;
375         case x64::MOP_movzwq_m_r:
376             assmbler.MovZx(kW, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
377             break;
378         /* movsx */
379         case x64::MOP_movsbw_r_r:
380             assmbler.MovSx(kB, kW, TransferReg(opnd0), TransferReg(opnd1));
381             break;
382         case x64::MOP_movsbl_r_r:
383             assmbler.MovSx(kB, kL, TransferReg(opnd0), TransferReg(opnd1));
384             break;
385         case x64::MOP_movsbq_r_r:
386             assmbler.MovSx(kB, kQ, TransferReg(opnd0), TransferReg(opnd1));
387             break;
388         case x64::MOP_movswl_r_r:
389             assmbler.MovSx(kW, kL, TransferReg(opnd0), TransferReg(opnd1));
390             break;
391         case x64::MOP_movswq_r_r:
392             assmbler.MovSx(kW, kQ, TransferReg(opnd0), TransferReg(opnd1));
393             break;
394         case x64::MOP_movslq_r_r:
395             assmbler.MovSx(kL, kQ, TransferReg(opnd0), TransferReg(opnd1));
396             break;
397         case x64::MOP_movsbw_m_r:
398             assmbler.MovSx(kB, kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
399             break;
400         case x64::MOP_movsbl_m_r:
401             assmbler.MovSx(kB, kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
402             break;
403         case x64::MOP_movsbq_m_r:
404             assmbler.MovSx(kB, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
405             break;
406         case x64::MOP_movswl_m_r:
407             assmbler.MovSx(kW, kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
408             break;
409         case x64::MOP_movswq_m_r:
410             assmbler.MovSx(kW, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
411             break;
412         case x64::MOP_movslq_m_r:
413             assmbler.MovSx(kL, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
414             break;
415         /* add */
416         case x64::MOP_addb_r_r:
417             assmbler.Add(kB, TransferReg(opnd0), TransferReg(opnd1));
418             break;
419         case x64::MOP_addw_r_r:
420             assmbler.Add(kW, TransferReg(opnd0), TransferReg(opnd1));
421             break;
422         case x64::MOP_addl_r_r:
423             assmbler.Add(kL, TransferReg(opnd0), TransferReg(opnd1));
424             break;
425         case x64::MOP_addq_r_r:
426             assmbler.Add(kQ, TransferReg(opnd0), TransferReg(opnd1));
427             break;
428         case x64::MOP_addb_i_r:
429             assmbler.Add(kB, TransferImm(opnd0), TransferReg(opnd1));
430             break;
431         case x64::MOP_addw_i_r:
432             assmbler.Add(kW, TransferImm(opnd0), TransferReg(opnd1));
433             break;
434         case x64::MOP_addl_i_r:
435             assmbler.Add(kL, TransferImm(opnd0), TransferReg(opnd1));
436             break;
437         case x64::MOP_addq_i_r:
438             assmbler.Add(kQ, TransferImm(opnd0), TransferReg(opnd1));
439             break;
440         case x64::MOP_addb_m_r:
441             assmbler.Add(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
442             break;
443         case x64::MOP_addw_m_r:
444             assmbler.Add(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
445             break;
446         case x64::MOP_addl_m_r:
447             assmbler.Add(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
448             break;
449         case x64::MOP_addq_m_r:
450             assmbler.Add(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
451             break;
452         case x64::MOP_addb_r_m:
453             assmbler.Add(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
454             break;
455         case x64::MOP_addw_r_m:
456             assmbler.Add(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
457             break;
458         case x64::MOP_addl_r_m:
459             assmbler.Add(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
460             break;
461         case x64::MOP_addq_r_m:
462             assmbler.Add(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
463             break;
464         case x64::MOP_addb_i_m:
465             assmbler.Add(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
466             break;
467         case x64::MOP_addw_i_m:
468             assmbler.Add(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
469             break;
470         case x64::MOP_addl_i_m:
471             assmbler.Add(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
472             break;
473         case x64::MOP_addq_i_m:
474             assmbler.Add(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
475             break;
476         /* add floating point */
477         case x64::MOP_adds_r_r:
478             assmbler.Add(TransferReg(opnd0), TransferReg(opnd1));
479             break;
480         case x64::MOP_adds_m_r:
481             assmbler.Add(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
482             break;
483         case x64::MOP_addd_r_r:
484             assmbler.Add(TransferReg(opnd0), TransferReg(opnd1), false);
485             break;
486         case x64::MOP_addd_m_r:
487             assmbler.Add(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1), false);
488             break;
489         /* movabs */
490         case x64::MOP_movabs_i_r:
491             assmbler.Movabs(TransferImm(opnd0), TransferReg(opnd1));
492             break;
493         case x64::MOP_movabs_l_r:
494             assmbler.Movabs(TransferLabel(opnd0, funcUniqueId), TransferReg(opnd1));
495             break;
496         /* push */
497         case x64::MOP_pushq_r:
498             assmbler.Push(kQ, TransferReg(opnd0));
499             break;
500         /* pop */
501         case x64::MOP_popq_r:
502             assmbler.Pop(kQ, TransferReg(opnd0));
503             break;
504         /* lea */
505         case x64::MOP_leaw_m_r:
506             assmbler.Lea(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
507             break;
508         case x64::MOP_leal_m_r:
509             assmbler.Lea(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
510             break;
511         case x64::MOP_leaq_m_r:
512             assmbler.Lea(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
513             break;
514         /* sub , sbb */
515         case x64::MOP_subb_r_r:
516             assmbler.Sub(kB, TransferReg(opnd0), TransferReg(opnd1));
517             break;
518         case x64::MOP_subw_r_r:
519             assmbler.Sub(kW, TransferReg(opnd0), TransferReg(opnd1));
520             break;
521         case x64::MOP_subl_r_r:
522             assmbler.Sub(kL, TransferReg(opnd0), TransferReg(opnd1));
523             break;
524         case x64::MOP_subq_r_r:
525             assmbler.Sub(kQ, TransferReg(opnd0), TransferReg(opnd1));
526             break;
527         case x64::MOP_subb_i_r:
528             assmbler.Sub(kB, TransferImm(opnd0), TransferReg(opnd1));
529             break;
530         case x64::MOP_subw_i_r:
531             assmbler.Sub(kW, TransferImm(opnd0), TransferReg(opnd1));
532             break;
533         case x64::MOP_subl_i_r:
534             assmbler.Sub(kL, TransferImm(opnd0), TransferReg(opnd1));
535             break;
536         case x64::MOP_subq_i_r:
537             assmbler.Sub(kQ, TransferImm(opnd0), TransferReg(opnd1));
538             break;
539         case x64::MOP_subb_m_r:
540             assmbler.Sub(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
541             break;
542         case x64::MOP_subw_m_r:
543             assmbler.Sub(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
544             break;
545         case x64::MOP_subl_m_r:
546             assmbler.Sub(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
547             break;
548         case x64::MOP_subq_m_r:
549             assmbler.Sub(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
550             break;
551         case x64::MOP_subb_r_m:
552             assmbler.Sub(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
553             break;
554         case x64::MOP_subw_r_m:
555             assmbler.Sub(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
556             break;
557         case x64::MOP_subl_r_m:
558             assmbler.Sub(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
559             break;
560         case x64::MOP_subq_r_m:
561             assmbler.Sub(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
562             break;
563         case x64::MOP_subb_i_m:
564             assmbler.Sub(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
565             break;
566         case x64::MOP_subw_i_m:
567             assmbler.Sub(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
568             break;
569         case x64::MOP_subl_i_m:
570             assmbler.Sub(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
571             break;
572         case x64::MOP_subq_i_m:
573             assmbler.Sub(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
574             break;
575         /* sub floating point */
576         case x64::MOP_subs_r_r:
577             assmbler.Sub(TransferReg(opnd0), TransferReg(opnd1));
578             break;
579         case x64::MOP_subs_m_r:
580             assmbler.Sub(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
581             break;
582         case x64::MOP_subd_r_r:
583             assmbler.Sub(TransferReg(opnd0), TransferReg(opnd1), false);
584             break;
585         case x64::MOP_subd_m_r:
586             assmbler.Sub(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1), false);
587             break;
588         /* and */
589         case x64::MOP_andb_r_r:
590             assmbler.And(kB, TransferReg(opnd0), TransferReg(opnd1));
591             break;
592         case x64::MOP_andw_r_r:
593             assmbler.And(kW, TransferReg(opnd0), TransferReg(opnd1));
594             break;
595         case x64::MOP_andl_r_r:
596             assmbler.And(kL, TransferReg(opnd0), TransferReg(opnd1));
597             break;
598         case x64::MOP_andq_r_r:
599             assmbler.And(kQ, TransferReg(opnd0), TransferReg(opnd1));
600             break;
601         case x64::MOP_andb_i_r:
602             assmbler.And(kB, TransferImm(opnd0), TransferReg(opnd1));
603             break;
604         case x64::MOP_andw_i_r:
605             assmbler.And(kW, TransferImm(opnd0), TransferReg(opnd1));
606             break;
607         case x64::MOP_andl_i_r:
608             assmbler.And(kL, TransferImm(opnd0), TransferReg(opnd1));
609             break;
610         case x64::MOP_andq_i_r:
611             assmbler.And(kQ, TransferImm(opnd0), TransferReg(opnd1));
612             break;
613         case x64::MOP_andb_m_r:
614             assmbler.And(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
615             break;
616         case x64::MOP_andw_m_r:
617             assmbler.And(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
618             break;
619         case x64::MOP_andl_m_r:
620             assmbler.And(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
621             break;
622         case x64::MOP_andq_m_r:
623             assmbler.And(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
624             break;
625         case x64::MOP_andb_r_m:
626             assmbler.And(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
627             break;
628         case x64::MOP_andw_r_m:
629             assmbler.And(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
630             break;
631         case x64::MOP_andl_r_m:
632             assmbler.And(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
633             break;
634         case x64::MOP_andq_r_m:
635             assmbler.And(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
636             break;
637         case x64::MOP_andb_i_m:
638             assmbler.And(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
639             break;
640         case x64::MOP_andw_i_m:
641             assmbler.And(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
642             break;
643         case x64::MOP_andl_i_m:
644             assmbler.And(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
645             break;
646         case x64::MOP_andq_i_m:
647             assmbler.And(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
648             break;
649         /* or */
650         case x64::MOP_orb_r_r:
651             assmbler.Or(kB, TransferReg(opnd0), TransferReg(opnd1));
652             break;
653         case x64::MOP_orw_r_r:
654             assmbler.Or(kW, TransferReg(opnd0), TransferReg(opnd1));
655             break;
656         case x64::MOP_orl_r_r:
657             assmbler.Or(kL, TransferReg(opnd0), TransferReg(opnd1));
658             break;
659         case x64::MOP_orq_r_r:
660             assmbler.Or(kQ, TransferReg(opnd0), TransferReg(opnd1));
661             break;
662         case x64::MOP_orb_m_r:
663             assmbler.Or(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
664             break;
665         case x64::MOP_orw_m_r:
666             assmbler.Or(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
667             break;
668         case x64::MOP_orl_m_r:
669             assmbler.Or(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
670             break;
671         case x64::MOP_orq_m_r:
672             assmbler.Or(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
673             break;
674         case x64::MOP_orb_i_r:
675             assmbler.Or(kB, TransferImm(opnd0), TransferReg(opnd1));
676             break;
677         case x64::MOP_orw_i_r:
678             assmbler.Or(kW, TransferImm(opnd0), TransferReg(opnd1));
679             break;
680         case x64::MOP_orl_i_r:
681             assmbler.Or(kL, TransferImm(opnd0), TransferReg(opnd1));
682             break;
683         case x64::MOP_orq_i_r:
684             assmbler.Or(kQ, TransferImm(opnd0), TransferReg(opnd1));
685             break;
686         case x64::MOP_orb_r_m:
687             assmbler.Or(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
688             break;
689         case x64::MOP_orw_r_m:
690             assmbler.Or(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
691             break;
692         case x64::MOP_orl_r_m:
693             assmbler.Or(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
694             break;
695         case x64::MOP_orq_r_m:
696             assmbler.Or(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
697             break;
698         case x64::MOP_orb_i_m:
699             assmbler.Or(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
700             break;
701         case x64::MOP_orw_i_m:
702             assmbler.Or(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
703             break;
704         case x64::MOP_orl_i_m:
705             assmbler.Or(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
706             break;
707         case x64::MOP_orq_i_m:
708             assmbler.Or(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
709             break;
710         /* xor */
711         case x64::MOP_xorb_r_r:
712             assmbler.Xor(kB, TransferReg(opnd0), TransferReg(opnd1));
713             break;
714         case x64::MOP_xorw_r_r:
715             assmbler.Xor(kW, TransferReg(opnd0), TransferReg(opnd1));
716             break;
717         case x64::MOP_xorl_r_r:
718             assmbler.Xor(kL, TransferReg(opnd0), TransferReg(opnd1));
719             break;
720         case x64::MOP_xorq_r_r:
721             assmbler.Xor(kQ, TransferReg(opnd0), TransferReg(opnd1));
722             break;
723         case x64::MOP_xorb_i_r:
724             assmbler.Xor(kB, TransferImm(opnd0), TransferReg(opnd1));
725             break;
726         case x64::MOP_xorw_i_r:
727             assmbler.Xor(kW, TransferImm(opnd0), TransferReg(opnd1));
728             break;
729         case x64::MOP_xorl_i_r:
730             assmbler.Xor(kL, TransferImm(opnd0), TransferReg(opnd1));
731             break;
732         case x64::MOP_xorq_i_r:
733             assmbler.Xor(kQ, TransferImm(opnd0), TransferReg(opnd1));
734             break;
735         case x64::MOP_xorb_m_r:
736             assmbler.Xor(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
737             break;
738         case x64::MOP_xorw_m_r:
739             assmbler.Xor(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
740             break;
741         case x64::MOP_xorl_m_r:
742             assmbler.Xor(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
743             break;
744         case x64::MOP_xorq_m_r:
745             assmbler.Xor(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
746             break;
747         case x64::MOP_xorb_r_m:
748             assmbler.Xor(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
749             break;
750         case x64::MOP_xorw_r_m:
751             assmbler.Xor(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
752             break;
753         case x64::MOP_xorl_r_m:
754             assmbler.Xor(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
755             break;
756         case x64::MOP_xorq_r_m:
757             assmbler.Xor(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
758             break;
759         case x64::MOP_xorb_i_m:
760             assmbler.Xor(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
761             break;
762         case x64::MOP_xorw_i_m:
763             assmbler.Xor(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
764             break;
765         case x64::MOP_xorl_i_m:
766             assmbler.Xor(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
767             break;
768         case x64::MOP_xorq_i_m:
769             assmbler.Xor(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
770             break;
771         /* not */
772         case x64::MOP_notb_r:
773             assmbler.Not(kB, TransferReg(opnd0));
774             break;
775         case x64::MOP_notw_r:
776             assmbler.Not(kW, TransferReg(opnd0));
777             break;
778         case x64::MOP_notl_r:
779             assmbler.Not(kL, TransferReg(opnd0));
780             break;
781         case x64::MOP_notq_r:
782             assmbler.Not(kQ, TransferReg(opnd0));
783             break;
784         case x64::MOP_notb_m:
785             assmbler.Not(kB, TransferMem(opnd0, funcUniqueId));
786             break;
787         case x64::MOP_notw_m:
788             assmbler.Not(kW, TransferMem(opnd0, funcUniqueId));
789             break;
790         case x64::MOP_notl_m:
791             assmbler.Not(kL, TransferMem(opnd0, funcUniqueId));
792             break;
793         case x64::MOP_notq_m:
794             assmbler.Not(kQ, TransferMem(opnd0, funcUniqueId));
795             break;
796         /* neg */
797         case x64::MOP_negb_r:
798             assmbler.Neg(kB, TransferReg(opnd0));
799             break;
800         case x64::MOP_negw_r:
801             assmbler.Neg(kW, TransferReg(opnd0));
802             break;
803         case x64::MOP_negl_r:
804             assmbler.Neg(kL, TransferReg(opnd0));
805             break;
806         case x64::MOP_negq_r:
807             assmbler.Neg(kQ, TransferReg(opnd0));
808             break;
809         case x64::MOP_negb_m:
810             assmbler.Neg(kB, TransferMem(opnd0, funcUniqueId));
811             break;
812         case x64::MOP_negw_m:
813             assmbler.Neg(kW, TransferMem(opnd0, funcUniqueId));
814             break;
815         case x64::MOP_negl_m:
816             assmbler.Neg(kL, TransferMem(opnd0, funcUniqueId));
817             break;
818         case x64::MOP_negq_m:
819             assmbler.Neg(kQ, TransferMem(opnd0, funcUniqueId));
820             break;
821         /* div, cwd, cdq, cqo */
822         case x64::MOP_idivw_r:
823             assmbler.Idiv(kW, TransferReg(opnd0));
824             break;
825         case x64::MOP_idivl_r:
826             assmbler.Idiv(kL, TransferReg(opnd0));
827             break;
828         case x64::MOP_idivq_r:
829             assmbler.Idiv(kQ, TransferReg(opnd0));
830             break;
831         case x64::MOP_idivw_m:
832             assmbler.Idiv(kW, TransferMem(opnd0, funcUniqueId));
833             break;
834         case x64::MOP_idivl_m:
835             assmbler.Idiv(kL, TransferMem(opnd0, funcUniqueId));
836             break;
837         case x64::MOP_idivq_m:
838             assmbler.Idiv(kQ, TransferMem(opnd0, funcUniqueId));
839             break;
840         case x64::MOP_divw_r:
841             assmbler.Div(kW, TransferReg(opnd0));
842             break;
843         case x64::MOP_divl_r:
844             assmbler.Div(kL, TransferReg(opnd0));
845             break;
846         case x64::MOP_divq_r:
847             assmbler.Div(kQ, TransferReg(opnd0));
848             break;
849         case x64::MOP_divw_m:
850             assmbler.Div(kW, TransferMem(opnd0, funcUniqueId));
851             break;
852         case x64::MOP_divl_m:
853             assmbler.Div(kL, TransferMem(opnd0, funcUniqueId));
854             break;
855         case x64::MOP_divq_m:
856             assmbler.Div(kQ, TransferMem(opnd0, funcUniqueId));
857             break;
858         case x64::MOP_cwd:
859             assmbler.Cwd();
860             break;
861         case x64::MOP_cdq:
862             assmbler.Cdq();
863             break;
864         case x64::MOP_cqo:
865             assmbler.Cqo();
866             break;
867         /* shl */
868         case x64::MOP_shlb_r_r:
869             assmbler.Shl(kB, TransferReg(opnd0), TransferReg(opnd1));
870             break;
871         case x64::MOP_shlw_r_r:
872             assmbler.Shl(kW, TransferReg(opnd0), TransferReg(opnd1));
873             break;
874         case x64::MOP_shll_r_r:
875             assmbler.Shl(kL, TransferReg(opnd0), TransferReg(opnd1));
876             break;
877         case x64::MOP_shlq_r_r:
878             assmbler.Shl(kQ, TransferReg(opnd0), TransferReg(opnd1));
879             break;
880         case x64::MOP_shlb_i_r:
881             assmbler.Shl(kB, TransferImm(opnd0), TransferReg(opnd1));
882             break;
883         case x64::MOP_shlw_i_r:
884             assmbler.Shl(kW, TransferImm(opnd0), TransferReg(opnd1));
885             break;
886         case x64::MOP_shll_i_r:
887             assmbler.Shl(kL, TransferImm(opnd0), TransferReg(opnd1));
888             break;
889         case x64::MOP_shlq_i_r:
890             assmbler.Shl(kQ, TransferImm(opnd0), TransferReg(opnd1));
891             break;
892         case x64::MOP_shlb_r_m:
893             assmbler.Shl(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
894             break;
895         case x64::MOP_shlw_r_m:
896             assmbler.Shl(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
897             break;
898         case x64::MOP_shll_r_m:
899             assmbler.Shl(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
900             break;
901         case x64::MOP_shlq_r_m:
902             assmbler.Shl(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
903             break;
904         case x64::MOP_shlb_i_m:
905             assmbler.Shl(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
906             break;
907         case x64::MOP_shlw_i_m:
908             assmbler.Shl(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
909             break;
910         case x64::MOP_shll_i_m:
911             assmbler.Shl(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
912             break;
913         case x64::MOP_shlq_i_m:
914             assmbler.Shl(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
915             break;
916         /* sar */
917         case x64::MOP_sarb_r_r:
918             assmbler.Sar(kB, TransferReg(opnd0), TransferReg(opnd1));
919             break;
920         case x64::MOP_sarw_r_r:
921             assmbler.Sar(kW, TransferReg(opnd0), TransferReg(opnd1));
922             break;
923         case x64::MOP_sarl_r_r:
924             assmbler.Sar(kL, TransferReg(opnd0), TransferReg(opnd1));
925             break;
926         case x64::MOP_sarq_r_r:
927             assmbler.Sar(kQ, TransferReg(opnd0), TransferReg(opnd1));
928             break;
929         case x64::MOP_sarb_i_r:
930             assmbler.Sar(kB, TransferImm(opnd0), TransferReg(opnd1));
931             break;
932         case x64::MOP_sarw_i_r:
933             assmbler.Sar(kW, TransferImm(opnd0), TransferReg(opnd1));
934             break;
935         case x64::MOP_sarl_i_r:
936             assmbler.Sar(kL, TransferImm(opnd0), TransferReg(opnd1));
937             break;
938         case x64::MOP_sarq_i_r:
939             assmbler.Sar(kQ, TransferImm(opnd0), TransferReg(opnd1));
940             break;
941         case x64::MOP_sarb_r_m:
942             assmbler.Sar(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
943             break;
944         case x64::MOP_sarw_r_m:
945             assmbler.Sar(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
946             break;
947         case x64::MOP_sarl_r_m:
948             assmbler.Sar(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
949             break;
950         case x64::MOP_sarq_r_m:
951             assmbler.Sar(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
952             break;
953         case x64::MOP_sarb_i_m:
954             assmbler.Sar(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
955             break;
956         case x64::MOP_sarw_i_m:
957             assmbler.Sar(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
958             break;
959         case x64::MOP_sarl_i_m:
960             assmbler.Sar(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
961             break;
962         case x64::MOP_sarq_i_m:
963             assmbler.Sar(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
964             break;
965         /* shr */
966         case x64::MOP_shrb_r_r:
967             assmbler.Shr(kB, TransferReg(opnd0), TransferReg(opnd1));
968             break;
969         case x64::MOP_shrw_r_r:
970             assmbler.Shr(kW, TransferReg(opnd0), TransferReg(opnd1));
971             break;
972         case x64::MOP_shrl_r_r:
973             assmbler.Shr(kL, TransferReg(opnd0), TransferReg(opnd1));
974             break;
975         case x64::MOP_shrq_r_r:
976             assmbler.Shr(kQ, TransferReg(opnd0), TransferReg(opnd1));
977             break;
978         case x64::MOP_shrb_i_r:
979             assmbler.Shr(kB, TransferImm(opnd0), TransferReg(opnd1));
980             break;
981         case x64::MOP_shrw_i_r:
982             assmbler.Shr(kW, TransferImm(opnd0), TransferReg(opnd1));
983             break;
984         case x64::MOP_shrl_i_r:
985             assmbler.Shr(kL, TransferImm(opnd0), TransferReg(opnd1));
986             break;
987         case x64::MOP_shrq_i_r:
988             assmbler.Shr(kQ, TransferImm(opnd0), TransferReg(opnd1));
989             break;
990         case x64::MOP_shrb_r_m:
991             assmbler.Shr(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
992             break;
993         case x64::MOP_shrw_r_m:
994             assmbler.Shr(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
995             break;
996         case x64::MOP_shrl_r_m:
997             assmbler.Shr(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
998             break;
999         case x64::MOP_shrq_r_m:
1000             assmbler.Shr(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
1001             break;
1002         case x64::MOP_shrb_i_m:
1003             assmbler.Shr(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1004             break;
1005         case x64::MOP_shrw_i_m:
1006             assmbler.Shr(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1007             break;
1008         case x64::MOP_shrl_i_m:
1009             assmbler.Shr(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1010             break;
1011         case x64::MOP_shrq_i_m:
1012             assmbler.Shr(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1013             break;
1014         /* jmp */
1015         case x64::MOP_jmpq_r:
1016             assmbler.Jmp(TransferReg(opnd0));
1017             break;
1018         case x64::MOP_jmpq_m:
1019             assmbler.Jmp(TransferMem(opnd0, funcUniqueId));
1020             break;
1021         case x64::MOP_jmpq_l:
1022             assmbler.Jmp(TransferLabel(opnd0, funcUniqueId));
1023             break;
1024         /* je, jne */
1025         case x64::MOP_je_l:
1026             assmbler.Je(TransferLabel(opnd0, funcUniqueId));
1027             break;
1028         case x64::MOP_ja_l:
1029             assmbler.Ja(TransferLabel(opnd0, funcUniqueId));
1030             break;
1031         case x64::MOP_jae_l:
1032             assmbler.Jae(TransferLabel(opnd0, funcUniqueId));
1033             break;
1034         case x64::MOP_jne_l:
1035             assmbler.Jne(TransferLabel(opnd0, funcUniqueId));
1036             break;
1037         case x64::MOP_jb_l:
1038             assmbler.Jb(TransferLabel(opnd0, funcUniqueId));
1039             break;
1040         case x64::MOP_jbe_l:
1041             assmbler.Jbe(TransferLabel(opnd0, funcUniqueId));
1042             break;
1043         case x64::MOP_jg_l:
1044             assmbler.Jg(TransferLabel(opnd0, funcUniqueId));
1045             break;
1046         case x64::MOP_jge_l:
1047             assmbler.Jge(TransferLabel(opnd0, funcUniqueId));
1048             break;
1049         case x64::MOP_jl_l:
1050             assmbler.Jl(TransferLabel(opnd0, funcUniqueId));
1051             break;
1052         case x64::MOP_jle_l:
1053             assmbler.Jle(TransferLabel(opnd0, funcUniqueId));
1054             break;
1055         /* cmp */
1056         case x64::MOP_cmpb_r_r:
1057             assmbler.Cmp(kB, TransferReg(opnd0), TransferReg(opnd1));
1058             break;
1059         case x64::MOP_cmpw_r_r:
1060             assmbler.Cmp(kW, TransferReg(opnd0), TransferReg(opnd1));
1061             break;
1062         case x64::MOP_cmpl_r_r:
1063             assmbler.Cmp(kL, TransferReg(opnd0), TransferReg(opnd1));
1064             break;
1065         case x64::MOP_cmpq_r_r:
1066             assmbler.Cmp(kQ, TransferReg(opnd0), TransferReg(opnd1));
1067             break;
1068         case x64::MOP_cmpb_i_r:
1069             assmbler.Cmp(kB, TransferImm(opnd0), TransferReg(opnd1));
1070             break;
1071         case x64::MOP_cmpw_i_r:
1072             assmbler.Cmp(kW, TransferImm(opnd0), TransferReg(opnd1));
1073             break;
1074         case x64::MOP_cmpl_i_r:
1075             assmbler.Cmp(kL, TransferImm(opnd0), TransferReg(opnd1));
1076             break;
1077         case x64::MOP_cmpq_i_r:
1078             assmbler.Cmp(kQ, TransferImm(opnd0), TransferReg(opnd1));
1079             break;
1080         case x64::MOP_cmpb_m_r:
1081             assmbler.Cmp(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1082             break;
1083         case x64::MOP_cmpw_m_r:
1084             assmbler.Cmp(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1085             break;
1086         case x64::MOP_cmpl_m_r:
1087             assmbler.Cmp(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1088             break;
1089         case x64::MOP_cmpq_m_r:
1090             assmbler.Cmp(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1091             break;
1092         case x64::MOP_cmpb_r_m:
1093             assmbler.Cmp(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
1094             break;
1095         case x64::MOP_cmpw_r_m:
1096             assmbler.Cmp(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
1097             break;
1098         case x64::MOP_cmpl_r_m:
1099             assmbler.Cmp(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
1100             break;
1101         case x64::MOP_cmpq_r_m:
1102             assmbler.Cmp(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
1103             break;
1104         case x64::MOP_cmpb_i_m:
1105             assmbler.Cmp(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1106             break;
1107         case x64::MOP_cmpw_i_m:
1108             assmbler.Cmp(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1109             break;
1110         case x64::MOP_cmpl_i_m:
1111             assmbler.Cmp(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1112             break;
1113         case x64::MOP_cmpq_i_m:
1114             assmbler.Cmp(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1115             break;
1116         case x64::MOP_testq_r_r:
1117             assmbler.Test(kQ, TransferReg(opnd0), TransferReg(opnd1));
1118             break;
1119         /* setcc */
1120         case x64::MOP_seta_r:
1121             assmbler.Seta(TransferReg(opnd0));
1122             break;
1123         case x64::MOP_setae_r:
1124             assmbler.Setae(TransferReg(opnd0));
1125             break;
1126         case x64::MOP_setb_r:
1127             assmbler.Setb(TransferReg(opnd0));
1128             break;
1129         case x64::MOP_seto_r:
1130             assmbler.Seto(TransferReg(opnd0));
1131             break;
1132         case x64::MOP_setbe_r:
1133             assmbler.Setbe(TransferReg(opnd0));
1134             break;
1135         case x64::MOP_sete_r:
1136             assmbler.Sete(TransferReg(opnd0));
1137             break;
1138         case x64::MOP_setg_r:
1139             assmbler.Setg(TransferReg(opnd0));
1140             break;
1141         case x64::MOP_setge_r:
1142             assmbler.Setge(TransferReg(opnd0));
1143             break;
1144         case x64::MOP_setl_r:
1145             assmbler.Setl(TransferReg(opnd0));
1146             break;
1147         case x64::MOP_setle_r:
1148             assmbler.Setle(TransferReg(opnd0));
1149             break;
1150         case x64::MOP_setne_r:
1151             assmbler.Setne(TransferReg(opnd0));
1152             break;
1153         case x64::MOP_seta_m:
1154             assmbler.Seta(TransferMem(opnd0, funcUniqueId));
1155             break;
1156         case x64::MOP_setae_m:
1157             assmbler.Setae(TransferMem(opnd0, funcUniqueId));
1158             break;
1159         case x64::MOP_setb_m:
1160             assmbler.Setb(TransferMem(opnd0, funcUniqueId));
1161             break;
1162         case x64::MOP_seto_m:
1163             assmbler.Seto(TransferMem(opnd0, funcUniqueId));
1164             break;
1165         case x64::MOP_setbe_m:
1166             assmbler.Setbe(TransferMem(opnd0, funcUniqueId));
1167             break;
1168         case x64::MOP_sete_m:
1169             assmbler.Sete(TransferMem(opnd0, funcUniqueId));
1170             break;
1171         case x64::MOP_setl_m:
1172             assmbler.Setl(TransferMem(opnd0, funcUniqueId));
1173             break;
1174         case x64::MOP_setle_m:
1175             assmbler.Setle(TransferMem(opnd0, funcUniqueId));
1176             break;
1177         case x64::MOP_setg_m:
1178             assmbler.Setg(TransferMem(opnd0, funcUniqueId));
1179             break;
1180         case x64::MOP_setge_m:
1181             assmbler.Setge(TransferMem(opnd0, funcUniqueId));
1182             break;
1183         case x64::MOP_setne_m:
1184             assmbler.Setne(TransferMem(opnd0, funcUniqueId));
1185             break;
1186         /* cmova & cmovae */
1187         case x64::MOP_cmovaw_r_r:
1188             assmbler.Cmova(kW, TransferReg(opnd0), TransferReg(opnd1));
1189             break;
1190         case x64::MOP_cmoval_r_r:
1191             assmbler.Cmova(kL, TransferReg(opnd0), TransferReg(opnd1));
1192             break;
1193         case x64::MOP_cmovaq_r_r:
1194             assmbler.Cmova(kQ, TransferReg(opnd0), TransferReg(opnd1));
1195             break;
1196         case x64::MOP_cmovaw_m_r:
1197             assmbler.Cmova(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1198             break;
1199         case x64::MOP_cmoval_m_r:
1200             assmbler.Cmova(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1201             break;
1202         case x64::MOP_cmovaq_m_r:
1203             assmbler.Cmova(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1204             break;
1205         case x64::MOP_cmovaew_r_r:
1206             assmbler.Cmovae(kW, TransferReg(opnd0), TransferReg(opnd1));
1207             break;
1208         case x64::MOP_cmovael_r_r:
1209             assmbler.Cmovae(kL, TransferReg(opnd0), TransferReg(opnd1));
1210             break;
1211         case x64::MOP_cmovaeq_r_r:
1212             assmbler.Cmovae(kQ, TransferReg(opnd0), TransferReg(opnd1));
1213             break;
1214         case x64::MOP_cmovaew_m_r:
1215             assmbler.Cmovae(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1216             break;
1217         case x64::MOP_cmovael_m_r:
1218             assmbler.Cmovae(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1219             break;
1220         case x64::MOP_cmovaeq_m_r:
1221             assmbler.Cmovae(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1222             break;
1223         /* cmovb & cmovbe */
1224         case x64::MOP_cmovbw_r_r:
1225             assmbler.Cmovb(kW, TransferReg(opnd0), TransferReg(opnd1));
1226             break;
1227         case x64::MOP_cmovbl_r_r:
1228             assmbler.Cmovb(kL, TransferReg(opnd0), TransferReg(opnd1));
1229             break;
1230         case x64::MOP_cmovbq_r_r:
1231             assmbler.Cmovb(kQ, TransferReg(opnd0), TransferReg(opnd1));
1232             break;
1233         case x64::MOP_cmovbw_m_r:
1234             assmbler.Cmovb(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1235             break;
1236         case x64::MOP_cmovbl_m_r:
1237             assmbler.Cmovb(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1238             break;
1239         case x64::MOP_cmovbq_m_r:
1240             assmbler.Cmovb(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1241             break;
1242         case x64::MOP_cmovbew_r_r:
1243             assmbler.Cmovbe(kW, TransferReg(opnd0), TransferReg(opnd1));
1244             break;
1245         case x64::MOP_cmovbel_r_r:
1246             assmbler.Cmovbe(kL, TransferReg(opnd0), TransferReg(opnd1));
1247             break;
1248         case x64::MOP_cmovbeq_r_r:
1249             assmbler.Cmovbe(kQ, TransferReg(opnd0), TransferReg(opnd1));
1250             break;
1251         case x64::MOP_cmovbew_m_r:
1252             assmbler.Cmovbe(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1253             break;
1254         case x64::MOP_cmovbel_m_r:
1255             assmbler.Cmovbe(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1256             break;
1257         case x64::MOP_cmovbeq_m_r:
1258             assmbler.Cmovbe(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1259             break;
1260         /* cmove */
1261         case x64::MOP_cmovew_r_r:
1262             assmbler.Cmove(kW, TransferReg(opnd0), TransferReg(opnd1));
1263             break;
1264         case x64::MOP_cmovel_r_r:
1265             assmbler.Cmove(kL, TransferReg(opnd0), TransferReg(opnd1));
1266             break;
1267         case x64::MOP_cmoveq_r_r:
1268             assmbler.Cmove(kQ, TransferReg(opnd0), TransferReg(opnd1));
1269             break;
1270         case x64::MOP_cmovew_m_r:
1271             assmbler.Cmove(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1272             break;
1273         case x64::MOP_cmovel_m_r:
1274             assmbler.Cmove(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1275             break;
1276         case x64::MOP_cmoveq_m_r:
1277             assmbler.Cmove(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1278             break;
1279         /* cmovg & cmovge */
1280         case x64::MOP_cmovgw_r_r:
1281             assmbler.Cmovg(kW, TransferReg(opnd0), TransferReg(opnd1));
1282             break;
1283         case x64::MOP_cmovgl_r_r:
1284             assmbler.Cmovg(kL, TransferReg(opnd0), TransferReg(opnd1));
1285             break;
1286         case x64::MOP_cmovgq_r_r:
1287             assmbler.Cmovg(kQ, TransferReg(opnd0), TransferReg(opnd1));
1288             break;
1289         case x64::MOP_cmovgw_m_r:
1290             assmbler.Cmovg(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1291             break;
1292         case x64::MOP_cmovgl_m_r:
1293             assmbler.Cmovg(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1294             break;
1295         case x64::MOP_cmovgq_m_r:
1296             assmbler.Cmovg(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1297             break;
1298         case x64::MOP_cmovgew_r_r:
1299             assmbler.Cmovge(kW, TransferReg(opnd0), TransferReg(opnd1));
1300             break;
1301         case x64::MOP_cmovgel_r_r:
1302             assmbler.Cmovge(kL, TransferReg(opnd0), TransferReg(opnd1));
1303             break;
1304         case x64::MOP_cmovgeq_r_r:
1305             assmbler.Cmovge(kQ, TransferReg(opnd0), TransferReg(opnd1));
1306             break;
1307         case x64::MOP_cmovgew_m_r:
1308             assmbler.Cmovge(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1309             break;
1310         case x64::MOP_cmovgel_m_r:
1311             assmbler.Cmovge(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1312             break;
1313         case x64::MOP_cmovgeq_m_r:
1314             assmbler.Cmovge(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1315             break;
1316         /* cmovl & cmovle */
1317         case x64::MOP_cmovlw_r_r:
1318             assmbler.Cmovl(kW, TransferReg(opnd0), TransferReg(opnd1));
1319             break;
1320         case x64::MOP_cmovll_r_r:
1321             assmbler.Cmovl(kL, TransferReg(opnd0), TransferReg(opnd1));
1322             break;
1323         case x64::MOP_cmovlq_r_r:
1324             assmbler.Cmovl(kQ, TransferReg(opnd0), TransferReg(opnd1));
1325             break;
1326         case x64::MOP_cmovlw_m_r:
1327             assmbler.Cmovl(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1328             break;
1329         case x64::MOP_cmovll_m_r:
1330             assmbler.Cmovl(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1331             break;
1332         case x64::MOP_cmovlq_m_r:
1333             assmbler.Cmovl(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1334             break;
1335         case x64::MOP_cmovlew_r_r:
1336             assmbler.Cmovle(kW, TransferReg(opnd0), TransferReg(opnd1));
1337             break;
1338         case x64::MOP_cmovlel_r_r:
1339             assmbler.Cmovle(kL, TransferReg(opnd0), TransferReg(opnd1));
1340             break;
1341         case x64::MOP_cmovleq_r_r:
1342             assmbler.Cmovle(kQ, TransferReg(opnd0), TransferReg(opnd1));
1343             break;
1344         case x64::MOP_cmovlew_m_r:
1345             assmbler.Cmovle(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1346             break;
1347         case x64::MOP_cmovlel_m_r:
1348             assmbler.Cmovle(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1349             break;
1350         case x64::MOP_cmovleq_m_r:
1351             assmbler.Cmovle(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1352             break;
1353         /* cmovne */
1354         case x64::MOP_cmovnew_r_r:
1355             assmbler.Cmovne(kW, TransferReg(opnd0), TransferReg(opnd1));
1356             break;
1357         case x64::MOP_cmovnel_r_r:
1358             assmbler.Cmovne(kL, TransferReg(opnd0), TransferReg(opnd1));
1359             break;
1360         case x64::MOP_cmovneq_r_r:
1361             assmbler.Cmovne(kQ, TransferReg(opnd0), TransferReg(opnd1));
1362             break;
1363         case x64::MOP_cmovnew_m_r:
1364             assmbler.Cmovne(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1365             break;
1366         case x64::MOP_cmovnel_m_r:
1367             assmbler.Cmovne(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1368             break;
1369         case x64::MOP_cmovneq_m_r:
1370             assmbler.Cmovne(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1371             break;
1372         case x64::MOP_cmovow_r_r:
1373             assmbler.Cmovo(kW, TransferReg(opnd0), TransferReg(opnd1));
1374             break;
1375         case x64::MOP_cmovol_r_r:
1376             assmbler.Cmovo(kL, TransferReg(opnd0), TransferReg(opnd1));
1377             break;
1378         case x64::MOP_cmovoq_r_r:
1379             assmbler.Cmovo(kQ, TransferReg(opnd0), TransferReg(opnd1));
1380             break;
1381         /* call */
1382         case x64::MOP_callq_r: {
1383             assmbler.Call(kQ, TransferReg(opnd0));
1384             if (insn.GetStackMap() != nullptr) {
1385                 auto referenceMap = insn.GetStackMap()->GetReferenceMap().SerializeInfo();
1386                 auto deoptInfo = insn.GetStackMap()->GetDeoptInfo().SerializeInfo();
1387                 assmbler.RecordStackmap(referenceMap, deoptInfo);
1388             }
1389             break;
1390         }
1391         case x64::MOP_callq_l: {
1392             assmbler.Call(kQ, TransferFuncName(opnd0));
1393             if (insn.GetStackMap() != nullptr) {
1394                 auto referenceMap = insn.GetStackMap()->GetReferenceMap().SerializeInfo();
1395                 auto deoptInfo = insn.GetStackMap()->GetDeoptInfo().SerializeInfo();
1396                 assmbler.RecordStackmap(referenceMap, deoptInfo);
1397             }
1398             break;
1399         }
1400 
1401         case x64::MOP_callq_m: {
1402             assmbler.Call(kQ, TransferMem(opnd0, funcUniqueId));
1403             if (insn.GetStackMap() != nullptr) {
1404                 auto referenceMap = insn.GetStackMap()->GetReferenceMap().SerializeInfo();
1405                 auto deoptInfo = insn.GetStackMap()->GetDeoptInfo().SerializeInfo();
1406                 assmbler.RecordStackmap(referenceMap, deoptInfo);
1407             }
1408             break;
1409         }
1410 
1411         /* ret */
1412         case x64::MOP_retq:
1413             assmbler.Ret();
1414             break;
1415         case x64::MOP_leaveq:
1416             assmbler.Leave();
1417             break;
1418         /* imul */
1419         case x64::MOP_imulw_r_r:
1420             assmbler.Imul(kW, TransferReg(opnd0), TransferReg(opnd1));
1421             break;
1422         case x64::MOP_imull_r_r:
1423             assmbler.Imul(kL, TransferReg(opnd0), TransferReg(opnd1));
1424             break;
1425         case x64::MOP_imulq_r_r:
1426             assmbler.Imul(kQ, TransferReg(opnd0), TransferReg(opnd1));
1427             break;
1428         /* mul float */
1429         case x64::MOP_mulfs_r_r:
1430             assmbler.Mul(TransferReg(opnd0), TransferReg(opnd1));
1431             break;
1432         case x64::MOP_mulfd_r_r:
1433             assmbler.Mul(TransferReg(opnd0), TransferReg(opnd1), false);
1434             break;
1435         /* nop */
1436         case x64::MOP_nop:
1437             assmbler.Nop();
1438             break;
1439         /* byte swap */
1440         case x64::MOP_bswapl_r:
1441             assmbler.Bswap(kL, TransferReg(opnd0));
1442             break;
1443         case x64::MOP_bswapq_r:
1444             assmbler.Bswap(kQ, TransferReg(opnd0));
1445             break;
1446         case x64::MOP_xchgb_r_r:
1447             assmbler.Xchg(kB, TransferReg(opnd0), TransferReg(opnd1));
1448             break;
1449         /* pseudo instruction */
1450         case x64::MOP_pseudo_ret_int:
1451             assmbler.DealWithPseudoInst(curMd.GetName());
1452             break;
1453         /* floating point and */
1454         case x64::MOP_andd_r_r:
1455             assmbler.And(TransferReg(opnd0), TransferReg(opnd1), false);
1456             break;
1457         case x64::MOP_ands_r_r:
1458             assmbler.And(TransferReg(opnd0), TransferReg(opnd1));
1459             break;
1460         /* floating div */
1461         case x64::MOP_divsd_r:
1462             assmbler.Divsd(TransferReg(opnd0), TransferReg(opnd1));
1463             break;
1464         case x64::MOP_divsd_m:
1465             assmbler.Divsd(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1466             break;
1467         /* convert int2float */
1468         case x64::MOP_cvtsi2ssq_r:
1469             assmbler.Cvtsi2ss(kQ, TransferReg(opnd0), TransferReg(opnd1));
1470             break;
1471         case x64::MOP_cvtsi2ssl_r:
1472             assmbler.Cvtsi2ss(kL, TransferReg(opnd0), TransferReg(opnd1));
1473             break;
1474         case x64::MOP_cvtsi2sdq_r:
1475             assmbler.Cvtsi2sd(kQ, TransferReg(opnd0), TransferReg(opnd1));
1476             break;
1477         case x64::MOP_cvtsi2sdl_r:
1478             assmbler.Cvtsi2sd(kL, TransferReg(opnd0), TransferReg(opnd1));
1479             break;
1480         /*convert float2int */
1481         case x64::MOP_cvttsd2siq_r:
1482             assmbler.Cvttsd2si(kQ, TransferReg(opnd0), TransferReg(opnd1));
1483             break;
1484         case x64::MOP_cvttsd2sil_r:
1485             assmbler.Cvttsd2si(kL, TransferReg(opnd0), TransferReg(opnd1));
1486             break;
1487         case x64::MOP_cvttss2siq_r:
1488             assmbler.Cvttss2si(kQ, TransferReg(opnd0), TransferReg(opnd1));
1489             break;
1490         case x64::MOP_cvttss2sil_r:
1491             assmbler.Cvttss2si(kL, TransferReg(opnd0), TransferReg(opnd1));
1492             break;
1493         /* convert float2float */
1494         case x64::MOP_cvtss2sd_r:
1495             assmbler.Cvtss2sd(TransferReg(opnd0), TransferReg(opnd1));
1496             break;
1497         case x64::MOP_cvtsd2ss_r:
1498             assmbler.Cvtsd2ss(TransferReg(opnd0), TransferReg(opnd1));
1499             break;
1500         /* unordered compare */
1501         case x64::MOP_ucomisd_r_r:
1502             assmbler.Ucomisd(TransferReg(opnd0), TransferReg(opnd1));
1503             break;
1504         case x64::MOP_cmpeqsd_r_r:
1505             assmbler.Cmpeqsd(TransferReg(opnd0), TransferReg(opnd1));
1506             break;
1507         case x64::MOP_sqrts_r_r:
1508             assmbler.Sqrtss_r(TransferReg(opnd0), TransferReg(opnd1));
1509             break;
1510         case x64::MOP_sqrtd_r_r:
1511             assmbler.Sqrtsd_r(TransferReg(opnd0), TransferReg(opnd1));
1512             break;
1513         default: {
1514             insn.Dump();
1515             LogInfo::MapleLogger() << "\n";
1516             FATAL(kLncFatal, "unsupported instruction");
1517             break;
1518         }
1519     }
1520 }
1521 
EmitFunctionHeader(CGFunc & cgFunc)1522 void X64Emitter::EmitFunctionHeader(CGFunc &cgFunc)
1523 {
1524     const MIRSymbol *funcSymbol = cgFunc.GetFunction().GetFuncSymbol();
1525     uint32 symIdx = funcSymbol->GetNameStrIdx().get();
1526     const string &symName = funcSymbol->GetName();
1527     assmbler.StoreNameIntoSymMap(symIdx, symName);
1528 
1529     SymbolAttr funcAttr = kSAGlobal;
1530     if (funcSymbol->GetFunction()->GetAttr(FUNCATTR_weak)) {
1531         funcAttr = kSAWeak;
1532     } else if (funcSymbol->GetFunction()->GetAttr(FUNCATTR_local)) {
1533         funcAttr = kSALocal;
1534     } else if (!cgFunc.GetCG()->GetMIRModule()->IsCModule()) {
1535         funcAttr = kSAHidden;
1536     }
1537     if (cgFunc.GetFunction().GetAttr(FUNCATTR_section)) {
1538         const string &sectionName = cgFunc.GetFunction().GetAttrs().GetPrefixSectionName();
1539         assmbler.EmitFunctionHeader(symIdx, funcAttr, &sectionName);
1540     } else {
1541         assmbler.EmitFunctionHeader(symIdx, funcAttr, nullptr);
1542     }
1543 }
1544 
EmitBBHeaderLabel(CGFunc & cgFunc,LabelIdx labIdx,uint32 freq)1545 void X64Emitter::EmitBBHeaderLabel(CGFunc &cgFunc, LabelIdx labIdx, uint32 freq)
1546 {
1547     uint32 funcUniqueId = cgFunc.GetUniqueID();
1548     /* Concatenate BB Label Name and its idx */
1549     string bbLabel = ".L.";
1550     bbLabel.append(to_string(funcUniqueId));
1551     bbLabel.append("__");
1552     bbLabel.append(to_string(labIdx));
1553     int64 labelSymIdx = CalculateLabelSymIdx(funcUniqueId, static_cast<int64>(labIdx));
1554     assmbler.StoreNameIntoSymMap(labelSymIdx, bbLabel);
1555 
1556     if (cgFunc.GetCG()->GenerateVerboseCG()) {
1557         const string &labelName = cgFunc.GetFunction().GetLabelTab()->GetName(labIdx);
1558         /* If label name has @ as its first char, it is not from MIR */
1559         if (!labelName.empty() && labelName.at(0) != '@') {
1560             assmbler.EmitBBLabel(labelSymIdx, true, freq, &labelName);
1561         } else {
1562             assmbler.EmitBBLabel(labelSymIdx, true, freq);
1563         }
1564     } else {
1565         assmbler.EmitBBLabel(labelSymIdx);
1566     }
1567 }
1568 
1569 /* Specially, emit switch table here */
EmitJmpTable(const CGFunc & cgFunc)1570 void X64Emitter::EmitJmpTable(const CGFunc &cgFunc)
1571 {
1572     for (auto &it : cgFunc.GetEmitStVec()) {
1573         MIRSymbol *st = it.second;
1574         DEBUG_ASSERT(st->IsReadOnly(), "NYI");
1575         uint32 symIdx = st->GetNameStrIdx().get();
1576         const string &symName = st->GetName();
1577         assmbler.StoreNameIntoSymMap(symIdx, symName);
1578 
1579         MIRAggConst *arrayConst = safe_cast<MIRAggConst>(st->GetKonst());
1580         CHECK_NULL_FATAL(arrayConst);
1581         uint32 funcUniqueId = cgFunc.GetUniqueID();
1582         vector<int64> labelSymIdxs;
1583         for (size_t i = 0; i < arrayConst->GetConstVec().size(); i++) {
1584             MIRLblConst *lblConst = safe_cast<MIRLblConst>(arrayConst->GetConstVecItem(i));
1585             CHECK_NULL_FATAL(lblConst);
1586             uint32 labelIdx = lblConst->GetValue();
1587             string labelName = ".L." + to_string(funcUniqueId) + "__" + to_string(labelIdx);
1588             int64 labelSymIdx = CalculateLabelSymIdx(funcUniqueId, labelIdx);
1589             assmbler.StoreNameIntoSymMap(labelSymIdx, labelName);
1590             labelSymIdxs.push_back(labelSymIdx);
1591         }
1592         assmbler.EmitJmpTableElem(symIdx, labelSymIdxs);
1593     }
1594 }
1595 
EmitFunctionFoot(CGFunc & cgFunc)1596 void X64Emitter::EmitFunctionFoot(CGFunc &cgFunc)
1597 {
1598     const MIRSymbol *funcSymbol = cgFunc.GetFunction().GetFuncSymbol();
1599     uint32 symIdx = funcSymbol->GetNameStrIdx().get();
1600     SymbolAttr funcAttr = kSALocal;
1601     if (funcSymbol->GetFunction()->GetAttr(FUNCATTR_weak)) {
1602         funcAttr = kSAWeak;
1603     } else if (funcSymbol->GetFunction()->GetAttr(FUNCATTR_local)) {
1604         funcAttr = kSALocal;
1605     } else if (!funcSymbol->GetFunction()->GetAttr(FUNCATTR_static)) {
1606         funcAttr = kSAGlobal;
1607     }
1608     assmbler.EmitFunctionFoot(symIdx, funcAttr);
1609 }
1610 
EmitStructure(MIRConst & mirConst,CG & cg,bool belongsToDataSec)1611 uint64 X64Emitter::EmitStructure(MIRConst &mirConst, CG &cg, bool belongsToDataSec)
1612 {
1613     uint32 subStructFieldCounts = 0;
1614     uint64 valueSize = EmitStructure(mirConst, cg, subStructFieldCounts, belongsToDataSec);
1615     return valueSize;
1616 }
1617 
EmitStructure(MIRConst & mirConst,CG & cg,uint32 & subStructFieldCounts,bool belongsToDataSec)1618 uint64 X64Emitter::EmitStructure(MIRConst &mirConst, CG &cg, uint32 &subStructFieldCounts, bool belongsToDataSec)
1619 {
1620     StructEmitInfo *sEmitInfo = cg.GetMIRModule()->GetMemPool()->New<StructEmitInfo>();
1621     CHECK_NULL_FATAL(sEmitInfo);
1622     MIRType &mirType = mirConst.GetType();
1623     MIRAggConst &structCt = static_cast<MIRAggConst &>(mirConst);
1624     MIRStructType &structType = static_cast<MIRStructType &>(mirType);
1625     uint8 structPack = static_cast<uint8>(structType.GetTypeAttrs().GetPack());
1626     uint64 valueSize = 0;
1627     MIRTypeKind structKind = structType.GetKind();
1628     /* all elements of struct. */
1629     uint8 num = structKind == kTypeUnion ? 1 : static_cast<uint8>(structType.GetFieldsSize());
1630     BECommon *beCommon = Globals::GetInstance()->GetBECommon();
1631     /* total size of emitted elements size. */
1632     uint64 sizeInByte = GetSymbolSize(structType.GetTypeIndex());
1633     uint32 fieldIdx = structKind == kTypeUnion ? structCt.GetFieldIdItem(0) : 1;
1634     for (uint32 i = 0; i < num; ++i) {
1635         MIRConst *elemConst =
1636             structKind == kTypeStruct ? structCt.GetAggConstElement(i + 1) : structCt.GetAggConstElement(fieldIdx);
1637         MIRType *elemType = structKind == kTypeUnion ? &(elemConst->GetType()) : structType.GetElemType(i);
1638         MIRType *nextElemType = i != static_cast<uint32>(num - 1) ? structType.GetElemType(i + 1) : nullptr;
1639         uint64 elemSize = GetSymbolSize(elemType->GetTypeIndex());
1640         uint8 charBitWidth = GetPrimTypeSize(PTY_i8) * k8Bits;
1641         MIRTypeKind elemKind = elemType->GetKind();
1642         if (elemKind == kTypeBitField) {
1643             if (elemConst == nullptr) {
1644                 MIRIntConst *zeroFill = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, *elemType);
1645                 elemConst = zeroFill;
1646             }
1647             pair<int32, int32> fieldOffsetPair = beCommon->GetFieldOffset(structType, fieldIdx);
1648             uint64 fieldOffset =
1649                 static_cast<uint64>(static_cast<int64>(fieldOffsetPair.first)) * static_cast<uint64>(charBitWidth) +
1650                 static_cast<uint64>(static_cast<int64>(fieldOffsetPair.second));
1651             EmitBitField(*sEmitInfo, *elemConst, nextElemType, fieldOffset);
1652         } else {
1653             if (elemConst != nullptr) {
1654                 if (IsPrimitiveVector(elemType->GetPrimType())) {
1655                     valueSize += EmitVector(*elemConst);
1656                 } else if (IsPrimitiveScalar(elemType->GetPrimType())) {
1657                     valueSize += EmitSingleElement(*elemConst, belongsToDataSec, true);
1658                 } else if (elemKind == kTypeArray) {
1659                     if (elemType->GetSize() != 0) {
1660                         valueSize += EmitArray(*elemConst, cg, belongsToDataSec);
1661                     }
1662                 } else if (elemKind == kTypeStruct || elemKind == kTypeClass || elemKind == kTypeUnion) {
1663                     valueSize += EmitStructure(*elemConst, cg, subStructFieldCounts, belongsToDataSec);
1664                     fieldIdx += subStructFieldCounts;
1665                 } else {
1666                     DEBUG_ASSERT(false, "should not run here");
1667                 }
1668             } else {
1669                 assmbler.EmitNull(elemSize);
1670             }
1671             sEmitInfo->IncreaseTotalSize(elemSize);
1672             sEmitInfo->SetNextFieldOffset(sEmitInfo->GetTotalSize() * charBitWidth);
1673         }
1674 
1675         if (nextElemType != nullptr && nextElemType->GetKind() != kTypeBitField) {
1676             DEBUG_ASSERT(i < static_cast<uint32>(num - 1), "NYI");
1677             uint8 nextAlign = Globals::GetInstance()->GetBECommon()->GetTypeAlign(nextElemType->GetTypeIndex());
1678             auto fieldAttr = structType.GetFields()[i + 1].second.second;
1679             nextAlign = fieldAttr.IsPacked() ? 1 : min(nextAlign, structPack);
1680             DEBUG_ASSERT(nextAlign != 0, "expect non-zero");
1681             /* append size, append 0 when align need. */
1682             uint64 totalSize = sEmitInfo->GetTotalSize();
1683             uint64 psize = (totalSize % nextAlign == 0) ? 0 : (nextAlign - (totalSize % nextAlign));
1684             /* element is uninitialized, emit null constant. */
1685             if (psize != 0) {
1686                 assmbler.EmitNull(psize);
1687                 sEmitInfo->IncreaseTotalSize(psize);
1688                 sEmitInfo->SetNextFieldOffset(sEmitInfo->GetTotalSize() * charBitWidth);
1689             }
1690         }
1691         fieldIdx++;
1692     }
1693     if (structType.GetKind() == kTypeStruct) {
1694         /* The reason of subtracting one is that fieldIdx adds one at the end of the cycle. */
1695         subStructFieldCounts = fieldIdx - 1;
1696     } else if (structType.GetKind() == kTypeUnion) {
1697         subStructFieldCounts = static_cast<uint32>(beCommon->GetStructFieldCount(structType.GetTypeIndex()));
1698     }
1699 
1700     uint64 opSize = sizeInByte - sEmitInfo->GetTotalSize();
1701     if (opSize != 0) {
1702         assmbler.EmitNull(opSize);
1703     }
1704     return valueSize;
1705 }
1706 
EmitVector(MIRConst & mirConst,bool belongsToDataSec)1707 uint64 X64Emitter::EmitVector(MIRConst &mirConst, bool belongsToDataSec)
1708 {
1709     MIRType &mirType = mirConst.GetType();
1710     MIRAggConst &vecCt = static_cast<MIRAggConst &>(mirConst);
1711     size_t uNum = vecCt.GetConstVec().size();
1712     uint64 valueSize = 0;
1713     for (size_t i = 0; i < uNum; ++i) {
1714         MIRConst *elemConst = vecCt.GetConstVecItem(i);
1715         if (IsPrimitiveScalar(elemConst->GetType().GetPrimType())) {
1716             uint64 elemSize = EmitSingleElement(*elemConst, belongsToDataSec);
1717             valueSize += elemSize;
1718         } else {
1719             DEBUG_ASSERT(false, "EmitVector: should not run here");
1720         }
1721     }
1722     size_t lanes = GetVecLanes(mirType.GetPrimType());
1723     if (lanes > uNum) {
1724         MIRIntConst zConst(0, vecCt.GetConstVecItem(0)->GetType());
1725         for (size_t i = uNum; i < lanes; i++) {
1726             uint64 elemSize = EmitSingleElement(zConst, belongsToDataSec);
1727             valueSize += elemSize;
1728         }
1729     }
1730     return valueSize;
1731 }
1732 
EmitArray(MIRConst & mirConst,CG & cg,bool belongsToDataSec)1733 uint64 X64Emitter::EmitArray(MIRConst &mirConst, CG &cg, bool belongsToDataSec)
1734 {
1735     MIRType &mirType = mirConst.GetType();
1736     MIRAggConst &arrayCt = static_cast<MIRAggConst &>(mirConst);
1737     MIRArrayType &arrayType = static_cast<MIRArrayType &>(mirType);
1738     size_t uNum = arrayCt.GetConstVec().size();
1739     uint32 dim = arrayType.GetSizeArrayItem(0);
1740     TyIdx elmTyIdx = arrayType.GetElemTyIdx();
1741     MIRType *subTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(elmTyIdx);
1742     uint64 valueSize = 0;
1743     if (uNum == 0 && dim) {
1744         while (subTy->GetKind() == kTypeArray) {
1745             MIRArrayType *aSubTy = static_cast<MIRArrayType *>(subTy);
1746             if (aSubTy->GetSizeArrayItem(0) > 0) {
1747                 dim *= (aSubTy->GetSizeArrayItem(0));
1748             }
1749             elmTyIdx = aSubTy->GetElemTyIdx();
1750             subTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(elmTyIdx);
1751         }
1752     }
1753     for (size_t i = 0; i < uNum; ++i) {
1754         MIRConst *elemConst = arrayCt.GetConstVecItem(i);
1755         if (IsPrimitiveVector(subTy->GetPrimType())) {
1756             valueSize += EmitVector(*elemConst, belongsToDataSec);
1757         } else if (IsPrimitiveScalar(elemConst->GetType().GetPrimType())) {
1758             if (cg.GetMIRModule()->IsCModule()) {
1759                 bool strLiteral = false;
1760                 if (arrayType.GetDim() == 1) {
1761                     MIRType *ety = arrayType.GetElemType();
1762                     if (ety->GetPrimType() == PTY_i8 || ety->GetPrimType() == PTY_u8) {
1763                         strLiteral = true;
1764                     }
1765                 }
1766                 valueSize += EmitSingleElement(*elemConst, belongsToDataSec, !strLiteral);
1767             } else {
1768                 valueSize += EmitSingleElement(*elemConst, belongsToDataSec);
1769             }
1770         } else if (elemConst->GetType().GetKind() == kTypeArray) {
1771             valueSize += EmitArray(*elemConst, cg, belongsToDataSec);
1772         } else if (elemConst->GetType().GetKind() == kTypeStruct || elemConst->GetType().GetKind() == kTypeClass ||
1773                    elemConst->GetType().GetKind() == kTypeUnion) {
1774             valueSize += EmitStructure(*elemConst, cg);
1775         } else if (elemConst->GetKind() == kConstAddrofFunc) {
1776             valueSize += EmitSingleElement(*elemConst, belongsToDataSec);
1777         } else {
1778             DEBUG_ASSERT(false, "should not run here");
1779         }
1780     }
1781     int64 iNum = (arrayType.GetSizeArrayItem(0) > 0) ? (static_cast<int64>(arrayType.GetSizeArrayItem(0))) - uNum : 0;
1782     if (iNum > 0) {
1783         if (uNum > 0) {
1784             uint64 unInSizeInByte =
1785                 static_cast<uint64>(iNum) *
1786                 static_cast<uint64>(GetSymbolSize(arrayCt.GetConstVecItem(0)->GetType().GetTypeIndex()));
1787             if (unInSizeInByte != 0) {
1788                 assmbler.EmitNull(unInSizeInByte);
1789             }
1790         } else {
1791             uint64 sizeInByte = GetSymbolSize(elmTyIdx) * dim;
1792             assmbler.EmitNull(sizeInByte);
1793         }
1794     }
1795     return valueSize;
1796 }
1797 
EmitAddrofElement(MIRConst & mirConst,bool belongsToDataSec)1798 void X64Emitter::EmitAddrofElement(MIRConst &mirConst, bool belongsToDataSec)
1799 {
1800     MIRAddrofConst &symAddr = static_cast<MIRAddrofConst &>(mirConst);
1801     StIdx stIdx = symAddr.GetSymbolIndex();
1802     MIRSymbol *symAddrSym =
1803         stIdx.IsGlobal()
1804             ? GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx())
1805             : CG::GetCurCGFunc()->GetMirModule().CurFunction()->GetSymTab()->GetSymbolFromStIdx(stIdx.Idx());
1806     string addrName = symAddrSym->GetName();
1807     if (!stIdx.IsGlobal() && symAddrSym->GetStorageClass() == kScPstatic) {
1808         uint32 funcUniqueId = CG::GetCurCGFunc()->GetUniqueID();
1809         addrName += to_string(funcUniqueId);
1810     }
1811     uint32 symIdx = symAddrSym->GetNameStrIdx();
1812     int32 symAddrOfs = 0;
1813     int32 structFieldOfs = 0;
1814     if (symAddr.GetOffset() != 0) {
1815         symAddrOfs = symAddr.GetOffset();
1816     }
1817     if (symAddr.GetFieldID() > 1) {
1818         MIRStructType *structType = static_cast<MIRStructType *>(symAddrSym->GetType());
1819         DEBUG_ASSERT(structType != nullptr, "EmitScalarConstant: non-zero fieldID for non-structure");
1820         structFieldOfs = Globals::GetInstance()->GetBECommon()->GetFieldOffset(*structType, symAddr.GetFieldID()).first;
1821     }
1822     assmbler.StoreNameIntoSymMap(symIdx, addrName);
1823     assmbler.EmitAddrValue(symIdx, symAddrOfs, structFieldOfs, belongsToDataSec);
1824 }
1825 
EmitSingleElement(MIRConst & mirConst,bool belongsToDataSec,bool isIndirect)1826 uint32 X64Emitter::EmitSingleElement(MIRConst &mirConst, bool belongsToDataSec, bool isIndirect)
1827 {
1828     MIRType &elmType = mirConst.GetType();
1829     uint64 elemSize = elmType.GetSize();
1830     MIRConstKind kind = mirConst.GetKind();
1831     switch (kind) {
1832         case kConstAddrof:
1833             EmitAddrofElement(mirConst, belongsToDataSec);
1834             break;
1835         case kConstAddrofFunc: {
1836             MIRAddroffuncConst &funcAddr = static_cast<MIRAddroffuncConst &>(mirConst);
1837             MIRFunction *func = GlobalTables::GetFunctionTable().GetFuncTable().at(funcAddr.GetValue());
1838             MIRSymbol *symAddrSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx());
1839 
1840             uint32 symIdx = symAddrSym->GetNameStrIdx();
1841             const string &name = symAddrSym->GetName();
1842             assmbler.StoreNameIntoSymMap(symIdx, name);
1843             assmbler.EmitAddrOfFuncValue(symIdx, belongsToDataSec);
1844             break;
1845         }
1846         case kConstInt: {
1847             MIRIntConst &intCt = static_cast<MIRIntConst &>(mirConst);
1848             uint32 sizeInBits = elemSize << kLeftShift3Bits;
1849             if (intCt.GetActualBitWidth() > sizeInBits) {
1850                 DEBUG_ASSERT(false, "actual value is larger than expected");
1851             }
1852             int64 value = intCt.GetExtValue();
1853             assmbler.EmitIntValue(value, elemSize, belongsToDataSec);
1854             break;
1855         }
1856         case kConstLblConst: {
1857             MIRLblConst &lbl = static_cast<MIRLblConst &>(mirConst);
1858             uint32 labelIdx = lbl.GetValue();
1859             uint32 funcUniqueId = lbl.GetPUIdx();
1860             string labelName = ".L." + to_string(funcUniqueId) + "__" + to_string(labelIdx);
1861             int64 symIdx = CalculateLabelSymIdx(funcUniqueId, labelIdx);
1862             assmbler.StoreNameIntoSymMap(symIdx, labelName);
1863             assmbler.EmitLabelValue(symIdx, belongsToDataSec);
1864             break;
1865         }
1866         case kConstStrConst: {
1867             MIRStrConst &strCt = static_cast<MIRStrConst &>(mirConst);
1868             if (isIndirect) {
1869                 uint32 strIdx = strCt.GetValue().GetIdx();
1870                 string strName = ".LSTR__" + to_string(strIdx);
1871                 int64 strSymIdx = CalculateStrLabelSymIdx(GlobalTables::GetGsymTable().GetSymbolTableSize(), strIdx);
1872                 stringPtr.push_back(strIdx);
1873                 assmbler.StoreNameIntoSymMap(strSymIdx, strName);
1874                 assmbler.EmitIndirectString(strSymIdx, belongsToDataSec);
1875             } else {
1876                 const string &ustr = GlobalTables::GetUStrTable().GetStringFromStrIdx(strCt.GetValue());
1877                 assmbler.EmitDirectString(ustr, belongsToDataSec);
1878             }
1879             break;
1880         }
1881         default:
1882             FATAL(kLncFatal, "EmitSingleElement: unsupport variable kind");
1883             break;
1884     }
1885     return elemSize;
1886 }
1887 
EmitBitField(StructEmitInfo & structEmitInfo,MIRConst & mirConst,const MIRType * nextType,uint64 fieldOffset,bool belongsToDataSec)1888 void X64Emitter::EmitBitField(StructEmitInfo &structEmitInfo, MIRConst &mirConst, const MIRType *nextType,
1889                               uint64 fieldOffset, bool belongsToDataSec)
1890 {
1891     MIRType &mirType = mirConst.GetType();
1892     if (fieldOffset > structEmitInfo.GetNextFieldOffset()) {
1893         uint16 curFieldOffset = structEmitInfo.GetNextFieldOffset() - structEmitInfo.GetCombineBitFieldWidth();
1894         structEmitInfo.SetCombineBitFieldWidth(fieldOffset - curFieldOffset);
1895         EmitCombineBfldValue(structEmitInfo);
1896         DEBUG_ASSERT(structEmitInfo.GetNextFieldOffset() <= fieldOffset,
1897                      "structEmitInfo's nextFieldOffset > fieldOffset");
1898         structEmitInfo.SetNextFieldOffset(fieldOffset);
1899     }
1900     uint32 fieldSize = static_cast<MIRBitFieldType &>(mirType).GetFieldSize();
1901     MIRIntConst &fieldValue = static_cast<MIRIntConst &>(mirConst);
1902     /* Truncate the size of FieldValue to the bit field size. */
1903     if (fieldSize < fieldValue.GetActualBitWidth()) {
1904         fieldValue.Trunc(fieldSize);
1905     }
1906     /* Clear higher Bits for signed value  */
1907     if (structEmitInfo.GetCombineBitFieldValue() != 0) {
1908         structEmitInfo.SetCombineBitFieldValue((~(~0ULL << structEmitInfo.GetCombineBitFieldWidth())) &
1909                                                structEmitInfo.GetCombineBitFieldValue());
1910     }
1911     if (CGOptions::IsBigEndian()) {
1912         uint64 beValue = static_cast<uint64>(fieldValue.GetExtValue());
1913         if (fieldValue.IsNegative()) {
1914             beValue = beValue - ((beValue >> fieldSize) << fieldSize);
1915         }
1916         structEmitInfo.SetCombineBitFieldValue((structEmitInfo.GetCombineBitFieldValue() << fieldSize) + beValue);
1917     } else {
1918         structEmitInfo.SetCombineBitFieldValue(
1919             (static_cast<uint64>(fieldValue.GetExtValue()) << structEmitInfo.GetCombineBitFieldWidth()) +
1920             structEmitInfo.GetCombineBitFieldValue());
1921     }
1922     structEmitInfo.IncreaseCombineBitFieldWidth(fieldSize);
1923     structEmitInfo.IncreaseNextFieldOffset(fieldSize);
1924     if ((nextType == nullptr) || (nextType->GetKind() != kTypeBitField)) {
1925         /* emit structEmitInfo->combineBitFieldValue */
1926         EmitCombineBfldValue(structEmitInfo);
1927     }
1928 }
1929 
EmitCombineBfldValue(StructEmitInfo & structEmitInfo,bool belongsToDataSec)1930 void X64Emitter::EmitCombineBfldValue(StructEmitInfo &structEmitInfo, bool belongsToDataSec)
1931 {
1932     uint8 charBitWidth = GetPrimTypeSize(PTY_i8) * k8Bits;
1933     const uint64 kGetLow8Bits = 0x00000000000000ffUL;
1934     auto emitBfldValue = [&structEmitInfo, charBitWidth, belongsToDataSec, this](bool flag) {
1935         while (structEmitInfo.GetCombineBitFieldWidth() > charBitWidth) {
1936             uint8 shift = flag ? (structEmitInfo.GetCombineBitFieldWidth() - charBitWidth) : 0U;
1937             uint64 tmp = (structEmitInfo.GetCombineBitFieldValue() >> shift) & kGetLow8Bits;
1938             assmbler.EmitBitFieldValue(tmp, belongsToDataSec);
1939             structEmitInfo.DecreaseCombineBitFieldWidth(charBitWidth);
1940             uint64 value =
1941                 flag ? structEmitInfo.GetCombineBitFieldValue() - (tmp << structEmitInfo.GetCombineBitFieldWidth())
1942                      : structEmitInfo.GetCombineBitFieldValue() >> charBitWidth;
1943             structEmitInfo.SetCombineBitFieldValue(value);
1944         }
1945     };
1946     if (CGOptions::IsBigEndian()) {
1947         /*
1948          * If the total number of bits in the bit field is not a multiple of 8,
1949          * the bits must be aligned to 8 bits to prevent errors in the emit.
1950          */
1951         auto width = static_cast<uint8>(RoundUp(structEmitInfo.GetCombineBitFieldWidth(), charBitWidth));
1952         if (structEmitInfo.GetCombineBitFieldWidth() < width) {
1953             structEmitInfo.SetCombineBitFieldValue(structEmitInfo.GetCombineBitFieldValue()
1954                                                    << (width - structEmitInfo.GetCombineBitFieldWidth()));
1955             structEmitInfo.IncreaseCombineBitFieldWidth(
1956                 static_cast<uint8>(width - structEmitInfo.GetCombineBitFieldWidth()));
1957         }
1958         emitBfldValue(true);
1959     } else {
1960         emitBfldValue(false);
1961     }
1962     if (structEmitInfo.GetCombineBitFieldWidth() != 0) {
1963         uint64 value = structEmitInfo.GetCombineBitFieldValue() & kGetLow8Bits;
1964         assmbler.EmitBitFieldValue(value, belongsToDataSec);
1965     }
1966     CHECK_FATAL(charBitWidth != 0, "divide by zero");
1967     if ((structEmitInfo.GetNextFieldOffset() % charBitWidth) != 0) {
1968         uint8 value = charBitWidth - static_cast<uint8>((structEmitInfo.GetNextFieldOffset() % charBitWidth));
1969         structEmitInfo.IncreaseNextFieldOffset(value);
1970     }
1971     structEmitInfo.SetTotalSize(structEmitInfo.GetNextFieldOffset() / charBitWidth);
1972     structEmitInfo.SetCombineBitFieldValue(0);
1973     structEmitInfo.SetCombineBitFieldWidth(0);
1974 }
1975 
EmitLocalVariable(CGFunc & cgFunc)1976 void X64Emitter::EmitLocalVariable(CGFunc &cgFunc)
1977 {
1978     /* function local pstatic initialization */
1979     MIRSymbolTable *lSymTab = cgFunc.GetFunction().GetSymTab();
1980     if (lSymTab != nullptr) {
1981         uint32 funcUniqueId = cgFunc.GetUniqueID();
1982         size_t lsize = lSymTab->GetSymbolTableSize();
1983         vector<string> emittedLocalSym;
1984         for (uint32 i = 0; i < lsize; i++) {
1985             MIRSymbol *symbol = lSymTab->GetSymbolFromStIdx(i);
1986             if (symbol != nullptr && symbol->GetStorageClass() == kScPstatic) {
1987                 const string &symbolName = symbol->GetName() + to_string(funcUniqueId);
1988                 /* Local static names can repeat, if repeat, pass */
1989                 bool found = false;
1990                 for (auto name : emittedLocalSym) {
1991                     if (name == symbolName) {
1992                         found = true;
1993                         break;
1994                     }
1995                 }
1996                 if (found) {
1997                     continue;
1998                 }
1999                 emittedLocalSym.push_back(symbolName);
2000 
2001                 uint32 symIdx = symbol->GetNameStrIdx().get();
2002                 assmbler.StoreNameIntoSymMap(symIdx, symbolName, true);
2003 
2004                 MIRConst *ct = symbol->GetKonst();
2005                 MIRType *ty = symbol->GetType();
2006                 uint64 sizeInByte = GetSymbolSize(ty->GetTypeIndex());
2007                 uint8 alignInByte = GetSymbolAlign(*symbol);
2008                 if (ct == nullptr) {
2009                     alignInByte = GetSymbolAlign(*symbol, true);
2010                     assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSALocal, kSBss);
2011                 } else {
2012                     MIRTypeKind kind = ty->GetKind();
2013                     uint64 valueSize = 0;
2014                     bool isFloatTy =
2015                         (ct->GetKind() == maple::kConstDoubleConst || ct->GetKind() == maple::kConstFloatConst);
2016                     auto secType = isFloatTy ? kSText : kSData;
2017                     assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSALocal, secType);
2018                     if (kind == kTypeStruct || kind == kTypeUnion || kind == kTypeClass) {
2019                         valueSize = EmitStructure(*ct, *cgFunc.GetCG());
2020                     } else if (IsPrimitiveVector(ty->GetPrimType())) {
2021                         valueSize = EmitVector(*ct);
2022                     } else if (kind == kTypeArray) {
2023                         valueSize = EmitArray(*ct, *cgFunc.GetCG());
2024                     } else if (isFloatTy) {
2025                         MIRType &elmType = ct->GetType();
2026                         uint64 elemSize = elmType.GetSize();
2027                         if (ct->GetKind() == maple::kConstDoubleConst) {
2028                             MIRDoubleConst &dCt = static_cast<MIRDoubleConst&>(*ct);
2029                             int64 value = dCt.GetIntValue();
2030                             assmbler.EmitFloatValue(symIdx, value, elemSize);
2031                         } else {
2032                             MIRFloatConst &fCt = static_cast<MIRFloatConst&>(*ct);
2033                             int64 value = fCt.GetIntValue();
2034                             assmbler.EmitFloatValue(symIdx, value, elemSize);
2035                         }
2036                     } else {
2037                         valueSize = EmitSingleElement(*ct, true);
2038                     }
2039                     assmbler.PostEmitVariable(symIdx, kSALocal, valueSize, isFloatTy);
2040                 }
2041             }
2042         }
2043     }
2044 }
2045 
EmitStringPointers()2046 void X64Emitter::EmitStringPointers()
2047 {
2048     for (uint32 strIdx : stringPtr) {
2049         string ustr = GlobalTables::GetUStrTable().GetStringFromStrIdx(strIdx);
2050         int64 strSymIdx = CalculateStrLabelSymIdx(GlobalTables::GetGsymTable().GetSymbolTableSize(), strIdx);
2051         assmbler.EmitDirectString(ustr, true, strSymIdx);
2052     }
2053 }
2054 
EmitGlobalVariable(CG & cg)2055 void X64Emitter::EmitGlobalVariable(CG &cg)
2056 {
2057     uint64 size = GlobalTables::GetGsymTable().GetSymbolTableSize();
2058     for (uint64 i = 0; i < size; ++i) {
2059         MIRSymbol *mirSymbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(i);
2060 
2061         if (mirSymbol == nullptr || mirSymbol->IsDeleted() || mirSymbol->GetStorageClass() == kScUnused) {
2062             continue;
2063         }
2064 
2065         MIRStorageClass storageClass = mirSymbol->GetStorageClass();
2066         /* symbols we do not emit here. */
2067         if (storageClass == kScTypeInfo || storageClass == kScTypeInfoName || storageClass == kScTypeCxxAbi) {
2068             continue;
2069         }
2070 
2071         MIRType *mirType = mirSymbol->GetType();
2072         if (mirType == nullptr) {
2073             continue;
2074         }
2075         int64 symIdx = mirSymbol->GetNameStrIdx().get();
2076         uint64 sizeInByte = GetSymbolSize(mirType->GetTypeIndex());
2077         uint8 alignInByte = GetSymbolAlign(*mirSymbol);
2078 
2079         /* Uninitialized global/static variables */
2080         if ((storageClass == kScGlobal || storageClass == kScFstatic) && !mirSymbol->IsConst()) {
2081             if (mirSymbol->IsGctibSym()) {
2082                 continue;
2083             }
2084             assmbler.StoreNameIntoSymMap(symIdx, mirSymbol->GetName());
2085             SectionKind secKind;
2086             if (mirSymbol->IsThreadLocal()) {
2087                 secKind = kSTbss;
2088             } else if (maplebe::CGOptions::IsNoCommon()) {
2089                 secKind = kSBss;
2090             } else {
2091                 secKind = kSComm;
2092                 alignInByte = GetSymbolAlign(*mirSymbol, true);
2093             }
2094             assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, secKind);
2095             continue;
2096         }
2097         MIRTypeKind kind = mirType->GetKind();
2098         /* Initialized global/static variables. */
2099         if (storageClass == kScGlobal || (storageClass == kScFstatic && !mirSymbol->IsReadOnly())) {
2100             MIRConst *mirConst = mirSymbol->GetKonst();
2101             uint64 valueSize = 0;
2102             assmbler.StoreNameIntoSymMap(symIdx, mirSymbol->GetName());
2103             if (mirSymbol->IsThreadLocal()) {
2104                 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, kSTdata);
2105             } else {
2106                 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, kSData);
2107             }
2108             if (IsPrimitiveVector(mirType->GetPrimType())) {
2109                 valueSize = EmitVector(*mirConst);
2110             } else if (IsPrimitiveScalar(mirType->GetPrimType())) {
2111                 valueSize = EmitSingleElement(*mirConst, true, cg.GetMIRModule()->IsCModule());
2112             } else if (kind == kTypeArray) {
2113                 CHECK_FATAL(!mirSymbol->HasAddrOfValues(), "EmitGlobalVariable: need EmitConstantTable");
2114                 valueSize = EmitArray(*mirConst, cg);
2115             } else if (kind == kTypeStruct || kind == kTypeClass || kind == kTypeUnion) {
2116                 CHECK_FATAL(!mirSymbol->HasAddrOfValues(), "EmitGlobalVariable: need EmitConstantTable");
2117                 EmitStructure(*mirConst, cg);
2118             } else {
2119                 DEBUG_ASSERT(false, "EmitGlobalVariable: Unknown mirKind");
2120             }
2121             assmbler.PostEmitVariable(symIdx, kSAGlobal, valueSize);
2122         } else if (mirSymbol->IsReadOnly()) { /* If symbol is const & static */
2123             MIRConst *mirConst = mirSymbol->GetKonst();
2124             assmbler.StoreNameIntoSymMap(symIdx, mirSymbol->GetName());
2125             if (mirConst == nullptr) {
2126                 alignInByte = GetSymbolAlign(*mirSymbol, true);
2127                 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, kSComm);
2128             } else {
2129                 SymbolAttr symAttr = kSAGlobal;
2130                 if (mirSymbol->IsWeak()) {
2131                     symAttr = kSAWeak;
2132                 } else if (storageClass == kScPstatic ||
2133                            (storageClass == kScFstatic && mirSymbol->sectionAttr == UStrIdx(0))) {
2134                     symAttr = kSAStatic;
2135                 }
2136                 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, symAttr, kSRodata);
2137                 if (IsPrimitiveVector(mirType->GetPrimType())) {
2138                     (void)EmitVector(*mirConst, false);
2139                 } else if (IsPrimitiveScalar(mirType->GetPrimType())) {
2140                     if (storageClass == kScPstatic) {
2141                         (void)EmitSingleElement(*mirConst, false, true);
2142                     } else {
2143                         (void)EmitSingleElement(*mirConst, false);
2144                     }
2145                 } else if (kind == kTypeArray) {
2146                     (void)EmitArray(*mirConst, cg, false);
2147                 } else if (kind == kTypeStruct || kind == kTypeUnion || kind == kTypeClass) {
2148                     (void)EmitStructure(*mirConst, cg);
2149                 } else {
2150                     FATAL(kLncFatal, "Unknown type in Global pstatic");
2151                 }
2152             }
2153         }
2154     } /* end proccess all mirSymbols. */
2155     EmitStringPointers();
2156 }
2157 
Run(CGFunc & cgFunc)2158 void X64Emitter::Run(CGFunc &cgFunc)
2159 {
2160     X64CGFunc &x64CGFunc = static_cast<X64CGFunc &>(cgFunc);
2161     uint32 funcUniqueId = cgFunc.GetUniqueID();
2162 
2163     assmbler.SetLastModulePC(cgFunc.GetMirModule().GetLastModulePC());
2164 
2165     /* emit local variable(s) if exists */
2166     EmitLocalVariable(cgFunc);
2167 
2168     /* emit function header */
2169     EmitFunctionHeader(cgFunc);
2170 
2171     /* emit instructions */
2172     FOR_ALL_BB(bb, &x64CGFunc)
2173     {
2174         if (bb->IsUnreachable()) {
2175             continue;
2176         }
2177 
2178         /* emit bb headers */
2179         if (bb->GetLabIdx() != MIRLabelTable::GetDummyLabel()) {
2180             EmitBBHeaderLabel(cgFunc, bb->GetLabIdx(), bb->GetFrequency());
2181         }
2182 
2183         FOR_BB_INSNS(insn, bb)
2184         {
2185             EmitInsn(*insn, funcUniqueId);
2186         }
2187     }
2188 
2189     /* emit switch table if exists */
2190     EmitJmpTable(cgFunc);
2191 
2192     EmitFunctionFoot(cgFunc);
2193 
2194     cgFunc.GetMirModule().SetCurModulePC(assmbler.GetCurModulePC());
2195 
2196     assmbler.ClearLocalSymMap();
2197 }
2198 
PhaseRun(CGFunc & f)2199 bool CgEmission::PhaseRun(CGFunc &f)
2200 {
2201     Emitter *emitter = f.GetCG()->GetEmitter();
2202     CHECK_NULL_FATAL(emitter);
2203     static_cast<X64Emitter *>(emitter)->Run(f);
2204     return false;
2205 }
2206 
EmitDwFormAddr(const DBGDie & die,const DBGDieAttr & attr,DwAt attrName,DwTag tagName,DebugInfo & di)2207 void X64Emitter::EmitDwFormAddr(const DBGDie &die, const DBGDieAttr &attr, DwAt attrName, DwTag tagName, DebugInfo &di)
2208 {
2209     MapleVector<DBGDieAttr *> attrvec = die.GetAttrVec();
2210     if (attrName == static_cast<uint32>(DW_AT_low_pc) && tagName == static_cast<uint32>(DW_TAG_compile_unit)) {
2211         assmbler.EmitDwFormAddr(true);
2212     }
2213     if (attrName == static_cast<uint32>(DW_AT_low_pc) && tagName == static_cast<uint32>(DW_TAG_subprogram)) {
2214         /* if decl, name should be found; if def, we try DW_AT_specification */
2215         DBGDieAttr *name = LFindAttribute(attrvec, static_cast<DwAt>(DW_AT_name));
2216         if (name == nullptr) {
2217             DBGDieAttr *spec = LFindAttribute(attrvec, static_cast<DwAt>(DW_AT_specification));
2218             CHECK_FATAL(spec != nullptr, "spec is null in Emitter::EmitDIAttrValue");
2219             DBGDie *decl = di.GetDie(spec->GetId());
2220             name = LFindAttribute(decl->GetAttrVec(), static_cast<DwAt>(DW_AT_name));
2221             CHECK_FATAL(name != nullptr, "name is null in Emitter::EmitDIAttrValue");
2222         }
2223         const std::string &str = GlobalTables::GetStrTable().GetStringFromStrIdx(name->GetId());
2224         MIRBuilder *mirbuilder = GetCG()->GetMIRModule()->GetMIRBuilder();
2225         MIRFunction *mfunc = mirbuilder->GetFunctionFromName(str);
2226         MapleMap<MIRFunction *, std::pair<LabelIdx, LabelIdx>>::iterator it = CG::GetFuncWrapLabels().find(mfunc);
2227         if (it != CG::GetFuncWrapLabels().end()) {
2228             /* it is a <pair> */
2229             assmbler.EmitLabel(mfunc->GetPuidx(), (*it).second.first);
2230         } else {
2231             PUIdx pIdx = GetCG()->GetMIRModule()->CurFunction()->GetPuidx();
2232             assmbler.EmitLabel(pIdx, attr.GetId()); /* maybe deadbeef */
2233         }
2234     }
2235     if (attrName == static_cast<uint32>(DW_AT_low_pc) && tagName == static_cast<uint32>(DW_TAG_label)) {
2236         DBGDie *subpgm = die.GetParent();
2237         DEBUG_ASSERT(subpgm->GetTag() == DW_TAG_subprogram, "Label DIE should be a child of a Subprogram DIE");
2238         DBGDieAttr *fnameAttr = LFindAttribute(subpgm->GetAttrVec(), static_cast<DwAt>(DW_AT_name));
2239         if (!fnameAttr) {
2240             DBGDieAttr *specAttr = LFindAttribute(subpgm->GetAttrVec(), static_cast<DwAt>(DW_AT_specification));
2241             CHECK_FATAL(specAttr, "pointer is null");
2242             DBGDie *twin = di.GetDie(static_cast<uint32>(specAttr->GetU()));
2243             fnameAttr = LFindAttribute(twin->GetAttrVec(), static_cast<DwAt>(DW_AT_name));
2244         }
2245     }
2246     if (attrName == static_cast<uint32>(DW_AT_high_pc)) {
2247         if (tagName == static_cast<uint32>(DW_TAG_compile_unit)) {
2248             assmbler.EmitDwFormData8();
2249         }
2250     }
2251     if (attrName != static_cast<uint32>(DW_AT_high_pc) && attrName != static_cast<uint32>(DW_AT_low_pc)) {
2252         assmbler.EmitDwFormAddr();
2253     }
2254 }
2255 
EmitDwFormRef4(DBGDie & die,const DBGDieAttr & attr,DwAt attrName,DwTag tagName,DebugInfo & di)2256 void X64Emitter::EmitDwFormRef4(DBGDie &die, const DBGDieAttr &attr, DwAt attrName, DwTag tagName, DebugInfo &di)
2257 {
2258     if (attrName == static_cast<uint32>(DW_AT_type)) {
2259         DBGDie *die0 = di.GetDie(static_cast<uint32>(attr.GetU()));
2260         if (die0->GetOffset()) {
2261             assmbler.EmitDwFormRef4(die0->GetOffset());
2262         } else {
2263             /* unknown type, missing mplt */
2264             assmbler.EmitDwFormRef4(di.GetDummyTypeDie()->GetOffset(), true);
2265         }
2266     } else if (attrName == static_cast<uint32>(DW_AT_specification) || attrName == static_cast<uint32>(DW_AT_sibling)) {
2267         DBGDie *die0 = di.GetDie(static_cast<uint32>(attr.GetU()));
2268         DEBUG_ASSERT(die0->GetOffset(), "");
2269         assmbler.EmitDwFormRef4(die0->GetOffset());
2270     } else if (attrName == static_cast<uint32>(DW_AT_object_pointer)) {
2271         GStrIdx thisIdx = GlobalTables::GetStrTable().GetStrIdxFromName(kDebugMapleThis);
2272         DBGDie *that = LFindChildDieWithName(die, static_cast<DwTag>(DW_TAG_formal_parameter), thisIdx);
2273         /* need to find the this or self based on the source language
2274             what is the name for 'this' used in mapleir?
2275             this has to be with respect to a function */
2276         if (that) {
2277             assmbler.EmitDwFormRef4(that->GetOffset());
2278         } else {
2279             assmbler.EmitDwFormRef4(attr.GetU());
2280         }
2281     } else {
2282         assmbler.EmitDwFormRef4(attr.GetU(), false, true);
2283     }
2284 }
2285 
EmitDwFormData8(const DBGDieAttr & attr,DwAt attrName,DwTag tagName,DebugInfo & di,MapleVector<DBGDieAttr * > & attrvec)2286 void X64Emitter::EmitDwFormData8(const DBGDieAttr &attr, DwAt attrName, DwTag tagName, DebugInfo &di,
2287                                  MapleVector<DBGDieAttr *> &attrvec)
2288 {
2289     if (attrName == static_cast<uint32>(DW_AT_high_pc)) {
2290         if (tagName == static_cast<uint32>(DW_TAG_compile_unit)) {
2291             assmbler.EmitDwFormData8();
2292         } else if (tagName == static_cast<uint32>(DW_TAG_subprogram)) {
2293             DBGDieAttr *name = LFindAttribute(attrvec, static_cast<DwAt>(DW_AT_name));
2294             if (name == nullptr) {
2295                 DBGDieAttr *spec = LFindAttribute(attrvec, static_cast<DwAt>(DW_AT_specification));
2296                 CHECK_FATAL(spec != nullptr, "spec is null in Emitter::EmitDIAttrValue");
2297                 DBGDie *decl = di.GetDie(spec->GetId());
2298                 name = LFindAttribute(decl->GetAttrVec(), static_cast<DwAt>(DW_AT_name));
2299                 CHECK_FATAL(name != nullptr, "name is null in Emitter::EmitDIAttrValue");
2300             }
2301             const std::string &str = GlobalTables::GetStrTable().GetStringFromStrIdx(name->GetId());
2302 
2303             MIRBuilder *mirbuilder = GetCG()->GetMIRModule()->GetMIRBuilder();
2304             MIRFunction *mfunc = mirbuilder->GetFunctionFromName(str);
2305             MapleMap<MIRFunction *, std::pair<LabelIdx, LabelIdx>>::iterator it = CG::GetFuncWrapLabels().find(mfunc);
2306             uint32 endLabelFuncPuIdx;
2307             uint32 startLabelFuncPuIdx;
2308             uint32 endLabelIdx;
2309             uint32 startLabelIdx;
2310             if (it != CG::GetFuncWrapLabels().end()) {
2311                 /* end label */
2312                 endLabelFuncPuIdx = mfunc->GetPuidx();
2313                 endLabelIdx = (*it).second.second;
2314             } else {
2315                 /* maybe deadbeef */
2316                 endLabelFuncPuIdx = GetCG()->GetMIRModule()->CurFunction()->GetPuidx();
2317                 endLabelIdx = (*it).second.second;
2318             }
2319             if (it != CG::GetFuncWrapLabels().end()) {
2320                 /* start label */
2321                 startLabelFuncPuIdx = mfunc->GetPuidx();
2322                 startLabelIdx = (*it).second.first;
2323             } else {
2324                 DBGDieAttr *lowpc = LFindAttribute(attrvec, static_cast<DwAt>(DW_AT_low_pc));
2325                 CHECK_FATAL(lowpc != nullptr, "lowpc is null in Emitter::EmitDIAttrValue");
2326                 /* maybe deadbeef */
2327                 startLabelFuncPuIdx = GetCG()->GetMIRModule()->CurFunction()->GetPuidx();
2328                 startLabelIdx = lowpc->GetId();
2329             }
2330             assmbler.EmitDwFormData8(endLabelFuncPuIdx, startLabelFuncPuIdx, endLabelIdx, startLabelIdx);
2331         }
2332     } else {
2333         assmbler.EmitDwFormData(attr.GetI(), k8Bytes);
2334     }
2335 }
2336 
EmitDIAttrValue(DBGDie & die,DBGDieAttr & attr,DwAt attrName,DwTag tagName,DebugInfo & di)2337 void X64Emitter::EmitDIAttrValue(DBGDie &die, DBGDieAttr &attr, DwAt attrName, DwTag tagName, DebugInfo &di)
2338 {
2339     MapleVector<DBGDieAttr *> &attrvec = die.GetAttrVec();
2340     switch (attr.GetDwForm()) {
2341         case DW_FORM_string:
2342             assmbler.EmitDwFormString(GlobalTables::GetStrTable().GetStringFromStrIdx(attr.GetId()));
2343             break;
2344         case DW_FORM_strp:
2345             assmbler.EmitDwFormStrp(attr.GetId(), GlobalTables::GetStrTable().StringTableSize());
2346             break;
2347         case DW_FORM_data1:
2348             assmbler.EmitDwFormData(attr.GetI(), k1Byte);
2349             break;
2350         case DW_FORM_data2:
2351             assmbler.EmitDwFormData(attr.GetI(), k2Bytes);
2352             break;
2353         case DW_FORM_data4:
2354             assmbler.EmitDwFormData(attr.GetI(), k4Bytes);
2355             break;
2356         case DW_FORM_data8:
2357             EmitDwFormData8(attr, attrName, tagName, di, attrvec);
2358             break;
2359         case DW_FORM_sec_offset:
2360             if (attrName == static_cast<uint32>(DW_AT_stmt_list)) {
2361                 assmbler.EmitDwFormSecOffset();
2362             }
2363             break;
2364         case DW_FORM_addr:
2365             EmitDwFormAddr(die, attr, attrName, tagName, di);
2366             break;
2367         case DW_FORM_ref4:
2368             EmitDwFormRef4(die, attr, attrName, tagName, di);
2369             break;
2370         case DW_FORM_exprloc: {
2371             DBGExprLoc *elp = attr.GetPtr();
2372             switch (elp->GetOp()) {
2373                 case DW_OP_call_frame_cfa:
2374                     assmbler.EmitDwFormExprlocCfa(elp->GetOp());
2375                     break;
2376                 case DW_OP_addr:
2377                     assmbler.EmitDwFormExprlocAddr(elp->GetOp(),
2378                                                    GlobalTables::GetStrTable()
2379                                                    .GetStringFromStrIdx(static_cast<uint32>(elp->GetGvarStridx()))
2380                                                    .c_str());
2381                     break;
2382                 case DW_OP_fbreg:
2383                     assmbler.EmitDwFormExprlocFbreg(elp->GetOp(), elp->GetFboffset(),
2384                                                     namemangler::GetSleb128Size(elp->GetFboffset()));
2385                     break;
2386                 case DW_OP_breg0:
2387                 case DW_OP_breg1:
2388                 case DW_OP_breg2:
2389                 case DW_OP_breg3:
2390                 case DW_OP_breg4:
2391                 case DW_OP_breg5:
2392                 case DW_OP_breg6:
2393                 case DW_OP_breg7:
2394                     assmbler.EmitDwFormExprlocBregn(elp->GetOp(), GetDwOpName(elp->GetOp()));
2395                     break;
2396                 default:
2397                     assmbler.EmitDwFormExprloc(uintptr(elp));
2398                     break;
2399             }
2400             break;
2401         }
2402         default:
2403             CHECK_FATAL(maple::GetDwFormName(attr.GetDwForm()) != nullptr,
2404                         "GetDwFormName return null in Emitter::EmitDIAttrValue");
2405             LogInfo::MapleLogger() << "unhandled : " << maple::GetDwFormName(attr.GetDwForm()) << std::endl;
2406             DEBUG_ASSERT(0, "NYI");
2407     }
2408 }
2409 
EmitDIDebugInfoSection(DebugInfo & mirdi)2410 void X64Emitter::EmitDIDebugInfoSection(DebugInfo &mirdi)
2411 {
2412     assmbler.EmitDIDebugInfoSectionHeader(mirdi.GetDebugInfoLength());
2413     /*
2414      * 7.5.1.2 type unit header
2415      * currently empty...
2416      *
2417      * 7.5.2 Debugging Information Entry (DIE)
2418      */
2419     X64Emitter *emitter = this;
2420     MapleVector<DBGAbbrevEntry *> &abbrevVec = mirdi.GetAbbrevVec();
2421     ApplyInPrefixOrder(mirdi.GetCompUnit(), [&abbrevVec, &emitter, &mirdi, this](DBGDie *die) {
2422         if (!die) {
2423             /* emit the null entry and return */
2424             emitter->GetAssembler().EmitDIDebugSectionEnd(kSDebugInfo);
2425             return;
2426         }
2427         bool verbose = emitter->GetCG()->GenerateVerboseAsm();
2428         if (verbose) {
2429             CHECK_FATAL(maple::GetDwTagName(die->GetTag()) != nullptr,
2430                         "GetDwTagName(die->GetTag()) return null in Emitter::EmitDIDebugInfoSection");
2431         }
2432         uint32 abbrevId = die->GetAbbrevId();
2433         emitter->GetAssembler().EmitDIDebugInfoSectionAbbrevId(verbose, abbrevId, maple::GetDwTagName(die->GetTag()),
2434                                                                die->GetOffset(), die->GetSize());
2435         DBGAbbrevEntry *diae = LFindAbbrevEntry(abbrevVec, abbrevId);
2436         CHECK_FATAL(diae != nullptr, "diae is null in Emitter::EmitDIDebugInfoSection");
2437         std::string sfile, spath;
2438         if (diae->GetTag() == static_cast<uint32>(DW_TAG_compile_unit) && sfile.empty()) {
2439             /* get full source path from fileMap[2] */
2440             if (emitter->GetFileMap().size() > k2ByteSize) { /* have src file map */
2441                 std::string srcPath = emitter->GetFileMap()[k2ByteSize];
2442                 size_t t = srcPath.rfind("/");
2443                 DEBUG_ASSERT(t != std::string::npos, "");
2444                 sfile = srcPath.substr(t + 1);
2445                 spath = srcPath.substr(0, t);
2446             }
2447         }
2448 
2449         UpdateAttrAndEmit(sfile, mirdi, *diae, *die, spath);
2450     });
2451 }
2452 
UpdateAttrAndEmit(const string & sfile,DebugInfo & mirdi,DBGAbbrevEntry & diae,DBGDie & die,const string & spath)2453 void X64Emitter::UpdateAttrAndEmit(const string &sfile, DebugInfo &mirdi, DBGAbbrevEntry &diae, DBGDie &die,
2454                                    const string &spath)
2455 {
2456     X64Emitter *emitter = this;
2457     MapleVector<uint32> &apl = diae.GetAttrPairs(); /* attribute pair list */
2458     bool verbose = emitter->GetCG()->GenerateVerboseAsm();
2459     for (size_t i = 0; i < diae.GetAttrPairs().size(); i += k2ByteSize) {
2460         DBGDieAttr *attr = LFindAttribute(die.GetAttrVec(), DwAt(apl[i]));
2461         CHECK_FATAL(attr != nullptr, "attr is null");
2462         if (!LShouldEmit(unsigned(apl[i + 1]))) {
2463             continue;
2464         }
2465 
2466         /* update DW_AT_name and DW_AT_comp_dir attrs under DW_TAG_compile_unit
2467             to be C/C++ */
2468         if (!sfile.empty()) {
2469             if (attr->GetDwAt() == static_cast<uint32>(DW_AT_name)) {
2470                 attr->SetId(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(sfile).GetIdx());
2471                 emitter->GetCG()->GetMIRModule()->GetDbgInfo()->AddStrps(attr->GetId());
2472             } else if (attr->GetDwAt() == static_cast<uint32>(DW_AT_comp_dir)) {
2473                 attr->SetId(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(spath).GetIdx());
2474                 emitter->GetCG()->GetMIRModule()->GetDbgInfo()->AddStrps(attr->GetId());
2475             }
2476         }
2477         emitter->GetAssembler().EmitDIFormSpecification(unsigned(apl[i + 1]));
2478         emitter->EmitDIAttrValue(die, *attr, unsigned(apl[i]), diae.GetTag(), mirdi);
2479         if (verbose) {
2480             std::string dwAtName = maple::GetDwAtName(unsigned(apl[i]));
2481             std::string dwForName = maple::GetDwFormName(unsigned(apl[i + 1]));
2482             emitter->GetAssembler().EmitDIDwName(dwAtName, dwForName);
2483             if (apl[i + 1] == static_cast<uint32>(DW_FORM_strp) || apl[i + 1] == static_cast<uint32>(DW_FORM_string)) {
2484                 emitter->GetAssembler().EmitDIDWFormStr(
2485                     GlobalTables::GetStrTable().GetStringFromStrIdx(attr->GetId()).c_str());
2486             } else if (apl[i] == static_cast<uint32>(DW_AT_data_member_location)) {
2487                 emitter->GetAssembler().EmitDIDWDataMemberLocaltion(apl[i + 1], uintptr(attr));
2488             }
2489         }
2490         emitter->GetAssembler().EmitLine();
2491     }
2492 }
2493 
EmitDIDebugAbbrevSection(DebugInfo & mirdi)2494 void X64Emitter::EmitDIDebugAbbrevSection(DebugInfo &mirdi)
2495 {
2496     assmbler.EmitDIDebugAbbrevSectionHeader();
2497 
2498     /* construct a list of DI abbrev entries
2499        1. DW_TAG_compile_unit 0x11
2500        2. DW_TAG_subprogram   0x2e */
2501     bool verbose = GetCG()->GenerateVerboseAsm();
2502     for (DBGAbbrevEntry *diae : mirdi.GetAbbrevVec()) {
2503         if (!diae) {
2504             continue;
2505         }
2506         CHECK_FATAL(maple::GetDwTagName(diae->GetTag()) != nullptr,
2507                     "GetDwTagName return null in X64Emitter::EmitDIDebugAbbrevSection");
2508         assmbler.EmitDIDebugAbbrevDiae(verbose, diae->GetAbbrevId(), diae->GetTag(),
2509                                        maple::GetDwTagName(diae->GetTag()), diae->GetWithChildren());
2510 
2511         MapleVector<uint32> &apl = diae->GetAttrPairs(); /* attribute pair list */
2512 
2513         for (size_t i = 0; i < diae->GetAttrPairs().size(); i += k2ByteSize) {
2514             CHECK_FATAL(maple::GetDwAtName(unsigned(apl[i])) != nullptr,
2515                         "GetDwAtName return null in X64Emitter::EmitDIDebugAbbrevSection");
2516             CHECK_FATAL(maple::GetDwFormName(unsigned(apl[i + 1])) != nullptr,
2517                         "GetDwFormName return null in X64Emitter::EmitDIDebugAbbrevSection");
2518             assmbler.EmitDIDebugAbbrevDiaePairItem(verbose, apl[i], apl[1 + 1], maple::GetDwAtName(unsigned(apl[i])),
2519                                                    maple::GetDwFormName(unsigned(apl[i + 1])));
2520         }
2521         assmbler.EmitDIDebugSectionEnd(kSDebugAbbrev);
2522         assmbler.EmitDIDebugSectionEnd(kSDebugAbbrev);
2523     }
2524     assmbler.EmitDIDebugSectionEnd(kSDebugAbbrev);
2525 }
2526 
EmitDIDebugStrSection()2527 void X64Emitter::EmitDIDebugStrSection()
2528 {
2529     std::vector<std::string> debugStrs;
2530     std::vector<uint32> strps;
2531     for (auto it : GetCG()->GetMIRModule()->GetDbgInfo()->GetStrps()) {
2532         const std::string &name = GlobalTables::GetStrTable().GetStringFromStrIdx(it);
2533         (void)debugStrs.emplace_back(name);
2534         (void)strps.emplace_back(it);
2535     }
2536     assmbler.EmitDIDebugStrSection(strps, debugStrs, GlobalTables::GetGsymTable().GetSymbolTableSize(),
2537                                    GlobalTables::GetStrTable().StringTableSize());
2538 }
2539 
EmitDebugInfo(CG & cg)2540 void X64Emitter::EmitDebugInfo(CG &cg)
2541 {
2542     if (!cg.GetCGOptions().WithDwarf()) {
2543         return;
2544     }
2545     SetupDBGInfo(cg.GetMIRModule()->GetDbgInfo());
2546     assmbler.EmitDIHeaderFileInfo();
2547     EmitDIDebugInfoSection(*(cg.GetMIRModule()->GetDbgInfo()));
2548     EmitDIDebugAbbrevSection(*(cg.GetMIRModule()->GetDbgInfo()));
2549     assmbler.EmitDIDebugARangesSection();
2550     assmbler.EmitDIDebugRangesSection();
2551     assmbler.EmitDIDebugLineSection();
2552     EmitDIDebugStrSection();
2553 }
2554 
2555 MAPLE_TRANSFORM_PHASE_REGISTER(CgEmission, cgemit)
2556 } /* namespace maplebe */
2557