• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ASM_ASSEMBLER_H
17 #define ASM_ASSEMBLER_H
18 
19 #include "assembler.h"
20 
21 namespace assembler {
22 
23 #if TARGRISCV64
24 #define CMNT "\t# "
25 #else
26 #define CMNT "\t// "
27 #endif
28 #define TEXT_BEGIN text0
29 #define TEXT_END etext0
30 #define DEBUG_INFO_0 debug_info0
31 #define DEBUG_ABBREV_0 debug_abbrev0
32 #define DEBUG_LINE_0 debug_line0
33 #define DEBUG_STR_LABEL ASF
34 
35 #define XSTR(s) #s
36 
37 enum Directive : uint8 { kAlign, kComm, kFile, kFuncType, kHidden, kName, kObjType, kSection, kSize, kZero };
38 
39 class AsmAssembler : public Assembler {
40 public:
AsmAssembler(const std::string & outputFileName)41     explicit AsmAssembler(const std::string &outputFileName) : Assembler()
42     {
43         outFStream.open(outputFileName, std::ios::trunc);
44     }
45 
46     ~AsmAssembler() = default;
47 
CloseOutput()48     void CloseOutput() override
49     {
50         Assembler::CloseOutput();
51 
52         auto options = maplebe::CGOptions::GetInstance();
53         options.GetLogStream() << "~~~~~~~~~~~~~~ LiteCG x64 disasm begin ~~~~~~~~~~~~~~\n";
54         options.GetLogStream() << outStream.str();
55         options.GetLogStream() << "~~~~~~~~~~~~~~ LiteCG x64 disasm end  ~~~~~~~~~~~~~~~\n";
56     }
57 
58     void InitialFileInfo(const std::string &inputFileName) override;
59     void EmitFunctionHeader(int64 symIdx, SymbolAttr funcAttr, const std::string *secName) override;
60     void EmitBBLabel(int64 labelSymIdx, bool genVerboseInfo, uint32 freq, const std::string *mirName) override;
61     void EmitJmpTableElem(int64 jmpLabelIdx, const std::vector<int64> &labelIdxs) override;
62     void EmitFunctionFoot(int64 symIdx, SymbolAttr funcAttr) override;
63     /* emit variable's value */
64     void EmitVariable(int64 symIdx, uint64 sizeInByte, uint8 alignInByte, SymbolAttr symAttr,
65                       SectionKind sectionKind) override;
66     void EmitDirectString(const std::string &ustr, bool belongsToDataSec, int64 strSymIdx, bool emitAscii) override;
67     void EmitIndirectString(int64 strSymIdx, bool belongsToDataSec) override;
68     void EmitIntValue(int64 value, size_t valueSize, bool belongsToDataSec) override;
69     void EmitFloatValue(int64 symIdx, int64 value, size_t valueSize) override;
70     void EmitAddrValue(int64 symIdx, int32 symAddrOfs, int32 structFieldOfs, bool belongsToDataSec) override;
71     void EmitAddrOfFuncValue(int64 symIdx, bool belongsToDataSec) override;
72     void EmitLabelValue(int64 symIdx, bool belongsToDataSec) override;
73     void EmitBitFieldValue(uint64 combineBitFieldValue, bool belongsToDataSec) override;
74     void EmitNull(uint64 sizeInByte) override;
75     void PostEmitVariable(int64 symIdx, SymbolAttr symAttr, uint64 sizeInByte, bool belongsToTextSec) override;
FinalizeFileInfo()76     void FinalizeFileInfo() override {}
77 
78     /* emit debug info */
79     void EmitDIHeader() override;
80     void EmitDIFooter() override;
81     void EmitDIHeaderFileInfo() override;
82     void EmitDIDebugInfoSectionHeader(uint64 debugInfoLength) override;
83     void EmitDIDebugInfoSectionAbbrevId(bool verbose, uint32 abbrevId, const std::string &dieTagName, uint32 offset,
84                                         uint32 size) override;
85     void EmitDIFormSpecification(unsigned int dwform) override;
86     void EmitDebugComment(const char* comment) override;
87 
88     /* EmitDIAttrValue */
89     void EmitDwFormString(const std::string &name) override;
90     void EmitDwFormStrp(uint32 strLabelId, size_t strTableSize) override;
91     void EmitDwFormData(int32 attrValue, uint8 sizeInByte) override;
92     void EmitDwFormData8() override;
93     void EmitDwFormData8(uint32 endLabelFuncPuIdx, uint32 startLabelFuncPuIdx, uint32 endLabelIdx,
94                          uint32 startLabelIdx) override;
95     void EmitLabel(uint32 funcPuIdx, uint32 labIdx) override;
96     void EmitDwFormSecOffset() override;
97     void EmitDwFormAddr(bool emitTextBegin) override;
98     void EmitDwFormRef4(uint64 offsetOrValue, bool unknownType, bool emitOffset) override;
99     void EmitDwFormExprlocCfa(uint32 dwOp) override;
100     void EmitDwFormExprlocAddr(uint32 dwOp, const std::string &addrStr) override;
101     void EmitDwFormExprlocFbreg(uint32 dwOp, int fboffset, size_t sleb128Size) override;
102     void EmitDwFormExprlocBregn(uint32 dwOp, const std::string &dwOpName) override; /* n=0~7 */
103     void EmitDwFormExprloc(uintptr elp) override;
104 
105     void EmitDIDwName(const std::string &dwAtName, const std::string &dwForName) override;
EmitDIDWFormStr(const std::string & formStr)106     void EmitDIDWFormStr(const std::string &formStr) override
107     {
108         Emit(" : ");
109         Emit(formStr);
110     }
111 
EmitDIDWDataMemberLocaltion(unsigned int lableIdx,uintptr_t attr)112     void EmitDIDWDataMemberLocaltion(unsigned int lableIdx, uintptr_t attr) override
113     {
114         Emit(" : ");
115         Emit(lableIdx);
116         Emit("  attr= ");
117         EmitHexUnsigned(attr);
118     }
119 
EmitDIDebugAbbrevSectionHeader()120     void EmitDIDebugAbbrevSectionHeader() override
121     {
122         Emit("\t.section\t.debug_abbrev,\"\",@progbits\n");
123         Emit(".L" XSTR(DEBUG_ABBREV_0) ":\n");
124     }
125 
126     void EmitDIDebugAbbrevDiae(bool verbose, uint32 abbrevId, uint32 tag, const std::string &dwTagName,
127                                bool withChildren) override;
128     void EmitDIDebugAbbrevDiaePairItem(bool verbose, uint32 aplAt, uint32 aplFrom, const std::string &dwAtName,
129                                        const std::string &dwFromName) override;
130 
EmitDIDebugSectionEnd(SectionKind secKind)131     void EmitDIDebugSectionEnd(SectionKind secKind) override
132     {
133         Emit("\t.byte    0x0\n");
134     }
135 
EmitDIDebugARangesSection()136     void EmitDIDebugARangesSection() override
137     {
138         Emit("\t.section\t.debug_aranges,\"\",@progbits\n");
139     }
140 
EmitDIDebugRangesSection()141     void EmitDIDebugRangesSection() override
142     {
143         Emit("\t.section\t.debug_ranges,\"\",@progbits\n");
144     }
145 
EmitDIDebugLineSection()146     void EmitDIDebugLineSection() override
147     {
148         Emit("\t.section\t.debug_line,\"\",@progbits\n");
149         Emit(".L" XSTR(DEBUG_LINE_0) ":\n");
150     }
151 
152     void EmitDIDebugStrSection(const std::vector<uint32> &strps, const std::vector<std::string> &debugStrs, uint64 size,
153                                size_t strTableSize) override;
154     void EmitHexUnsigned(uint64 num);
155     void EmitDecUnsigned(uint64 num);
156     void EmitDecSigned(int64 num);
157 
EmitLine()158     void EmitLine() override
159     {
160         Emit("\n");
161     }
162 
163     /* start of X64 instructions */
164     /* mov */
165     void Mov(InsnSize insnSize, Reg srcReg, Reg destReg) override;
166     void Mov(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
167     void Mov(InsnSize insnSize, const Mem &mem, Reg reg) override;
168     void Mov(InsnSize insnSize, Reg reg, const Mem &mem) override;
169     void Mov(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
170     /* floating point mov */
171     void Mov(Reg srcReg, Reg destReg, bool isMovD) override;
172     void MovF(const Mem &mem, Reg reg, bool isSingle) override;
173     void MovF(Reg reg, const Mem &mem, bool isSingle) override;
174     /* movabs */
175     void Movabs(const ImmOpnd &immOpnd, Reg reg) override;
176     void Movabs(int64 symIdx, Reg reg) override;
177     /* push */
178     void Push(InsnSize insnSize, Reg reg) override;
179     /* pop */
180     void Pop(InsnSize insnSize, Reg reg) override;
181     /* lea */
182     void Lea(InsnSize insnSize, const Mem &mem, Reg reg) override;
183     /* movzx */
184     void MovZx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg) override;
185     void MovZx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg) override;
186     /* movsx */
187     void MovSx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg) override;
188     void MovSx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg) override;
189     /* add */
190     void Add(InsnSize insnSize, Reg srcReg, Reg destReg) override;
191     void Add(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
192     void Add(InsnSize insnSize, const Mem &mem, Reg reg) override;
193     void Add(InsnSize insnSize, Reg reg, const Mem &mem) override;
194     void Add(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
195     /* add floating point */
196     void Add(Reg srcReg, Reg destReg, bool isSingle) override;
197     void Add(const Mem &mem, Reg reg, bool isSingle) override;
198     /* sub */
199     void Sub(InsnSize insnSize, Reg srcReg, Reg destReg) override;
200     void Sub(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
201     void Sub(InsnSize insnSize, const Mem &mem, Reg reg) override;
202     void Sub(InsnSize insnSize, Reg reg, const Mem &mem) override;
203     void Sub(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
204     /* sub floating point */
205     void Sub(Reg srcReg, Reg destReg, bool isSingle) override;
206     void Sub(const Mem &mem, Reg reg, bool isSingle) override;
207     /* and */
208     void And(InsnSize insnSize, Reg srcReg, Reg destReg) override;
209     void And(InsnSize insnSize, const Mem &mem, Reg reg) override;
210     void And(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
211     void And(InsnSize insnSize, Reg reg, const Mem &mem) override;
212     void And(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
213     /* or */
214     void Or(InsnSize insnSize, Reg srcReg, Reg destReg) override;
215     void Or(InsnSize insnSize, const Mem &mem, Reg reg) override;
216     void Or(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
217     void Or(InsnSize insnSize, Reg reg, const Mem &mem) override;
218     void Or(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
219     /* xor */
220     void Xor(InsnSize insnSize, Reg srcReg, Reg destReg) override;
221     void Xor(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
222     void Xor(InsnSize insnSize, const Mem &mem, Reg reg) override;
223     void Xor(InsnSize insnSize, Reg reg, const Mem &mem) override;
224     void Xor(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
225     /* not */
226     void Not(InsnSize insnSize, Reg reg) override;
227     void Not(InsnSize insnSize, const Mem &mem) override;
228     /* bsr */
229     void Bsr(InsnSize insnSize, Reg srcReg, Reg destReg) override;
230     /* neg */
231     void Neg(InsnSize insnSize, Reg reg) override;
232     void Neg(InsnSize insnSize, const Mem &mem) override;
233     /* div & cwd, cdq, cqo */
234     void Idiv(InsnSize insnSize, Reg reg) override;
235     void Idiv(InsnSize insnSize, const Mem &mem) override;
236     void Div(InsnSize insnSize, Reg reg) override;
237     void Div(InsnSize insnSize, const Mem &mem) override;
238     void Cwd() override;
239     void Cdq() override;
240     void Cqo() override;
241     /* shl */
242     void Shl(InsnSize insnSize, Reg srcReg, Reg destReg) override;
243     void Shl(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
244     void Shl(InsnSize insnSize, Reg reg, const Mem &mem) override;
245     void Shl(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
246     /* sar */
247     void Sar(InsnSize insnSize, Reg srcReg, Reg destReg) override;
248     void Sar(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
249     void Sar(InsnSize insnSize, Reg reg, const Mem &mem) override;
250     void Sar(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
251     /* shr */
252     void Shr(InsnSize insnSize, Reg srcReg, Reg destReg) override;
253     void Shr(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
254     void Shr(InsnSize insnSize, Reg reg, const Mem &mem) override;
255     void Shr(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
256     /* jmp */
257     void Jmp(Reg reg) override;
258     void Jmp(const Mem &mem) override;
259     void Jmp(int64 symIdx) override;
260     /* jump condition */
261     void Je(int64 symIdx) override;
262     void Ja(int64 symIdx) override;
263     void Jae(int64 symIdx) override;
264     void Jne(int64 symIdx) override;
265     void Jb(int64 symIdx) override;
266     void Jbe(int64 symIdx) override;
267     void Jg(int64 symIdx) override;
268     void Jge(int64 symIdx) override;
269     void Jl(int64 symIdx) override;
270     void Jle(int64 symIdx) override;
271     /* cmp */
272     void Cmp(InsnSize insnSize, Reg srcReg, Reg destReg) override;
273     void Cmp(InsnSize insnSize, const Mem &mem, Reg reg) override;
274     void Cmp(InsnSize insnSize, Reg reg, const Mem &mem) override;
275     void Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override;
276     void Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override;
277     /* test */
278     void Test(InsnSize insnSize, Reg srcReg, Reg destReg) override;
279     /* set */
280     void Setbe(Reg reg) override;
281     void Setbe(const Mem &mem) override;
282     void Setle(Reg reg) override;
283     void Setle(const Mem &mem) override;
284     void Setae(Reg reg) override;
285     void Setae(const Mem &mem) override;
286     void Setge(Reg reg) override;
287     void Setge(const Mem &mem) override;
288     void Setne(Reg reg) override;
289     void Setne(const Mem &mem) override;
290     void Setb(Reg reg) override;
291     void Setb(const Mem &mem) override;
292     void Setl(Reg reg) override;
293     void Setl(const Mem &mem) override;
294     void Seta(Reg reg) override;
295     void Seta(const Mem &mem) override;
296     void Setg(Reg reg) override;
297     void Setg(const Mem &mem) override;
298     void Sete(Reg reg) override;
299     void Sete(const Mem &mem) override;
300     void Seto(Reg reg) override;
301     void Seto(const Mem &mem) override;
302     /* cmov */
303     void Cmova(InsnSize insnSize, Reg srcReg, Reg destReg) override;
304     void Cmova(InsnSize insnSize, const Mem &mem, Reg reg) override;
305     void Cmovae(InsnSize insnSize, Reg srcReg, Reg destReg) override;
306     void Cmovae(InsnSize insnSize, const Mem &mem, Reg reg) override;
307     void Cmovb(InsnSize insnSize, Reg srcReg, Reg destReg) override;
308     void Cmovb(InsnSize insnSize, const Mem &mem, Reg reg) override;
309     void Cmovbe(InsnSize insnSize, Reg srcReg, Reg destReg) override;
310     void Cmovbe(InsnSize insnSize, const Mem &mem, Reg reg) override;
311     void Cmove(InsnSize insnSize, Reg srcReg, Reg destReg) override;
312     void Cmove(InsnSize insnSize, const Mem &mem, Reg reg) override;
313     void Cmovg(InsnSize insnSize, Reg srcReg, Reg destReg) override;
314     void Cmovg(InsnSize insnSize, const Mem &mem, Reg reg) override;
315     void Cmovge(InsnSize insnSize, Reg srcReg, Reg destReg) override;
316     void Cmovge(InsnSize insnSize, const Mem &mem, Reg reg) override;
317     void Cmovl(InsnSize insnSize, Reg srcReg, Reg destReg) override;
318     void Cmovl(InsnSize insnSize, const Mem &mem, Reg reg) override;
319     void Cmovle(InsnSize insnSize, Reg srcReg, Reg destReg) override;
320     void Cmovle(InsnSize insnSize, const Mem &mem, Reg reg) override;
321     void Cmovne(InsnSize insnSize, Reg srcReg, Reg destReg) override;
322     void Cmovne(InsnSize insnSize, const Mem &mem, Reg reg) override;
323     void Cmovo(InsnSize insnSize, Reg srcReg, Reg destReg) override;
324     /* call */
325     void Call(InsnSize insnSize, Reg reg) override;
326     void Call(InsnSize insnSize, const Mem &mem) override;
327     void Call(InsnSize insnSize, int64 symIdx) override;
328     /* ret */
329     void Ret() override;
330     /* leave */
331     void Leave() override;
332     /* imul */
333     void Imul(InsnSize insnSize, Reg srcReg, Reg destReg) override;
334     /* mul float */
335     void Mul(Reg srcReg, Reg destReg, bool isSingle) override;
336     void Mul(const Mem &mem, Reg reg, bool isSingle) override;
337     /* nop */
338     void Nop(InsnSize insnSize, const Mem &mem) override;
339     void Nop() override;
340     /* byte swap */
341     void Bswap(InsnSize insnSize, Reg reg) override;
342     void Xchg(InsnSize insnSize, Reg srcReg, Reg destReg) override;
343     /* pseudo insn */
344     void DealWithPseudoInst(const std::string &insn) override;
345     /* floating point */
346     void MovF(Reg srcReg, Reg destReg, bool isSingle) override;
347     /* floating point and */
348     void And(Reg srcReg, Reg destReg, bool isSingle) override;
349     void And(const Mem &mem, Reg reg, bool isSingle) override;
350     /* floating div */
351     void Divsd(Reg srcReg, Reg destReg) override;
352     void Divsd(const Mem &mem, Reg reg) override;
353     /* convert int2float */
354     void Cvtsi2ss(InsnSize insnSize, Reg srcReg, Reg destReg) override;
355     void Cvtsi2sd(InsnSize insnSize, Reg srcReg, Reg destReg) override;
356     /*convert float2int */
357     void Cvttsd2si(InsnSize insnSize, Reg srcReg, Reg destReg) override;
358     void Cvttss2si(InsnSize insnSize, Reg srcReg, Reg destReg) override;
359     /* convert float2float */
360     void Cvtss2sd(Reg srcReg, Reg destReg) override;
361     void Cvtsd2ss(Reg srcReg, Reg destReg) override;
362     /* unordered compare */
363     void Ucomisd(Reg srcReg, Reg destReg) override;
364     void Ucomiss(Reg srcReg, Reg destReg) override;
365     void Cmpeqsd(Reg srcReg, Reg destReg) override;
366     /* float sqrt*/
367     void Sqrtss_r(Reg srcReg, Reg destReg) override;
368     void Sqrtsd_r(Reg srcReg, Reg destReg) override;
369     /* end of X64 instructions */
370     /* process stackmap */
RecordStackmap(const std::vector<uint8> & referenceMap,const std::vector<uint8> & deoptInfo)371     void RecordStackmap(const std::vector<uint8> &referenceMap, const std::vector<uint8> &deoptInfo) override {}
GetCurModulePC()372     uint32 GetCurModulePC() override { return 0; }
SetLastModulePC(uint32 pc)373     void SetLastModulePC(uint32 pc) override {}
374 
375 private:
EmitComment(std::string comment)376     void EmitComment(std::string comment)
377     {
378         EmitDebugComment(comment.c_str());
379     }
380 
381     void EmitSizeDirective(uint8 elemSize, int64 value, bool isSymbol, bool isLocal = false)
382     {
383         std::unordered_map<uint8, std::string> symSizeDirMap = {
384             {k1Byte, ".byte"}, {k2Bytes, ".value"}, {k4Bytes, ".long"}, {k8Bytes, ".quad"}};
385         Emit("\t");
386         Emit(symSizeDirMap.at(elemSize));
387         Emit("\t");
388         if (isSymbol) {
389             std::string name = GetNameFromSymMap(value, isLocal);
390             Emit(name);
391         } else {
392             Emit(value);
393         }
394         Emit("\n");
395     }
396 
EmitSectionDirective(SectionKind sectionKind)397     void EmitSectionDirective(SectionKind sectionKind)
398     {
399         std::unordered_map<SectionKind, std::string> secDirMap = {{kSBss, ".bss\t"},       {kSData, ".data\n"},
400                                                                   {kSRodata, ".rodata\n"}, {kSTbss, ".tbss\t"},
401                                                                   {kSTdata, ".tdata\n"},   {kSText, ".text\n"}};
402         Emit("\t.section\t");
403         Emit(secDirMap.at(sectionKind));
404     }
405 
406     void EmitSymbolAttrDirective(SymbolAttr symAttr, int64 symIdx, bool isLocal = false)
407     {
408         std::unordered_map<SymbolAttr, std::string> symAttrDirMap = {{kSAGlobal, ".global"},
409                                                                      {kSALocal, ".local"},
410                                                                      {kSAHidden, ".hidden"},
411                                                                      {kSAStatic, ".local"},
412                                                                      {kSAWeak, ".weak"}};
413         std::string name = GetNameFromSymMap(symIdx, isLocal);
414         Emit("\t");
415         Emit(symAttrDirMap.at(symAttr));
416         Emit("\t");
417         Emit(name);
418         Emit("\n");
419     }
420 
421     void EmitDirective(Directive directive, int64 symIdx = 0, bool isLocal = false, uint8 alignInByte = 0)
422     {
423         std::string name = "";
424         if (symIdx != 0) {
425             name = GetNameFromSymMap(symIdx, isLocal);
426         }
427         switch (directive) {
428             case kAlign: {
429                 if (alignInByte > 0) {
430                     Emit("\t.align\t");
431                     Emit(alignInByte);
432                     Emit("\n");
433                 }
434                 break;
435             }
436             case kFile:
437                 Emit("\t.file\t");
438                 break;
439             case kFuncType:
440                 Emit("\t.type\t");
441                 Emit(name);
442                 Emit(", @function\n");
443                 break;
444             case kHidden:
445 
446                 Emit(name);
447                 Emit("\n");
448                 break;
449             case kName:
450                 Emit(name);
451                 Emit(":\n");
452                 break;
453             case kObjType:
454                 Emit("\t.type\t");
455                 Emit(name);
456                 Emit(", @object\n");
457                 break;
458             case kSection:
459                 Emit("\t.section\t");
460                 break;
461             case kSize:
462                 Emit("\t.size\t");
463                 Emit(name);
464                 Emit(", .-");
465                 Emit(name);
466                 Emit("\n");
467                 break;
468             case kZero:
469                 Emit("\t.zero\t");
470                 break;
471             default:
472                 CHECK_FATAL(false, "EmitDirective: unsupport directive");
473                 break;
474         }
475     }
476 
EmitInsnSuffix(InsnSize insnSize)477     void EmitInsnSuffix(InsnSize insnSize)
478     {
479         std::unordered_map<InsnSize, std::string> insnSuffixDirMap = {{kB, "b"}, {kW, "w"}, {kL, "l"}, {kQ, "q"}};
480         Emit(insnSuffixDirMap.at(insnSize));
481     }
482 
EmitReg(Reg reg)483     void EmitReg(Reg reg)
484     {
485         std::string regStr = kRegStrMap.at(reg);
486         Emit("%");
487         Emit(regStr);
488     }
489 
EmitSymbol(int64 symIdx)490     void EmitSymbol(int64 symIdx)
491     {
492         std::string symbolName = GetNameFromSymMap(symIdx);
493         Emit("$");
494         Emit(symbolName);
495     }
496 
EmitMem(const Mem & mem)497     void EmitMem(const Mem &mem)
498     {
499         /* emit displacement */
500         if (mem.disp.first != 0) {
501             std::string dispSymName = GetNameFromSymMap(mem.disp.first);
502             Emit(dispSymName);
503             if (mem.disp.second != 0) {
504                 Emit("+");
505                 Emit(mem.disp.second);
506             }
507         } else {
508             Emit(mem.disp.second);
509         }
510         /* emit base & index registers */
511         Emit("(");
512         if (mem.base != ERR) {
513             EmitReg(mem.base);
514         }
515         if (mem.index != ERR) {
516             Emit(", ");
517             EmitReg(mem.index);
518             Emit(", ");
519             Emit(mem.s);
520         }
521         Emit(")");
522     }
523 
EmitImm(int64 imm)524     void EmitImm(int64 imm)
525     {
526         Emit("$");
527         Emit(imm);
528     }
529 
EmitLabel(int64 symIdx)530     void EmitLabel(int64 symIdx)
531     {
532         std::string labelName = GetNameFromSymMap(symIdx);
533         if (symIdx < 0 && labelName[0] != '.') {
534             Emit("$");
535         }
536         Emit(labelName);
537     }
538 
EmitRegReg(Reg srcReg,Reg destReg)539     void EmitRegReg(Reg srcReg, Reg destReg)
540     {
541         EmitReg(srcReg);
542         Emit(",\t");
543         EmitReg(destReg);
544     }
545 
EmitImmOrSymbolReg(int64 val,bool isSymbol,Reg reg)546     void EmitImmOrSymbolReg(int64 val, bool isSymbol, Reg reg)
547     {
548         if (isSymbol) {
549             EmitSymbol(val);
550         } else {
551             EmitImm(val);
552         }
553         Emit(",\t");
554         EmitReg(reg);
555     }
556 
EmitLabelReg(int64 labelIdx,Reg reg)557     void EmitLabelReg(int64 labelIdx, Reg reg)
558     {
559         EmitLabel(labelIdx);
560         Emit(",\t");
561         EmitReg(reg);
562     }
563 
EmitMemReg(const Mem & mem,Reg reg)564     void EmitMemReg(const Mem &mem, Reg reg)
565     {
566         EmitMem(mem);
567         Emit(",\t");
568         EmitReg(reg);
569     }
570 
EmitRegMem(Reg reg,const Mem & mem)571     void EmitRegMem(Reg reg, const Mem &mem)
572     {
573         EmitReg(reg);
574         Emit(",\t");
575         EmitMem(mem);
576     }
577 
EmitImmOrSymbolMem(int64 val,bool isSymbol,Mem mem)578     void EmitImmOrSymbolMem(int64 val, bool isSymbol, Mem mem)
579     {
580         if (isSymbol) {
581             EmitSymbol(val);
582         } else {
583             EmitImm(val);
584         }
585         Emit(",\t");
586         EmitMem(mem);
587     }
588 
EmitLabelMem(int64 labelIdx,const Mem & mem)589     void EmitLabelMem(int64 labelIdx, const Mem &mem)
590     {
591         EmitLabel(labelIdx);
592         Emit(",\t");
593         EmitMem(mem);
594     }
595 }; /* class AsmAssembler */
596 } /* namespace assembler */
597 
598 #endif /* ASM_ASSEMBLER_H */