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 */