45 class MCAsmStreamer final :
public MCStreamer {
46 std::unique_ptr<formatted_raw_ostream> OSOwner;
49 std::unique_ptr<MCInstPrinter> InstPrinter;
50 std::unique_ptr<MCAssembler> Assembler;
57 unsigned IsVerboseAsm : 1;
58 unsigned ShowInst : 1;
59 unsigned UseDwarfDirectory : 1;
61 void EmitRegisterName(int64_t
Register);
63 void printDwarfFileDirective(
unsigned FileNo,
StringRef Directory,
67 bool UseDwarfDirectory,
74 bool isVerboseAsm,
bool useDwarfDirectory,
75 MCInstPrinter *printer, std::unique_ptr<MCCodeEmitter> emitter,
76 std::unique_ptr<MCAsmBackend> asmbackend,
bool showInst)
78 MAI(
Context.getAsmInfo()), InstPrinter(printer),
81 (asmbackend) ? asmbackend->createObjectWriter(NullStream)
83 CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
84 ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
87 InstPrinter->setCommentStream(CommentStream);
88 if (Assembler->getBackendPtr())
89 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
91 Context.setUseNamesOnTempLabels(
true);
95 MCAssembler *getAssemblerPtr()
override {
return nullptr; }
97 inline void EmitEOL() {
99 emitExplicitComments();
105 EmitCommentsAndEOL();
108 void emitSyntaxDirective()
override;
110 void EmitCommentsAndEOL();
113 bool isVerboseAsm()
const override {
return IsVerboseAsm; }
116 bool hasRawTextSupport()
const override {
return true; }
121 void AddComment(
const Twine &
T,
bool EOL =
true)
override;
132 return CommentStream;
135 void emitRawComment(
const Twine &
T,
bool TabPrefix =
true)
override;
137 void addExplicitComment(
const Twine &
T)
override;
138 void emitExplicitComments()
override;
141 void AddBlankLine()
override {
148 void changeSection(
MCSection *Section,
const MCExpr *Subsection)
override;
151 bool KeepOriginalSym)
override;
155 void emitGNUAttribute(
unsigned Tag,
unsigned Value)
override;
158 return InstPrinter->getMnemonic(&
MI).first;
168 void emitBuildVersion(
unsigned Platform,
unsigned Major,
unsigned Minor,
170 void emitDarwinTargetVariantBuildVersion(
unsigned Platform,
unsigned Major,
171 unsigned Minor,
unsigned Update,
173 void emitThumbFunc(
MCSymbol *Func)
override;
181 void emitSymbolDesc(
MCSymbol *
Symbol,
unsigned DescValue)
override;
183 void EmitCOFFSymbolStorageClass(
int StorageClass)
override;
184 void EmitCOFFSymbolType(
int Type)
override;
185 void EndCOFFSymbolDef()
override;
190 void EmitCOFFImgRel32(
MCSymbol const *
Symbol, int64_t Offset)
override;
193 unsigned ByteAlign)
override;
225 void emitValueImpl(
const MCExpr *
Value,
unsigned Size,
228 void emitIntValueInHex(
uint64_t Value,
unsigned Size)
override;
229 void emitIntValueInHexWithPadding(
uint64_t Value,
unsigned Size)
override;
231 void emitULEB128Value(
const MCExpr *
Value)
override;
233 void emitSLEB128Value(
const MCExpr *
Value)
override;
235 void emitDTPRel32Value(
const MCExpr *
Value)
override;
236 void emitDTPRel64Value(
const MCExpr *
Value)
override;
237 void emitTPRel32Value(
const MCExpr *
Value)
override;
238 void emitTPRel64Value(
const MCExpr *
Value)
override;
240 void emitGPRel64Value(
const MCExpr *
Value)
override;
242 void emitGPRel32Value(
const MCExpr *
Value)
override;
247 void emitFill(
const MCExpr &NumValues, int64_t Size, int64_t Expr,
251 unsigned ValueSize = 1,
252 unsigned MaxBytesToEmit = 0)
override;
255 unsigned MaxBytesToEmit = 0)
override;
257 void emitValueToOffset(
const MCExpr *Offset,
261 void emitFileDirective(
StringRef Filename)
override;
269 unsigned CUID = 0)
override;
273 unsigned CUID = 0)
override;
274 void emitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
unsigned Column,
275 unsigned Flags,
unsigned Isa,
276 unsigned Discriminator,
278 MCSymbol *getDwarfLineTableSymbol(
unsigned CUID)
override;
280 bool EmitCVFileDirective(
unsigned FileNo,
StringRef Filename,
283 bool EmitCVFuncIdDirective(
unsigned FuncId)
override;
284 bool EmitCVInlineSiteIdDirective(
unsigned FunctionId,
unsigned IAFunc,
285 unsigned IAFile,
unsigned IALine,
286 unsigned IACol,
SMLoc Loc)
override;
287 void emitCVLocDirective(
unsigned FunctionId,
unsigned FileNo,
unsigned Line,
288 unsigned Column,
bool PrologueEnd,
bool IsStmt,
290 void emitCVLinetableDirective(
unsigned FunctionId,
const MCSymbol *FnStart,
292 void emitCVInlineLinetableDirective(
unsigned PrimaryFunctionId,
293 unsigned SourceFileId,
294 unsigned SourceLineNum,
298 void PrintCVDefRangePrefix(
299 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges);
301 void emitCVDefRangeDirective(
302 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
305 void emitCVDefRangeDirective(
306 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
309 void emitCVDefRangeDirective(
310 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
313 void emitCVDefRangeDirective(
314 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
317 void emitCVStringTableDirective()
override;
318 void emitCVFileChecksumsDirective()
override;
319 void emitCVFileChecksumOffsetDirective(
unsigned FileNo)
override;
320 void EmitCVFPOData(
const MCSymbol *ProcSym,
SMLoc L)
override;
322 void emitIdent(
StringRef IdentString)
override;
323 void emitCFIBKeyFrame()
override;
324 void emitCFISections(
bool EH,
bool Debug)
override;
325 void emitCFIDefCfa(int64_t
Register, int64_t Offset)
override;
326 void emitCFIDefCfaOffset(int64_t Offset)
override;
327 void emitCFIDefCfaRegister(int64_t
Register)
override;
328 void emitCFILLVMDefAspaceCfa(int64_t
Register, int64_t Offset,
330 void emitCFIOffset(int64_t
Register, int64_t Offset)
override;
331 void emitCFIPersonality(
const MCSymbol *Sym,
unsigned Encoding)
override;
332 void emitCFILsda(
const MCSymbol *Sym,
unsigned Encoding)
override;
333 void emitCFIRememberState()
override;
334 void emitCFIRestoreState()
override;
335 void emitCFIRestore(int64_t
Register)
override;
336 void emitCFISameValue(int64_t
Register)
override;
337 void emitCFIRelOffset(int64_t
Register, int64_t Offset)
override;
338 void emitCFIAdjustCfaOffset(int64_t Adjustment)
override;
339 void emitCFIEscape(
StringRef Values)
override;
340 void emitCFIGnuArgsSize(int64_t Size)
override;
341 void emitCFISignalFrame()
override;
342 void emitCFIUndefined(int64_t
Register)
override;
343 void emitCFIRegister(int64_t Register1, int64_t Register2)
override;
344 void emitCFIWindowSave()
override;
345 void emitCFINegateRAState()
override;
346 void emitCFIReturnColumn(int64_t
Register)
override;
349 void EmitWinCFIEndProc(
SMLoc Loc)
override;
350 void EmitWinCFIFuncletOrFuncEnd(
SMLoc Loc)
override;
351 void EmitWinCFIStartChained(
SMLoc Loc)
override;
352 void EmitWinCFIEndChained(
SMLoc Loc)
override;
356 void EmitWinCFIAllocStack(
unsigned Size,
SMLoc Loc)
override;
361 void EmitWinCFIPushFrame(
bool Code,
SMLoc Loc)
override;
362 void EmitWinCFIEndProlog(
SMLoc Loc)
override;
364 void EmitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
bool Except,
366 void EmitWinEHHandlerData(
SMLoc Loc)
override;
377 void emitBundleAlignMode(
unsigned AlignPow2)
override;
378 void emitBundleLock(
bool AlignToEnd)
override;
379 void emitBundleUnlock()
override;
385 void emitAddrsig()
override;
386 void emitAddrsigSym(
const MCSymbol *Sym)
override;
391 void emitRawTextImpl(
StringRef String)
override;
393 void finishImpl()
override;
395 void emitDwarfUnitLength(
uint64_t Length,
const Twine &Comment)
override;
398 const Twine &Comment)
override;
400 void emitDwarfLineStartLabel(
MCSymbol *StartSym)
override;
404 void emitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
408 void doFinalizationAtSectionEnd(
MCSection *Section)
override;
413 void MCAsmStreamer::AddComment(
const Twine &
T,
bool EOL) {
414 if (!IsVerboseAsm)
return;
416 T.toVector(CommentToEmit);
419 CommentToEmit.push_back(
'\n');
422 void MCAsmStreamer::EmitCommentsAndEOL() {
431 "Comment array not newline terminated");
435 size_t Position = Comments.
find(
'\n');
438 Comments = Comments.
substr(Position+1);
439 }
while (!Comments.
empty());
441 CommentToEmit.
clear();
445 assert(Bytes > 0 && Bytes <= 8 &&
"Invalid size!");
446 return Value & ((
uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
449 void MCAsmStreamer::emitRawComment(
const Twine &
T,
bool TabPrefix) {
456 void MCAsmStreamer::addExplicitComment(
const Twine &
T) {
461 ExplicitCommentToEmit.
append(
"\t");
464 ExplicitCommentToEmit.
append(
c.slice(2,
c.size()).str());
466 size_t p = 2, len =
c.size() - 2;
469 size_t newp =
std::min(len,
c.find_first_of(
"\r\n",
p));
470 ExplicitCommentToEmit.
append(
"\t");
472 ExplicitCommentToEmit.
append(
c.slice(
p, newp).str());
475 ExplicitCommentToEmit.
append(
"\n");
479 ExplicitCommentToEmit.
append(
"\t");
480 ExplicitCommentToEmit.
append(
c.str());
481 }
else if (
c.front() ==
'#') {
483 ExplicitCommentToEmit.
append(
"\t");
485 ExplicitCommentToEmit.
append(
c.slice(1,
c.size()).str());
487 assert(
false &&
"Unexpected Assembly Comment");
489 if (
c.back() ==
'\n')
490 emitExplicitComments();
493 void MCAsmStreamer::emitExplicitComments() {
494 StringRef Comments = ExplicitCommentToEmit;
495 if (!Comments.
empty())
497 ExplicitCommentToEmit.
clear();
500 void MCAsmStreamer::changeSection(
MCSection *Section,
501 const MCExpr *Subsection) {
502 assert(Section &&
"Cannot switch to a null section!");
504 TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS);
506 Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
511 void MCAsmStreamer::emitELFSymverDirective(
const MCSymbol *OriginalSym,
513 bool KeepOriginalSym) {
515 OriginalSym->
print(OS, MAI);
517 if (!KeepOriginalSym && !
Name.contains(
"@@@"))
536 assert(NbArgs != -1 && ((
size_t)NbArgs) ==
Args.size() &&
"Malformed LOH!");
537 assert(str !=
"" &&
"Invalid LOH name");
551 void MCAsmStreamer::emitGNUAttribute(
unsigned Tag,
unsigned Value) {
552 OS <<
"\t.gnu_attribute " <<
Tag <<
", " <<
Value <<
"\n";
567 assert(!
Options.empty() &&
"At least one option is required!");
568 OS <<
"\t.linker_option \"" <<
Options[0] <<
'"';
571 OS <<
", " <<
'"' << *
it <<
'"';
601 if (SDKVersion.
empty())
603 OS <<
'\t' <<
"sdk_version " << SDKVersion.
getMajor();
604 if (
auto Minor = SDKVersion.
getMinor()) {
605 OS <<
", " << *Minor;
607 OS <<
", " << *Subminor;
613 unsigned Minor,
unsigned Update,
617 OS <<
", " << Update;
640 void MCAsmStreamer::emitBuildVersion(
unsigned Platform,
unsigned Major,
641 unsigned Minor,
unsigned Update,
644 OS <<
"\t.build_version " << PlatformName <<
", " << Major <<
", " << Minor;
646 OS <<
", " << Update;
651 void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(
652 unsigned Platform,
unsigned Major,
unsigned Minor,
unsigned Update,
654 emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
657 void MCAsmStreamer::emitThumbFunc(
MCSymbol *Func) {
660 OS <<
"\t.thumb_func";
664 Func->print(OS, MAI);
672 if (
auto *
E = dyn_cast<MCTargetExpr>(
Value))
673 if (
E->inlineAssignedExpr())
689 OS <<
".lto_set_conditional ";
698 Alias->
print(OS, MAI);
721 default:
return false;
744 OS <<
"\t.no_dead_strip\t";
749 OS <<
"\t.private_extern\t";
758 OS <<
"\t.weak_definition\t";
776 void MCAsmStreamer::emitSymbolDesc(
MCSymbol *
Symbol,
unsigned DescValue) {
777 OS <<
".desc" <<
' ';
779 OS <<
',' << DescValue;
783 void MCAsmStreamer::emitSyntaxDirective() {
785 OS <<
"\t.intel_syntax noprefix";
800 void MCAsmStreamer::EmitCOFFSymbolStorageClass (
int StorageClass) {
805 void MCAsmStreamer::EmitCOFFSymbolType (
int Type) {
806 OS <<
"\t.type\t" <<
Type <<
';';
810 void MCAsmStreamer::EndCOFFSymbolDef() {
816 OS <<
"\t.safeseh\t";
827 void MCAsmStreamer::EmitCOFFSectionIndex(
MCSymbol const *
Symbol) {
834 OS <<
"\t.secrel32\t";
841 void MCAsmStreamer::EmitCOFFImgRel32(
MCSymbol const *
Symbol, int64_t Offset) {
854 void MCAsmStreamer::emitXCOFFLocalCommonSymbol(
MCSymbol *LabelSym,
859 "We only support writing log base-2 alignment format with XCOFF.");
863 LabelSym->
print(OS, MAI);
864 OS <<
',' <<
Size <<
',';
865 CsectSym->
print(OS, MAI);
877 void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
899 switch (Visibility) {
919 if (cast<MCSymbolXCOFF>(
Symbol)->hasRename())
920 emitXCOFFRenameDirective(
Symbol,
921 cast<MCSymbolXCOFF>(
Symbol)->getSymbolTableName());
924 void MCAsmStreamer::emitXCOFFRenameDirective(
const MCSymbol *
Name,
927 Name->print(OS, MAI);
930 for (
char C : Rename) {
941 OS <<
"\t.ref " <<
Name;
977 unsigned ByteAlign) {
987 OS <<
',' << ByteAlign;
991 OS <<
',' <<
Log2_32(ByteAlign);
1008 ".zerofill is a Mach-O specific directive");
1035 ".zerofill is a Mach-O specific directive");
1050 const auto BeginPtr =
Data.begin(), EndPtr =
Data.end();
1051 for (
const unsigned char C :
make_range(BeginPtr, EndPtr - 1)) {
1062 assert(!
Data.empty() &&
"Cannot generate an empty list.");
1063 const auto printCharacterInOctal = [&OS](
unsigned char C) {
1069 const auto printOneCharacterFor = [printCharacterInOctal](
1070 auto printOnePrintingCharacter) {
1071 return [printCharacterInOctal, printOnePrintingCharacter](
unsigned char C) {
1073 printOnePrintingCharacter(
static_cast<char>(
C));
1076 printCharacterInOctal(
C);
1079 const auto printCharacterList = [
Data, &OS](
const auto &printOneCharacter) {
1080 const auto BeginPtr =
Data.begin(), EndPtr =
Data.end();
1081 for (
const unsigned char C :
make_range(BeginPtr, EndPtr - 1)) {
1082 printOneCharacter(
C);
1085 printOneCharacter(*(EndPtr - 1));
1089 printCharacterList(printCharacterInOctal);
1092 printCharacterList(printOneCharacterFor([&OS](
char C) {
1093 const char AsmCharLitBuf[2] = {
'\'',
C};
1094 OS <<
StringRef(AsmCharLitBuf,
sizeof(AsmCharLitBuf));
1105 for (
unsigned char C :
Data) {
1112 for (
unsigned char C :
Data) {
1113 if (
C ==
'"' ||
C ==
'\\') {
1114 OS <<
'\\' << (char)
C;
1153 assert(getCurrentSectionOnly() &&
1154 "Cannot emit contents before setting section!");
1155 if (
Data.empty())
return;
1170 "hasPairedDoubleQuoteStringConstants target must support "
1171 "PlainString Directive");
1173 "hasPairedDoubleQuoteStringConstants target must support ByteList "
1175 if (
Data.back() == 0) {
1190 PrintQuotedString(
Data, OS);
1195 if (
Data.size() != 1 && emitAsString(
Data))
1201 TS->emitRawBytes(
Data);
1205 for (
const unsigned char C :
Data.bytes()) {
1213 const size_t Cols = 4;
1214 for (
size_t I = 0, EI =
alignTo(
Data.size(), Cols);
I < EI;
I += Cols) {
1218 for (; J < EJ - 1; ++J)
1219 OS <<
format(
"0x%02x", uint8_t(
Data[J])) <<
", ";
1225 void MCAsmStreamer::emitIntValue(
uint64_t Value,
unsigned Size) {
1229 void MCAsmStreamer::emitIntValueInHex(
uint64_t Value,
unsigned Size) {
1233 void MCAsmStreamer::emitIntValueInHexWithPadding(
uint64_t Value,
1238 void MCAsmStreamer::emitValueImpl(
const MCExpr *
Value,
unsigned Size,
1240 assert(Size <= 8 &&
"Invalid size");
1241 assert(getCurrentSectionOnly() &&
1242 "Cannot emit contents before setting section!");
1254 if (!
Value->evaluateAsAbsolute(IntValue))
1269 unsigned ByteOffset =
1270 IsLittleEndian ?
Emitted : (Remaining - EmissionSize);
1271 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
1277 std::numeric_limits<unsigned long long>::digits) &&
1278 "undefined behavior");
1279 ValueToEmit &= ~0ULL >>
Shift;
1280 emitIntValue(ValueToEmit, EmissionSize);
1289 TS->emitValue(
Value);
1296 void MCAsmStreamer::emitULEB128Value(
const MCExpr *
Value) {
1298 if (
Value->evaluateAsAbsolute(IntValue)) {
1299 emitULEB128IntValue(IntValue);
1302 OS <<
"\t.uleb128 ";
1307 void MCAsmStreamer::emitSLEB128Value(
const MCExpr *
Value) {
1309 if (
Value->evaluateAsAbsolute(IntValue)) {
1310 emitSLEB128IntValue(IntValue);
1313 OS <<
"\t.sleb128 ";
1318 void MCAsmStreamer::emitDTPRel64Value(
const MCExpr *
Value) {
1325 void MCAsmStreamer::emitDTPRel32Value(
const MCExpr *
Value) {
1332 void MCAsmStreamer::emitTPRel64Value(
const MCExpr *
Value) {
1339 void MCAsmStreamer::emitTPRel32Value(
const MCExpr *
Value) {
1346 void MCAsmStreamer::emitGPRel64Value(
const MCExpr *
Value) {
1353 void MCAsmStreamer::emitGPRel32Value(
const MCExpr *
Value) {
1360 void MCAsmStreamer::emitFill(
const MCExpr &NumBytes,
uint64_t FillValue,
1362 int64_t IntNumBytes;
1363 const bool IsAbsolute = NumBytes.evaluateAsAbsolute(IntNumBytes);
1364 if (IsAbsolute && IntNumBytes == 0)
1370 OS << ZeroDirective;
1371 NumBytes.
print(OS, MAI);
1373 OS <<
',' << (
int)FillValue;
1378 "Cannot emit non-absolute expression lengths of fill.");
1379 for (
int i = 0;
i < IntNumBytes; ++
i) {
1390 void MCAsmStreamer::emitFill(
const MCExpr &NumValues, int64_t Size,
1391 int64_t Expr,
SMLoc Loc) {
1394 NumValues.
print(OS, MAI);
1395 OS <<
", " <<
Size <<
", 0x";
1402 unsigned MaxBytesToEmit) {
1416 switch (ValueSize) {
1420 OS <<
"\t.p2align\t";
1434 if (
Value || MaxBytesToEmit) {
1439 OS <<
", " << MaxBytesToEmit;
1447 switch (ValueSize) {
1449 case 1: OS <<
".balign";
break;
1450 case 2: OS <<
".balignw";
break;
1451 case 4: OS <<
".balignl";
break;
1458 OS <<
", " << MaxBytesToEmit;
1462 void MCAsmStreamer::emitCodeAlignment(
unsigned ByteAlignment,
1464 unsigned MaxBytesToEmit) {
1470 void MCAsmStreamer::emitValueToOffset(
const MCExpr *Offset,
1471 unsigned char Value,
1476 OS <<
", " << (unsigned)
Value;
1480 void MCAsmStreamer::emitFileDirective(
StringRef Filename) {
1483 PrintQuotedString(Filename, OS);
1487 void MCAsmStreamer::emitFileDirective(
StringRef Filename,
1493 PrintQuotedString(Filename, OS);
1495 if (!CompilerVerion.
empty()) {
1496 PrintQuotedString(CompilerVerion, OS);
1498 if (!TimeStamp.
empty()) {
1500 PrintQuotedString(TimeStamp, OS);
1502 if (!Description.
empty()) {
1504 PrintQuotedString(Description, OS);
1509 void MCAsmStreamer::printDwarfFileDirective(
1515 if (!UseDwarfDirectory && !Directory.
empty()) {
1519 FullPathName = Directory;
1522 Filename = FullPathName;
1526 OS <<
"\t.file\t" << FileNo <<
' ';
1527 if (!Directory.
empty()) {
1528 PrintQuotedString(Directory, OS);
1531 PrintQuotedString(Filename, OS);
1533 OS <<
" md5 0x" << Checksum->
digest();
1536 PrintQuotedString(*
Source, OS);
1543 assert(CUID == 0 &&
"multiple CUs not supported by MCAsmStreamer");
1552 FileNo = FileNoOrErr.
get();
1562 printDwarfFileDirective(FileNo, Directory, Filename, Checksum,
Source,
1563 UseDwarfDirectory, OS1);
1566 TS->emitDwarfFileDirective(OS1.str());
1568 emitRawText(OS1.str());
1573 void MCAsmStreamer::emitDwarfFile0Directive(
StringRef Directory,
1583 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
1592 printDwarfFileDirective(0, Directory, Filename, Checksum,
Source,
1593 UseDwarfDirectory, OS1);
1596 TS->emitDwarfFileDirective(OS1.str());
1598 emitRawText(OS1.str());
1601 void MCAsmStreamer::emitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
1602 unsigned Column,
unsigned Flags,
1603 unsigned Isa,
unsigned Discriminator,
1612 Discriminator, FileName);
1616 OS <<
"\t.loc\t" << FileNo <<
" " << Line <<
" " << Column;
1619 OS <<
" basic_block";
1621 OS <<
" prologue_end";
1623 OS <<
" epilogue_begin";
1625 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
1636 OS <<
" isa " << Isa;
1638 OS <<
" discriminator " << Discriminator;
1644 << Line <<
':' << Column;
1648 Discriminator, FileName);
1651 MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(
unsigned CUID) {
1657 bool MCAsmStreamer::EmitCVFileDirective(
unsigned FileNo,
StringRef Filename,
1660 if (!getContext().getCVContext().addFile(*
this, FileNo, Filename, Checksum,
1664 OS <<
"\t.cv_file\t" << FileNo <<
' ';
1665 PrintQuotedString(Filename, OS);
1673 PrintQuotedString(
toHex(Checksum), OS);
1680 bool MCAsmStreamer::EmitCVFuncIdDirective(
unsigned FuncId) {
1681 OS <<
"\t.cv_func_id " <<
FuncId <<
'\n';
1685 bool MCAsmStreamer::EmitCVInlineSiteIdDirective(
unsigned FunctionId,
1688 unsigned IALine,
unsigned IACol,
1690 OS <<
"\t.cv_inline_site_id " << FunctionId <<
" within " << IAFunc
1691 <<
" inlined_at " << IAFile <<
' ' << IALine <<
' ' << IACol <<
'\n';
1693 IALine, IACol, Loc);
1696 void MCAsmStreamer::emitCVLocDirective(
unsigned FunctionId,
unsigned FileNo,
1697 unsigned Line,
unsigned Column,
1698 bool PrologueEnd,
bool IsStmt,
1701 if (!checkCVLocSection(FunctionId, FileNo, Loc))
1704 OS <<
"\t.cv_loc\t" << FunctionId <<
" " << FileNo <<
" " << Line <<
" "
1707 OS <<
" prologue_end";
1720 void MCAsmStreamer::emitCVLinetableDirective(
unsigned FunctionId,
1723 OS <<
"\t.cv_linetable\t" << FunctionId <<
", ";
1724 FnStart->
print(OS, MAI);
1726 FnEnd->
print(OS, MAI);
1731 void MCAsmStreamer::emitCVInlineLinetableDirective(
unsigned PrimaryFunctionId,
1732 unsigned SourceFileId,
1733 unsigned SourceLineNum,
1736 OS <<
"\t.cv_inline_linetable\t" << PrimaryFunctionId <<
' ' << SourceFileId
1737 <<
' ' << SourceLineNum <<
' ';
1738 FnStartSym->
print(OS, MAI);
1740 FnEndSym->
print(OS, MAI);
1743 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1746 void MCAsmStreamer::PrintCVDefRangePrefix(
1747 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {
1748 OS <<
"\t.cv_def_range\t";
1749 for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
1751 Range.first->print(OS, MAI);
1753 Range.second->print(OS, MAI);
1757 void MCAsmStreamer::emitCVDefRangeDirective(
1758 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1760 PrintCVDefRangePrefix(Ranges);
1761 OS <<
", reg_rel, ";
1767 void MCAsmStreamer::emitCVDefRangeDirective(
1768 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1770 PrintCVDefRangePrefix(Ranges);
1771 OS <<
", subfield_reg, ";
1776 void MCAsmStreamer::emitCVDefRangeDirective(
1777 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1779 PrintCVDefRangePrefix(Ranges);
1785 void MCAsmStreamer::emitCVDefRangeDirective(
1786 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1788 PrintCVDefRangePrefix(Ranges);
1789 OS <<
", frame_ptr_rel, ";
1794 void MCAsmStreamer::emitCVStringTableDirective() {
1795 OS <<
"\t.cv_stringtable";
1799 void MCAsmStreamer::emitCVFileChecksumsDirective() {
1800 OS <<
"\t.cv_filechecksums";
1804 void MCAsmStreamer::emitCVFileChecksumOffsetDirective(
unsigned FileNo) {
1805 OS <<
"\t.cv_filechecksumoffset\t" << FileNo;
1809 void MCAsmStreamer::EmitCVFPOData(
const MCSymbol *ProcSym,
SMLoc L) {
1810 OS <<
"\t.cv_fpo_data\t";
1811 ProcSym->
print(OS, MAI);
1815 void MCAsmStreamer::emitIdent(
StringRef IdentString) {
1818 PrintQuotedString(IdentString, OS);
1822 void MCAsmStreamer::emitCFISections(
bool EH,
bool Debug) {
1824 OS <<
"\t.cfi_sections ";
1828 OS <<
", .debug_frame";
1830 OS <<
".debug_frame";
1837 OS <<
"\t.cfi_startproc";
1845 OS <<
"\t.cfi_endproc";
1849 void MCAsmStreamer::EmitRegisterName(int64_t
Register) {
1856 InstPrinter->printRegName(OS, *LLVMRegister);
1863 void MCAsmStreamer::emitCFIDefCfa(int64_t
Register, int64_t Offset) {
1865 OS <<
"\t.cfi_def_cfa ";
1871 void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset) {
1873 OS <<
"\t.cfi_def_cfa_offset " <<
Offset;
1877 void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t
Register, int64_t Offset,
1880 OS <<
"\t.cfi_llvm_def_aspace_cfa ";
1888 OS <<
"\t.cfi_escape ";
1889 if (!Values.
empty()) {
1890 size_t e = Values.
size() - 1;
1891 for (
size_t i = 0;
i <
e; ++
i)
1892 OS <<
format(
"0x%02x", uint8_t(Values[
i])) <<
", ";
1893 OS <<
format(
"0x%02x", uint8_t(Values[
e]));
1897 void MCAsmStreamer::emitCFIEscape(
StringRef Values) {
1903 void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size) {
1906 uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
1913 void MCAsmStreamer::emitCFIDefCfaRegister(int64_t
Register) {
1915 OS <<
"\t.cfi_def_cfa_register ";
1920 void MCAsmStreamer::emitCFIOffset(int64_t
Register, int64_t Offset) {
1922 OS <<
"\t.cfi_offset ";
1928 void MCAsmStreamer::emitCFIPersonality(
const MCSymbol *Sym,
1929 unsigned Encoding) {
1931 OS <<
"\t.cfi_personality " << Encoding <<
", ";
1932 Sym->
print(OS, MAI);
1936 void MCAsmStreamer::emitCFILsda(
const MCSymbol *Sym,
unsigned Encoding) {
1938 OS <<
"\t.cfi_lsda " << Encoding <<
", ";
1939 Sym->
print(OS, MAI);
1943 void MCAsmStreamer::emitCFIRememberState() {
1945 OS <<
"\t.cfi_remember_state";
1949 void MCAsmStreamer::emitCFIRestoreState() {
1951 OS <<
"\t.cfi_restore_state";
1955 void MCAsmStreamer::emitCFIRestore(int64_t
Register) {
1957 OS <<
"\t.cfi_restore ";
1962 void MCAsmStreamer::emitCFISameValue(int64_t
Register) {
1964 OS <<
"\t.cfi_same_value ";
1969 void MCAsmStreamer::emitCFIRelOffset(int64_t
Register, int64_t Offset) {
1971 OS <<
"\t.cfi_rel_offset ";
1977 void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment) {
1979 OS <<
"\t.cfi_adjust_cfa_offset " << Adjustment;
1983 void MCAsmStreamer::emitCFISignalFrame() {
1985 OS <<
"\t.cfi_signal_frame";
1989 void MCAsmStreamer::emitCFIUndefined(int64_t
Register) {
1991 OS <<
"\t.cfi_undefined ";
1996 void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
1998 OS <<
"\t.cfi_register ";
1999 EmitRegisterName(Register1);
2001 EmitRegisterName(Register2);
2005 void MCAsmStreamer::emitCFIWindowSave() {
2007 OS <<
"\t.cfi_window_save";
2011 void MCAsmStreamer::emitCFINegateRAState() {
2013 OS <<
"\t.cfi_negate_ra_state";
2017 void MCAsmStreamer::emitCFIReturnColumn(int64_t
Register) {
2019 OS <<
"\t.cfi_return_column ";
2024 void MCAsmStreamer::emitCFIBKeyFrame() {
2026 OS <<
"\t.cfi_b_key_frame";
2038 void MCAsmStreamer::EmitWinCFIEndProc(
SMLoc Loc) {
2041 OS <<
"\t.seh_endproc";
2045 void MCAsmStreamer::EmitWinCFIFuncletOrFuncEnd(
SMLoc Loc) {
2048 OS <<
"\t.seh_endfunclet";
2052 void MCAsmStreamer::EmitWinCFIStartChained(
SMLoc Loc) {
2055 OS <<
"\t.seh_startchained";
2059 void MCAsmStreamer::EmitWinCFIEndChained(
SMLoc Loc) {
2062 OS <<
"\t.seh_endchained";
2066 void MCAsmStreamer::EmitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
2067 bool Except,
SMLoc Loc) {
2070 OS <<
"\t.seh_handler ";
2071 Sym->
print(OS, MAI);
2079 void MCAsmStreamer::EmitWinEHHandlerData(
SMLoc Loc) {
2094 MCSection *XData = getAssociatedXDataSection(TextSec);
2095 SwitchSectionNoChange(XData);
2097 OS <<
"\t.seh_handlerdata";
2104 OS <<
"\t.seh_pushreg ";
2105 InstPrinter->printRegName(OS,
Register);
2113 OS <<
"\t.seh_setframe ";
2114 InstPrinter->printRegName(OS,
Register);
2119 void MCAsmStreamer::EmitWinCFIAllocStack(
unsigned Size,
SMLoc Loc) {
2122 OS <<
"\t.seh_stackalloc " <<
Size;
2130 OS <<
"\t.seh_savereg ";
2131 InstPrinter->printRegName(OS,
Register);
2140 OS <<
"\t.seh_savexmm ";
2141 InstPrinter->printRegName(OS,
Register);
2146 void MCAsmStreamer::EmitWinCFIPushFrame(
bool Code,
SMLoc Loc) {
2149 OS <<
"\t.seh_pushframe";
2155 void MCAsmStreamer::EmitWinCFIEndProlog(
SMLoc Loc) {
2158 OS <<
"\t.seh_endprologue";
2165 OS <<
"\t.cg_profile ";
2166 From->getSymbol().print(OS, MAI);
2169 OS <<
", " << Count;
2173 void MCAsmStreamer::AddEncodingComment(
const MCInst &Inst,
2181 if (!getAssembler().getEmitterPtr())
2184 getAssembler().getEmitter().encodeInstruction(Inst, VecOS,
Fixups, STI);
2191 for (
unsigned i = 0,
e =
Code.size() * 8;
i !=
e; ++
i)
2194 for (
unsigned i = 0,
e =
Fixups.size();
i !=
e; ++
i) {
2197 getAssembler().getBackend().getFixupKindInfo(
F.getKind());
2198 for (
unsigned j = 0;
j !=
Info.TargetSize; ++
j) {
2199 unsigned Index =
F.getOffset() * 8 +
Info.TargetOffset +
j;
2200 assert(Index <
Code.size() * 8 &&
"Invalid offset in fixup!");
2207 OS <<
"encoding: [";
2208 for (
unsigned i = 0,
e =
Code.size();
i !=
e; ++
i) {
2213 uint8_t MapEntry = FixupMap[
i * 8 + 0];
2214 for (
unsigned j = 1;
j != 8; ++
j) {
2215 if (FixupMap[
i * 8 +
j] == MapEntry)
2218 MapEntry = uint8_t(~0U);
2222 if (MapEntry != uint8_t(~0U)) {
2223 if (MapEntry == 0) {
2224 OS <<
format(
"0x%02x", uint8_t(Code[
i]));
2228 OS <<
format(
"0x%02x", uint8_t(Code[
i])) <<
'\''
2229 << char(
'A' + MapEntry - 1) <<
'\'';
2231 OS << char(
'A' + MapEntry - 1);
2236 for (
unsigned j = 8;
j--;) {
2241 FixupBit =
i * 8 +
j;
2243 FixupBit =
i * 8 + (7-
j);
2245 if (uint8_t MapEntry = FixupMap[FixupBit]) {
2246 assert(
Bit == 0 &&
"Encoder wrote into fixed up bit!");
2247 OS << char(
'A' + MapEntry - 1);
2255 for (
unsigned i = 0,
e =
Fixups.size();
i !=
e; ++
i) {
2258 getAssembler().getBackend().getFixupKindInfo(
F.getKind());
2259 OS <<
" fixup " << char(
'A' +
i) <<
" - "
2260 <<
"offset: " <<
F.getOffset() <<
", value: ";
2261 F.getValue()->print(OS, MAI);
2262 OS <<
", kind: " <<
Info.Name <<
"\n";
2266 void MCAsmStreamer::emitInstruction(
const MCInst &Inst,
2268 assert(getCurrentSectionOnly() &&
2269 "Cannot emit contents before setting section!");
2277 AddEncodingComment(Inst, STI);
2281 Inst.
dump_pretty(GetCommentOS(), InstPrinter.get(),
"\n ");
2282 GetCommentOS() <<
"\n";
2285 if(getTargetStreamer())
2286 getTargetStreamer()->prettyPrintAsm(*InstPrinter, 0, Inst, STI, OS);
2288 InstPrinter->printInst(&Inst, 0,
"", STI, OS);
2291 if (Comments.
size() && Comments.
back() !=
'\n')
2292 GetCommentOS() <<
"\n";
2297 void MCAsmStreamer::emitPseudoProbe(
2300 OS <<
"\t.pseudoprobe\t" << Guid <<
" " <<
Index <<
" " <<
Type <<
" "
2304 for (
const auto &Site : InlineStack)
2305 OS <<
" @ " << std::get<0>(Site) <<
":" << std::get<1>(Site);
2309 void MCAsmStreamer::emitBundleAlignMode(
unsigned AlignPow2) {
2310 OS <<
"\t.bundle_align_mode " << AlignPow2;
2314 void MCAsmStreamer::emitBundleLock(
bool AlignToEnd) {
2315 OS <<
"\t.bundle_lock";
2317 OS <<
" align_to_end";
2321 void MCAsmStreamer::emitBundleUnlock() {
2322 OS <<
"\t.bundle_unlock";
2335 Expr->
print(OS, MAI);
2341 void MCAsmStreamer::emitAddrsig() {
2346 void MCAsmStreamer::emitAddrsigSym(
const MCSymbol *Sym) {
2347 OS <<
"\t.addrsig_sym ";
2348 Sym->
print(OS, MAI);
2355 void MCAsmStreamer::emitRawTextImpl(
StringRef String) {
2362 void MCAsmStreamer::finishImpl() {
2364 if (getContext().getGenDwarfForAssembly())
2377 const auto &Tables = getContext().getMCDwarfLineTables();
2378 if (!Tables.empty()) {
2379 assert(Tables.size() == 1 &&
"asm output only supports one line table");
2380 if (
auto *Label = Tables.begin()->second.getLabel()) {
2381 SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
2387 void MCAsmStreamer::emitDwarfUnitLength(
uint64_t Length,
const Twine &Comment) {
2400 const Twine &Comment) {
2408 return getContext().createTempSymbol(
Prefix +
"_end");
2412 void MCAsmStreamer::emitDwarfLineStartLabel(
MCSymbol *StartSym) {
2423 emitLabel(DebugLineSymTmp);
2427 unsigned LengthFieldSize =
2433 emitAssignment(StartSym, OuterSym);
2439 void MCAsmStreamer::emitDwarfLineEndEntry(
MCSection *Section,
2447 ".loc should not be generated together with raw data!");
2459 emitDwarfAdvanceLineAddr(
INT64_MAX, LastLabel, SectionEnd,
2464 void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
2469 ".loc/.file don't need raw data in debug line section!");
2472 AddComment(
"Set address to " +
Label->getName());
2473 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2475 emitIntValue(dwarf::DW_LNE_set_address, 1);
2480 AddComment(
"Start sequence");
2488 AddComment(
"End sequence");
2489 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2490 emitULEB128IntValue(1);
2491 emitIntValue(dwarf::DW_LNE_end_sequence, 1);
2496 AddComment(
"Advance line " +
Twine(LineDelta));
2497 emitIntValue(dwarf::DW_LNS_advance_line, 1);
2498 emitSLEB128IntValue(LineDelta);
2499 emitIntValue(dwarf::DW_LNS_copy, 1);
2502 void MCAsmStreamer::doFinalizationAtSectionEnd(
MCSection *Section) {
2508 SwitchSectionNoChange(Section);
2510 MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());
2517 std::unique_ptr<formatted_raw_ostream> OS,
2518 bool isVerboseAsm,
bool useDwarfDirectory,
2520 std::unique_ptr<MCCodeEmitter> &&CE,
2521 std::unique_ptr<MCAsmBackend> &&MAB,