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 §ionName = cgFunc.GetFunction().GetAttrs().GetPrefixSectionName();
1613 assmbler.EmitFunctionHeader(symIdx, funcAttr, §ionName);
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