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