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