• 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_cg.h"
18 
19 using namespace std;
20 using namespace assembler;
21 
22 namespace maplebe {
GetSymbolAlign(const MIRSymbol & mirSymbol,bool isComm)23 uint8 X64Emitter::GetSymbolAlign(const MIRSymbol &mirSymbol, bool isComm)
24 {
25     uint8 alignInByte = mirSymbol.GetAttrs().GetAlignValue();
26     MIRTypeKind kind = mirSymbol.GetType()->GetKind();
27     if (isComm) {
28         MIRStorageClass storage = mirSymbol.GetStorageClass();
29         if ((kind == kTypeArray) && ((storage == kScGlobal) || (storage == kScPstatic) || (storage == kScFstatic)) &&
30             alignInByte < kSizeOfPTR) {
31             alignInByte = kQ;
32             return alignInByte;
33         }
34     }
35     if (alignInByte == 0) {
36         if (kind == kTypeArray) {
37             return alignInByte;
38         } else {
39             alignInByte = Globals::GetInstance()->GetBECommon()->GetTypeAlign(mirSymbol.GetType()->GetTypeIndex());
40         }
41     }
42     return alignInByte;
43 }
44 
GetSymbolSize(const TyIdx typeIndex)45 uint64 X64Emitter::GetSymbolSize(const TyIdx typeIndex)
46 {
47     uint64 sizeInByte = Globals::GetInstance()->GetBECommon()->GetTypeSize(typeIndex);
48     return sizeInByte;
49 }
50 
TransferReg(Operand * opnd) const51 Reg X64Emitter::TransferReg(Operand *opnd) const
52 {
53     RegOperand *v = static_cast<RegOperand *>(opnd);
54     DEBUG_ASSERT(v != nullptr, "nullptr check");
55     /* check whether this reg is still virtual */
56     CHECK_FATAL(v->IsPhysicalRegister(), "register is still virtual or reg num is 0");
57 
58     uint8 regType = -1;
59     switch (v->GetSize()) {
60         case k8BitSize:
61             regType = v->IsHigh8Bit() ? X64CG::kR8HighList : X64CG::kR8LowList;
62             break;
63         case k16BitSize:
64             regType = X64CG::kR16List;
65             break;
66         case k32BitSize:
67             regType = X64CG::kR32List;
68             break;
69         case k64BitSize:
70             regType = X64CG::kR64List;
71             break;
72         case k128BitSize:
73             regType = X64CG::kR128List;
74             break;
75         default:
76             FATAL(kLncFatal, "unkown reg size");
77             break;
78     }
79     CHECK_FATAL(v->GetRegisterNumber() < kRegArray[regType].size(), "NIY, reg out of range");
80     Reg reg = kRegArray[regType][v->GetRegisterNumber()];
81     CHECK_FATAL(reg != Reg::ERR, "error reg");
82     return reg;
83 }
84 
TransferImm(Operand * opnd)85 pair<int64, bool> X64Emitter::TransferImm(Operand *opnd)
86 {
87     ImmOperand *v = static_cast<ImmOperand *>(opnd);
88     if (v->GetKind() == Operand::kOpdStImmediate) {
89         uint32 symIdx = v->GetSymbol()->GetNameStrIdx().get();
90         const string &symName = v->GetName();
91         assmbler.StoreNameIntoSymMap(symIdx, symName);
92         return pair<int64, bool>(symIdx, true);
93     } else {
94         return pair<int64, bool>(v->GetValue(), false);
95     }
96 }
97 
TransferMem(Operand * opnd,uint32 funcUniqueId)98 Mem X64Emitter::TransferMem(Operand *opnd, uint32 funcUniqueId)
99 {
100     MemOperand *v = static_cast<MemOperand *>(opnd);
101     Mem mem;
102     mem.size = v->GetSize();
103     if (v->GetOffsetOperand() != nullptr) {
104         ImmOperand *ofset = v->GetOffsetOperand();
105         if (ofset->GetKind() == Operand::kOpdStImmediate) {
106             string symbolName = ofset->GetName();
107             const MIRSymbol *symbol = ofset->GetSymbol();
108 
109             MIRStorageClass storageClass = symbol->GetStorageClass();
110             bool isLocalVar = ofset->GetSymbol()->IsLocal();
111             if (storageClass == kScPstatic && isLocalVar) {
112                 symbolName.append(to_string(funcUniqueId));
113             }
114 
115             int64 symIdx;
116             /* 2 : if it is a bb label, the second position in symbolName is '.' */
117             if (symbolName.size() > 2 && symbolName[2] == '.') {
118                 string delimiter = "__";
119                 size_t pos = symbolName.find(delimiter);
120                 /* 3: index starts after ".L." */
121                 uint32 itsFuncUniqueId = pos > 3 ? static_cast<uint32>(stoi(symbolName.substr(3, pos))) : 0;
122                 /* 2: delimiter.length() */
123                 uint32 labelIdx = static_cast<uint32_t>(stoi(symbolName.substr(pos + 2, symbolName.length())));
124                 symIdx = CalculateLabelSymIdx(itsFuncUniqueId, labelIdx);
125             } else {
126                 symIdx = symbol->GetNameStrIdx().get();
127             }
128             assmbler.StoreNameIntoSymMap(symIdx, symbolName);
129             mem.disp.first = symIdx;
130         }
131         if (ofset->GetValue() != 0) {
132             mem.disp.second = ofset->GetValue();
133         }
134     }
135     if (v->GetBaseRegister() != nullptr) {
136         if (v->GetIndexRegister() != nullptr && v->GetBaseRegister()->GetRegisterNumber() == x64::RBP) {
137             mem.base = ERR;
138         } else {
139             mem.base = TransferReg(v->GetBaseRegister());
140         }
141     }
142     if (v->GetIndexRegister() != nullptr) {
143         mem.index = TransferReg(v->GetIndexRegister());
144         uint8 s = static_cast<uint8>(v->GetScaleOperand()->GetValue());
145         /* 1, 2, 4, 8: allowed range for s */
146         CHECK_FATAL(s == 1 || s == 2 || s == 4 || s == 8, "mem.s is not 1, 2, 4, or 8");
147         mem.s = s;
148     }
149     mem.SetMemType();
150     return mem;
151 }
152 
TransferLabel(Operand * opnd,uint32 funcUniqueId)153 int64 X64Emitter::TransferLabel(Operand *opnd, uint32 funcUniqueId)
154 {
155     LabelOperand *v = static_cast<LabelOperand *>(opnd);
156     int64 labelSymIdx = CalculateLabelSymIdx(funcUniqueId, v->GetLabelIndex());
157     assmbler.StoreNameIntoSymMap(labelSymIdx, std::string(v->GetParentFunc().c_str()));
158     return labelSymIdx;
159 }
160 
TransferFuncName(Operand * opnd)161 uint32 X64Emitter::TransferFuncName(Operand *opnd)
162 {
163     FuncNameOperand *v = static_cast<FuncNameOperand *>(opnd);
164     uint32 funcSymIdx = v->GetFunctionSymbol()->GetNameStrIdx().get();
165     assmbler.StoreNameIntoSymMap(funcSymIdx, v->GetName());
166     return funcSymIdx;
167 }
168 
EmitInsn(Insn & insn,uint32 funcUniqueId)169 void X64Emitter::EmitInsn(Insn &insn, uint32 funcUniqueId)
170 {
171     MOperator mop = insn.GetMachineOpcode();
172     const InsnDesc &curMd = X64CG::kMd[mop];
173     uint32 opndNum = curMd.GetOpndMDLength(); /* Get operands Number */
174 
175     /* Get operand(s) */
176     Operand *opnd0 = nullptr;
177     Operand *opnd1 = nullptr;
178     if (opndNum > 0) {
179         opnd0 = &insn.GetOperand(0);
180         if (opndNum > 1) {
181             opnd1 = &insn.GetOperand(1);
182         }
183     }
184 
185     auto dbgComment = insn.GetDebugComment();
186     if (currDebugComment != dbgComment) {
187         currDebugComment = dbgComment;
188         if (dbgComment != nullptr) {
189             assmbler.EmitDebugComment(dbgComment->c_str());
190         } else {
191             assmbler.EmitDebugComment("");
192         }
193     }
194     switch (mop) {
195         /* mov */
196         case x64::MOP_movb_r_r:
197             assmbler.Mov(kB, TransferReg(opnd0), TransferReg(opnd1));
198             break;
199         case x64::MOP_movw_r_r:
200             assmbler.Mov(kW, TransferReg(opnd0), TransferReg(opnd1));
201             break;
202         case x64::MOP_movl_r_r:
203             assmbler.Mov(kL, TransferReg(opnd0), TransferReg(opnd1));
204             break;
205         case x64::MOP_movq_r_r:
206             assmbler.Mov(kQ, TransferReg(opnd0), TransferReg(opnd1));
207             break;
208         case x64::MOP_movb_m_r:
209             assmbler.Mov(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
210             break;
211         case x64::MOP_movw_m_r:
212             assmbler.Mov(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
213             break;
214         case x64::MOP_movl_m_r:
215             assmbler.Mov(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
216             break;
217         case x64::MOP_movq_m_r:
218             assmbler.Mov(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
219             break;
220         case x64::MOP_movb_i_r:
221             assmbler.Mov(kB, TransferImm(opnd0), TransferReg(opnd1));
222             break;
223         case x64::MOP_movw_i_r:
224             assmbler.Mov(kW, TransferImm(opnd0), TransferReg(opnd1));
225             break;
226         case x64::MOP_movl_i_r:
227             assmbler.Mov(kL, TransferImm(opnd0), TransferReg(opnd1));
228             break;
229         case x64::MOP_movq_i_r:
230             assmbler.Mov(kQ, TransferImm(opnd0), TransferReg(opnd1));
231             break;
232         case x64::MOP_movb_i_m:
233             assmbler.Mov(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
234             break;
235         case x64::MOP_movw_i_m:
236             assmbler.Mov(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
237             break;
238         case x64::MOP_movl_i_m:
239             assmbler.Mov(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
240             break;
241         case x64::MOP_movb_r_m:
242             assmbler.Mov(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
243             break;
244         case x64::MOP_movw_r_m:
245             assmbler.Mov(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
246             break;
247         case x64::MOP_movl_r_m:
248             assmbler.Mov(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
249             break;
250         case x64::MOP_movq_r_m:
251             assmbler.Mov(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
252             break;
253         /* floating point mov */
254         case x64::MOP_movd_fr_r:
255         case x64::MOP_movd_r_fr:
256             assmbler.Mov(TransferReg(opnd0), TransferReg(opnd1));
257             break;
258         case x64::MOP_movq_fr_r:
259         case x64::MOP_movq_r_fr:
260             assmbler.Mov(TransferReg(opnd0), TransferReg(opnd1), false);
261             break;
262         case x64::MOP_movfs_r_r:
263             assmbler.MovF(TransferReg(opnd0), TransferReg(opnd1));
264             break;
265         case x64::MOP_movfd_r_r:
266             assmbler.MovF(TransferReg(opnd0), TransferReg(opnd1), false);
267             break;
268         case x64::MOP_movfs_m_r:
269             assmbler.MovF(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
270             break;
271         case x64::MOP_movfs_r_m:
272             assmbler.MovF(TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
273             break;
274         case x64::MOP_movfd_m_r:
275             assmbler.MovF(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1), false);
276             break;
277         case x64::MOP_movfd_r_m:
278             assmbler.MovF(TransferReg(opnd0), TransferMem(opnd1, funcUniqueId), false);
279             break;
280         /* movzx */
281         case x64::MOP_movzbw_r_r:
282             assmbler.MovZx(kB, kW, TransferReg(opnd0), TransferReg(opnd1));
283             break;
284         case x64::MOP_movzbl_r_r:
285             assmbler.MovZx(kB, kL, TransferReg(opnd0), TransferReg(opnd1));
286             break;
287         case x64::MOP_movzbq_r_r:
288             assmbler.MovZx(kB, kQ, TransferReg(opnd0), TransferReg(opnd1));
289             break;
290         case x64::MOP_movzwl_r_r:
291             assmbler.MovZx(kW, kL, TransferReg(opnd0), TransferReg(opnd1));
292             break;
293         case x64::MOP_movzwq_r_r:
294             assmbler.MovZx(kW, kQ, TransferReg(opnd0), TransferReg(opnd1));
295             break;
296         case x64::MOP_movzbw_m_r:
297             assmbler.MovZx(kB, kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
298             break;
299         case x64::MOP_movzbl_m_r:
300             assmbler.MovZx(kB, kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
301             break;
302         case x64::MOP_movzbq_m_r:
303             assmbler.MovZx(kB, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
304             break;
305         case x64::MOP_movzwl_m_r:
306             assmbler.MovZx(kW, kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
307             break;
308         case x64::MOP_movzwq_m_r:
309             assmbler.MovZx(kW, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
310             break;
311         /* movsx */
312         case x64::MOP_movsbw_r_r:
313             assmbler.MovSx(kB, kW, TransferReg(opnd0), TransferReg(opnd1));
314             break;
315         case x64::MOP_movsbl_r_r:
316             assmbler.MovSx(kB, kL, TransferReg(opnd0), TransferReg(opnd1));
317             break;
318         case x64::MOP_movsbq_r_r:
319             assmbler.MovSx(kB, kQ, TransferReg(opnd0), TransferReg(opnd1));
320             break;
321         case x64::MOP_movswl_r_r:
322             assmbler.MovSx(kW, kL, TransferReg(opnd0), TransferReg(opnd1));
323             break;
324         case x64::MOP_movswq_r_r:
325             assmbler.MovSx(kW, kQ, TransferReg(opnd0), TransferReg(opnd1));
326             break;
327         case x64::MOP_movslq_r_r:
328             assmbler.MovSx(kL, kQ, TransferReg(opnd0), TransferReg(opnd1));
329             break;
330         case x64::MOP_movsbw_m_r:
331             assmbler.MovSx(kB, kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
332             break;
333         case x64::MOP_movsbl_m_r:
334             assmbler.MovSx(kB, kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
335             break;
336         case x64::MOP_movsbq_m_r:
337             assmbler.MovSx(kB, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
338             break;
339         case x64::MOP_movswl_m_r:
340             assmbler.MovSx(kW, kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
341             break;
342         case x64::MOP_movswq_m_r:
343             assmbler.MovSx(kW, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
344             break;
345         case x64::MOP_movslq_m_r:
346             assmbler.MovSx(kL, kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
347             break;
348         /* add */
349         case x64::MOP_addb_r_r:
350             assmbler.Add(kB, TransferReg(opnd0), TransferReg(opnd1));
351             break;
352         case x64::MOP_addw_r_r:
353             assmbler.Add(kW, TransferReg(opnd0), TransferReg(opnd1));
354             break;
355         case x64::MOP_addl_r_r:
356             assmbler.Add(kL, TransferReg(opnd0), TransferReg(opnd1));
357             break;
358         case x64::MOP_addq_r_r:
359             assmbler.Add(kQ, TransferReg(opnd0), TransferReg(opnd1));
360             break;
361         case x64::MOP_addb_i_r:
362             assmbler.Add(kB, TransferImm(opnd0), TransferReg(opnd1));
363             break;
364         case x64::MOP_addw_i_r:
365             assmbler.Add(kW, TransferImm(opnd0), TransferReg(opnd1));
366             break;
367         case x64::MOP_addl_i_r:
368             assmbler.Add(kL, TransferImm(opnd0), TransferReg(opnd1));
369             break;
370         case x64::MOP_addq_i_r:
371             assmbler.Add(kQ, TransferImm(opnd0), TransferReg(opnd1));
372             break;
373         case x64::MOP_addb_m_r:
374             assmbler.Add(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
375             break;
376         case x64::MOP_addw_m_r:
377             assmbler.Add(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
378             break;
379         case x64::MOP_addl_m_r:
380             assmbler.Add(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
381             break;
382         case x64::MOP_addq_m_r:
383             assmbler.Add(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
384             break;
385         case x64::MOP_addb_r_m:
386             assmbler.Add(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
387             break;
388         case x64::MOP_addw_r_m:
389             assmbler.Add(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
390             break;
391         case x64::MOP_addl_r_m:
392             assmbler.Add(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
393             break;
394         case x64::MOP_addq_r_m:
395             assmbler.Add(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
396             break;
397         case x64::MOP_addb_i_m:
398             assmbler.Add(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
399             break;
400         case x64::MOP_addw_i_m:
401             assmbler.Add(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
402             break;
403         case x64::MOP_addl_i_m:
404             assmbler.Add(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
405             break;
406         case x64::MOP_addq_i_m:
407             assmbler.Add(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
408             break;
409         /* add floating point */
410         case x64::MOP_adds_r_r:
411             assmbler.Add(TransferReg(opnd0), TransferReg(opnd1));
412             break;
413         case x64::MOP_adds_m_r:
414             assmbler.Add(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
415             break;
416         case x64::MOP_addd_r_r:
417             assmbler.Add(TransferReg(opnd0), TransferReg(opnd1), false);
418             break;
419         case x64::MOP_addd_m_r:
420             assmbler.Add(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1), false);
421             break;
422         /* movabs */
423         case x64::MOP_movabs_i_r:
424             assmbler.Movabs(TransferImm(opnd0), TransferReg(opnd1));
425             break;
426         case x64::MOP_movabs_l_r:
427             assmbler.Movabs(TransferLabel(opnd0, funcUniqueId), TransferReg(opnd1));
428             break;
429         /* push */
430         case x64::MOP_pushq_r:
431             assmbler.Push(kQ, TransferReg(opnd0));
432             break;
433         /* pop */
434         case x64::MOP_popq_r:
435             assmbler.Pop(kQ, TransferReg(opnd0));
436             break;
437         /* lea */
438         case x64::MOP_leaw_m_r:
439             assmbler.Lea(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
440             break;
441         case x64::MOP_leal_m_r:
442             assmbler.Lea(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
443             break;
444         case x64::MOP_leaq_m_r:
445             assmbler.Lea(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
446             break;
447         /* sub , sbb */
448         case x64::MOP_subb_r_r:
449             assmbler.Sub(kB, TransferReg(opnd0), TransferReg(opnd1));
450             break;
451         case x64::MOP_subw_r_r:
452             assmbler.Sub(kW, TransferReg(opnd0), TransferReg(opnd1));
453             break;
454         case x64::MOP_subl_r_r:
455             assmbler.Sub(kL, TransferReg(opnd0), TransferReg(opnd1));
456             break;
457         case x64::MOP_subq_r_r:
458             assmbler.Sub(kQ, TransferReg(opnd0), TransferReg(opnd1));
459             break;
460         case x64::MOP_subb_i_r:
461             assmbler.Sub(kB, TransferImm(opnd0), TransferReg(opnd1));
462             break;
463         case x64::MOP_subw_i_r:
464             assmbler.Sub(kW, TransferImm(opnd0), TransferReg(opnd1));
465             break;
466         case x64::MOP_subl_i_r:
467             assmbler.Sub(kL, TransferImm(opnd0), TransferReg(opnd1));
468             break;
469         case x64::MOP_subq_i_r:
470             assmbler.Sub(kQ, TransferImm(opnd0), TransferReg(opnd1));
471             break;
472         case x64::MOP_subb_m_r:
473             assmbler.Sub(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
474             break;
475         case x64::MOP_subw_m_r:
476             assmbler.Sub(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
477             break;
478         case x64::MOP_subl_m_r:
479             assmbler.Sub(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
480             break;
481         case x64::MOP_subq_m_r:
482             assmbler.Sub(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
483             break;
484         case x64::MOP_subb_r_m:
485             assmbler.Sub(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
486             break;
487         case x64::MOP_subw_r_m:
488             assmbler.Sub(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
489             break;
490         case x64::MOP_subl_r_m:
491             assmbler.Sub(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
492             break;
493         case x64::MOP_subq_r_m:
494             assmbler.Sub(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
495             break;
496         case x64::MOP_subb_i_m:
497             assmbler.Sub(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
498             break;
499         case x64::MOP_subw_i_m:
500             assmbler.Sub(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
501             break;
502         case x64::MOP_subl_i_m:
503             assmbler.Sub(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
504             break;
505         case x64::MOP_subq_i_m:
506             assmbler.Sub(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
507             break;
508         /* sub floating point */
509         case x64::MOP_subs_r_r:
510             assmbler.Sub(TransferReg(opnd0), TransferReg(opnd1));
511             break;
512         case x64::MOP_subs_m_r:
513             assmbler.Sub(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
514             break;
515         case x64::MOP_subd_r_r:
516             assmbler.Sub(TransferReg(opnd0), TransferReg(opnd1), false);
517             break;
518         case x64::MOP_subd_m_r:
519             assmbler.Sub(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1), false);
520             break;
521         /* and */
522         case x64::MOP_andb_r_r:
523             assmbler.And(kB, TransferReg(opnd0), TransferReg(opnd1));
524             break;
525         case x64::MOP_andw_r_r:
526             assmbler.And(kW, TransferReg(opnd0), TransferReg(opnd1));
527             break;
528         case x64::MOP_andl_r_r:
529             assmbler.And(kL, TransferReg(opnd0), TransferReg(opnd1));
530             break;
531         case x64::MOP_andq_r_r:
532             assmbler.And(kQ, TransferReg(opnd0), TransferReg(opnd1));
533             break;
534         case x64::MOP_andb_i_r:
535             assmbler.And(kB, TransferImm(opnd0), TransferReg(opnd1));
536             break;
537         case x64::MOP_andw_i_r:
538             assmbler.And(kW, TransferImm(opnd0), TransferReg(opnd1));
539             break;
540         case x64::MOP_andl_i_r:
541             assmbler.And(kL, TransferImm(opnd0), TransferReg(opnd1));
542             break;
543         case x64::MOP_andq_i_r:
544             assmbler.And(kQ, TransferImm(opnd0), TransferReg(opnd1));
545             break;
546         case x64::MOP_andb_m_r:
547             assmbler.And(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
548             break;
549         case x64::MOP_andw_m_r:
550             assmbler.And(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
551             break;
552         case x64::MOP_andl_m_r:
553             assmbler.And(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
554             break;
555         case x64::MOP_andq_m_r:
556             assmbler.And(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
557             break;
558         case x64::MOP_andb_r_m:
559             assmbler.And(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
560             break;
561         case x64::MOP_andw_r_m:
562             assmbler.And(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
563             break;
564         case x64::MOP_andl_r_m:
565             assmbler.And(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
566             break;
567         case x64::MOP_andq_r_m:
568             assmbler.And(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
569             break;
570         case x64::MOP_andb_i_m:
571             assmbler.And(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
572             break;
573         case x64::MOP_andw_i_m:
574             assmbler.And(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
575             break;
576         case x64::MOP_andl_i_m:
577             assmbler.And(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
578             break;
579         case x64::MOP_andq_i_m:
580             assmbler.And(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
581             break;
582         /* or */
583         case x64::MOP_orb_r_r:
584             assmbler.Or(kB, TransferReg(opnd0), TransferReg(opnd1));
585             break;
586         case x64::MOP_orw_r_r:
587             assmbler.Or(kW, TransferReg(opnd0), TransferReg(opnd1));
588             break;
589         case x64::MOP_orl_r_r:
590             assmbler.Or(kL, TransferReg(opnd0), TransferReg(opnd1));
591             break;
592         case x64::MOP_orq_r_r:
593             assmbler.Or(kQ, TransferReg(opnd0), TransferReg(opnd1));
594             break;
595         case x64::MOP_orb_m_r:
596             assmbler.Or(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
597             break;
598         case x64::MOP_orw_m_r:
599             assmbler.Or(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
600             break;
601         case x64::MOP_orl_m_r:
602             assmbler.Or(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
603             break;
604         case x64::MOP_orq_m_r:
605             assmbler.Or(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
606             break;
607         case x64::MOP_orb_i_r:
608             assmbler.Or(kB, TransferImm(opnd0), TransferReg(opnd1));
609             break;
610         case x64::MOP_orw_i_r:
611             assmbler.Or(kW, TransferImm(opnd0), TransferReg(opnd1));
612             break;
613         case x64::MOP_orl_i_r:
614             assmbler.Or(kL, TransferImm(opnd0), TransferReg(opnd1));
615             break;
616         case x64::MOP_orq_i_r:
617             assmbler.Or(kQ, TransferImm(opnd0), TransferReg(opnd1));
618             break;
619         case x64::MOP_orb_r_m:
620             assmbler.Or(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
621             break;
622         case x64::MOP_orw_r_m:
623             assmbler.Or(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
624             break;
625         case x64::MOP_orl_r_m:
626             assmbler.Or(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
627             break;
628         case x64::MOP_orq_r_m:
629             assmbler.Or(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
630             break;
631         case x64::MOP_orb_i_m:
632             assmbler.Or(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
633             break;
634         case x64::MOP_orw_i_m:
635             assmbler.Or(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
636             break;
637         case x64::MOP_orl_i_m:
638             assmbler.Or(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
639             break;
640         case x64::MOP_orq_i_m:
641             assmbler.Or(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
642             break;
643         /* xor */
644         case x64::MOP_xorb_r_r:
645             assmbler.Xor(kB, TransferReg(opnd0), TransferReg(opnd1));
646             break;
647         case x64::MOP_xorw_r_r:
648             assmbler.Xor(kW, TransferReg(opnd0), TransferReg(opnd1));
649             break;
650         case x64::MOP_xorl_r_r:
651             assmbler.Xor(kL, TransferReg(opnd0), TransferReg(opnd1));
652             break;
653         case x64::MOP_xorq_r_r:
654             assmbler.Xor(kQ, TransferReg(opnd0), TransferReg(opnd1));
655             break;
656         case x64::MOP_xorb_i_r:
657             assmbler.Xor(kB, TransferImm(opnd0), TransferReg(opnd1));
658             break;
659         case x64::MOP_xorw_i_r:
660             assmbler.Xor(kW, TransferImm(opnd0), TransferReg(opnd1));
661             break;
662         case x64::MOP_xorl_i_r:
663             assmbler.Xor(kL, TransferImm(opnd0), TransferReg(opnd1));
664             break;
665         case x64::MOP_xorq_i_r:
666             assmbler.Xor(kQ, TransferImm(opnd0), TransferReg(opnd1));
667             break;
668         case x64::MOP_xorb_m_r:
669             assmbler.Xor(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
670             break;
671         case x64::MOP_xorw_m_r:
672             assmbler.Xor(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
673             break;
674         case x64::MOP_xorl_m_r:
675             assmbler.Xor(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
676             break;
677         case x64::MOP_xorq_m_r:
678             assmbler.Xor(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
679             break;
680         case x64::MOP_xorb_r_m:
681             assmbler.Xor(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
682             break;
683         case x64::MOP_xorw_r_m:
684             assmbler.Xor(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
685             break;
686         case x64::MOP_xorl_r_m:
687             assmbler.Xor(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
688             break;
689         case x64::MOP_xorq_r_m:
690             assmbler.Xor(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
691             break;
692         case x64::MOP_xorb_i_m:
693             assmbler.Xor(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
694             break;
695         case x64::MOP_xorw_i_m:
696             assmbler.Xor(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
697             break;
698         case x64::MOP_xorl_i_m:
699             assmbler.Xor(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
700             break;
701         case x64::MOP_xorq_i_m:
702             assmbler.Xor(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
703             break;
704         case x64::MOP_bsrq_r_r:
705             assmbler.Bsr(kQ, TransferReg(opnd1), TransferReg(opnd0));
706             break;
707         case x64::MOP_bsrl_r_r:
708             assmbler.Bsr(kL, TransferReg(opnd1), TransferReg(opnd0));
709             break;
710         /* not */
711         case x64::MOP_notb_r:
712             assmbler.Not(kB, TransferReg(opnd0));
713             break;
714         case x64::MOP_notw_r:
715             assmbler.Not(kW, TransferReg(opnd0));
716             break;
717         case x64::MOP_notl_r:
718             assmbler.Not(kL, TransferReg(opnd0));
719             break;
720         case x64::MOP_notq_r:
721             assmbler.Not(kQ, TransferReg(opnd0));
722             break;
723         case x64::MOP_notb_m:
724             assmbler.Not(kB, TransferMem(opnd0, funcUniqueId));
725             break;
726         case x64::MOP_notw_m:
727             assmbler.Not(kW, TransferMem(opnd0, funcUniqueId));
728             break;
729         case x64::MOP_notl_m:
730             assmbler.Not(kL, TransferMem(opnd0, funcUniqueId));
731             break;
732         case x64::MOP_notq_m:
733             assmbler.Not(kQ, TransferMem(opnd0, funcUniqueId));
734             break;
735         /* neg */
736         case x64::MOP_negb_r:
737             assmbler.Neg(kB, TransferReg(opnd0));
738             break;
739         case x64::MOP_negw_r:
740             assmbler.Neg(kW, TransferReg(opnd0));
741             break;
742         case x64::MOP_negl_r:
743             assmbler.Neg(kL, TransferReg(opnd0));
744             break;
745         case x64::MOP_negq_r:
746             assmbler.Neg(kQ, TransferReg(opnd0));
747             break;
748         case x64::MOP_negb_m:
749             assmbler.Neg(kB, TransferMem(opnd0, funcUniqueId));
750             break;
751         case x64::MOP_negw_m:
752             assmbler.Neg(kW, TransferMem(opnd0, funcUniqueId));
753             break;
754         case x64::MOP_negl_m:
755             assmbler.Neg(kL, TransferMem(opnd0, funcUniqueId));
756             break;
757         case x64::MOP_negq_m:
758             assmbler.Neg(kQ, TransferMem(opnd0, funcUniqueId));
759             break;
760         /* div, cwd, cdq, cqo */
761         case x64::MOP_idivw_r:
762             assmbler.Idiv(kW, TransferReg(opnd0));
763             break;
764         case x64::MOP_idivl_r:
765             assmbler.Idiv(kL, TransferReg(opnd0));
766             break;
767         case x64::MOP_idivq_r:
768             assmbler.Idiv(kQ, TransferReg(opnd0));
769             break;
770         case x64::MOP_idivw_m:
771             assmbler.Idiv(kW, TransferMem(opnd0, funcUniqueId));
772             break;
773         case x64::MOP_idivl_m:
774             assmbler.Idiv(kL, TransferMem(opnd0, funcUniqueId));
775             break;
776         case x64::MOP_idivq_m:
777             assmbler.Idiv(kQ, TransferMem(opnd0, funcUniqueId));
778             break;
779         case x64::MOP_divw_r:
780             assmbler.Div(kW, TransferReg(opnd0));
781             break;
782         case x64::MOP_divl_r:
783             assmbler.Div(kL, TransferReg(opnd0));
784             break;
785         case x64::MOP_divq_r:
786             assmbler.Div(kQ, TransferReg(opnd0));
787             break;
788         case x64::MOP_divw_m:
789             assmbler.Div(kW, TransferMem(opnd0, funcUniqueId));
790             break;
791         case x64::MOP_divl_m:
792             assmbler.Div(kL, TransferMem(opnd0, funcUniqueId));
793             break;
794         case x64::MOP_divq_m:
795             assmbler.Div(kQ, TransferMem(opnd0, funcUniqueId));
796             break;
797         case x64::MOP_cwd:
798             assmbler.Cwd();
799             break;
800         case x64::MOP_cdq:
801             assmbler.Cdq();
802             break;
803         case x64::MOP_cqo:
804             assmbler.Cqo();
805             break;
806         /* shl */
807         case x64::MOP_shlb_r_r:
808             assmbler.Shl(kB, TransferReg(opnd0), TransferReg(opnd1));
809             break;
810         case x64::MOP_shlw_r_r:
811             assmbler.Shl(kW, TransferReg(opnd0), TransferReg(opnd1));
812             break;
813         case x64::MOP_shll_r_r:
814             assmbler.Shl(kL, TransferReg(opnd0), TransferReg(opnd1));
815             break;
816         case x64::MOP_shlq_r_r:
817             assmbler.Shl(kQ, TransferReg(opnd0), TransferReg(opnd1));
818             break;
819         case x64::MOP_shlb_i_r:
820             assmbler.Shl(kB, TransferImm(opnd0), TransferReg(opnd1));
821             break;
822         case x64::MOP_shlw_i_r:
823             assmbler.Shl(kW, TransferImm(opnd0), TransferReg(opnd1));
824             break;
825         case x64::MOP_shll_i_r:
826             assmbler.Shl(kL, TransferImm(opnd0), TransferReg(opnd1));
827             break;
828         case x64::MOP_shlq_i_r:
829             assmbler.Shl(kQ, TransferImm(opnd0), TransferReg(opnd1));
830             break;
831         case x64::MOP_shlb_r_m:
832             assmbler.Shl(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
833             break;
834         case x64::MOP_shlw_r_m:
835             assmbler.Shl(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
836             break;
837         case x64::MOP_shll_r_m:
838             assmbler.Shl(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
839             break;
840         case x64::MOP_shlq_r_m:
841             assmbler.Shl(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
842             break;
843         case x64::MOP_shlb_i_m:
844             assmbler.Shl(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
845             break;
846         case x64::MOP_shlw_i_m:
847             assmbler.Shl(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
848             break;
849         case x64::MOP_shll_i_m:
850             assmbler.Shl(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
851             break;
852         case x64::MOP_shlq_i_m:
853             assmbler.Shl(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
854             break;
855         /* sar */
856         case x64::MOP_sarb_r_r:
857             assmbler.Sar(kB, TransferReg(opnd0), TransferReg(opnd1));
858             break;
859         case x64::MOP_sarw_r_r:
860             assmbler.Sar(kW, TransferReg(opnd0), TransferReg(opnd1));
861             break;
862         case x64::MOP_sarl_r_r:
863             assmbler.Sar(kL, TransferReg(opnd0), TransferReg(opnd1));
864             break;
865         case x64::MOP_sarq_r_r:
866             assmbler.Sar(kQ, TransferReg(opnd0), TransferReg(opnd1));
867             break;
868         case x64::MOP_sarb_i_r:
869             assmbler.Sar(kB, TransferImm(opnd0), TransferReg(opnd1));
870             break;
871         case x64::MOP_sarw_i_r:
872             assmbler.Sar(kW, TransferImm(opnd0), TransferReg(opnd1));
873             break;
874         case x64::MOP_sarl_i_r:
875             assmbler.Sar(kL, TransferImm(opnd0), TransferReg(opnd1));
876             break;
877         case x64::MOP_sarq_i_r:
878             assmbler.Sar(kQ, TransferImm(opnd0), TransferReg(opnd1));
879             break;
880         case x64::MOP_sarb_r_m:
881             assmbler.Sar(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
882             break;
883         case x64::MOP_sarw_r_m:
884             assmbler.Sar(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
885             break;
886         case x64::MOP_sarl_r_m:
887             assmbler.Sar(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
888             break;
889         case x64::MOP_sarq_r_m:
890             assmbler.Sar(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
891             break;
892         case x64::MOP_sarb_i_m:
893             assmbler.Sar(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
894             break;
895         case x64::MOP_sarw_i_m:
896             assmbler.Sar(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
897             break;
898         case x64::MOP_sarl_i_m:
899             assmbler.Sar(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
900             break;
901         case x64::MOP_sarq_i_m:
902             assmbler.Sar(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
903             break;
904         /* shr */
905         case x64::MOP_shrb_r_r:
906             assmbler.Shr(kB, TransferReg(opnd0), TransferReg(opnd1));
907             break;
908         case x64::MOP_shrw_r_r:
909             assmbler.Shr(kW, TransferReg(opnd0), TransferReg(opnd1));
910             break;
911         case x64::MOP_shrl_r_r:
912             assmbler.Shr(kL, TransferReg(opnd0), TransferReg(opnd1));
913             break;
914         case x64::MOP_shrq_r_r:
915             assmbler.Shr(kQ, TransferReg(opnd0), TransferReg(opnd1));
916             break;
917         case x64::MOP_shrb_i_r:
918             assmbler.Shr(kB, TransferImm(opnd0), TransferReg(opnd1));
919             break;
920         case x64::MOP_shrw_i_r:
921             assmbler.Shr(kW, TransferImm(opnd0), TransferReg(opnd1));
922             break;
923         case x64::MOP_shrl_i_r:
924             assmbler.Shr(kL, TransferImm(opnd0), TransferReg(opnd1));
925             break;
926         case x64::MOP_shrq_i_r:
927             assmbler.Shr(kQ, TransferImm(opnd0), TransferReg(opnd1));
928             break;
929         case x64::MOP_shrb_r_m:
930             assmbler.Shr(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
931             break;
932         case x64::MOP_shrw_r_m:
933             assmbler.Shr(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
934             break;
935         case x64::MOP_shrl_r_m:
936             assmbler.Shr(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
937             break;
938         case x64::MOP_shrq_r_m:
939             assmbler.Shr(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
940             break;
941         case x64::MOP_shrb_i_m:
942             assmbler.Shr(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
943             break;
944         case x64::MOP_shrw_i_m:
945             assmbler.Shr(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
946             break;
947         case x64::MOP_shrl_i_m:
948             assmbler.Shr(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
949             break;
950         case x64::MOP_shrq_i_m:
951             assmbler.Shr(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
952             break;
953         /* jmp */
954         case x64::MOP_jmpq_r:
955             assmbler.Jmp(TransferReg(opnd0));
956             break;
957         case x64::MOP_jmpq_m:
958             assmbler.Jmp(TransferMem(opnd0, funcUniqueId));
959             break;
960         case x64::MOP_jmpq_l:
961             assmbler.Jmp(TransferLabel(opnd0, funcUniqueId));
962             break;
963         /* je, jne */
964         case x64::MOP_je_l:
965             assmbler.Je(TransferLabel(opnd0, funcUniqueId));
966             break;
967         case x64::MOP_ja_l:
968             assmbler.Ja(TransferLabel(opnd0, funcUniqueId));
969             break;
970         case x64::MOP_jae_l:
971             assmbler.Jae(TransferLabel(opnd0, funcUniqueId));
972             break;
973         case x64::MOP_jne_l:
974             assmbler.Jne(TransferLabel(opnd0, funcUniqueId));
975             break;
976         case x64::MOP_jb_l:
977             assmbler.Jb(TransferLabel(opnd0, funcUniqueId));
978             break;
979         case x64::MOP_jbe_l:
980             assmbler.Jbe(TransferLabel(opnd0, funcUniqueId));
981             break;
982         case x64::MOP_jg_l:
983             assmbler.Jg(TransferLabel(opnd0, funcUniqueId));
984             break;
985         case x64::MOP_jge_l:
986             assmbler.Jge(TransferLabel(opnd0, funcUniqueId));
987             break;
988         case x64::MOP_jl_l:
989             assmbler.Jl(TransferLabel(opnd0, funcUniqueId));
990             break;
991         case x64::MOP_jle_l:
992             assmbler.Jle(TransferLabel(opnd0, funcUniqueId));
993             break;
994         /* cmp */
995         case x64::MOP_cmpb_r_r:
996             assmbler.Cmp(kB, TransferReg(opnd0), TransferReg(opnd1));
997             break;
998         case x64::MOP_cmpw_r_r:
999             assmbler.Cmp(kW, TransferReg(opnd0), TransferReg(opnd1));
1000             break;
1001         case x64::MOP_cmpl_r_r:
1002             assmbler.Cmp(kL, TransferReg(opnd0), TransferReg(opnd1));
1003             break;
1004         case x64::MOP_cmpq_r_r:
1005             assmbler.Cmp(kQ, TransferReg(opnd0), TransferReg(opnd1));
1006             break;
1007         case x64::MOP_cmpb_i_r:
1008             assmbler.Cmp(kB, TransferImm(opnd0), TransferReg(opnd1));
1009             break;
1010         case x64::MOP_cmpw_i_r:
1011             assmbler.Cmp(kW, TransferImm(opnd0), TransferReg(opnd1));
1012             break;
1013         case x64::MOP_cmpl_i_r:
1014             assmbler.Cmp(kL, TransferImm(opnd0), TransferReg(opnd1));
1015             break;
1016         case x64::MOP_cmpq_i_r:
1017             assmbler.Cmp(kQ, TransferImm(opnd0), TransferReg(opnd1));
1018             break;
1019         case x64::MOP_cmpb_m_r:
1020             assmbler.Cmp(kB, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1021             break;
1022         case x64::MOP_cmpw_m_r:
1023             assmbler.Cmp(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1024             break;
1025         case x64::MOP_cmpl_m_r:
1026             assmbler.Cmp(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1027             break;
1028         case x64::MOP_cmpq_m_r:
1029             assmbler.Cmp(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1030             break;
1031         case x64::MOP_cmpb_r_m:
1032             assmbler.Cmp(kB, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
1033             break;
1034         case x64::MOP_cmpw_r_m:
1035             assmbler.Cmp(kW, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
1036             break;
1037         case x64::MOP_cmpl_r_m:
1038             assmbler.Cmp(kL, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
1039             break;
1040         case x64::MOP_cmpq_r_m:
1041             assmbler.Cmp(kQ, TransferReg(opnd0), TransferMem(opnd1, funcUniqueId));
1042             break;
1043         case x64::MOP_cmpb_i_m:
1044             assmbler.Cmp(kB, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1045             break;
1046         case x64::MOP_cmpw_i_m:
1047             assmbler.Cmp(kW, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1048             break;
1049         case x64::MOP_cmpl_i_m:
1050             assmbler.Cmp(kL, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1051             break;
1052         case x64::MOP_cmpq_i_m:
1053             assmbler.Cmp(kQ, TransferImm(opnd0), TransferMem(opnd1, funcUniqueId));
1054             break;
1055         case x64::MOP_testq_r_r:
1056             assmbler.Test(kQ, TransferReg(opnd0), TransferReg(opnd1));
1057             break;
1058         /* setcc */
1059         case x64::MOP_seta_r:
1060             assmbler.Seta(TransferReg(opnd0));
1061             break;
1062         case x64::MOP_setae_r:
1063             assmbler.Setae(TransferReg(opnd0));
1064             break;
1065         case x64::MOP_setb_r:
1066             assmbler.Setb(TransferReg(opnd0));
1067             break;
1068         case x64::MOP_seto_r:
1069             assmbler.Seto(TransferReg(opnd0));
1070             break;
1071         case x64::MOP_setbe_r:
1072             assmbler.Setbe(TransferReg(opnd0));
1073             break;
1074         case x64::MOP_sete_r:
1075             assmbler.Sete(TransferReg(opnd0));
1076             break;
1077         case x64::MOP_setg_r:
1078             assmbler.Setg(TransferReg(opnd0));
1079             break;
1080         case x64::MOP_setge_r:
1081             assmbler.Setge(TransferReg(opnd0));
1082             break;
1083         case x64::MOP_setl_r:
1084             assmbler.Setl(TransferReg(opnd0));
1085             break;
1086         case x64::MOP_setle_r:
1087             assmbler.Setle(TransferReg(opnd0));
1088             break;
1089         case x64::MOP_setne_r:
1090             assmbler.Setne(TransferReg(opnd0));
1091             break;
1092         case x64::MOP_seta_m:
1093             assmbler.Seta(TransferMem(opnd0, funcUniqueId));
1094             break;
1095         case x64::MOP_setae_m:
1096             assmbler.Setae(TransferMem(opnd0, funcUniqueId));
1097             break;
1098         case x64::MOP_setb_m:
1099             assmbler.Setb(TransferMem(opnd0, funcUniqueId));
1100             break;
1101         case x64::MOP_seto_m:
1102             assmbler.Seto(TransferMem(opnd0, funcUniqueId));
1103             break;
1104         case x64::MOP_setbe_m:
1105             assmbler.Setbe(TransferMem(opnd0, funcUniqueId));
1106             break;
1107         case x64::MOP_sete_m:
1108             assmbler.Sete(TransferMem(opnd0, funcUniqueId));
1109             break;
1110         case x64::MOP_setl_m:
1111             assmbler.Setl(TransferMem(opnd0, funcUniqueId));
1112             break;
1113         case x64::MOP_setle_m:
1114             assmbler.Setle(TransferMem(opnd0, funcUniqueId));
1115             break;
1116         case x64::MOP_setg_m:
1117             assmbler.Setg(TransferMem(opnd0, funcUniqueId));
1118             break;
1119         case x64::MOP_setge_m:
1120             assmbler.Setge(TransferMem(opnd0, funcUniqueId));
1121             break;
1122         case x64::MOP_setne_m:
1123             assmbler.Setne(TransferMem(opnd0, funcUniqueId));
1124             break;
1125         /* cmova & cmovae */
1126         case x64::MOP_cmovaw_r_r:
1127             assmbler.Cmova(kW, TransferReg(opnd0), TransferReg(opnd1));
1128             break;
1129         case x64::MOP_cmoval_r_r:
1130             assmbler.Cmova(kL, TransferReg(opnd0), TransferReg(opnd1));
1131             break;
1132         case x64::MOP_cmovaq_r_r:
1133             assmbler.Cmova(kQ, TransferReg(opnd0), TransferReg(opnd1));
1134             break;
1135         case x64::MOP_cmovaw_m_r:
1136             assmbler.Cmova(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1137             break;
1138         case x64::MOP_cmoval_m_r:
1139             assmbler.Cmova(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1140             break;
1141         case x64::MOP_cmovaq_m_r:
1142             assmbler.Cmova(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1143             break;
1144         case x64::MOP_cmovaew_r_r:
1145             assmbler.Cmovae(kW, TransferReg(opnd0), TransferReg(opnd1));
1146             break;
1147         case x64::MOP_cmovael_r_r:
1148             assmbler.Cmovae(kL, TransferReg(opnd0), TransferReg(opnd1));
1149             break;
1150         case x64::MOP_cmovaeq_r_r:
1151             assmbler.Cmovae(kQ, TransferReg(opnd0), TransferReg(opnd1));
1152             break;
1153         case x64::MOP_cmovaew_m_r:
1154             assmbler.Cmovae(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1155             break;
1156         case x64::MOP_cmovael_m_r:
1157             assmbler.Cmovae(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1158             break;
1159         case x64::MOP_cmovaeq_m_r:
1160             assmbler.Cmovae(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1161             break;
1162         /* cmovb & cmovbe */
1163         case x64::MOP_cmovbw_r_r:
1164             assmbler.Cmovb(kW, TransferReg(opnd0), TransferReg(opnd1));
1165             break;
1166         case x64::MOP_cmovbl_r_r:
1167             assmbler.Cmovb(kL, TransferReg(opnd0), TransferReg(opnd1));
1168             break;
1169         case x64::MOP_cmovbq_r_r:
1170             assmbler.Cmovb(kQ, TransferReg(opnd0), TransferReg(opnd1));
1171             break;
1172         case x64::MOP_cmovbw_m_r:
1173             assmbler.Cmovb(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1174             break;
1175         case x64::MOP_cmovbl_m_r:
1176             assmbler.Cmovb(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1177             break;
1178         case x64::MOP_cmovbq_m_r:
1179             assmbler.Cmovb(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1180             break;
1181         case x64::MOP_cmovbew_r_r:
1182             assmbler.Cmovbe(kW, TransferReg(opnd0), TransferReg(opnd1));
1183             break;
1184         case x64::MOP_cmovbel_r_r:
1185             assmbler.Cmovbe(kL, TransferReg(opnd0), TransferReg(opnd1));
1186             break;
1187         case x64::MOP_cmovbeq_r_r:
1188             assmbler.Cmovbe(kQ, TransferReg(opnd0), TransferReg(opnd1));
1189             break;
1190         case x64::MOP_cmovbew_m_r:
1191             assmbler.Cmovbe(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1192             break;
1193         case x64::MOP_cmovbel_m_r:
1194             assmbler.Cmovbe(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1195             break;
1196         case x64::MOP_cmovbeq_m_r:
1197             assmbler.Cmovbe(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1198             break;
1199         /* cmove */
1200         case x64::MOP_cmovew_r_r:
1201             assmbler.Cmove(kW, TransferReg(opnd0), TransferReg(opnd1));
1202             break;
1203         case x64::MOP_cmovel_r_r:
1204             assmbler.Cmove(kL, TransferReg(opnd0), TransferReg(opnd1));
1205             break;
1206         case x64::MOP_cmoveq_r_r:
1207             assmbler.Cmove(kQ, TransferReg(opnd0), TransferReg(opnd1));
1208             break;
1209         case x64::MOP_cmovew_m_r:
1210             assmbler.Cmove(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1211             break;
1212         case x64::MOP_cmovel_m_r:
1213             assmbler.Cmove(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1214             break;
1215         case x64::MOP_cmoveq_m_r:
1216             assmbler.Cmove(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1217             break;
1218         /* cmovg & cmovge */
1219         case x64::MOP_cmovgw_r_r:
1220             assmbler.Cmovg(kW, TransferReg(opnd0), TransferReg(opnd1));
1221             break;
1222         case x64::MOP_cmovgl_r_r:
1223             assmbler.Cmovg(kL, TransferReg(opnd0), TransferReg(opnd1));
1224             break;
1225         case x64::MOP_cmovgq_r_r:
1226             assmbler.Cmovg(kQ, TransferReg(opnd0), TransferReg(opnd1));
1227             break;
1228         case x64::MOP_cmovgw_m_r:
1229             assmbler.Cmovg(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1230             break;
1231         case x64::MOP_cmovgl_m_r:
1232             assmbler.Cmovg(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1233             break;
1234         case x64::MOP_cmovgq_m_r:
1235             assmbler.Cmovg(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1236             break;
1237         case x64::MOP_cmovgew_r_r:
1238             assmbler.Cmovge(kW, TransferReg(opnd0), TransferReg(opnd1));
1239             break;
1240         case x64::MOP_cmovgel_r_r:
1241             assmbler.Cmovge(kL, TransferReg(opnd0), TransferReg(opnd1));
1242             break;
1243         case x64::MOP_cmovgeq_r_r:
1244             assmbler.Cmovge(kQ, TransferReg(opnd0), TransferReg(opnd1));
1245             break;
1246         case x64::MOP_cmovgew_m_r:
1247             assmbler.Cmovge(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1248             break;
1249         case x64::MOP_cmovgel_m_r:
1250             assmbler.Cmovge(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1251             break;
1252         case x64::MOP_cmovgeq_m_r:
1253             assmbler.Cmovge(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1254             break;
1255         /* cmovl & cmovle */
1256         case x64::MOP_cmovlw_r_r:
1257             assmbler.Cmovl(kW, TransferReg(opnd0), TransferReg(opnd1));
1258             break;
1259         case x64::MOP_cmovll_r_r:
1260             assmbler.Cmovl(kL, TransferReg(opnd0), TransferReg(opnd1));
1261             break;
1262         case x64::MOP_cmovlq_r_r:
1263             assmbler.Cmovl(kQ, TransferReg(opnd0), TransferReg(opnd1));
1264             break;
1265         case x64::MOP_cmovlw_m_r:
1266             assmbler.Cmovl(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1267             break;
1268         case x64::MOP_cmovll_m_r:
1269             assmbler.Cmovl(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1270             break;
1271         case x64::MOP_cmovlq_m_r:
1272             assmbler.Cmovl(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1273             break;
1274         case x64::MOP_cmovlew_r_r:
1275             assmbler.Cmovle(kW, TransferReg(opnd0), TransferReg(opnd1));
1276             break;
1277         case x64::MOP_cmovlel_r_r:
1278             assmbler.Cmovle(kL, TransferReg(opnd0), TransferReg(opnd1));
1279             break;
1280         case x64::MOP_cmovleq_r_r:
1281             assmbler.Cmovle(kQ, TransferReg(opnd0), TransferReg(opnd1));
1282             break;
1283         case x64::MOP_cmovlew_m_r:
1284             assmbler.Cmovle(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1285             break;
1286         case x64::MOP_cmovlel_m_r:
1287             assmbler.Cmovle(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1288             break;
1289         case x64::MOP_cmovleq_m_r:
1290             assmbler.Cmovle(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1291             break;
1292         /* cmovne */
1293         case x64::MOP_cmovnew_r_r:
1294             assmbler.Cmovne(kW, TransferReg(opnd0), TransferReg(opnd1));
1295             break;
1296         case x64::MOP_cmovnel_r_r:
1297             assmbler.Cmovne(kL, TransferReg(opnd0), TransferReg(opnd1));
1298             break;
1299         case x64::MOP_cmovneq_r_r:
1300             assmbler.Cmovne(kQ, TransferReg(opnd0), TransferReg(opnd1));
1301             break;
1302         case x64::MOP_cmovnew_m_r:
1303             assmbler.Cmovne(kW, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1304             break;
1305         case x64::MOP_cmovnel_m_r:
1306             assmbler.Cmovne(kL, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1307             break;
1308         case x64::MOP_cmovneq_m_r:
1309             assmbler.Cmovne(kQ, TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1310             break;
1311         case x64::MOP_cmovow_r_r:
1312             assmbler.Cmovo(kW, TransferReg(opnd0), TransferReg(opnd1));
1313             break;
1314         case x64::MOP_cmovol_r_r:
1315             assmbler.Cmovo(kL, TransferReg(opnd0), TransferReg(opnd1));
1316             break;
1317         case x64::MOP_cmovoq_r_r:
1318             assmbler.Cmovo(kQ, TransferReg(opnd0), TransferReg(opnd1));
1319             break;
1320         /* call */
1321         case x64::MOP_callq_r: {
1322             assmbler.Call(kQ, TransferReg(opnd0));
1323             if (insn.GetStackMap() != nullptr) {
1324                 auto referenceMap = insn.GetStackMap()->GetReferenceMap().SerializeInfo();
1325                 auto deoptInfo = insn.GetStackMap()->GetDeoptInfo().SerializeInfo();
1326                 assmbler.RecordStackmap(referenceMap, deoptInfo);
1327             }
1328             break;
1329         }
1330         case x64::MOP_pure_call: {
1331             assmbler.Call(kQ, TransferReg(opnd0));
1332             break;
1333         }
1334         case x64::MOP_callq_l: {
1335             assmbler.Call(kQ, TransferFuncName(opnd0));
1336             if (insn.GetStackMap() != nullptr) {
1337                 auto referenceMap = insn.GetStackMap()->GetReferenceMap().SerializeInfo();
1338                 auto deoptInfo = insn.GetStackMap()->GetDeoptInfo().SerializeInfo();
1339                 assmbler.RecordStackmap(referenceMap, deoptInfo);
1340             }
1341             break;
1342         }
1343 
1344         case x64::MOP_callq_m: {
1345             assmbler.Call(kQ, TransferMem(opnd0, funcUniqueId));
1346             if (insn.GetStackMap() != nullptr) {
1347                 auto referenceMap = insn.GetStackMap()->GetReferenceMap().SerializeInfo();
1348                 auto deoptInfo = insn.GetStackMap()->GetDeoptInfo().SerializeInfo();
1349                 assmbler.RecordStackmap(referenceMap, deoptInfo);
1350             }
1351             break;
1352         }
1353 
1354         /* tail call */
1355         case x64::MOP_tail_callq_r: {
1356             assmbler.Jmp(TransferReg(opnd0));
1357             break;
1358         }
1359         case x64::MOP_tail_callq_l: {
1360             assmbler.Jmp(TransferFuncName(opnd0));
1361             break;
1362         }
1363         case x64::MOP_tail_callq_m: {
1364             assmbler.Jmp(TransferMem(opnd0, funcUniqueId));
1365             break;
1366         }
1367 
1368         /* ret */
1369         case x64::MOP_retq:
1370             assmbler.Ret();
1371             break;
1372         case x64::MOP_leaveq:
1373             assmbler.Leave();
1374             break;
1375         /* imul */
1376         case x64::MOP_imulw_r_r:
1377             assmbler.Imul(kW, TransferReg(opnd0), TransferReg(opnd1));
1378             break;
1379         case x64::MOP_imull_r_r:
1380             assmbler.Imul(kL, TransferReg(opnd0), TransferReg(opnd1));
1381             break;
1382         case x64::MOP_imulq_r_r:
1383             assmbler.Imul(kQ, TransferReg(opnd0), TransferReg(opnd1));
1384             break;
1385         /* mul float */
1386         case x64::MOP_mulfs_r_r:
1387             assmbler.Mul(TransferReg(opnd0), TransferReg(opnd1));
1388             break;
1389         case x64::MOP_mulfd_r_r:
1390             assmbler.Mul(TransferReg(opnd0), TransferReg(opnd1), false);
1391             break;
1392         /* nop */
1393         case x64::MOP_nop:
1394             assmbler.Nop();
1395             break;
1396         /* byte swap */
1397         case x64::MOP_bswapl_r:
1398             assmbler.Bswap(kL, TransferReg(opnd0));
1399             break;
1400         case x64::MOP_bswapq_r:
1401             assmbler.Bswap(kQ, TransferReg(opnd0));
1402             break;
1403         case x64::MOP_xchgb_r_r:
1404             assmbler.Xchg(kB, TransferReg(opnd0), TransferReg(opnd1));
1405             break;
1406         /* pseudo instruction */
1407         case x64::MOP_pseudo_ret_int:
1408             assmbler.DealWithPseudoInst(curMd.GetName());
1409             break;
1410         /* floating point and */
1411         case x64::MOP_andd_r_r:
1412             assmbler.And(TransferReg(opnd0), TransferReg(opnd1), false);
1413             break;
1414         case x64::MOP_ands_r_r:
1415             assmbler.And(TransferReg(opnd0), TransferReg(opnd1));
1416             break;
1417         /* floating div */
1418         case x64::MOP_divsd_r:
1419             assmbler.Divsd(TransferReg(opnd0), TransferReg(opnd1));
1420             break;
1421         case x64::MOP_divsd_m:
1422             assmbler.Divsd(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1423             break;
1424         /* convert int2float */
1425         case x64::MOP_cvtsi2ssq_r:
1426             assmbler.Cvtsi2ss(kQ, TransferReg(opnd0), TransferReg(opnd1));
1427             break;
1428         case x64::MOP_cvtsi2ssl_r:
1429             assmbler.Cvtsi2ss(kL, TransferReg(opnd0), TransferReg(opnd1));
1430             break;
1431         case x64::MOP_cvtsi2sdq_r:
1432             assmbler.Cvtsi2sd(kQ, TransferReg(opnd0), TransferReg(opnd1));
1433             break;
1434         case x64::MOP_cvtsi2sdl_r:
1435             assmbler.Cvtsi2sd(kL, TransferReg(opnd0), TransferReg(opnd1));
1436             break;
1437         /*convert float2int */
1438         case x64::MOP_cvttsd2siq_r:
1439             assmbler.Cvttsd2si(kQ, TransferReg(opnd0), TransferReg(opnd1));
1440             break;
1441         case x64::MOP_cvttsd2sil_r:
1442             assmbler.Cvttsd2si(kL, TransferReg(opnd0), TransferReg(opnd1));
1443             break;
1444         case x64::MOP_cvttss2siq_r:
1445             assmbler.Cvttss2si(kQ, TransferReg(opnd0), TransferReg(opnd1));
1446             break;
1447         case x64::MOP_cvttss2sil_r:
1448             assmbler.Cvttss2si(kL, TransferReg(opnd0), TransferReg(opnd1));
1449             break;
1450         /* convert float2float */
1451         case x64::MOP_cvtss2sd_r:
1452             assmbler.Cvtss2sd(TransferReg(opnd0), TransferReg(opnd1));
1453             break;
1454         case x64::MOP_cvtsd2ss_r:
1455             assmbler.Cvtsd2ss(TransferReg(opnd0), TransferReg(opnd1));
1456             break;
1457         /* unordered compare */
1458         case x64::MOP_ucomisd_r_r:
1459             assmbler.Ucomisd(TransferReg(opnd0), TransferReg(opnd1));
1460             break;
1461         case x64::MOP_cmpeqsd_r_r:
1462             assmbler.Cmpeqsd(TransferReg(opnd0), TransferReg(opnd1));
1463             break;
1464         case x64::MOP_sqrts_r_r:
1465             assmbler.Sqrtss_r(TransferReg(opnd0), TransferReg(opnd1));
1466             break;
1467         case x64::MOP_sqrtd_r_r:
1468             assmbler.Sqrtsd_r(TransferReg(opnd0), TransferReg(opnd1));
1469             break;
1470         case x64::MOP_get_heap_const_table: {
1471             // get machineCode from jsFunction
1472             Mem machineCodeMem;
1473             machineCodeMem.base = TransferReg(opnd1);
1474             machineCodeMem.disp.second = TransferImm(&insn.GetOperand(kInsnThirdOpnd)).first;
1475             machineCodeMem.SetMemType();
1476             assmbler.Mov(kQ, machineCodeMem, TransferReg(opnd0));
1477             // get constantTable from machineCode
1478             Mem constantTableMem;
1479             constantTableMem.base = TransferReg(opnd0);
1480             constantTableMem.disp.second = TransferImm(&insn.GetOperand(kInsnFourthOpnd)).first;
1481             constantTableMem.SetMemType();
1482             assmbler.Mov(kQ, constantTableMem, TransferReg(opnd0));
1483             break;
1484         }
1485         case x64::MOP_heap_const: {
1486             auto heapConstantTable = TransferReg(opnd1);
1487             auto &opnd2 = insn.GetOperand(kInsnThirdOpnd); // heapConstantIndex
1488             auto indexInConstantTable = TransferImm(&opnd2).first;
1489             Mem heapConstMem;
1490             heapConstMem.base = heapConstantTable;
1491             heapConstMem.disp.second = indexInConstantTable * k8ByteSize;
1492             heapConstMem.SetMemType();
1493             assmbler.Mov(kQ, heapConstMem, TransferReg(opnd0));
1494             break;
1495         }
1496         case x64::MOP_tagged_is_heapobject: {
1497             auto &srcReg = insn.GetOperand(kInsnThirdOpnd);
1498             assmbler.Test(kQ, TransferReg(opnd1), TransferReg(&srcReg));
1499             assmbler.Sete(TransferReg(opnd0));
1500             break;
1501         }
1502         case x64::MOP_is_stable_elements: {
1503             Mem bitFieldMem;
1504             bitFieldMem.base = TransferReg(opnd1);
1505             auto &bitFieldOffset = insn.GetOperand(kInsnThirdOpnd);
1506             bitFieldMem.disp.second = TransferImm(&bitFieldOffset).first;
1507             bitFieldMem.SetMemType();
1508             assmbler.Mov(kL, bitFieldMem, TransferReg(opnd0));
1509             auto &stableElemenBit = insn.GetOperand(kInsnFourthOpnd);
1510             assmbler.Shr(kL, TransferImm(&stableElemenBit), TransferReg(opnd0));
1511             ImmOpnd testBit {1, false};
1512             assmbler.And(kL, testBit, TransferReg(opnd0));
1513             break;
1514         }
1515         case MOP_has_pending_exception: {
1516             Mem exceptionMem;
1517             exceptionMem.base = TransferReg(opnd1);
1518             exceptionMem.disp.second = TransferImm(&insn.GetOperand(kInsnThirdOpnd)).first;
1519             exceptionMem.size = k64Bits;
1520             exceptionMem.SetMemType();
1521             ImmOpnd holeOpnd = TransferImm(&insn.GetOperand(kInsnFourthOpnd));
1522             assmbler.Cmp(kQ, holeOpnd, exceptionMem);
1523             assmbler.Setne(TransferReg(opnd0));
1524             break;
1525         }
1526         case x64::MOP_tagged_object_is_string: {
1527             auto dstReg = TransferReg(opnd0);
1528             auto srcReg = TransferReg(&insn.GetOperand(kInsnThirdOpnd));
1529             auto tmpReg1 = TransferReg(&insn.GetOperand(kInsnSeventhOpnd));
1530             auto tmpReg2 = TransferReg(&insn.GetOperand(kInsnEighthOpnd));
1531             Mem hclass;
1532             hclass.base = srcReg;
1533             hclass.disp.second = 0;
1534             hclass.SetMemType();
1535             assmbler.Mov(kQ, hclass, tmpReg2);
1536             Mem bitFieldMem;
1537             bitFieldMem.base = tmpReg2;
1538             auto &bitFieldOffset = insn.GetOperand(kInsnFourthOpnd);
1539             bitFieldMem.disp.second = TransferImm(&bitFieldOffset).first;
1540             bitFieldMem.SetMemType();
1541             bitFieldMem.size = k8ByteSize;
1542             assmbler.MovZx(kB, kL, bitFieldMem, tmpReg1);
1543             auto &stringFirst = insn.GetOperand(kInsnFifthOpnd);
1544             auto &stringLast = insn.GetOperand(kInsnSixthOpnd);
1545             int stringLastValue = TransferImm(&stringLast).first;
1546             int stringFirstValue = TransferImm(&stringFirst).first;
1547             ImmOpnd stringDis {stringLastValue - stringFirstValue, false};
1548             assmbler.Sub(kL, TransferImm(&stringFirst), tmpReg1);
1549             assmbler.Cmp(kL, stringDis, tmpReg1);
1550             assmbler.Setbe(dstReg);
1551             break;
1552         }
1553         case x64::MOP_is_cow_array: {
1554             auto dstReg = TransferReg(opnd0);
1555             auto srcReg = TransferReg(&insn.GetOperand(kInsnThirdOpnd));
1556             auto tmpReg1 = TransferReg(&insn.GetOperand(kInsnEighthOpnd));
1557             auto tmpReg2 = TransferReg(&insn.GetOperand(kInsnNinthOpnd));
1558             Mem elements;
1559             elements.base = srcReg;
1560             auto &elementsOffset = insn.GetOperand(kInsnFourthOpnd);
1561             elements.disp.second = TransferImm(&elementsOffset).first;
1562             elements.SetMemType();
1563             assmbler.Mov(kQ, elements, tmpReg2);
1564             Mem hclass;
1565             hclass.base = tmpReg2;
1566             hclass.disp.second = 0;
1567             hclass.SetMemType();
1568             assmbler.Mov(kQ, hclass, tmpReg2);
1569             Mem bitFieldMem;
1570             bitFieldMem.base = tmpReg2;
1571             auto &bitFieldOffset = insn.GetOperand(kInsnFifthOpnd);
1572             bitFieldMem.disp.second = TransferImm(&bitFieldOffset).first;
1573             bitFieldMem.SetMemType();
1574             bitFieldMem.size = k8ByteSize;
1575             assmbler.MovZx(kB, kL, bitFieldMem, tmpReg1);
1576             auto &cowArrary = insn.GetOperand(kInsnSixthOpnd);
1577             auto &cowArrayLast = insn.GetOperand(kInsnSeventhOpnd);
1578             int cowArrayLastValue = TransferImm(&cowArrayLast).first;
1579             int cowArrayFirstValue = TransferImm(&cowArrary).first;
1580             ImmOpnd cowDis {cowArrayLastValue - cowArrayFirstValue, false};
1581             assmbler.Sub(kL, TransferImm(&cowArrary), tmpReg1);
1582             assmbler.Cmp(kL, cowDis, tmpReg1);
1583             assmbler.Setbe(dstReg);
1584             break;
1585         }
1586         default: {
1587             insn.Dump();
1588             LogInfo::MapleLogger() << "\n";
1589             FATAL(kLncFatal, "unsupported instruction");
1590             break;
1591         }
1592     }
1593 }
1594 
EmitFunctionHeader(CGFunc & cgFunc)1595 void X64Emitter::EmitFunctionHeader(CGFunc &cgFunc)
1596 {
1597     const MIRSymbol *funcSymbol = cgFunc.GetFunction().GetFuncSymbol();
1598     DEBUG_ASSERT(funcSymbol != nullptr, "nullptr check");
1599     uint32 symIdx = funcSymbol->GetNameStrIdx().get();
1600     const string &symName = funcSymbol->GetName();
1601     assmbler.StoreNameIntoSymMap(symIdx, symName);
1602 
1603     SymbolAttr funcAttr = kSAGlobal;
1604     if (funcSymbol->GetFunction()->GetAttr(FUNCATTR_weak)) {
1605         funcAttr = kSAWeak;
1606     } else if (funcSymbol->GetFunction()->GetAttr(FUNCATTR_local)) {
1607         funcAttr = kSALocal;
1608     } else {
1609         funcAttr = kSAHidden;
1610     }
1611     if (cgFunc.GetFunction().GetAttr(FUNCATTR_section)) {
1612         const string &sectionName = cgFunc.GetFunction().GetAttrs().GetPrefixSectionName();
1613         assmbler.EmitFunctionHeader(symIdx, funcAttr, &sectionName);
1614     } else {
1615         assmbler.EmitFunctionHeader(symIdx, funcAttr, nullptr);
1616     }
1617 }
1618 
EmitBBHeaderLabel(CGFunc & cgFunc,LabelIdx labIdx,uint32 freq)1619 void X64Emitter::EmitBBHeaderLabel(CGFunc &cgFunc, LabelIdx labIdx, uint32 freq)
1620 {
1621     uint32 funcUniqueId = cgFunc.GetUniqueID();
1622     /* Concatenate BB Label Name and its idx */
1623     string bbLabel = ".L.";
1624     bbLabel.append(to_string(funcUniqueId));
1625     bbLabel.append("__");
1626     bbLabel.append(to_string(labIdx));
1627     int64 labelSymIdx = CalculateLabelSymIdx(funcUniqueId, labIdx);
1628     assmbler.StoreNameIntoSymMap(labelSymIdx, bbLabel);
1629 
1630     if (cgFunc.GetCG()->GenerateVerboseCG()) {
1631         const string &labelName = cgFunc.GetFunction().GetLabelTab()->GetName(labIdx);
1632         /* If label name has @ as its first char, it is not from MIR */
1633         if (!labelName.empty() && labelName.at(0) != '@') {
1634             assmbler.EmitBBLabel(labelSymIdx, true, freq, &labelName);
1635         } else {
1636             assmbler.EmitBBLabel(labelSymIdx, true, freq);
1637         }
1638     } else {
1639         assmbler.EmitBBLabel(labelSymIdx);
1640     }
1641 }
1642 
1643 /* Specially, emit switch table here */
EmitJmpTable(const CGFunc & cgFunc)1644 void X64Emitter::EmitJmpTable(const CGFunc &cgFunc)
1645 {
1646     for (auto &it : cgFunc.GetEmitStVec()) {
1647         MIRSymbol *st = it.second;
1648         DEBUG_ASSERT(st->IsReadOnly(), "NYI");
1649         uint32 symIdx = st->GetNameStrIdx().get();
1650         const string &symName = st->GetName();
1651         assmbler.StoreNameIntoSymMap(symIdx, symName);
1652 
1653         MIRAggConst *arrayConst = safe_cast<MIRAggConst>(st->GetKonst());
1654         CHECK_NULL_FATAL(arrayConst);
1655         uint32 funcUniqueId = cgFunc.GetUniqueID();
1656         vector<int64> labelSymIdxs;
1657         for (size_t i = 0; i < arrayConst->GetConstVec().size(); i++) {
1658             MIRLblConst *lblConst = safe_cast<MIRLblConst>(arrayConst->GetConstVecItem(i));
1659             CHECK_NULL_FATAL(lblConst);
1660             uint32 labelIdx = lblConst->GetValue();
1661             string labelName = ".L." + to_string(funcUniqueId) + "__" + to_string(labelIdx);
1662             int64 labelSymIdx = CalculateLabelSymIdx(funcUniqueId, labelIdx);
1663             assmbler.StoreNameIntoSymMap(labelSymIdx, labelName);
1664             labelSymIdxs.push_back(labelSymIdx);
1665         }
1666         assmbler.EmitJmpTableElem(symIdx, labelSymIdxs);
1667     }
1668 }
1669 
EmitFunctionFoot(CGFunc & cgFunc)1670 void X64Emitter::EmitFunctionFoot(CGFunc &cgFunc)
1671 {
1672     const MIRSymbol *funcSymbol = cgFunc.GetFunction().GetFuncSymbol();
1673     uint32 symIdx = funcSymbol->GetNameStrIdx().get();
1674     SymbolAttr funcAttr = kSAGlobal;
1675     assmbler.EmitFunctionFoot(symIdx, funcAttr);
1676 }
1677 
EmitArray(MIRConst & mirConst,CG & cg,bool belongsToDataSec)1678 uint64 X64Emitter::EmitArray(MIRConst &mirConst, CG &cg, bool belongsToDataSec)
1679 {
1680     uint64 valueSize = 0;
1681 #ifdef ARK_LITECG_DEBUG
1682     MIRType &mirType = mirConst.GetType();
1683     MIRAggConst &arrayCt = static_cast<MIRAggConst &>(mirConst);
1684     MIRArrayType &arrayType = static_cast<MIRArrayType &>(mirType);
1685     size_t uNum = arrayCt.GetConstVec().size();
1686     uint32 dim = arrayType.GetSizeArrayItem(0);
1687     TyIdx elmTyIdx = arrayType.GetElemTyIdx();
1688     MIRType *subTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(elmTyIdx);
1689     if (uNum == 0 && dim) {
1690         while (subTy->GetKind() == kTypeArray) {
1691             MIRArrayType *aSubTy = static_cast<MIRArrayType *>(subTy);
1692             if (aSubTy->GetSizeArrayItem(0) > 0) {
1693                 dim *= (aSubTy->GetSizeArrayItem(0));
1694             }
1695             elmTyIdx = aSubTy->GetElemTyIdx();
1696             subTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(elmTyIdx);
1697         }
1698     }
1699     for (size_t i = 0; i < uNum; ++i) {
1700         MIRConst *elemConst = arrayCt.GetConstVecItem(i);
1701         if (IsPrimitiveScalar(elemConst->GetType().GetPrimType())) {
1702             valueSize += EmitSingleElement(*elemConst, belongsToDataSec);
1703         } else if (elemConst->GetType().GetKind() == kTypeArray) {
1704             valueSize += EmitArray(*elemConst, cg, belongsToDataSec);
1705         } else if (elemConst->GetKind() == kConstAddrofFunc) {
1706             valueSize += EmitSingleElement(*elemConst, belongsToDataSec);
1707         } else {
1708             DEBUG_ASSERT(false, "should not run here");
1709         }
1710     }
1711     int64 iNum = (static_cast<int64>(arrayType.GetSizeArrayItem(0)) > 0) ?
1712         (static_cast<int64>(arrayType.GetSizeArrayItem(0))) - static_cast<int64>(uNum) : 0;
1713     if (iNum > 0) {
1714         if (uNum > 0) {
1715             uint64 unInSizeInByte =
1716                 static_cast<uint64>(iNum) *
1717                 static_cast<uint64>(GetSymbolSize(arrayCt.GetConstVecItem(0)->GetType().GetTypeIndex()));
1718             if (unInSizeInByte != 0) {
1719                 assmbler.EmitNull(unInSizeInByte);
1720             }
1721         } else {
1722             uint64 sizeInByte = GetSymbolSize(elmTyIdx) * dim;
1723             assmbler.EmitNull(sizeInByte);
1724         }
1725     }
1726 #endif
1727     return valueSize;
1728 }
1729 
EmitAddrofElement(MIRConst & mirConst,bool belongsToDataSec)1730 void X64Emitter::EmitAddrofElement(MIRConst &mirConst, bool belongsToDataSec)
1731 {
1732 #ifdef ARK_LITECG_DEBUG
1733     MIRAddrofConst &symAddr = static_cast<MIRAddrofConst &>(mirConst);
1734     StIdx stIdx = symAddr.GetSymbolIndex();
1735     CHECK_NULL_FATAL(CG::GetCurCGFunc()->GetMirModule().CurFunction());
1736     MIRSymbol *symAddrSym =
1737         stIdx.IsGlobal()
1738             ? GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx())
1739             : CG::GetCurCGFunc()->GetMirModule().CurFunction()->GetSymTab()->GetSymbolFromStIdx(stIdx.Idx());
1740     DEBUG_ASSERT(symAddrSym != nullptr, "symAddrSym should not be nullptr");
1741     string addrName = symAddrSym->GetName();
1742     if (!stIdx.IsGlobal() && symAddrSym->GetStorageClass() == kScPstatic) {
1743         uint32 funcUniqueId = CG::GetCurCGFunc()->GetUniqueID();
1744         addrName += to_string(funcUniqueId);
1745     }
1746     uint32 symIdx = symAddrSym->GetNameStrIdx();
1747     int32 symAddrOfs = 0;
1748     int32 structFieldOfs = 0;
1749     if (symAddr.GetOffset() != 0) {
1750         symAddrOfs = symAddr.GetOffset();
1751     }
1752     assmbler.StoreNameIntoSymMap(symIdx, addrName);
1753     assmbler.EmitAddrValue(symIdx, symAddrOfs, structFieldOfs, belongsToDataSec);
1754 #endif
1755 }
1756 
EmitSingleElement(MIRConst & mirConst,bool belongsToDataSec,bool isIndirect)1757 uint32 X64Emitter::EmitSingleElement(MIRConst &mirConst, bool belongsToDataSec, bool isIndirect)
1758 {
1759     MIRType &elmType = mirConst.GetType();
1760     uint64 elemSize = elmType.GetSize();
1761 #ifdef ARK_LITECG_DEBUG
1762     MIRConstKind kind = mirConst.GetKind();
1763     switch (kind) {
1764         case kConstAddrof:
1765             EmitAddrofElement(mirConst, belongsToDataSec);
1766             break;
1767         case kConstAddrofFunc: {
1768             MIRAddroffuncConst &funcAddr = static_cast<MIRAddroffuncConst &>(mirConst);
1769             MIRFunction *func = GlobalTables::GetFunctionTable().GetFuncTable().at(funcAddr.GetValue());
1770             MIRSymbol *symAddrSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx());
1771             DEBUG_ASSERT(symAddrSym != nullptr, "symAddrSym should not be nullptr");
1772             uint32 symIdx = symAddrSym->GetNameStrIdx();
1773             ASSERT_NOT_NULL(symAddrSym);
1774             const string &name = symAddrSym->GetName();
1775             assmbler.StoreNameIntoSymMap(symIdx, name);
1776             assmbler.EmitAddrOfFuncValue(symIdx, belongsToDataSec);
1777             break;
1778         }
1779         case kConstInt: {
1780             MIRIntConst &intCt = static_cast<MIRIntConst &>(mirConst);
1781             uint32 sizeInBits = elemSize << kLeftShift3Bits;
1782             if (intCt.GetActualBitWidth() > sizeInBits) {
1783                 DEBUG_ASSERT(false, "actual value is larger than expected");
1784             }
1785             int64 value = intCt.GetExtValue();
1786             assmbler.EmitIntValue(value, elemSize, belongsToDataSec);
1787             break;
1788         }
1789         case kConstLblConst: {
1790             MIRLblConst &lbl = static_cast<MIRLblConst &>(mirConst);
1791             uint32 labelIdx = lbl.GetValue();
1792             uint32 funcUniqueId = lbl.GetPUIdx();
1793             string labelName = ".L." + to_string(funcUniqueId) + "__" + to_string(labelIdx);
1794             int64 symIdx = CalculateLabelSymIdx(funcUniqueId, labelIdx);
1795             assmbler.StoreNameIntoSymMap(symIdx, labelName);
1796             assmbler.EmitLabelValue(symIdx, belongsToDataSec);
1797             break;
1798         }
1799         case kConstStrConst: {
1800             MIRStrConst &strCt = static_cast<MIRStrConst &>(mirConst);
1801             if (isIndirect) {
1802                 uint32 strIdx = strCt.GetValue().GetIdx();
1803                 string strName = ".LSTR__" + to_string(strIdx);
1804                 int64 strSymIdx = CalculateStrLabelSymIdx(GlobalTables::GetGsymTable().GetSymbolTableSize(), strIdx);
1805                 stringPtr.push_back(strIdx);
1806                 assmbler.StoreNameIntoSymMap(strSymIdx, strName);
1807                 assmbler.EmitIndirectString(strSymIdx, belongsToDataSec);
1808             } else {
1809                 const string &ustr = GlobalTables::GetUStrTable().GetStringFromStrIdx(strCt.GetValue());
1810                 assmbler.EmitDirectString(ustr, belongsToDataSec);
1811             }
1812             break;
1813         }
1814         default:
1815             FATAL(kLncFatal, "EmitSingleElement: unsupport variable kind");
1816             break;
1817     }
1818 #endif
1819     return elemSize;
1820 }
1821 
EmitLocalVariable(CGFunc & cgFunc)1822 void X64Emitter::EmitLocalVariable(CGFunc &cgFunc)
1823 {
1824     /* function local pstatic initialization */
1825     MIRSymbolTable *lSymTab = cgFunc.GetFunction().GetSymTab();
1826     if (lSymTab != nullptr) {
1827         uint32 funcUniqueId = cgFunc.GetUniqueID();
1828         size_t lsize = lSymTab->GetSymbolTableSize();
1829         vector<string> emittedLocalSym;
1830         for (uint32 i = 0; i < lsize; i++) {
1831             MIRSymbol *symbol = lSymTab->GetSymbolFromStIdx(i);
1832             if (symbol != nullptr && symbol->GetStorageClass() == kScPstatic) {
1833                 const string &symbolName = symbol->GetName() + to_string(funcUniqueId);
1834                 /* Local static names can repeat, if repeat, pass */
1835                 bool found = false;
1836                 for (auto name : emittedLocalSym) {
1837                     if (name == symbolName) {
1838                         found = true;
1839                         break;
1840                     }
1841                 }
1842                 if (found) {
1843                     continue;
1844                 }
1845                 emittedLocalSym.push_back(symbolName);
1846 
1847                 uint32 symIdx = symbol->GetNameStrIdx().get();
1848                 assmbler.StoreNameIntoSymMap(symIdx, symbolName, true);
1849 
1850                 MIRConst *ct = symbol->GetKonst();
1851                 MIRType *ty = symbol->GetType();
1852                 uint64 sizeInByte = GetSymbolSize(ty->GetTypeIndex());
1853                 uint8 alignInByte = GetSymbolAlign(*symbol);
1854                 if (ct == nullptr) {
1855                     alignInByte = GetSymbolAlign(*symbol, true);
1856                     assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSALocal, kSBss);
1857                 } else {
1858                     MIRTypeKind kind = ty->GetKind();
1859                     uint64 valueSize = 0;
1860                     bool isFloatTy =
1861                         (ct->GetKind() == maple::kConstDoubleConst || ct->GetKind() == maple::kConstFloatConst);
1862                     auto secType = isFloatTy ? kSText : kSData;
1863                     assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSALocal, secType);
1864                     if (kind == kTypeArray) {
1865                         valueSize = EmitArray(*ct, *cgFunc.GetCG());
1866                     } else if (isFloatTy) {
1867                         MIRType &elmType = ct->GetType();
1868                         uint64 elemSize = elmType.GetSize();
1869                         if (ct->GetKind() == maple::kConstDoubleConst) {
1870                             MIRDoubleConst &dCt = static_cast<MIRDoubleConst&>(*ct);
1871                             int64 value = dCt.GetIntValue();
1872                             assmbler.EmitFloatValue(symIdx, value, elemSize);
1873                         } else {
1874                             MIRFloatConst &fCt = static_cast<MIRFloatConst&>(*ct);
1875                             int64 value = fCt.GetIntValue();
1876                             assmbler.EmitFloatValue(symIdx, value, elemSize);
1877                         }
1878                     } else {
1879                         valueSize = EmitSingleElement(*ct, true);
1880                     }
1881                     assmbler.PostEmitVariable(symIdx, kSALocal, valueSize, isFloatTy);
1882                 }
1883             }
1884         }
1885     }
1886 }
1887 
EmitStringPointers()1888 void X64Emitter::EmitStringPointers()
1889 {
1890 #ifdef ARK_LITECG_DEBUG
1891     for (uint32 strIdx : stringPtr) {
1892         string ustr = GlobalTables::GetUStrTable().GetStringFromStrIdx(strIdx);
1893         int64 strSymIdx = CalculateStrLabelSymIdx(GlobalTables::GetGsymTable().GetSymbolTableSize(), strIdx);
1894         assmbler.EmitDirectString(ustr, true, strSymIdx);
1895     }
1896 #endif
1897 }
1898 
EmitGlobalVariable(CG & cg)1899 void X64Emitter::EmitGlobalVariable(CG &cg)
1900 {
1901 #ifdef ARK_LITECG_DEBUG
1902     uint64 size = GlobalTables::GetGsymTable().GetSymbolTableSize();
1903     for (uint64 i = 0; i < size; ++i) {
1904         MIRSymbol *mirSymbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(i);
1905 
1906         if (mirSymbol == nullptr || mirSymbol->IsDeleted() || mirSymbol->GetStorageClass() == kScUnused) {
1907             continue;
1908         }
1909 
1910         MIRStorageClass storageClass = mirSymbol->GetStorageClass();
1911         /* symbols we do not emit here. */
1912         if (storageClass == kScTypeInfo || storageClass == kScTypeInfoName || storageClass == kScTypeCxxAbi) {
1913             continue;
1914         }
1915 
1916         MIRType *mirType = mirSymbol->GetType();
1917         if (mirType == nullptr) {
1918             continue;
1919         }
1920         int64 symIdx = mirSymbol->GetNameStrIdx().get();
1921         uint64 sizeInByte = GetSymbolSize(mirType->GetTypeIndex());
1922         uint8 alignInByte = GetSymbolAlign(*mirSymbol);
1923 
1924         /* Uninitialized global/static variables */
1925         if ((storageClass == kScGlobal || storageClass == kScFstatic) && !mirSymbol->IsConst()) {
1926             if (mirSymbol->IsGctibSym()) {
1927                 continue;
1928             }
1929             assmbler.StoreNameIntoSymMap(symIdx, mirSymbol->GetName());
1930             SectionKind secKind;
1931             if (mirSymbol->IsThreadLocal()) {
1932                 secKind = kSTbss;
1933             } else {
1934                 secKind = kSComm;
1935                 alignInByte = GetSymbolAlign(*mirSymbol, true);
1936             }
1937             assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, secKind);
1938             continue;
1939         }
1940         MIRTypeKind kind = mirType->GetKind();
1941         /* Initialized global/static variables. */
1942         if (storageClass == kScGlobal || (storageClass == kScFstatic && !mirSymbol->IsReadOnly())) {
1943             MIRConst *mirConst = mirSymbol->GetKonst();
1944             uint64 valueSize = 0;
1945             assmbler.StoreNameIntoSymMap(symIdx, mirSymbol->GetName());
1946             if (mirSymbol->IsThreadLocal()) {
1947                 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, kSTdata);
1948             } else {
1949                 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, kSData);
1950             }
1951             if (IsPrimitiveScalar(mirType->GetPrimType())) {
1952                 valueSize = EmitSingleElement(*mirConst, true, cg.GetMIRModule()->IsCModule());
1953             } else if (kind == kTypeArray) {
1954                 CHECK_FATAL(!mirSymbol->HasAddrOfValues(), "EmitGlobalVariable: need EmitConstantTable");
1955                 valueSize = EmitArray(*mirConst, cg);
1956             } else {
1957                 DEBUG_ASSERT(false, "EmitGlobalVariable: Unknown mirKind");
1958             }
1959             assmbler.PostEmitVariable(symIdx, kSAGlobal, valueSize);
1960         } else if (mirSymbol->IsReadOnly()) { /* If symbol is const & static */
1961             MIRConst *mirConst = mirSymbol->GetKonst();
1962             assmbler.StoreNameIntoSymMap(symIdx, mirSymbol->GetName());
1963             if (mirConst == nullptr) {
1964                 alignInByte = GetSymbolAlign(*mirSymbol, true);
1965                 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, kSComm);
1966             } else {
1967                 SymbolAttr symAttr = kSAGlobal;
1968                 if (mirSymbol->IsWeak()) {
1969                     symAttr = kSAWeak;
1970                 } else if (storageClass == kScPstatic ||
1971                            (storageClass == kScFstatic && mirSymbol->sectionAttr == UStrIdx(0))) {
1972                     symAttr = kSAStatic;
1973                 }
1974                 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, symAttr, kSRodata);
1975                 if (IsPrimitiveScalar(mirType->GetPrimType())) {
1976                     if (storageClass == kScPstatic) {
1977                         (void)EmitSingleElement(*mirConst, false, true);
1978                     } else {
1979                         (void)EmitSingleElement(*mirConst, false);
1980                     }
1981                 } else if (kind == kTypeArray) {
1982                     (void)EmitArray(*mirConst, cg, false);
1983                 } else {
1984                     FATAL(kLncFatal, "Unknown type in Global pstatic");
1985                 }
1986             }
1987         }
1988     } /* end proccess all mirSymbols. */
1989     EmitStringPointers();
1990 #endif
1991 }
1992 
Run(CGFunc & cgFunc)1993 void X64Emitter::Run(CGFunc &cgFunc)
1994 {
1995     X64CGFunc &x64CGFunc = static_cast<X64CGFunc &>(cgFunc);
1996     uint32 funcUniqueId = cgFunc.GetUniqueID();
1997 
1998     assmbler.SetLastModulePC(cgFunc.GetMirModule().GetLastModulePC());
1999 
2000     /* emit local variable(s) if exists */
2001     EmitLocalVariable(cgFunc);
2002 
2003     /* emit function header */
2004     EmitFunctionHeader(cgFunc);
2005 
2006     /* emit instructions */
2007     FOR_ALL_BB(bb, &x64CGFunc)
2008     {
2009         if (bb->IsUnreachable()) {
2010             continue;
2011         }
2012 
2013         /* emit bb headers */
2014         if (bb->GetLabIdx() != MIRLabelTable::GetDummyLabel()) {
2015             EmitBBHeaderLabel(cgFunc, bb->GetLabIdx(), bb->GetFrequency());
2016         }
2017 
2018         FOR_BB_INSNS(insn, bb)
2019         {
2020             EmitInsn(*insn, funcUniqueId);
2021         }
2022     }
2023 
2024     /* emit switch table if exists */
2025     EmitJmpTable(cgFunc);
2026 
2027     EmitFunctionFoot(cgFunc);
2028 
2029     cgFunc.GetMirModule().SetCurModulePC(assmbler.GetCurModulePC());
2030 
2031     assmbler.ClearLocalSymMap();
2032 }
2033 } /* namespace maplebe */
2034