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