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 { EmitEOL(); }
146 void changeSection(
MCSection *Section,
const MCExpr *Subsection)
override;
149 bool KeepOriginalSym)
override;
153 void emitGNUAttribute(
unsigned Tag,
unsigned Value)
override;
156 return InstPrinter->getMnemonic(&
MI).first;
166 void emitBuildVersion(
unsigned Platform,
unsigned Major,
unsigned Minor,
168 void emitDarwinTargetVariantBuildVersion(
unsigned Platform,
unsigned Major,
169 unsigned Minor,
unsigned Update,
171 void emitThumbFunc(
MCSymbol *Func)
override;
179 void emitSymbolDesc(
MCSymbol *
Symbol,
unsigned DescValue)
override;
181 void emitCOFFSymbolStorageClass(
int StorageClass)
override;
182 void emitCOFFSymbolType(
int Type)
override;
183 void endCOFFSymbolDef()
override;
188 void emitCOFFImgRel32(
MCSymbol const *
Symbol, int64_t Offset)
override;
191 unsigned ByteAlign)
override;
223 void emitValueImpl(
const MCExpr *
Value,
unsigned Size,
226 void emitIntValueInHex(
uint64_t Value,
unsigned Size)
override;
227 void emitIntValueInHexWithPadding(
uint64_t Value,
unsigned Size)
override;
229 void emitULEB128Value(
const MCExpr *
Value)
override;
231 void emitSLEB128Value(
const MCExpr *
Value)
override;
233 void emitDTPRel32Value(
const MCExpr *
Value)
override;
234 void emitDTPRel64Value(
const MCExpr *
Value)
override;
235 void emitTPRel32Value(
const MCExpr *
Value)
override;
236 void emitTPRel64Value(
const MCExpr *
Value)
override;
238 void emitGPRel64Value(
const MCExpr *
Value)
override;
240 void emitGPRel32Value(
const MCExpr *
Value)
override;
245 void emitFill(
const MCExpr &NumValues, int64_t Size, int64_t Expr,
249 unsigned ValueSize = 1,
250 unsigned MaxBytesToEmit = 0)
override;
253 unsigned MaxBytesToEmit = 0)
override;
255 void emitValueToOffset(
const MCExpr *Offset,
259 void emitFileDirective(
StringRef Filename)
override;
267 unsigned CUID = 0)
override;
271 unsigned CUID = 0)
override;
272 void emitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
unsigned Column,
273 unsigned Flags,
unsigned Isa,
274 unsigned Discriminator,
276 MCSymbol *getDwarfLineTableSymbol(
unsigned CUID)
override;
278 bool emitCVFileDirective(
unsigned FileNo,
StringRef Filename,
281 bool emitCVFuncIdDirective(
unsigned FuncId)
override;
282 bool emitCVInlineSiteIdDirective(
unsigned FunctionId,
unsigned IAFunc,
283 unsigned IAFile,
unsigned IALine,
284 unsigned IACol,
SMLoc Loc)
override;
285 void emitCVLocDirective(
unsigned FunctionId,
unsigned FileNo,
unsigned Line,
286 unsigned Column,
bool PrologueEnd,
bool IsStmt,
288 void emitCVLinetableDirective(
unsigned FunctionId,
const MCSymbol *FnStart,
290 void emitCVInlineLinetableDirective(
unsigned PrimaryFunctionId,
291 unsigned SourceFileId,
292 unsigned SourceLineNum,
296 void PrintCVDefRangePrefix(
297 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges);
299 void emitCVDefRangeDirective(
300 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
303 void emitCVDefRangeDirective(
304 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
307 void emitCVDefRangeDirective(
308 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
311 void emitCVDefRangeDirective(
312 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
315 void emitCVStringTableDirective()
override;
316 void emitCVFileChecksumsDirective()
override;
317 void emitCVFileChecksumOffsetDirective(
unsigned FileNo)
override;
318 void emitCVFPOData(
const MCSymbol *ProcSym,
SMLoc L)
override;
320 void emitIdent(
StringRef IdentString)
override;
321 void emitCFIBKeyFrame()
override;
322 void emitCFIMTETaggedFrame()
override;
323 void emitCFISections(
bool EH,
bool Debug)
override;
324 void emitCFIDefCfa(int64_t
Register, int64_t Offset)
override;
325 void emitCFIDefCfaOffset(int64_t Offset)
override;
326 void emitCFIDefCfaRegister(int64_t
Register)
override;
327 void emitCFILLVMDefAspaceCfa(int64_t
Register, int64_t Offset,
329 void emitCFIOffset(int64_t
Register, int64_t Offset)
override;
330 void emitCFIPersonality(
const MCSymbol *Sym,
unsigned Encoding)
override;
331 void emitCFILsda(
const MCSymbol *Sym,
unsigned Encoding)
override;
332 void emitCFIRememberState()
override;
333 void emitCFIRestoreState()
override;
334 void emitCFIRestore(int64_t
Register)
override;
335 void emitCFISameValue(int64_t
Register)
override;
336 void emitCFIRelOffset(int64_t
Register, int64_t Offset)
override;
337 void emitCFIAdjustCfaOffset(int64_t Adjustment)
override;
338 void emitCFIEscape(
StringRef Values)
override;
339 void emitCFIGnuArgsSize(int64_t Size)
override;
340 void emitCFISignalFrame()
override;
341 void emitCFIUndefined(int64_t
Register)
override;
342 void emitCFIRegister(int64_t Register1, int64_t Register2)
override;
343 void emitCFIWindowSave()
override;
344 void emitCFINegateRAState()
override;
345 void emitCFIReturnColumn(int64_t
Register)
override;
348 void emitWinCFIEndProc(
SMLoc Loc)
override;
349 void emitWinCFIFuncletOrFuncEnd(
SMLoc Loc)
override;
350 void emitWinCFIStartChained(
SMLoc Loc)
override;
351 void emitWinCFIEndChained(
SMLoc Loc)
override;
355 void emitWinCFIAllocStack(
unsigned Size,
SMLoc Loc)
override;
360 void emitWinCFIPushFrame(
bool Code,
SMLoc Loc)
override;
361 void emitWinCFIEndProlog(
SMLoc Loc)
override;
363 void emitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
bool Except,
365 void emitWinEHHandlerData(
SMLoc Loc)
override;
376 void emitBundleAlignMode(
unsigned AlignPow2)
override;
377 void emitBundleLock(
bool AlignToEnd)
override;
378 void emitBundleUnlock()
override;
384 void emitAddrsig()
override;
385 void emitAddrsigSym(
const MCSymbol *Sym)
override;
390 void emitRawTextImpl(
StringRef String)
override;
392 void finishImpl()
override;
394 void emitDwarfUnitLength(
uint64_t Length,
const Twine &Comment)
override;
397 const Twine &Comment)
override;
399 void emitDwarfLineStartLabel(
MCSymbol *StartSym)
override;
403 void emitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
407 void doFinalizationAtSectionEnd(
MCSection *Section)
override;
412 void MCAsmStreamer::AddComment(
const Twine &T,
bool EOL) {
413 if (!IsVerboseAsm)
return;
415 T.toVector(CommentToEmit);
418 CommentToEmit.push_back(
'\n');
421 void MCAsmStreamer::EmitCommentsAndEOL() {
430 "Comment array not newline terminated");
434 size_t Position = Comments.
find(
'\n');
437 Comments = Comments.
substr(Position+1);
438 }
while (!Comments.
empty());
440 CommentToEmit.
clear();
444 assert(Bytes > 0 && Bytes <= 8 &&
"Invalid size!");
445 return Value & ((
uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
448 void MCAsmStreamer::emitRawComment(
const Twine &T,
bool TabPrefix) {
455 void MCAsmStreamer::addExplicitComment(
const Twine &T) {
460 ExplicitCommentToEmit.
append(
"\t");
463 ExplicitCommentToEmit.
append(
c.slice(2,
c.size()).str());
465 size_t p = 2, len =
c.size() - 2;
468 size_t newp =
std::min(len,
c.find_first_of(
"\r\n",
p));
469 ExplicitCommentToEmit.
append(
"\t");
471 ExplicitCommentToEmit.
append(
c.slice(
p, newp).str());
474 ExplicitCommentToEmit.
append(
"\n");
478 ExplicitCommentToEmit.
append(
"\t");
479 ExplicitCommentToEmit.
append(
c.str());
480 }
else if (
c.front() ==
'#') {
482 ExplicitCommentToEmit.
append(
"\t");
484 ExplicitCommentToEmit.
append(
c.slice(1,
c.size()).str());
486 assert(
false &&
"Unexpected Assembly Comment");
488 if (
c.back() ==
'\n')
489 emitExplicitComments();
492 void MCAsmStreamer::emitExplicitComments() {
493 StringRef Comments = ExplicitCommentToEmit;
494 if (!Comments.
empty())
496 ExplicitCommentToEmit.
clear();
499 void MCAsmStreamer::changeSection(
MCSection *Section,
500 const MCExpr *Subsection) {
501 assert(Section &&
"Cannot switch to a null section!");
503 TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS);
505 Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
510 void MCAsmStreamer::emitELFSymverDirective(
const MCSymbol *OriginalSym,
512 bool KeepOriginalSym) {
514 OriginalSym->
print(OS, MAI);
516 if (!KeepOriginalSym && !
Name.contains(
"@@@"))
535 assert(NbArgs != -1 && ((
size_t)NbArgs) ==
Args.size() &&
"Malformed LOH!");
536 assert(str !=
"" &&
"Invalid LOH name");
550 void MCAsmStreamer::emitGNUAttribute(
unsigned Tag,
unsigned Value) {
551 OS <<
"\t.gnu_attribute " <<
Tag <<
", " <<
Value <<
"\n";
566 assert(!
Options.empty() &&
"At least one option is required!");
567 OS <<
"\t.linker_option \"" <<
Options[0] <<
'"';
570 OS <<
", " <<
'"' << *
it <<
'"';
600 if (SDKVersion.
empty())
602 OS <<
'\t' <<
"sdk_version " << SDKVersion.
getMajor();
603 if (
auto Minor = SDKVersion.
getMinor()) {
604 OS <<
", " << *Minor;
606 OS <<
", " << *Subminor;
612 unsigned Minor,
unsigned Update,
616 OS <<
", " << Update;
639 void MCAsmStreamer::emitBuildVersion(
unsigned Platform,
unsigned Major,
640 unsigned Minor,
unsigned Update,
643 OS <<
"\t.build_version " << PlatformName <<
", " << Major <<
", " << Minor;
645 OS <<
", " << Update;
650 void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(
651 unsigned Platform,
unsigned Major,
unsigned Minor,
unsigned Update,
653 emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
656 void MCAsmStreamer::emitThumbFunc(
MCSymbol *Func) {
659 OS <<
"\t.thumb_func";
663 Func->print(OS, MAI);
671 if (
auto *
E = dyn_cast<MCTargetExpr>(
Value))
672 if (
E->inlineAssignedExpr())
688 OS <<
".lto_set_conditional ";
697 Alias->
print(OS, MAI);
720 default:
return false;
743 OS <<
"\t.no_dead_strip\t";
748 OS <<
"\t.private_extern\t";
757 OS <<
"\t.weak_definition\t";
775 void MCAsmStreamer::emitSymbolDesc(
MCSymbol *
Symbol,
unsigned DescValue) {
776 OS <<
".desc" <<
' ';
778 OS <<
',' << DescValue;
782 void MCAsmStreamer::emitSyntaxDirective() {
784 OS <<
"\t.intel_syntax noprefix";
799 void MCAsmStreamer::emitCOFFSymbolStorageClass(
int StorageClass) {
804 void MCAsmStreamer::emitCOFFSymbolType(
int Type) {
805 OS <<
"\t.type\t" <<
Type <<
';';
809 void MCAsmStreamer::endCOFFSymbolDef() {
815 OS <<
"\t.safeseh\t";
826 void MCAsmStreamer::emitCOFFSectionIndex(
MCSymbol const *
Symbol) {
833 OS <<
"\t.secrel32\t";
840 void MCAsmStreamer::emitCOFFImgRel32(
MCSymbol const *
Symbol, int64_t Offset) {
853 void MCAsmStreamer::emitXCOFFLocalCommonSymbol(
MCSymbol *LabelSym,
858 "We only support writing log base-2 alignment format with XCOFF.");
862 LabelSym->
print(OS, MAI);
863 OS <<
',' <<
Size <<
',';
864 CsectSym->
print(OS, MAI);
876 void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
898 switch (Visibility) {
918 if (cast<MCSymbolXCOFF>(
Symbol)->hasRename())
919 emitXCOFFRenameDirective(
Symbol,
920 cast<MCSymbolXCOFF>(
Symbol)->getSymbolTableName());
923 void MCAsmStreamer::emitXCOFFRenameDirective(
const MCSymbol *
Name,
926 Name->print(OS, MAI);
929 for (
char C : Rename) {
940 OS <<
"\t.ref " <<
Name;
976 unsigned ByteAlign) {
986 OS <<
',' << ByteAlign;
990 OS <<
',' <<
Log2_32(ByteAlign);
1007 ".zerofill is a Mach-O specific directive");
1034 ".zerofill is a Mach-O specific directive");
1049 const auto BeginPtr =
Data.begin(), EndPtr =
Data.end();
1050 for (
const unsigned char C :
make_range(BeginPtr, EndPtr - 1)) {
1061 assert(!
Data.empty() &&
"Cannot generate an empty list.");
1062 const auto printCharacterInOctal = [&OS](
unsigned char C) {
1068 const auto printOneCharacterFor = [printCharacterInOctal](
1069 auto printOnePrintingCharacter) {
1070 return [printCharacterInOctal, printOnePrintingCharacter](
unsigned char C) {
1072 printOnePrintingCharacter(
static_cast<char>(
C));
1075 printCharacterInOctal(
C);
1078 const auto printCharacterList = [
Data, &OS](
const auto &printOneCharacter) {
1079 const auto BeginPtr =
Data.begin(), EndPtr =
Data.end();
1080 for (
const unsigned char C :
make_range(BeginPtr, EndPtr - 1)) {
1081 printOneCharacter(
C);
1084 printOneCharacter(*(EndPtr - 1));
1088 printCharacterList(printCharacterInOctal);
1091 printCharacterList(printOneCharacterFor([&OS](
char C) {
1092 const char AsmCharLitBuf[2] = {
'\'',
C};
1093 OS <<
StringRef(AsmCharLitBuf,
sizeof(AsmCharLitBuf));
1104 for (
unsigned char C :
Data) {
1111 for (
unsigned char C :
Data) {
1112 if (
C ==
'"' ||
C ==
'\\') {
1113 OS <<
'\\' << (char)
C;
1152 assert(getCurrentSectionOnly() &&
1153 "Cannot emit contents before setting section!");
1154 if (
Data.empty())
return;
1169 "hasPairedDoubleQuoteStringConstants target must support "
1170 "PlainString Directive");
1172 "hasPairedDoubleQuoteStringConstants target must support ByteList "
1174 if (
Data.back() == 0) {
1189 PrintQuotedString(
Data, OS);
1194 if (
Data.size() != 1 && emitAsString(
Data))
1200 TS->emitRawBytes(
Data);
1204 for (
const unsigned char C :
Data.bytes()) {
1212 const size_t Cols = 4;
1213 for (
size_t I = 0, EI =
alignTo(
Data.size(), Cols);
I < EI;
I += Cols) {
1217 for (; J < EJ - 1; ++J)
1218 OS <<
format(
"0x%02x", uint8_t(
Data[J])) <<
", ";
1224 void MCAsmStreamer::emitIntValue(
uint64_t Value,
unsigned Size) {
1228 void MCAsmStreamer::emitIntValueInHex(
uint64_t Value,
unsigned Size) {
1232 void MCAsmStreamer::emitIntValueInHexWithPadding(
uint64_t Value,
1237 void MCAsmStreamer::emitValueImpl(
const MCExpr *
Value,
unsigned Size,
1239 assert(Size <= 8 &&
"Invalid size");
1240 assert(getCurrentSectionOnly() &&
1241 "Cannot emit contents before setting section!");
1253 if (!
Value->evaluateAsAbsolute(IntValue))
1268 unsigned ByteOffset =
1269 IsLittleEndian ?
Emitted : (Remaining - EmissionSize);
1270 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
1276 std::numeric_limits<unsigned long long>::digits) &&
1277 "undefined behavior");
1278 ValueToEmit &= ~0ULL >>
Shift;
1279 emitIntValue(ValueToEmit, EmissionSize);
1288 TS->emitValue(
Value);
1295 void MCAsmStreamer::emitULEB128Value(
const MCExpr *
Value) {
1297 if (
Value->evaluateAsAbsolute(IntValue)) {
1298 emitULEB128IntValue(IntValue);
1301 OS <<
"\t.uleb128 ";
1306 void MCAsmStreamer::emitSLEB128Value(
const MCExpr *
Value) {
1308 if (
Value->evaluateAsAbsolute(IntValue)) {
1309 emitSLEB128IntValue(IntValue);
1312 OS <<
"\t.sleb128 ";
1317 void MCAsmStreamer::emitDTPRel64Value(
const MCExpr *
Value) {
1324 void MCAsmStreamer::emitDTPRel32Value(
const MCExpr *
Value) {
1331 void MCAsmStreamer::emitTPRel64Value(
const MCExpr *
Value) {
1338 void MCAsmStreamer::emitTPRel32Value(
const MCExpr *
Value) {
1345 void MCAsmStreamer::emitGPRel64Value(
const MCExpr *
Value) {
1352 void MCAsmStreamer::emitGPRel32Value(
const MCExpr *
Value) {
1359 void MCAsmStreamer::emitFill(
const MCExpr &NumBytes,
uint64_t FillValue,
1361 int64_t IntNumBytes;
1362 const bool IsAbsolute = NumBytes.evaluateAsAbsolute(IntNumBytes);
1363 if (IsAbsolute && IntNumBytes == 0)
1369 OS << ZeroDirective;
1370 NumBytes.
print(OS, MAI);
1372 OS <<
',' << (
int)FillValue;
1377 "Cannot emit non-absolute expression lengths of fill.");
1378 for (
int i = 0;
i < IntNumBytes; ++
i) {
1389 void MCAsmStreamer::emitFill(
const MCExpr &NumValues, int64_t Size,
1390 int64_t Expr,
SMLoc Loc) {
1393 NumValues.
print(OS, MAI);
1394 OS <<
", " <<
Size <<
", 0x";
1401 unsigned MaxBytesToEmit) {
1415 switch (ValueSize) {
1419 OS <<
"\t.p2align\t";
1433 if (
Value || MaxBytesToEmit) {
1438 OS <<
", " << MaxBytesToEmit;
1446 switch (ValueSize) {
1448 case 1: OS <<
".balign";
break;
1449 case 2: OS <<
".balignw";
break;
1450 case 4: OS <<
".balignl";
break;
1457 OS <<
", " << MaxBytesToEmit;
1461 void MCAsmStreamer::emitCodeAlignment(
unsigned ByteAlignment,
1463 unsigned MaxBytesToEmit) {
1469 void MCAsmStreamer::emitValueToOffset(
const MCExpr *Offset,
1470 unsigned char Value,
1475 OS <<
", " << (unsigned)
Value;
1479 void MCAsmStreamer::emitFileDirective(
StringRef Filename) {
1482 PrintQuotedString(Filename, OS);
1486 void MCAsmStreamer::emitFileDirective(
StringRef Filename,
1492 PrintQuotedString(Filename, OS);
1494 if (!CompilerVerion.
empty()) {
1495 PrintQuotedString(CompilerVerion, OS);
1497 if (!TimeStamp.
empty()) {
1499 PrintQuotedString(TimeStamp, OS);
1501 if (!Description.
empty()) {
1503 PrintQuotedString(Description, OS);
1508 void MCAsmStreamer::printDwarfFileDirective(
1514 if (!UseDwarfDirectory && !Directory.
empty()) {
1518 FullPathName = Directory;
1521 Filename = FullPathName;
1525 OS <<
"\t.file\t" << FileNo <<
' ';
1526 if (!Directory.
empty()) {
1527 PrintQuotedString(Directory, OS);
1530 PrintQuotedString(Filename, OS);
1532 OS <<
" md5 0x" << Checksum->
digest();
1535 PrintQuotedString(*
Source, OS);
1542 assert(CUID == 0 &&
"multiple CUs not supported by MCAsmStreamer");
1551 FileNo = FileNoOrErr.
get();
1561 printDwarfFileDirective(FileNo, Directory, Filename, Checksum,
Source,
1562 UseDwarfDirectory, OS1);
1565 TS->emitDwarfFileDirective(OS1.str());
1567 emitRawText(OS1.str());
1572 void MCAsmStreamer::emitDwarfFile0Directive(
StringRef Directory,
1582 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
1591 printDwarfFileDirective(0, Directory, Filename, Checksum,
Source,
1592 UseDwarfDirectory, OS1);
1595 TS->emitDwarfFileDirective(OS1.str());
1597 emitRawText(OS1.str());
1600 void MCAsmStreamer::emitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
1601 unsigned Column,
unsigned Flags,
1602 unsigned Isa,
unsigned Discriminator,
1611 Discriminator, FileName);
1615 OS <<
"\t.loc\t" << FileNo <<
" " << Line <<
" " << Column;
1618 OS <<
" basic_block";
1620 OS <<
" prologue_end";
1622 OS <<
" epilogue_begin";
1624 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
1635 OS <<
" isa " << Isa;
1637 OS <<
" discriminator " << Discriminator;
1643 << Line <<
':' << Column;
1647 Discriminator, FileName);
1650 MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(
unsigned CUID) {
1656 bool MCAsmStreamer::emitCVFileDirective(
unsigned FileNo,
StringRef Filename,
1659 if (!getContext().getCVContext().addFile(*
this, FileNo, Filename, Checksum,
1663 OS <<
"\t.cv_file\t" << FileNo <<
' ';
1664 PrintQuotedString(Filename, OS);
1672 PrintQuotedString(
toHex(Checksum), OS);
1679 bool MCAsmStreamer::emitCVFuncIdDirective(
unsigned FuncId) {
1680 OS <<
"\t.cv_func_id " <<
FuncId <<
'\n';
1684 bool MCAsmStreamer::emitCVInlineSiteIdDirective(
unsigned FunctionId,
1687 unsigned IALine,
unsigned IACol,
1689 OS <<
"\t.cv_inline_site_id " << FunctionId <<
" within " << IAFunc
1690 <<
" inlined_at " << IAFile <<
' ' << IALine <<
' ' << IACol <<
'\n';
1692 IALine, IACol, Loc);
1695 void MCAsmStreamer::emitCVLocDirective(
unsigned FunctionId,
unsigned FileNo,
1696 unsigned Line,
unsigned Column,
1697 bool PrologueEnd,
bool IsStmt,
1700 if (!checkCVLocSection(FunctionId, FileNo, Loc))
1703 OS <<
"\t.cv_loc\t" << FunctionId <<
" " << FileNo <<
" " << Line <<
" "
1706 OS <<
" prologue_end";
1719 void MCAsmStreamer::emitCVLinetableDirective(
unsigned FunctionId,
1722 OS <<
"\t.cv_linetable\t" << FunctionId <<
", ";
1723 FnStart->
print(OS, MAI);
1725 FnEnd->
print(OS, MAI);
1730 void MCAsmStreamer::emitCVInlineLinetableDirective(
unsigned PrimaryFunctionId,
1731 unsigned SourceFileId,
1732 unsigned SourceLineNum,
1735 OS <<
"\t.cv_inline_linetable\t" << PrimaryFunctionId <<
' ' << SourceFileId
1736 <<
' ' << SourceLineNum <<
' ';
1737 FnStartSym->
print(OS, MAI);
1739 FnEndSym->
print(OS, MAI);
1742 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1745 void MCAsmStreamer::PrintCVDefRangePrefix(
1746 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {
1747 OS <<
"\t.cv_def_range\t";
1748 for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
1750 Range.first->print(OS, MAI);
1752 Range.second->print(OS, MAI);
1756 void MCAsmStreamer::emitCVDefRangeDirective(
1757 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1759 PrintCVDefRangePrefix(Ranges);
1760 OS <<
", reg_rel, ";
1766 void MCAsmStreamer::emitCVDefRangeDirective(
1767 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1769 PrintCVDefRangePrefix(Ranges);
1770 OS <<
", subfield_reg, ";
1775 void MCAsmStreamer::emitCVDefRangeDirective(
1776 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1778 PrintCVDefRangePrefix(Ranges);
1784 void MCAsmStreamer::emitCVDefRangeDirective(
1785 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1787 PrintCVDefRangePrefix(Ranges);
1788 OS <<
", frame_ptr_rel, ";
1793 void MCAsmStreamer::emitCVStringTableDirective() {
1794 OS <<
"\t.cv_stringtable";
1798 void MCAsmStreamer::emitCVFileChecksumsDirective() {
1799 OS <<
"\t.cv_filechecksums";
1803 void MCAsmStreamer::emitCVFileChecksumOffsetDirective(
unsigned FileNo) {
1804 OS <<
"\t.cv_filechecksumoffset\t" << FileNo;
1808 void MCAsmStreamer::emitCVFPOData(
const MCSymbol *ProcSym,
SMLoc L) {
1809 OS <<
"\t.cv_fpo_data\t";
1810 ProcSym->
print(OS, MAI);
1814 void MCAsmStreamer::emitIdent(
StringRef IdentString) {
1817 PrintQuotedString(IdentString, OS);
1821 void MCAsmStreamer::emitCFISections(
bool EH,
bool Debug) {
1823 OS <<
"\t.cfi_sections ";
1827 OS <<
", .debug_frame";
1829 OS <<
".debug_frame";
1836 OS <<
"\t.cfi_startproc";
1844 OS <<
"\t.cfi_endproc";
1848 void MCAsmStreamer::EmitRegisterName(int64_t
Register) {
1855 InstPrinter->printRegName(OS, *LLVMRegister);
1862 void MCAsmStreamer::emitCFIDefCfa(int64_t
Register, int64_t Offset) {
1864 OS <<
"\t.cfi_def_cfa ";
1870 void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset) {
1872 OS <<
"\t.cfi_def_cfa_offset " <<
Offset;
1876 void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t
Register, int64_t Offset,
1879 OS <<
"\t.cfi_llvm_def_aspace_cfa ";
1887 OS <<
"\t.cfi_escape ";
1888 if (!Values.
empty()) {
1889 size_t e = Values.
size() - 1;
1890 for (
size_t i = 0;
i <
e; ++
i)
1891 OS <<
format(
"0x%02x", uint8_t(Values[
i])) <<
", ";
1892 OS <<
format(
"0x%02x", uint8_t(Values[
e]));
1896 void MCAsmStreamer::emitCFIEscape(
StringRef Values) {
1902 void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size) {
1905 uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
1912 void MCAsmStreamer::emitCFIDefCfaRegister(int64_t
Register) {
1914 OS <<
"\t.cfi_def_cfa_register ";
1919 void MCAsmStreamer::emitCFIOffset(int64_t
Register, int64_t Offset) {
1921 OS <<
"\t.cfi_offset ";
1927 void MCAsmStreamer::emitCFIPersonality(
const MCSymbol *Sym,
1928 unsigned Encoding) {
1930 OS <<
"\t.cfi_personality " << Encoding <<
", ";
1931 Sym->
print(OS, MAI);
1935 void MCAsmStreamer::emitCFILsda(
const MCSymbol *Sym,
unsigned Encoding) {
1937 OS <<
"\t.cfi_lsda " << Encoding <<
", ";
1938 Sym->
print(OS, MAI);
1942 void MCAsmStreamer::emitCFIRememberState() {
1944 OS <<
"\t.cfi_remember_state";
1948 void MCAsmStreamer::emitCFIRestoreState() {
1950 OS <<
"\t.cfi_restore_state";
1954 void MCAsmStreamer::emitCFIRestore(int64_t
Register) {
1956 OS <<
"\t.cfi_restore ";
1961 void MCAsmStreamer::emitCFISameValue(int64_t
Register) {
1963 OS <<
"\t.cfi_same_value ";
1968 void MCAsmStreamer::emitCFIRelOffset(int64_t
Register, int64_t Offset) {
1970 OS <<
"\t.cfi_rel_offset ";
1976 void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment) {
1978 OS <<
"\t.cfi_adjust_cfa_offset " << Adjustment;
1982 void MCAsmStreamer::emitCFISignalFrame() {
1984 OS <<
"\t.cfi_signal_frame";
1988 void MCAsmStreamer::emitCFIUndefined(int64_t
Register) {
1990 OS <<
"\t.cfi_undefined ";
1995 void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
1997 OS <<
"\t.cfi_register ";
1998 EmitRegisterName(Register1);
2000 EmitRegisterName(Register2);
2004 void MCAsmStreamer::emitCFIWindowSave() {
2006 OS <<
"\t.cfi_window_save";
2010 void MCAsmStreamer::emitCFINegateRAState() {
2012 OS <<
"\t.cfi_negate_ra_state";
2016 void MCAsmStreamer::emitCFIReturnColumn(int64_t
Register) {
2018 OS <<
"\t.cfi_return_column ";
2023 void MCAsmStreamer::emitCFIBKeyFrame() {
2025 OS <<
"\t.cfi_b_key_frame";
2029 void MCAsmStreamer::emitCFIMTETaggedFrame() {
2031 OS <<
"\t.cfi_mte_tagged_frame";
2043 void MCAsmStreamer::emitWinCFIEndProc(
SMLoc Loc) {
2046 OS <<
"\t.seh_endproc";
2050 void MCAsmStreamer::emitWinCFIFuncletOrFuncEnd(
SMLoc Loc) {
2053 OS <<
"\t.seh_endfunclet";
2057 void MCAsmStreamer::emitWinCFIStartChained(
SMLoc Loc) {
2060 OS <<
"\t.seh_startchained";
2064 void MCAsmStreamer::emitWinCFIEndChained(
SMLoc Loc) {
2067 OS <<
"\t.seh_endchained";
2071 void MCAsmStreamer::emitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
2072 bool Except,
SMLoc Loc) {
2075 OS <<
"\t.seh_handler ";
2076 Sym->
print(OS, MAI);
2078 const Triple &
T = getContext().getTargetTriple();
2082 OS <<
", " << Marker <<
"unwind";
2084 OS <<
", " << Marker <<
"except";
2088 void MCAsmStreamer::emitWinEHHandlerData(
SMLoc Loc) {
2103 MCSection *XData = getAssociatedXDataSection(TextSec);
2104 switchSectionNoChange(XData);
2106 OS <<
"\t.seh_handlerdata";
2113 OS <<
"\t.seh_pushreg ";
2114 InstPrinter->printRegName(OS,
Register);
2122 OS <<
"\t.seh_setframe ";
2123 InstPrinter->printRegName(OS,
Register);
2128 void MCAsmStreamer::emitWinCFIAllocStack(
unsigned Size,
SMLoc Loc) {
2131 OS <<
"\t.seh_stackalloc " <<
Size;
2139 OS <<
"\t.seh_savereg ";
2140 InstPrinter->printRegName(OS,
Register);
2149 OS <<
"\t.seh_savexmm ";
2150 InstPrinter->printRegName(OS,
Register);
2155 void MCAsmStreamer::emitWinCFIPushFrame(
bool Code,
SMLoc Loc) {
2158 OS <<
"\t.seh_pushframe";
2164 void MCAsmStreamer::emitWinCFIEndProlog(
SMLoc Loc) {
2167 OS <<
"\t.seh_endprologue";
2174 OS <<
"\t.cg_profile ";
2175 From->getSymbol().print(OS, MAI);
2178 OS <<
", " << Count;
2182 void MCAsmStreamer::AddEncodingComment(
const MCInst &Inst,
2190 if (!getAssembler().getEmitterPtr())
2193 getAssembler().getEmitter().encodeInstruction(Inst, VecOS,
Fixups, STI);
2200 for (
unsigned i = 0,
e =
Code.size() * 8;
i !=
e; ++
i)
2203 for (
unsigned i = 0,
e =
Fixups.size();
i !=
e; ++
i) {
2206 getAssembler().getBackend().getFixupKindInfo(
F.getKind());
2207 for (
unsigned j = 0;
j !=
Info.TargetSize; ++
j) {
2208 unsigned Index =
F.getOffset() * 8 +
Info.TargetOffset +
j;
2216 OS <<
"encoding: [";
2217 for (
unsigned i = 0,
e =
Code.size();
i !=
e; ++
i) {
2222 uint8_t MapEntry = FixupMap[
i * 8 + 0];
2223 for (
unsigned j = 1;
j != 8; ++
j) {
2224 if (FixupMap[
i * 8 +
j] == MapEntry)
2227 MapEntry = uint8_t(~0U);
2231 if (MapEntry != uint8_t(~0U)) {
2232 if (MapEntry == 0) {
2233 OS <<
format(
"0x%02x", uint8_t(Code[
i]));
2237 OS <<
format(
"0x%02x", uint8_t(Code[
i])) <<
'\''
2238 << char(
'A' + MapEntry - 1) <<
'\'';
2240 OS << char(
'A' + MapEntry - 1);
2245 for (
unsigned j = 8;
j--;) {
2250 FixupBit =
i * 8 +
j;
2252 FixupBit =
i * 8 + (7-
j);
2254 if (uint8_t MapEntry = FixupMap[FixupBit]) {
2255 assert(
Bit == 0 &&
"Encoder wrote into fixed up bit!");
2256 OS << char(
'A' + MapEntry - 1);
2264 for (
unsigned i = 0,
e =
Fixups.size();
i !=
e; ++
i) {
2267 getAssembler().getBackend().getFixupKindInfo(
F.getKind());
2268 OS <<
" fixup " << char(
'A' +
i) <<
" - "
2269 <<
"offset: " <<
F.getOffset() <<
", value: ";
2270 F.getValue()->print(OS, MAI);
2271 OS <<
", kind: " <<
Info.Name <<
"\n";
2275 void MCAsmStreamer::emitInstruction(
const MCInst &Inst,
2277 assert(getCurrentSectionOnly() &&
2278 "Cannot emit contents before setting section!");
2286 AddEncodingComment(Inst, STI);
2290 Inst.
dump_pretty(getCommentOS(), InstPrinter.get(),
"\n ");
2291 getCommentOS() <<
"\n";
2294 if(getTargetStreamer())
2295 getTargetStreamer()->prettyPrintAsm(*InstPrinter, 0, Inst, STI, OS);
2297 InstPrinter->printInst(&Inst, 0,
"", STI, OS);
2300 if (Comments.
size() && Comments.
back() !=
'\n')
2301 getCommentOS() <<
"\n";
2306 void MCAsmStreamer::emitPseudoProbe(
2309 OS <<
"\t.pseudoprobe\t" << Guid <<
" " <<
Index <<
" " <<
Type <<
" "
2313 for (
const auto &Site : InlineStack)
2314 OS <<
" @ " << std::get<0>(Site) <<
":" << std::get<1>(Site);
2318 void MCAsmStreamer::emitBundleAlignMode(
unsigned AlignPow2) {
2319 OS <<
"\t.bundle_align_mode " << AlignPow2;
2323 void MCAsmStreamer::emitBundleLock(
bool AlignToEnd) {
2324 OS <<
"\t.bundle_lock";
2326 OS <<
" align_to_end";
2330 void MCAsmStreamer::emitBundleUnlock() {
2331 OS <<
"\t.bundle_unlock";
2344 Expr->
print(OS, MAI);
2350 void MCAsmStreamer::emitAddrsig() {
2355 void MCAsmStreamer::emitAddrsigSym(
const MCSymbol *Sym) {
2356 OS <<
"\t.addrsig_sym ";
2357 Sym->
print(OS, MAI);
2364 void MCAsmStreamer::emitRawTextImpl(
StringRef String) {
2371 void MCAsmStreamer::finishImpl() {
2373 if (getContext().getGenDwarfForAssembly())
2386 const auto &Tables = getContext().getMCDwarfLineTables();
2387 if (!Tables.empty()) {
2388 assert(Tables.size() == 1 &&
"asm output only supports one line table");
2389 if (
auto *Label = Tables.begin()->second.getLabel()) {
2390 switchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
2396 void MCAsmStreamer::emitDwarfUnitLength(
uint64_t Length,
const Twine &Comment) {
2409 const Twine &Comment) {
2417 return getContext().createTempSymbol(
Prefix +
"_end");
2421 void MCAsmStreamer::emitDwarfLineStartLabel(
MCSymbol *StartSym) {
2432 emitLabel(DebugLineSymTmp);
2436 unsigned LengthFieldSize =
2442 emitAssignment(StartSym, OuterSym);
2448 void MCAsmStreamer::emitDwarfLineEndEntry(
MCSection *Section,
2456 ".loc should not be generated together with raw data!");
2468 emitDwarfAdvanceLineAddr(
INT64_MAX, LastLabel, SectionEnd,
2473 void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
2478 ".loc/.file don't need raw data in debug line section!");
2481 AddComment(
"Set address to " +
Label->getName());
2482 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2484 emitIntValue(dwarf::DW_LNE_set_address, 1);
2489 AddComment(
"Start sequence");
2497 AddComment(
"End sequence");
2498 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2499 emitULEB128IntValue(1);
2500 emitIntValue(dwarf::DW_LNE_end_sequence, 1);
2505 AddComment(
"Advance line " +
Twine(LineDelta));
2506 emitIntValue(dwarf::DW_LNS_advance_line, 1);
2507 emitSLEB128IntValue(LineDelta);
2508 emitIntValue(dwarf::DW_LNS_copy, 1);
2511 void MCAsmStreamer::doFinalizationAtSectionEnd(
MCSection *Section) {
2517 switchSectionNoChange(Section);
2519 MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());
2526 std::unique_ptr<formatted_raw_ostream> OS,
2527 bool isVerboseAsm,
bool useDwarfDirectory,
2529 std::unique_ptr<MCCodeEmitter> &&CE,
2530 std::unique_ptr<MCAsmBackend> &&MAB,