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 /* ret */
1355 case x64::MOP_retq:
1356 assmbler.Ret();
1357 break;
1358 case x64::MOP_leaveq:
1359 assmbler.Leave();
1360 break;
1361 /* imul */
1362 case x64::MOP_imulw_r_r:
1363 assmbler.Imul(kW, TransferReg(opnd0), TransferReg(opnd1));
1364 break;
1365 case x64::MOP_imull_r_r:
1366 assmbler.Imul(kL, TransferReg(opnd0), TransferReg(opnd1));
1367 break;
1368 case x64::MOP_imulq_r_r:
1369 assmbler.Imul(kQ, TransferReg(opnd0), TransferReg(opnd1));
1370 break;
1371 /* mul float */
1372 case x64::MOP_mulfs_r_r:
1373 assmbler.Mul(TransferReg(opnd0), TransferReg(opnd1));
1374 break;
1375 case x64::MOP_mulfd_r_r:
1376 assmbler.Mul(TransferReg(opnd0), TransferReg(opnd1), false);
1377 break;
1378 /* nop */
1379 case x64::MOP_nop:
1380 assmbler.Nop();
1381 break;
1382 /* byte swap */
1383 case x64::MOP_bswapl_r:
1384 assmbler.Bswap(kL, TransferReg(opnd0));
1385 break;
1386 case x64::MOP_bswapq_r:
1387 assmbler.Bswap(kQ, TransferReg(opnd0));
1388 break;
1389 case x64::MOP_xchgb_r_r:
1390 assmbler.Xchg(kB, TransferReg(opnd0), TransferReg(opnd1));
1391 break;
1392 /* pseudo instruction */
1393 case x64::MOP_pseudo_ret_int:
1394 assmbler.DealWithPseudoInst(curMd.GetName());
1395 break;
1396 /* floating point and */
1397 case x64::MOP_andd_r_r:
1398 assmbler.And(TransferReg(opnd0), TransferReg(opnd1), false);
1399 break;
1400 case x64::MOP_ands_r_r:
1401 assmbler.And(TransferReg(opnd0), TransferReg(opnd1));
1402 break;
1403 /* floating div */
1404 case x64::MOP_divsd_r:
1405 assmbler.Divsd(TransferReg(opnd0), TransferReg(opnd1));
1406 break;
1407 case x64::MOP_divsd_m:
1408 assmbler.Divsd(TransferMem(opnd0, funcUniqueId), TransferReg(opnd1));
1409 break;
1410 /* convert int2float */
1411 case x64::MOP_cvtsi2ssq_r:
1412 assmbler.Cvtsi2ss(kQ, TransferReg(opnd0), TransferReg(opnd1));
1413 break;
1414 case x64::MOP_cvtsi2ssl_r:
1415 assmbler.Cvtsi2ss(kL, TransferReg(opnd0), TransferReg(opnd1));
1416 break;
1417 case x64::MOP_cvtsi2sdq_r:
1418 assmbler.Cvtsi2sd(kQ, TransferReg(opnd0), TransferReg(opnd1));
1419 break;
1420 case x64::MOP_cvtsi2sdl_r:
1421 assmbler.Cvtsi2sd(kL, TransferReg(opnd0), TransferReg(opnd1));
1422 break;
1423 /*convert float2int */
1424 case x64::MOP_cvttsd2siq_r:
1425 assmbler.Cvttsd2si(kQ, TransferReg(opnd0), TransferReg(opnd1));
1426 break;
1427 case x64::MOP_cvttsd2sil_r:
1428 assmbler.Cvttsd2si(kL, TransferReg(opnd0), TransferReg(opnd1));
1429 break;
1430 case x64::MOP_cvttss2siq_r:
1431 assmbler.Cvttss2si(kQ, TransferReg(opnd0), TransferReg(opnd1));
1432 break;
1433 case x64::MOP_cvttss2sil_r:
1434 assmbler.Cvttss2si(kL, TransferReg(opnd0), TransferReg(opnd1));
1435 break;
1436 /* convert float2float */
1437 case x64::MOP_cvtss2sd_r:
1438 assmbler.Cvtss2sd(TransferReg(opnd0), TransferReg(opnd1));
1439 break;
1440 case x64::MOP_cvtsd2ss_r:
1441 assmbler.Cvtsd2ss(TransferReg(opnd0), TransferReg(opnd1));
1442 break;
1443 /* unordered compare */
1444 case x64::MOP_ucomisd_r_r:
1445 assmbler.Ucomisd(TransferReg(opnd0), TransferReg(opnd1));
1446 break;
1447 case x64::MOP_cmpeqsd_r_r:
1448 assmbler.Cmpeqsd(TransferReg(opnd0), TransferReg(opnd1));
1449 break;
1450 case x64::MOP_sqrts_r_r:
1451 assmbler.Sqrtss_r(TransferReg(opnd0), TransferReg(opnd1));
1452 break;
1453 case x64::MOP_sqrtd_r_r:
1454 assmbler.Sqrtsd_r(TransferReg(opnd0), TransferReg(opnd1));
1455 break;
1456 default: {
1457 insn.Dump();
1458 LogInfo::MapleLogger() << "\n";
1459 FATAL(kLncFatal, "unsupported instruction");
1460 break;
1461 }
1462 }
1463 }
1464
EmitFunctionHeader(CGFunc & cgFunc)1465 void X64Emitter::EmitFunctionHeader(CGFunc &cgFunc)
1466 {
1467 const MIRSymbol *funcSymbol = cgFunc.GetFunction().GetFuncSymbol();
1468 DEBUG_ASSERT(funcSymbol != nullptr, "nullptr check");
1469 uint32 symIdx = funcSymbol->GetNameStrIdx().get();
1470 const string &symName = funcSymbol->GetName();
1471 assmbler.StoreNameIntoSymMap(symIdx, symName);
1472
1473 SymbolAttr funcAttr = kSAGlobal;
1474 if (funcSymbol->GetFunction()->GetAttr(FUNCATTR_weak)) {
1475 funcAttr = kSAWeak;
1476 } else if (funcSymbol->GetFunction()->GetAttr(FUNCATTR_local)) {
1477 funcAttr = kSALocal;
1478 } else {
1479 funcAttr = kSAHidden;
1480 }
1481 if (cgFunc.GetFunction().GetAttr(FUNCATTR_section)) {
1482 const string §ionName = cgFunc.GetFunction().GetAttrs().GetPrefixSectionName();
1483 assmbler.EmitFunctionHeader(symIdx, funcAttr, §ionName);
1484 } else {
1485 assmbler.EmitFunctionHeader(symIdx, funcAttr, nullptr);
1486 }
1487 }
1488
EmitBBHeaderLabel(CGFunc & cgFunc,LabelIdx labIdx,uint32 freq)1489 void X64Emitter::EmitBBHeaderLabel(CGFunc &cgFunc, LabelIdx labIdx, uint32 freq)
1490 {
1491 uint32 funcUniqueId = cgFunc.GetUniqueID();
1492 /* Concatenate BB Label Name and its idx */
1493 string bbLabel = ".L.";
1494 bbLabel.append(to_string(funcUniqueId));
1495 bbLabel.append("__");
1496 bbLabel.append(to_string(labIdx));
1497 int64 labelSymIdx = CalculateLabelSymIdx(funcUniqueId, labIdx);
1498 assmbler.StoreNameIntoSymMap(labelSymIdx, bbLabel);
1499
1500 if (cgFunc.GetCG()->GenerateVerboseCG()) {
1501 const string &labelName = cgFunc.GetFunction().GetLabelTab()->GetName(labIdx);
1502 /* If label name has @ as its first char, it is not from MIR */
1503 if (!labelName.empty() && labelName.at(0) != '@') {
1504 assmbler.EmitBBLabel(labelSymIdx, true, freq, &labelName);
1505 } else {
1506 assmbler.EmitBBLabel(labelSymIdx, true, freq);
1507 }
1508 } else {
1509 assmbler.EmitBBLabel(labelSymIdx);
1510 }
1511 }
1512
1513 /* Specially, emit switch table here */
EmitJmpTable(const CGFunc & cgFunc)1514 void X64Emitter::EmitJmpTable(const CGFunc &cgFunc)
1515 {
1516 for (auto &it : cgFunc.GetEmitStVec()) {
1517 MIRSymbol *st = it.second;
1518 DEBUG_ASSERT(st->IsReadOnly(), "NYI");
1519 uint32 symIdx = st->GetNameStrIdx().get();
1520 const string &symName = st->GetName();
1521 assmbler.StoreNameIntoSymMap(symIdx, symName);
1522
1523 MIRAggConst *arrayConst = safe_cast<MIRAggConst>(st->GetKonst());
1524 CHECK_NULL_FATAL(arrayConst);
1525 uint32 funcUniqueId = cgFunc.GetUniqueID();
1526 vector<int64> labelSymIdxs;
1527 for (size_t i = 0; i < arrayConst->GetConstVec().size(); i++) {
1528 MIRLblConst *lblConst = safe_cast<MIRLblConst>(arrayConst->GetConstVecItem(i));
1529 CHECK_NULL_FATAL(lblConst);
1530 uint32 labelIdx = lblConst->GetValue();
1531 string labelName = ".L." + to_string(funcUniqueId) + "__" + to_string(labelIdx);
1532 int64 labelSymIdx = CalculateLabelSymIdx(funcUniqueId, labelIdx);
1533 assmbler.StoreNameIntoSymMap(labelSymIdx, labelName);
1534 labelSymIdxs.push_back(labelSymIdx);
1535 }
1536 assmbler.EmitJmpTableElem(symIdx, labelSymIdxs);
1537 }
1538 }
1539
EmitFunctionFoot(CGFunc & cgFunc)1540 void X64Emitter::EmitFunctionFoot(CGFunc &cgFunc)
1541 {
1542 const MIRSymbol *funcSymbol = cgFunc.GetFunction().GetFuncSymbol();
1543 uint32 symIdx = funcSymbol->GetNameStrIdx().get();
1544 SymbolAttr funcAttr = kSAGlobal;
1545 assmbler.EmitFunctionFoot(symIdx, funcAttr);
1546 }
1547
EmitArray(MIRConst & mirConst,CG & cg,bool belongsToDataSec)1548 uint64 X64Emitter::EmitArray(MIRConst &mirConst, CG &cg, bool belongsToDataSec)
1549 {
1550 uint64 valueSize = 0;
1551 #ifdef ARK_LITECG_DEBUG
1552 MIRType &mirType = mirConst.GetType();
1553 MIRAggConst &arrayCt = static_cast<MIRAggConst &>(mirConst);
1554 MIRArrayType &arrayType = static_cast<MIRArrayType &>(mirType);
1555 size_t uNum = arrayCt.GetConstVec().size();
1556 uint32 dim = arrayType.GetSizeArrayItem(0);
1557 TyIdx elmTyIdx = arrayType.GetElemTyIdx();
1558 MIRType *subTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(elmTyIdx);
1559 if (uNum == 0 && dim) {
1560 while (subTy->GetKind() == kTypeArray) {
1561 MIRArrayType *aSubTy = static_cast<MIRArrayType *>(subTy);
1562 if (aSubTy->GetSizeArrayItem(0) > 0) {
1563 dim *= (aSubTy->GetSizeArrayItem(0));
1564 }
1565 elmTyIdx = aSubTy->GetElemTyIdx();
1566 subTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(elmTyIdx);
1567 }
1568 }
1569 for (size_t i = 0; i < uNum; ++i) {
1570 MIRConst *elemConst = arrayCt.GetConstVecItem(i);
1571 if (IsPrimitiveScalar(elemConst->GetType().GetPrimType())) {
1572 valueSize += EmitSingleElement(*elemConst, belongsToDataSec);
1573 } else if (elemConst->GetType().GetKind() == kTypeArray) {
1574 valueSize += EmitArray(*elemConst, cg, belongsToDataSec);
1575 } else if (elemConst->GetKind() == kConstAddrofFunc) {
1576 valueSize += EmitSingleElement(*elemConst, belongsToDataSec);
1577 } else {
1578 DEBUG_ASSERT(false, "should not run here");
1579 }
1580 }
1581 int64 iNum = (static_cast<int64>(arrayType.GetSizeArrayItem(0)) > 0) ?
1582 (static_cast<int64>(arrayType.GetSizeArrayItem(0))) - static_cast<int64>(uNum) : 0;
1583 if (iNum > 0) {
1584 if (uNum > 0) {
1585 uint64 unInSizeInByte =
1586 static_cast<uint64>(iNum) *
1587 static_cast<uint64>(GetSymbolSize(arrayCt.GetConstVecItem(0)->GetType().GetTypeIndex()));
1588 if (unInSizeInByte != 0) {
1589 assmbler.EmitNull(unInSizeInByte);
1590 }
1591 } else {
1592 uint64 sizeInByte = GetSymbolSize(elmTyIdx) * dim;
1593 assmbler.EmitNull(sizeInByte);
1594 }
1595 }
1596 #endif
1597 return valueSize;
1598 }
1599
EmitAddrofElement(MIRConst & mirConst,bool belongsToDataSec)1600 void X64Emitter::EmitAddrofElement(MIRConst &mirConst, bool belongsToDataSec)
1601 {
1602 #ifdef ARK_LITECG_DEBUG
1603 MIRAddrofConst &symAddr = static_cast<MIRAddrofConst &>(mirConst);
1604 StIdx stIdx = symAddr.GetSymbolIndex();
1605 CHECK_NULL_FATAL(CG::GetCurCGFunc()->GetMirModule().CurFunction());
1606 MIRSymbol *symAddrSym =
1607 stIdx.IsGlobal()
1608 ? GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx())
1609 : CG::GetCurCGFunc()->GetMirModule().CurFunction()->GetSymTab()->GetSymbolFromStIdx(stIdx.Idx());
1610 DEBUG_ASSERT(symAddrSym != nullptr, "symAddrSym should not be nullptr");
1611 string addrName = symAddrSym->GetName();
1612 if (!stIdx.IsGlobal() && symAddrSym->GetStorageClass() == kScPstatic) {
1613 uint32 funcUniqueId = CG::GetCurCGFunc()->GetUniqueID();
1614 addrName += to_string(funcUniqueId);
1615 }
1616 uint32 symIdx = symAddrSym->GetNameStrIdx();
1617 int32 symAddrOfs = 0;
1618 int32 structFieldOfs = 0;
1619 if (symAddr.GetOffset() != 0) {
1620 symAddrOfs = symAddr.GetOffset();
1621 }
1622 assmbler.StoreNameIntoSymMap(symIdx, addrName);
1623 assmbler.EmitAddrValue(symIdx, symAddrOfs, structFieldOfs, belongsToDataSec);
1624 #endif
1625 }
1626
EmitSingleElement(MIRConst & mirConst,bool belongsToDataSec,bool isIndirect)1627 uint32 X64Emitter::EmitSingleElement(MIRConst &mirConst, bool belongsToDataSec, bool isIndirect)
1628 {
1629 MIRType &elmType = mirConst.GetType();
1630 uint64 elemSize = elmType.GetSize();
1631 #ifdef ARK_LITECG_DEBUG
1632 MIRConstKind kind = mirConst.GetKind();
1633 switch (kind) {
1634 case kConstAddrof:
1635 EmitAddrofElement(mirConst, belongsToDataSec);
1636 break;
1637 case kConstAddrofFunc: {
1638 MIRAddroffuncConst &funcAddr = static_cast<MIRAddroffuncConst &>(mirConst);
1639 MIRFunction *func = GlobalTables::GetFunctionTable().GetFuncTable().at(funcAddr.GetValue());
1640 MIRSymbol *symAddrSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx());
1641 DEBUG_ASSERT(symAddrSym != nullptr, "symAddrSym should not be nullptr");
1642 uint32 symIdx = symAddrSym->GetNameStrIdx();
1643 ASSERT_NOT_NULL(symAddrSym);
1644 const string &name = symAddrSym->GetName();
1645 assmbler.StoreNameIntoSymMap(symIdx, name);
1646 assmbler.EmitAddrOfFuncValue(symIdx, belongsToDataSec);
1647 break;
1648 }
1649 case kConstInt: {
1650 MIRIntConst &intCt = static_cast<MIRIntConst &>(mirConst);
1651 uint32 sizeInBits = elemSize << kLeftShift3Bits;
1652 if (intCt.GetActualBitWidth() > sizeInBits) {
1653 DEBUG_ASSERT(false, "actual value is larger than expected");
1654 }
1655 int64 value = intCt.GetExtValue();
1656 assmbler.EmitIntValue(value, elemSize, belongsToDataSec);
1657 break;
1658 }
1659 case kConstLblConst: {
1660 MIRLblConst &lbl = static_cast<MIRLblConst &>(mirConst);
1661 uint32 labelIdx = lbl.GetValue();
1662 uint32 funcUniqueId = lbl.GetPUIdx();
1663 string labelName = ".L." + to_string(funcUniqueId) + "__" + to_string(labelIdx);
1664 int64 symIdx = CalculateLabelSymIdx(funcUniqueId, labelIdx);
1665 assmbler.StoreNameIntoSymMap(symIdx, labelName);
1666 assmbler.EmitLabelValue(symIdx, belongsToDataSec);
1667 break;
1668 }
1669 case kConstStrConst: {
1670 MIRStrConst &strCt = static_cast<MIRStrConst &>(mirConst);
1671 if (isIndirect) {
1672 uint32 strIdx = strCt.GetValue().GetIdx();
1673 string strName = ".LSTR__" + to_string(strIdx);
1674 int64 strSymIdx = CalculateStrLabelSymIdx(GlobalTables::GetGsymTable().GetSymbolTableSize(), strIdx);
1675 stringPtr.push_back(strIdx);
1676 assmbler.StoreNameIntoSymMap(strSymIdx, strName);
1677 assmbler.EmitIndirectString(strSymIdx, belongsToDataSec);
1678 } else {
1679 const string &ustr = GlobalTables::GetUStrTable().GetStringFromStrIdx(strCt.GetValue());
1680 assmbler.EmitDirectString(ustr, belongsToDataSec);
1681 }
1682 break;
1683 }
1684 default:
1685 FATAL(kLncFatal, "EmitSingleElement: unsupport variable kind");
1686 break;
1687 }
1688 #endif
1689 return elemSize;
1690 }
1691
EmitLocalVariable(CGFunc & cgFunc)1692 void X64Emitter::EmitLocalVariable(CGFunc &cgFunc)
1693 {
1694 /* function local pstatic initialization */
1695 MIRSymbolTable *lSymTab = cgFunc.GetFunction().GetSymTab();
1696 if (lSymTab != nullptr) {
1697 uint32 funcUniqueId = cgFunc.GetUniqueID();
1698 size_t lsize = lSymTab->GetSymbolTableSize();
1699 vector<string> emittedLocalSym;
1700 for (uint32 i = 0; i < lsize; i++) {
1701 MIRSymbol *symbol = lSymTab->GetSymbolFromStIdx(i);
1702 if (symbol != nullptr && symbol->GetStorageClass() == kScPstatic) {
1703 const string &symbolName = symbol->GetName() + to_string(funcUniqueId);
1704 /* Local static names can repeat, if repeat, pass */
1705 bool found = false;
1706 for (auto name : emittedLocalSym) {
1707 if (name == symbolName) {
1708 found = true;
1709 break;
1710 }
1711 }
1712 if (found) {
1713 continue;
1714 }
1715 emittedLocalSym.push_back(symbolName);
1716
1717 uint32 symIdx = symbol->GetNameStrIdx().get();
1718 assmbler.StoreNameIntoSymMap(symIdx, symbolName, true);
1719
1720 MIRConst *ct = symbol->GetKonst();
1721 MIRType *ty = symbol->GetType();
1722 uint64 sizeInByte = GetSymbolSize(ty->GetTypeIndex());
1723 uint8 alignInByte = GetSymbolAlign(*symbol);
1724 if (ct == nullptr) {
1725 alignInByte = GetSymbolAlign(*symbol, true);
1726 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSALocal, kSBss);
1727 } else {
1728 MIRTypeKind kind = ty->GetKind();
1729 uint64 valueSize = 0;
1730 bool isFloatTy =
1731 (ct->GetKind() == maple::kConstDoubleConst || ct->GetKind() == maple::kConstFloatConst);
1732 auto secType = isFloatTy ? kSText : kSData;
1733 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSALocal, secType);
1734 if (kind == kTypeArray) {
1735 valueSize = EmitArray(*ct, *cgFunc.GetCG());
1736 } else if (isFloatTy) {
1737 MIRType &elmType = ct->GetType();
1738 uint64 elemSize = elmType.GetSize();
1739 if (ct->GetKind() == maple::kConstDoubleConst) {
1740 MIRDoubleConst &dCt = static_cast<MIRDoubleConst&>(*ct);
1741 int64 value = dCt.GetIntValue();
1742 assmbler.EmitFloatValue(symIdx, value, elemSize);
1743 } else {
1744 MIRFloatConst &fCt = static_cast<MIRFloatConst&>(*ct);
1745 int64 value = fCt.GetIntValue();
1746 assmbler.EmitFloatValue(symIdx, value, elemSize);
1747 }
1748 } else {
1749 valueSize = EmitSingleElement(*ct, true);
1750 }
1751 assmbler.PostEmitVariable(symIdx, kSALocal, valueSize, isFloatTy);
1752 }
1753 }
1754 }
1755 }
1756 }
1757
EmitStringPointers()1758 void X64Emitter::EmitStringPointers()
1759 {
1760 #ifdef ARK_LITECG_DEBUG
1761 for (uint32 strIdx : stringPtr) {
1762 string ustr = GlobalTables::GetUStrTable().GetStringFromStrIdx(strIdx);
1763 int64 strSymIdx = CalculateStrLabelSymIdx(GlobalTables::GetGsymTable().GetSymbolTableSize(), strIdx);
1764 assmbler.EmitDirectString(ustr, true, strSymIdx);
1765 }
1766 #endif
1767 }
1768
EmitGlobalVariable(CG & cg)1769 void X64Emitter::EmitGlobalVariable(CG &cg)
1770 {
1771 #ifdef ARK_LITECG_DEBUG
1772 uint64 size = GlobalTables::GetGsymTable().GetSymbolTableSize();
1773 for (uint64 i = 0; i < size; ++i) {
1774 MIRSymbol *mirSymbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(i);
1775
1776 if (mirSymbol == nullptr || mirSymbol->IsDeleted() || mirSymbol->GetStorageClass() == kScUnused) {
1777 continue;
1778 }
1779
1780 MIRStorageClass storageClass = mirSymbol->GetStorageClass();
1781 /* symbols we do not emit here. */
1782 if (storageClass == kScTypeInfo || storageClass == kScTypeInfoName || storageClass == kScTypeCxxAbi) {
1783 continue;
1784 }
1785
1786 MIRType *mirType = mirSymbol->GetType();
1787 if (mirType == nullptr) {
1788 continue;
1789 }
1790 int64 symIdx = mirSymbol->GetNameStrIdx().get();
1791 uint64 sizeInByte = GetSymbolSize(mirType->GetTypeIndex());
1792 uint8 alignInByte = GetSymbolAlign(*mirSymbol);
1793
1794 /* Uninitialized global/static variables */
1795 if ((storageClass == kScGlobal || storageClass == kScFstatic) && !mirSymbol->IsConst()) {
1796 if (mirSymbol->IsGctibSym()) {
1797 continue;
1798 }
1799 assmbler.StoreNameIntoSymMap(symIdx, mirSymbol->GetName());
1800 SectionKind secKind;
1801 if (mirSymbol->IsThreadLocal()) {
1802 secKind = kSTbss;
1803 } else {
1804 secKind = kSComm;
1805 alignInByte = GetSymbolAlign(*mirSymbol, true);
1806 }
1807 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, secKind);
1808 continue;
1809 }
1810 MIRTypeKind kind = mirType->GetKind();
1811 /* Initialized global/static variables. */
1812 if (storageClass == kScGlobal || (storageClass == kScFstatic && !mirSymbol->IsReadOnly())) {
1813 MIRConst *mirConst = mirSymbol->GetKonst();
1814 uint64 valueSize = 0;
1815 assmbler.StoreNameIntoSymMap(symIdx, mirSymbol->GetName());
1816 if (mirSymbol->IsThreadLocal()) {
1817 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, kSTdata);
1818 } else {
1819 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, kSData);
1820 }
1821 if (IsPrimitiveScalar(mirType->GetPrimType())) {
1822 valueSize = EmitSingleElement(*mirConst, true, cg.GetMIRModule()->IsCModule());
1823 } else if (kind == kTypeArray) {
1824 CHECK_FATAL(!mirSymbol->HasAddrOfValues(), "EmitGlobalVariable: need EmitConstantTable");
1825 valueSize = EmitArray(*mirConst, cg);
1826 } else {
1827 DEBUG_ASSERT(false, "EmitGlobalVariable: Unknown mirKind");
1828 }
1829 assmbler.PostEmitVariable(symIdx, kSAGlobal, valueSize);
1830 } else if (mirSymbol->IsReadOnly()) { /* If symbol is const & static */
1831 MIRConst *mirConst = mirSymbol->GetKonst();
1832 assmbler.StoreNameIntoSymMap(symIdx, mirSymbol->GetName());
1833 if (mirConst == nullptr) {
1834 alignInByte = GetSymbolAlign(*mirSymbol, true);
1835 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, kSAGlobal, kSComm);
1836 } else {
1837 SymbolAttr symAttr = kSAGlobal;
1838 if (mirSymbol->IsWeak()) {
1839 symAttr = kSAWeak;
1840 } else if (storageClass == kScPstatic ||
1841 (storageClass == kScFstatic && mirSymbol->sectionAttr == UStrIdx(0))) {
1842 symAttr = kSAStatic;
1843 }
1844 assmbler.EmitVariable(symIdx, sizeInByte, alignInByte, symAttr, kSRodata);
1845 if (IsPrimitiveScalar(mirType->GetPrimType())) {
1846 if (storageClass == kScPstatic) {
1847 (void)EmitSingleElement(*mirConst, false, true);
1848 } else {
1849 (void)EmitSingleElement(*mirConst, false);
1850 }
1851 } else if (kind == kTypeArray) {
1852 (void)EmitArray(*mirConst, cg, false);
1853 } else {
1854 FATAL(kLncFatal, "Unknown type in Global pstatic");
1855 }
1856 }
1857 }
1858 } /* end proccess all mirSymbols. */
1859 EmitStringPointers();
1860 #endif
1861 }
1862
Run(CGFunc & cgFunc)1863 void X64Emitter::Run(CGFunc &cgFunc)
1864 {
1865 X64CGFunc &x64CGFunc = static_cast<X64CGFunc &>(cgFunc);
1866 uint32 funcUniqueId = cgFunc.GetUniqueID();
1867
1868 assmbler.SetLastModulePC(cgFunc.GetMirModule().GetLastModulePC());
1869
1870 /* emit local variable(s) if exists */
1871 EmitLocalVariable(cgFunc);
1872
1873 /* emit function header */
1874 EmitFunctionHeader(cgFunc);
1875
1876 /* emit instructions */
1877 FOR_ALL_BB(bb, &x64CGFunc)
1878 {
1879 if (bb->IsUnreachable()) {
1880 continue;
1881 }
1882
1883 /* emit bb headers */
1884 if (bb->GetLabIdx() != MIRLabelTable::GetDummyLabel()) {
1885 EmitBBHeaderLabel(cgFunc, bb->GetLabIdx(), bb->GetFrequency());
1886 }
1887
1888 FOR_BB_INSNS(insn, bb)
1889 {
1890 EmitInsn(*insn, funcUniqueId);
1891 }
1892 }
1893
1894 /* emit switch table if exists */
1895 EmitJmpTable(cgFunc);
1896
1897 EmitFunctionFoot(cgFunc);
1898
1899 cgFunc.GetMirModule().SetCurModulePC(assmbler.GetCurModulePC());
1900
1901 assmbler.ClearLocalSymMap();
1902 }
1903 } /* namespace maplebe */
1904