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