42 class MCAsmStreamer final :
public MCStreamer {
43 std::unique_ptr<formatted_raw_ostream> OSOwner;
46 std::unique_ptr<MCInstPrinter> InstPrinter;
47 std::unique_ptr<MCCodeEmitter> Emitter;
48 std::unique_ptr<MCAsmBackend> AsmBackend;
54 unsigned IsVerboseAsm : 1;
55 unsigned ShowInst : 1;
56 unsigned UseDwarfDirectory : 1;
58 void EmitRegisterName(int64_t
Register);
64 bool isVerboseAsm,
bool useDwarfDirectory,
67 :
MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
68 MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter),
69 AsmBackend(asmbackend), CommentStream(CommentToEmit),
70 IsVerboseAsm(isVerboseAsm), ShowInst(showInst),
71 UseDwarfDirectory(useDwarfDirectory) {
74 InstPrinter->setCommentStream(CommentStream);
77 inline void EmitEOL() {
79 emitExplicitComments();
88 void EmitSyntaxDirective()
override;
90 void EmitCommentsAndEOL();
94 bool isVerboseAsm()
const override {
return IsVerboseAsm; }
97 bool hasRawTextSupport()
const override {
return true; }
103 void AddComment(
const Twine &
T,
bool EOL =
true)
override;
114 return CommentStream;
117 void emitRawComment(
const Twine &
T,
bool TabPrefix =
true)
override;
119 void addExplicitComment(
const Twine &
T)
override;
120 void emitExplicitComments()
override;
123 void AddBlankLine()
override {
139 unsigned Update)
override;
146 void EmitSymbolDesc(
MCSymbol *
Symbol,
unsigned DescValue)
override;
148 void EmitCOFFSymbolStorageClass(
int StorageClass)
override;
149 void EmitCOFFSymbolType(
int Type)
override;
150 void EndCOFFSymbolDef()
override;
172 void EmitBinaryData(
StringRef Data)
override;
176 void EmitValueImpl(
const MCExpr *
Value,
unsigned Size,
178 void EmitIntValue(uint64_t Value,
unsigned Size)
override;
180 void EmitULEB128Value(
const MCExpr *Value)
override;
182 void EmitSLEB128Value(
const MCExpr *Value)
override;
184 void EmitDTPRel32Value(
const MCExpr *Value)
override;
185 void EmitDTPRel64Value(
const MCExpr *Value)
override;
186 void EmitTPRel32Value(
const MCExpr *Value)
override;
187 void EmitTPRel64Value(
const MCExpr *Value)
override;
189 void EmitGPRel64Value(
const MCExpr *Value)
override;
191 void EmitGPRel32Value(
const MCExpr *Value)
override;
194 void emitFill(uint64_t NumBytes, uint8_t FillValue)
override;
196 void emitFill(
const MCExpr &NumBytes, uint64_t FillValue,
199 void emitFill(uint64_t NumValues, int64_t Size, int64_t Expr)
override;
201 void emitFill(
const MCExpr &NumValues, int64_t Size, int64_t Expr,
204 void EmitValueToAlignment(
unsigned ByteAlignment, int64_t Value = 0,
205 unsigned ValueSize = 1,
206 unsigned MaxBytesToEmit = 0)
override;
209 unsigned MaxBytesToEmit = 0)
override;
215 void EmitFileDirective(
StringRef Filename)
override;
216 unsigned EmitDwarfFileDirective(
unsigned FileNo,
StringRef Directory,
218 unsigned CUID = 0)
override;
219 void EmitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
220 unsigned Column,
unsigned Flags,
221 unsigned Isa,
unsigned Discriminator,
223 MCSymbol *getDwarfLineTableSymbol(
unsigned CUID)
override;
225 bool EmitCVFileDirective(
unsigned FileNo,
StringRef Filename)
override;
226 bool EmitCVFuncIdDirective(
unsigned FuncId)
override;
227 bool EmitCVInlineSiteIdDirective(
unsigned FunctionId,
unsigned IAFunc,
228 unsigned IAFile,
unsigned IALine,
229 unsigned IACol,
SMLoc Loc)
override;
230 void EmitCVLocDirective(
unsigned FunctionId,
unsigned FileNo,
unsigned Line,
231 unsigned Column,
bool PrologueEnd,
bool IsStmt,
233 void EmitCVLinetableDirective(
unsigned FunctionId,
const MCSymbol *FnStart,
235 void EmitCVInlineLinetableDirective(
unsigned PrimaryFunctionId,
236 unsigned SourceFileId,
237 unsigned SourceLineNum,
240 void EmitCVDefRangeDirective(
241 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
243 void EmitCVStringTableDirective()
override;
244 void EmitCVFileChecksumsDirective()
override;
246 void EmitIdent(
StringRef IdentString)
override;
247 void EmitCFISections(
bool EH,
bool Debug)
override;
249 void EmitCFIDefCfaOffset(int64_t
Offset)
override;
250 void EmitCFIDefCfaRegister(int64_t
Register)
override;
252 void EmitCFIPersonality(
const MCSymbol *Sym,
unsigned Encoding)
override;
253 void EmitCFILsda(
const MCSymbol *Sym,
unsigned Encoding)
override;
254 void EmitCFIRememberState()
override;
255 void EmitCFIRestoreState()
override;
256 void EmitCFISameValue(int64_t
Register)
override;
258 void EmitCFIAdjustCfaOffset(int64_t Adjustment)
override;
259 void EmitCFIEscape(
StringRef Values)
override;
260 void EmitCFIGnuArgsSize(int64_t Size)
override;
261 void EmitCFISignalFrame()
override;
262 void EmitCFIUndefined(int64_t
Register)
override;
263 void EmitCFIRegister(int64_t Register1, int64_t Register2)
override;
264 void EmitCFIWindowSave()
override;
267 void EmitWinCFIEndProc()
override;
268 void EmitWinCFIStartChained()
override;
269 void EmitWinCFIEndChained()
override;
270 void EmitWinCFIPushReg(
unsigned Register)
override;
271 void EmitWinCFISetFrame(
unsigned Register,
unsigned Offset)
override;
272 void EmitWinCFIAllocStack(
unsigned Size)
override;
273 void EmitWinCFISaveReg(
unsigned Register,
unsigned Offset)
override;
274 void EmitWinCFISaveXMM(
unsigned Register,
unsigned Offset)
override;
275 void EmitWinCFIPushFrame(
bool Code)
override;
276 void EmitWinCFIEndProlog()
override;
278 void EmitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
bool Except)
override;
279 void EmitWinEHHandlerData()
override;
283 void EmitBundleAlignMode(
unsigned AlignPow2)
override;
284 void EmitBundleLock(
bool AlignToEnd)
override;
285 void EmitBundleUnlock()
override;
295 void FinishImpl()
override;
305 void MCAsmStreamer::AddComment(
const Twine &
T,
bool EOL) {
306 if (!IsVerboseAsm)
return;
311 CommentToEmit.push_back(
'\n');
314 void MCAsmStreamer::EmitCommentsAndEOL() {
315 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
323 "Comment array not newline terminated");
326 OS.PadToColumn(MAI->getCommentColumn());
327 size_t Position = Comments.
find(
'\n');
328 OS << MAI->getCommentString() <<
' ' << Comments.
substr(0, Position) <<
'\n';
330 Comments = Comments.
substr(Position+1);
331 }
while (!Comments.
empty());
333 CommentToEmit.clear();
337 assert(Bytes > 0 && Bytes <= 8 &&
"Invalid size!");
338 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
341 void MCAsmStreamer::emitRawComment(
const Twine &T,
bool TabPrefix) {
344 OS << MAI->getCommentString() <<
T;
348 void MCAsmStreamer::addExplicitComment(
const Twine &T) {
353 ExplicitCommentToEmit.append(
"\t");
354 ExplicitCommentToEmit.append(MAI->getCommentString());
356 ExplicitCommentToEmit.append(c.
slice(2, c.
size()).str());
358 size_t p = 2, len = c.
size() - 2;
362 ExplicitCommentToEmit.append(
"\t");
363 ExplicitCommentToEmit.append(MAI->getCommentString());
364 ExplicitCommentToEmit.append(c.
slice(p, newp).
str());
367 ExplicitCommentToEmit.append(
"\n");
371 ExplicitCommentToEmit.append(
"\t");
372 ExplicitCommentToEmit.append(c.
str());
373 }
else if (c.
front() ==
'#') {
375 ExplicitCommentToEmit.append(
"\t");
376 ExplicitCommentToEmit.append(MAI->getCommentString());
377 ExplicitCommentToEmit.append(c.
slice(1, c.
size()).str());
379 assert(
false &&
"Unexpected Assembly Comment");
381 if (c.
back() ==
'\n')
382 emitExplicitComments();
385 void MCAsmStreamer::emitExplicitComments() {
386 StringRef Comments = ExplicitCommentToEmit;
387 if (!Comments.
empty())
389 ExplicitCommentToEmit.clear();
393 const MCExpr *Subsection) {
394 assert(Section &&
"Cannot switch to a null section!");
402 Symbol->
print(OS, MAI);
403 OS << MAI->getLabelSuffix();
413 assert(NbArgs != -1 && ((
size_t)NbArgs) == Args.
size() &&
"Malformed LOH!");
414 assert(str !=
"" &&
"Invalid LOH name");
432 case MCAF_Code16: OS <<
'\t'<< MAI->getCode16Directive();
break;
433 case MCAF_Code32: OS <<
'\t'<< MAI->getCode32Directive();
break;
434 case MCAF_Code64: OS <<
'\t'<< MAI->getCode64Directive();
break;
440 assert(!Options.
empty() &&
"At least one option is required!");
441 OS <<
"\t.linker_option \"" << Options[0] <<
'"';
443 ie = Options.end(); it != ie; ++it) {
444 OS <<
", " <<
'"' << *it <<
'"';
450 if (!MAI->doesSupportDataRegionDirectives())
463 unsigned Minor,
unsigned Update) {
470 OS <<
" " << Major <<
", " << Minor;
472 OS <<
", " << Update;
479 OS <<
"\t.thumb_func";
481 if (MAI->hasSubsectionsViaSymbols()) {
483 Func->
print(OS, MAI);
488 void MCAsmStreamer::EmitAssignment(
MCSymbol *Symbol,
const MCExpr *Value) {
489 Symbol->
print(OS, MAI);
491 Value->
print(OS, MAI);
498 void MCAsmStreamer::EmitWeakReference(
MCSymbol *Alias,
const MCSymbol *Symbol) {
500 Alias->
print(OS, MAI);
502 Symbol->
print(OS, MAI);
506 bool MCAsmStreamer::EmitSymbolAttribute(
MCSymbol *Symbol,
517 if (!MAI->hasDotTypeDotSizeDirective())
520 Symbol->
print(OS, MAI);
521 OS <<
',' << ((MAI->getCommentString()[0] !=
'@') ?
'@' :
'%');
523 default:
return false;
535 OS << MAI->getGlobalDirective();
543 if (!MAI->hasNoDeadStrip())
545 OS <<
"\t.no_dead_strip\t";
550 OS <<
"\t.private_extern\t";
554 case MCSA_Weak: OS << MAI->getWeakDirective();
break;
556 OS <<
"\t.weak_definition\t";
563 Symbol->
print(OS, MAI);
569 void MCAsmStreamer::EmitSymbolDesc(
MCSymbol *Symbol,
unsigned DescValue) {
570 OS <<
".desc" <<
' ';
571 Symbol->
print(OS, MAI);
572 OS <<
',' << DescValue;
576 void MCAsmStreamer::EmitSyntaxDirective() {
577 if (MAI->getAssemblerDialect() == 1) {
578 OS <<
"\t.intel_syntax noprefix";
586 void MCAsmStreamer::BeginCOFFSymbolDef(
const MCSymbol *Symbol) {
588 Symbol->
print(OS, MAI);
593 void MCAsmStreamer::EmitCOFFSymbolStorageClass (
int StorageClass) {
594 OS <<
"\t.scl\t" << StorageClass <<
';';
598 void MCAsmStreamer::EmitCOFFSymbolType (
int Type) {
599 OS <<
"\t.type\t" << Type <<
';';
603 void MCAsmStreamer::EndCOFFSymbolDef() {
608 void MCAsmStreamer::EmitCOFFSafeSEH(
MCSymbol const *Symbol) {
609 OS <<
"\t.safeseh\t";
610 Symbol->
print(OS, MAI);
614 void MCAsmStreamer::EmitCOFFSectionIndex(
MCSymbol const *Symbol) {
616 Symbol->
print(OS, MAI);
620 void MCAsmStreamer::EmitCOFFSecRel32(
MCSymbol const *Symbol, uint64_t
Offset) {
621 OS <<
"\t.secrel32\t";
622 Symbol->
print(OS, MAI);
628 void MCAsmStreamer::emitELFSize(
MCSymbol *Symbol,
const MCExpr *Value) {
629 assert(MAI->hasDotTypeDotSizeDirective());
631 Symbol->
print(OS, MAI);
633 Value->
print(OS, MAI);
637 void MCAsmStreamer::EmitCommonSymbol(
MCSymbol *Symbol, uint64_t Size,
640 Symbol->
print(OS, MAI);
643 if (ByteAlignment != 0) {
644 if (MAI->getCOMMDirectiveAlignmentIsInBytes())
645 OS <<
',' << ByteAlignment;
647 OS <<
',' <<
Log2_32(ByteAlignment);
656 void MCAsmStreamer::EmitLocalCommonSymbol(
MCSymbol *Symbol, uint64_t Size,
657 unsigned ByteAlign) {
659 Symbol->
print(OS, MAI);
663 switch (MAI->getLCOMMDirectiveAlignmentType()) {
667 OS <<
',' << ByteAlign;
671 OS <<
',' <<
Log2_32(ByteAlign);
679 uint64_t Size,
unsigned ByteAlignment) {
692 Symbol->
print(OS, MAI);
694 if (ByteAlignment != 0)
695 OS <<
',' <<
Log2_32(ByteAlignment);
704 uint64_t Size,
unsigned ByteAlignment) {
707 assert(Symbol &&
"Symbol shouldn't be NULL!");
711 Symbol->
print(OS, MAI);
716 if (ByteAlignment > 1) OS <<
", " <<
Log2_32(ByteAlignment);
721 static inline char toOctal(
int X) {
return (X&7)+
'0'; }
726 for (
unsigned i = 0, e = Data.
size();
i != e; ++
i) {
727 unsigned char C = Data[
i];
728 if (C ==
'"' || C ==
'\\') {
729 OS <<
'\\' << (char)C;
733 if (isprint((
unsigned char)
C)) {
739 case '\b': OS <<
"\\b";
break;
740 case '\f': OS <<
"\\f";
break;
741 case '\n': OS <<
"\\n";
break;
742 case '\r': OS <<
"\\r";
break;
743 case '\t': OS <<
"\\t";
break;
746 OS << toOctal(C >> 6);
747 OS << toOctal(C >> 3);
748 OS << toOctal(C >> 0);
756 void MCAsmStreamer::EmitBytes(
StringRef Data) {
757 assert(getCurrentSectionOnly() &&
758 "Cannot emit contents before setting section!");
759 if (Data.
empty())
return;
761 if (Data.
size() == 1) {
762 OS << MAI->getData8bitsDirective();
763 OS << (
unsigned)(
unsigned char)Data[0];
770 if (MAI->getAscizDirective() && Data.
back() == 0) {
771 OS << MAI->getAscizDirective();
774 OS << MAI->getAsciiDirective();
781 void MCAsmStreamer::EmitBinaryData(
StringRef Data) {
783 const size_t Cols = 4;
784 for (
size_t I = 0, EI =
alignTo(Data.
size(), Cols);
I < EI;
I += Cols) {
787 OS << MAI->getData8bitsDirective();
788 for (; J < EJ - 1; ++J)
789 OS <<
format(
"0x%02x", uint8_t(Data[J])) <<
", ";
790 OS <<
format(
"0x%02x", uint8_t(Data[J]));
795 void MCAsmStreamer::EmitIntValue(uint64_t Value,
unsigned Size) {
799 void MCAsmStreamer::EmitValueImpl(
const MCExpr *Value,
unsigned Size,
801 assert(Size <= 8 &&
"Invalid size");
802 assert(getCurrentSectionOnly() &&
803 "Cannot emit contents before setting section!");
804 const char *Directive =
nullptr;
807 case 1: Directive = MAI->getData8bitsDirective();
break;
808 case 2: Directive = MAI->getData16bitsDirective();
break;
809 case 4: Directive = MAI->getData32bitsDirective();
break;
810 case 8: Directive = MAI->getData64bitsDirective();
break;
815 if (!Value->evaluateAsAbsolute(IntValue))
822 bool IsLittleEndian = MAI->isLittleEndian();
823 for (
unsigned Emitted = 0; Emitted != Size;) {
824 unsigned Remaining = Size - Emitted;
830 unsigned ByteOffset =
831 IsLittleEndian ? Emitted : (Remaining - EmissionSize);
832 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
836 uint64_t Shift = 64 - EmissionSize * 8;
837 assert(Shift < static_cast<uint64_t>(
838 std::numeric_limits<unsigned long long>::digits) &&
839 "undefined behavior");
840 ValueToEmit &= ~0ULL >> Shift;
841 EmitIntValue(ValueToEmit, EmissionSize);
842 Emitted += EmissionSize;
847 assert(Directive &&
"Invalid size for machine code value!");
849 Value->
print(OS, MAI);
853 void MCAsmStreamer::EmitULEB128Value(
const MCExpr *Value) {
855 if (Value->evaluateAsAbsolute(IntValue)) {
856 EmitULEB128IntValue(IntValue);
860 Value->
print(OS, MAI);
864 void MCAsmStreamer::EmitSLEB128Value(
const MCExpr *Value) {
866 if (Value->evaluateAsAbsolute(IntValue)) {
867 EmitSLEB128IntValue(IntValue);
871 Value->
print(OS, MAI);
875 void MCAsmStreamer::EmitDTPRel64Value(
const MCExpr *Value) {
876 assert(MAI->getDTPRel64Directive() !=
nullptr);
877 OS << MAI->getDTPRel64Directive();
878 Value->
print(OS, MAI);
882 void MCAsmStreamer::EmitDTPRel32Value(
const MCExpr *Value) {
883 assert(MAI->getDTPRel32Directive() !=
nullptr);
884 OS << MAI->getDTPRel32Directive();
885 Value->
print(OS, MAI);
889 void MCAsmStreamer::EmitTPRel64Value(
const MCExpr *Value) {
890 assert(MAI->getTPRel64Directive() !=
nullptr);
891 OS << MAI->getTPRel64Directive();
892 Value->
print(OS, MAI);
896 void MCAsmStreamer::EmitTPRel32Value(
const MCExpr *Value) {
897 assert(MAI->getTPRel32Directive() !=
nullptr);
898 OS << MAI->getTPRel32Directive();
899 Value->
print(OS, MAI);
903 void MCAsmStreamer::EmitGPRel64Value(
const MCExpr *Value) {
904 assert(MAI->getGPRel64Directive() !=
nullptr);
905 OS << MAI->getGPRel64Directive();
906 Value->
print(OS, MAI);
910 void MCAsmStreamer::EmitGPRel32Value(
const MCExpr *Value) {
911 assert(MAI->getGPRel32Directive() !=
nullptr);
912 OS << MAI->getGPRel32Directive();
913 Value->
print(OS, MAI);
919 void MCAsmStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
920 if (NumBytes == 0)
return;
923 emitFill(*E, FillValue);
926 void MCAsmStreamer::emitFill(
const MCExpr &NumBytes, uint64_t FillValue,
928 if (
const char *ZeroDirective = MAI->getZeroDirective()) {
931 NumBytes.
print(OS, MAI);
933 OS <<
',' << (int)FillValue;
941 void MCAsmStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) {
946 emitFill(*E, Size, Expr);
949 void MCAsmStreamer::emitFill(
const MCExpr &NumValues, int64_t Size,
950 int64_t Expr,
SMLoc Loc) {
953 NumValues.
print(OS, MAI);
954 OS <<
", " << Size <<
", 0x";
959 void MCAsmStreamer::EmitValueToAlignment(
unsigned ByteAlignment, int64_t Value,
961 unsigned MaxBytesToEmit) {
969 OS <<
"\t.p2align\t";
983 if (Value || MaxBytesToEmit) {
988 OS <<
", " << MaxBytesToEmit;
998 case 1: OS <<
".balign";
break;
999 case 2: OS <<
".balignw";
break;
1000 case 4: OS <<
".balignl";
break;
1007 OS <<
", " << MaxBytesToEmit;
1011 void MCAsmStreamer::EmitCodeAlignment(
unsigned ByteAlignment,
1012 unsigned MaxBytesToEmit) {
1014 EmitValueToAlignment(ByteAlignment, MAI->getTextAlignFillValue(),
1018 void MCAsmStreamer::emitValueToOffset(
const MCExpr *Offset,
1019 unsigned char Value,
1023 Offset->
print(OS, MAI);
1028 void MCAsmStreamer::EmitFileDirective(
StringRef Filename) {
1029 assert(MAI->hasSingleParameterDotFile());
1035 unsigned MCAsmStreamer::EmitDwarfFileDirective(
unsigned FileNo,
1043 FileNo = Table.
getFile(Directory, Filename, FileNo);
1051 if (!UseDwarfDirectory && !Directory.
empty()) {
1055 FullPathName = Directory;
1058 Filename = FullPathName;
1062 OS <<
"\t.file\t" << FileNo <<
' ';
1063 if (!Directory.
empty()) {
1073 void MCAsmStreamer::EmitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
1074 unsigned Column,
unsigned Flags,
1076 unsigned Discriminator,
1078 OS <<
"\t.loc\t" << FileNo <<
" " << Line <<
" " << Column;
1080 OS <<
" basic_block";
1082 OS <<
" prologue_end";
1084 OS <<
" epilogue_begin";
1086 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
1090 if (Flags & DWARF2_FLAG_IS_STMT)
1097 OS <<
" isa " << Isa;
1099 OS <<
" discriminator " << Discriminator;
1102 OS.PadToColumn(MAI->getCommentColumn());
1103 OS << MAI->getCommentString() <<
' ' << FileName <<
':'
1104 << Line <<
':' << Column;
1108 Isa, Discriminator, FileName);
1111 MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(
unsigned CUID) {
1117 bool MCAsmStreamer::EmitCVFileDirective(
unsigned FileNo,
StringRef Filename) {
1118 if (!getContext().getCVContext().addFile(FileNo, Filename))
1121 OS <<
"\t.cv_file\t" << FileNo <<
' ';
1128 bool MCAsmStreamer::EmitCVFuncIdDirective(
unsigned FuncId) {
1129 OS <<
"\t.cv_func_id " << FuncId <<
'\n';
1133 bool MCAsmStreamer::EmitCVInlineSiteIdDirective(
unsigned FunctionId,
1136 unsigned IALine,
unsigned IACol,
1138 OS <<
"\t.cv_inline_site_id " << FunctionId <<
" within " << IAFunc
1139 <<
" inlined_at " << IAFile <<
' ' << IALine <<
' ' << IACol <<
'\n';
1141 IALine, IACol, Loc);
1144 void MCAsmStreamer::EmitCVLocDirective(
unsigned FunctionId,
unsigned FileNo,
1145 unsigned Line,
unsigned Column,
1146 bool PrologueEnd,
bool IsStmt,
1148 OS <<
"\t.cv_loc\t" << FunctionId <<
" " << FileNo <<
" " << Line <<
" "
1151 OS <<
" prologue_end";
1153 unsigned OldIsStmt = getContext().getCVContext().getCurrentCVLoc().isStmt();
1154 if (IsStmt != OldIsStmt) {
1164 OS.PadToColumn(MAI->getCommentColumn());
1165 OS << MAI->getCommentString() <<
' ' << FileName <<
':' << Line <<
':'
1170 PrologueEnd, IsStmt, FileName, Loc);
1173 void MCAsmStreamer::EmitCVLinetableDirective(
unsigned FunctionId,
1176 OS <<
"\t.cv_linetable\t" << FunctionId <<
", ";
1177 FnStart->
print(OS, MAI);
1179 FnEnd->
print(OS, MAI);
1184 void MCAsmStreamer::EmitCVInlineLinetableDirective(
unsigned PrimaryFunctionId,
1185 unsigned SourceFileId,
1186 unsigned SourceLineNum,
1189 OS <<
"\t.cv_inline_linetable\t" << PrimaryFunctionId <<
' ' << SourceFileId
1190 <<
' ' << SourceLineNum <<
' ';
1191 FnStartSym->
print(OS, MAI);
1193 FnEndSym->
print(OS, MAI);
1196 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1199 void MCAsmStreamer::EmitCVDefRangeDirective(
1200 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1202 OS <<
"\t.cv_def_range\t";
1203 for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
1205 Range.first->print(OS, MAI);
1207 Range.second->print(OS, MAI);
1215 void MCAsmStreamer::EmitCVStringTableDirective() {
1216 OS <<
"\t.cv_stringtable";
1220 void MCAsmStreamer::EmitCVFileChecksumsDirective() {
1221 OS <<
"\t.cv_filechecksums";
1225 void MCAsmStreamer::EmitIdent(
StringRef IdentString) {
1226 assert(MAI->hasIdentDirective() &&
".ident directive not supported");
1232 void MCAsmStreamer::EmitCFISections(
bool EH,
bool Debug) {
1234 OS <<
"\t.cfi_sections ";
1238 OS <<
", .debug_frame";
1240 OS <<
".debug_frame";
1247 OS <<
"\t.cfi_startproc";
1255 OS <<
"\t.cfi_endproc";
1259 void MCAsmStreamer::EmitRegisterName(int64_t
Register) {
1260 if (!MAI->useDwarfRegNumForCFI()) {
1263 InstPrinter->printRegName(OS, LLVMRegister);
1269 void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
1271 OS <<
"\t.cfi_def_cfa ";
1272 EmitRegisterName(Register);
1277 void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
1279 OS <<
"\t.cfi_def_cfa_offset " <<
Offset;
1284 OS <<
"\t.cfi_escape ";
1285 if (!Values.
empty()) {
1286 size_t e = Values.
size() - 1;
1287 for (
size_t i = 0;
i < e; ++
i)
1288 OS <<
format(
"0x%02x", uint8_t(Values[
i])) <<
", ";
1289 OS <<
format(
"0x%02x", uint8_t(Values[e]));
1293 void MCAsmStreamer::EmitCFIEscape(
StringRef Values) {
1299 void MCAsmStreamer::EmitCFIGnuArgsSize(int64_t Size) {
1302 uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
1309 void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
1311 OS <<
"\t.cfi_def_cfa_register ";
1312 EmitRegisterName(Register);
1316 void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
1318 OS <<
"\t.cfi_offset ";
1319 EmitRegisterName(Register);
1324 void MCAsmStreamer::EmitCFIPersonality(
const MCSymbol *Sym,
1325 unsigned Encoding) {
1327 OS <<
"\t.cfi_personality " << Encoding <<
", ";
1328 Sym->
print(OS, MAI);
1332 void MCAsmStreamer::EmitCFILsda(
const MCSymbol *Sym,
unsigned Encoding) {
1334 OS <<
"\t.cfi_lsda " << Encoding <<
", ";
1335 Sym->
print(OS, MAI);
1339 void MCAsmStreamer::EmitCFIRememberState() {
1341 OS <<
"\t.cfi_remember_state";
1345 void MCAsmStreamer::EmitCFIRestoreState() {
1347 OS <<
"\t.cfi_restore_state";
1351 void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
1353 OS <<
"\t.cfi_same_value ";
1354 EmitRegisterName(Register);
1358 void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1360 OS <<
"\t.cfi_rel_offset ";
1361 EmitRegisterName(Register);
1366 void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1368 OS <<
"\t.cfi_adjust_cfa_offset " << Adjustment;
1372 void MCAsmStreamer::EmitCFISignalFrame() {
1374 OS <<
"\t.cfi_signal_frame";
1378 void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1380 OS <<
"\t.cfi_undefined " <<
Register;
1384 void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1386 OS <<
"\t.cfi_register " << Register1 <<
", " << Register2;
1390 void MCAsmStreamer::EmitCFIWindowSave() {
1392 OS <<
"\t.cfi_window_save";
1396 void MCAsmStreamer::EmitWinCFIStartProc(
const MCSymbol *Symbol) {
1400 Symbol->
print(OS, MAI);
1404 void MCAsmStreamer::EmitWinCFIEndProc() {
1407 OS <<
"\t.seh_endproc";
1411 void MCAsmStreamer::EmitWinCFIStartChained() {
1414 OS <<
"\t.seh_startchained";
1418 void MCAsmStreamer::EmitWinCFIEndChained() {
1421 OS <<
"\t.seh_endchained";
1425 void MCAsmStreamer::EmitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
1429 OS <<
"\t.seh_handler ";
1430 Sym->
print(OS, MAI);
1438 void MCAsmStreamer::EmitWinEHHandlerData() {
1447 MCSection *XData = getAssociatedXDataSection(TextSec);
1448 SwitchSectionNoChange(XData);
1450 OS <<
"\t.seh_handlerdata";
1454 void MCAsmStreamer::EmitWinCFIPushReg(
unsigned Register) {
1457 OS <<
"\t.seh_pushreg " <<
Register;
1461 void MCAsmStreamer::EmitWinCFISetFrame(
unsigned Register,
unsigned Offset) {
1464 OS <<
"\t.seh_setframe " << Register <<
", " <<
Offset;
1468 void MCAsmStreamer::EmitWinCFIAllocStack(
unsigned Size) {
1471 OS <<
"\t.seh_stackalloc " << Size;
1475 void MCAsmStreamer::EmitWinCFISaveReg(
unsigned Register,
unsigned Offset) {
1478 OS <<
"\t.seh_savereg " << Register <<
", " <<
Offset;
1482 void MCAsmStreamer::EmitWinCFISaveXMM(
unsigned Register,
unsigned Offset) {
1485 OS <<
"\t.seh_savexmm " << Register <<
", " <<
Offset;
1489 void MCAsmStreamer::EmitWinCFIPushFrame(
bool Code) {
1492 OS <<
"\t.seh_pushframe";
1498 void MCAsmStreamer::EmitWinCFIEndProlog() {
1501 OS <<
"\t.seh_endprologue";
1505 void MCAsmStreamer::AddEncodingComment(
const MCInst &Inst,
1511 Emitter->encodeInstruction(Inst, VecOS, Fixups, STI);
1518 for (
unsigned i = 0, e = Code.
size() * 8;
i != e; ++
i)
1521 for (
unsigned i = 0, e = Fixups.
size();
i != e; ++
i) {
1524 for (
unsigned j = 0; j != Info.
TargetSize; ++j) {
1526 assert(Index < Code.
size() * 8 &&
"Invalid offset in fixup!");
1527 FixupMap[Index] = 1 +
i;
1533 OS <<
"encoding: [";
1534 for (
unsigned i = 0, e = Code.
size();
i != e; ++
i) {
1539 uint8_t MapEntry = FixupMap[
i * 8 + 0];
1540 for (
unsigned j = 1; j != 8; ++j) {
1541 if (FixupMap[
i * 8 + j] == MapEntry)
1544 MapEntry = uint8_t(~0U);
1548 if (MapEntry != uint8_t(~0U)) {
1549 if (MapEntry == 0) {
1550 OS <<
format(
"0x%02x", uint8_t(Code[
i]));
1554 OS <<
format(
"0x%02x", uint8_t(Code[i])) <<
'\''
1555 << char(
'A' + MapEntry - 1) <<
'\'';
1557 OS << char(
'A' + MapEntry - 1);
1562 for (
unsigned j = 8; j--;) {
1563 unsigned Bit = (Code[
i] >> j) & 1;
1566 if (MAI->isLittleEndian())
1567 FixupBit =
i * 8 + j;
1569 FixupBit =
i * 8 + (7-j);
1571 if (uint8_t MapEntry = FixupMap[FixupBit]) {
1572 assert(Bit == 0 &&
"Encoder wrote into fixed up bit!");
1573 OS << char(
'A' + MapEntry - 1);
1581 for (
unsigned i = 0, e = Fixups.
size();
i != e; ++
i) {
1584 OS <<
" fixup " << char(
'A' +
i) <<
" - " <<
"offset: " << F.
getOffset()
1585 <<
", value: " << *F.
getValue() <<
", kind: " << Info.
Name <<
"\n";
1589 void MCAsmStreamer::EmitInstruction(
const MCInst &Inst,
1591 assert(getCurrentSectionOnly() &&
1592 "Cannot emit contents before setting section!");
1596 AddEncodingComment(Inst, STI);
1600 Inst.
dump_pretty(GetCommentOS(), InstPrinter.get(),
"\n ");
1601 GetCommentOS() <<
"\n";
1604 if(getTargetStreamer())
1605 getTargetStreamer()->prettyPrintAsm(*InstPrinter, OS, Inst, STI);
1607 InstPrinter->printInst(&Inst, OS,
"", STI);
1612 void MCAsmStreamer::EmitBundleAlignMode(
unsigned AlignPow2) {
1613 OS <<
"\t.bundle_align_mode " << AlignPow2;
1617 void MCAsmStreamer::EmitBundleLock(
bool AlignToEnd) {
1618 OS <<
"\t.bundle_lock";
1620 OS <<
" align_to_end";
1624 void MCAsmStreamer::EmitBundleUnlock() {
1625 OS <<
"\t.bundle_unlock";
1632 Offset.
print(OS, MAI);
1636 Expr->
print(OS, MAI);
1646 if (!String.
empty() && String.
back() ==
'\n')
1652 void MCAsmStreamer::FinishImpl() {
1654 if (getContext().getGenDwarfForAssembly())
1660 auto &Tables = getContext().getMCDwarfLineTables();
1661 if (!Tables.empty()) {
1662 assert(Tables.size() == 1 &&
"asm output only supports one line table");
1663 if (
auto *Label = Tables.begin()->second.getLabel()) {
1664 SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
1671 std::unique_ptr<formatted_raw_ostream> OS,
1672 bool isVerboseAsm,
bool useDwarfDirectory,
1675 return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
1676 useDwarfDirectory, IP, CE, MAB, ShowInst);
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName)
This implements the DWARF2 '.loc fileno lineno ...' assembler directive.
Instances of this class represent a uniqued identifier for a section in the current translation unit...
virtual void EmitCFISameValue(int64_t Register)
virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding)
This represents a section on a Mach-O system (used by Mac OS X).
virtual void EmitCFIGnuArgsSize(int64_t Size)
#define DWARF2_FLAG_PROLOGUE_END
virtual void EmitWinCFIEndProlog()
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
.type _foo, STT_OBJECT # aka
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
const MCDummyFragment & getDummyFragment() const
A raw_ostream that writes to an SmallVector or SmallString.
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2)
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
virtual void EmitCFIDefCfaOffset(int64_t Offset)
LLVM_NODISCARD char back() const
back - Get the last character in the string.
.type _foo, STT_NOTYPE # aka
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
COFF::SymbolStorageClass StorageClass
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
unsigned TargetOffset
The bit offset to write the relocation into.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
virtual void EmitCFISections(bool EH, bool Debug)
static int64_t truncateToSize(int64_t Value, unsigned Bytes)
virtual void EmitWinEHHandlerData()
virtual void EmitCFIRememberState()
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding)
#define DWARF2_FLAG_IS_STMT
struct fuzzer::@269 Flags
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
virtual void EmitCFIEscape(StringRef Values)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
const char * Name
A target specific name for the fixup kind.
bool is_absolute(const Twine &path)
Is path absolute?
virtual void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt, StringRef FileName, SMLoc Loc)
This implements the CodeView '.cv_loc' assembler directive.
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
Context object for machine code objects.
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
.code16 (X86) / .code 16 (ARM)
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame)
StringRef getSectionName() const
.type _foo, STT_GNU_IFUNC
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
StringRef getSingleStringRef() const
This returns the twine as a single StringRef.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
virtual void EmitCFIRestoreState()
LLVM_NODISCARD char front() const
front - Get the first character in the string.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
uint32_t getOffset() const
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
Instances of this class represent a single low-level machine instruction.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Flag
These should be considered private to the implementation of the MCInstrDesc class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
This class is intended to be used as a base class for asm properties and features specific to the tar...
Streaming machine code generation interface.
const MCExpr * getValue() const
unsigned const MachineRegisterInfo * MRI
.weak_def_can_be_hidden (MachO)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
constexpr bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
The instances of the Type class are immutable: once they are created, they are never changed...
virtual void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart, const MCSymbol *FnEnd)
This implements the CodeView '.cv_linetable' assembler directive.
static char toOctal(int X)
#define DWARF2_FLAG_EPILOGUE_BEGIN
MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst)
Create a machine code streamer which will print out assembly for the native target, suitable for compiling with a native assembler.
virtual void EmitWinCFIPushReg(unsigned Register)
MCCodeEmitter - Generic instruction encoding interface.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
virtual void EmitCFIDefCfaRegister(int64_t Register)
MCLOHType
Linker Optimization Hint Type.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
.subsections_via_symbols (MachO)
#define DWARF2_FLAG_BASIC_BLOCK
virtual void EmitWinCFIEndChained()
virtual void EmitWinCFIEndProc()
virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, const MCExpr *Subsection) const =0
virtual void EmitCFIUndefined(int64_t Register)
bool empty() const
empty - Check if the array is empty.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
int getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
MCFixupKind getKind() const
virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values)
virtual void EmitWinCFIStartChained()
virtual void EmitLabel(MCSymbol *Symbol)
Emit a label for Symbol into the current section.
virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset)
virtual void EmitCFIOffset(int64_t Register, int64_t Offset)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
.type _foo, STT_TLS # aka
Promote Memory to Register
virtual void EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
This implements the CodeView '.cv_inline_linetable' assembler directive.
unsigned TargetSize
The number of bits written by this fixup.
virtual void EmitWinCFIAllocStack(unsigned Size)
static StringRef MCLOHDirectiveName()
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
const MCSymbol * Function
static void Emit(MCStreamer *MCOS)
StringRef getSegmentName() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
MCSection & getSection(bool SetUsed=true) const
Get the section associated with a defined, non-absolute symbol.
.code32 (X86) / .code 32 (ARM)
.type _foo, STT_COMMON # aka
virtual void EmitCVDefRangeDirective(ArrayRef< std::pair< const MCSymbol *, const MCSymbol * >> Ranges, StringRef FixedSizePortion)
This implements the CodeView '.cv_def_range' assembler directive.
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
virtual void EmitCFISignalFrame()
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset)
.type _foo, STT_FUNC # aka
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
MCSubtargetInfo - Generic base class for all target subtargets.
virtual void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset)
Target independent information on a fixup kind.
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static int MCLOHIdToNbArgs(MCLOHType Kind)
virtual bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol, SMLoc Loc)
Introduces an inline call site id for use with .cv_loc.
uint64_t PowerOf2Floor(uint64_t A)
Returns the power of two which is less than or equal to the given value.
LLVM Value Representation.
Generic interface to target specific assembler backends.
static cl::opt< bool, true > Debug("debug", cl::desc("Enable debug output"), cl::Hidden, cl::location(DebugFlag))
virtual bool EmitCVFuncIdDirective(unsigned FunctionId)
Introduces a function id for use with .cv_loc.
virtual void EmitWinCFIStartProc(const MCSymbol *Symbol)
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
static StringRef MCLOHIdToName(MCLOHType Kind)
This class implements an extremely fast bulk output stream that can only output to a stream...
void encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned Padding=0)
Utility function to encode a ULEB128 value to an output stream.
virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset)
virtual void EmitWinCFIPushFrame(bool Code)
StringRef - Represent a constant reference to a string, i.e.
static void PrintQuotedString(StringRef Data, raw_ostream &OS)
Represents a location in source code.
unsigned getFile(StringRef &Directory, StringRef &FileName, unsigned FileNumber=0)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment)
virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset)
virtual void EmitCFIWindowSave()
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).