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