48 std::unique_ptr<formatted_raw_ostream> OSOwner;
49 formatted_raw_ostream &OS;
51 std::unique_ptr<MCInstPrinter> InstPrinter;
52 std::unique_ptr<MCAssembler> Assembler;
54 SmallString<128> ExplicitCommentToEmit;
55 SmallString<128> CommentToEmit;
56 raw_svector_ostream CommentStream;
57 raw_null_ostream NullStream;
59 bool EmittedSectionDirective =
false;
61 bool IsVerboseAsm =
false;
62 bool ShowInst =
false;
63 bool UseDwarfDirectory =
false;
65 void EmitRegisterName(int64_t
Register);
66 void PrintQuotedString(StringRef
Data, raw_ostream &OS)
const;
67 void printDwarfFileDirective(
unsigned FileNo, StringRef Directory,
69 std::optional<MD5::MD5Result> Checksum,
70 std::optional<StringRef> Source,
71 bool UseDwarfDirectory,
72 raw_svector_ostream &OS)
const;
73 void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame)
override;
74 void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame)
override;
77 void emitDwarfLocDirectiveFlags(
unsigned Flags,
unsigned Isa,
78 unsigned Discriminator);
82 void emitDwarfLocDirectiveSuffix(
unsigned FileNo,
unsigned Line,
83 unsigned Column,
unsigned Flags,
84 unsigned Isa,
unsigned Discriminator,
85 StringRef FileName, StringRef Comment);
88 MCAsmStreamer(MCContext &
Context, std::unique_ptr<formatted_raw_ostream> os,
89 std::unique_ptr<MCInstPrinter>
printer,
90 std::unique_ptr<MCCodeEmitter> emitter,
91 std::unique_ptr<MCAsmBackend> asmbackend)
92 : MCAsmBaseStreamer(
Context), OSOwner(std::
move(os)), OS(*OSOwner),
94 Assembler(std::make_unique<MCAssembler>(
96 (asmbackend) ? asmbackend->createObjectWriter(NullStream)
98 CommentStream(CommentToEmit) {
100 if (Assembler->getBackendPtr())
101 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
103 Context.setUseNamesOnTempLabels(
true);
105 const MCTargetOptions &TO =
Context.getTargetOptions();
108 InstPrinter->setCommentStream(CommentStream);
112 UseDwarfDirectory =
false;
115 UseDwarfDirectory =
true;
119 Context.getAsmInfo().enableDwarfFileDirectoryDefault();
124 MCAssembler &getAssembler() {
return *Assembler; }
125 MCAssembler *getAssemblerPtr()
override {
return nullptr; }
127 inline void EmitEOL() {
129 emitExplicitComments();
135 EmitCommentsAndEOL();
138 void emitSyntaxDirective(StringRef Syntax, StringRef
Options)
override;
140 void EmitCommentsAndEOL();
143 bool isVerboseAsm()
const override {
return IsVerboseAsm; }
146 bool hasRawTextSupport()
const override {
return true; }
151 void AddComment(
const Twine &
T,
bool EOL =
true)
override;
154 void AddEncodingComment(
const MCInst &Inst,
const MCSubtargetInfo &);
159 raw_ostream &getCommentOS()
override {
162 return CommentStream;
165 void emitRawComment(
const Twine &
T,
bool TabPrefix =
true)
override;
167 void addExplicitComment(
const Twine &
T)
override;
168 void emitExplicitComments()
override;
171 void addBlankLine()
override { EmitEOL(); }
176 void switchSection(MCSection *Section, uint32_t Subsection)
override;
177 bool popSection()
override;
179 void emitELFSymverDirective(
const MCSymbol *OriginalSym, StringRef Name,
180 bool KeepOriginalSym)
override;
184 void emitGNUAttribute(
unsigned Tag,
unsigned Value)
override;
187 auto [Ptr,
Bits] = InstPrinter->getMnemonic(
MI);
188 assert((Bits != 0 || Ptr ==
nullptr) &&
189 "Invalid char pointer for instruction with no mnemonic");
193 void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc())
override;
195 void emitSubsectionsViaSymbols()
override;
196 void emitLinkerOptions(ArrayRef<std::string>
Options)
override;
199 unsigned Update, VersionTuple SDKVersion)
override;
200 void emitBuildVersion(
unsigned Platform,
unsigned Major,
unsigned Minor,
201 unsigned Update, VersionTuple SDKVersion)
override;
202 void emitDarwinTargetVariantBuildVersion(
unsigned Platform,
unsigned Major,
203 unsigned Minor,
unsigned Update,
204 VersionTuple SDKVersion)
override;
206 void emitAssignment(MCSymbol *Symbol,
const MCExpr *
Value)
override;
207 void emitConditionalAssignment(MCSymbol *Symbol,
208 const MCExpr *
Value)
override;
209 void emitWeakReference(MCSymbol *Alias,
const MCSymbol *Symbol)
override;
212 void emitSymbolDesc(MCSymbol *Symbol,
unsigned DescValue)
override;
213 void beginCOFFSymbolDef(
const MCSymbol *Symbol)
override;
214 void emitCOFFSymbolStorageClass(
int StorageClass)
override;
215 void emitCOFFSymbolType(
int Type)
override;
216 void endCOFFSymbolDef()
override;
217 void emitCOFFSafeSEH(MCSymbol
const *Symbol)
override;
218 void emitCOFFSymbolIndex(MCSymbol
const *Symbol)
override;
219 void emitCOFFSectionIndex(MCSymbol
const *Symbol)
override;
220 void emitCOFFSecRel32(MCSymbol
const *Symbol, uint64_t
Offset)
override;
221 void emitCOFFImgRel32(MCSymbol
const *Symbol, int64_t
Offset)
override;
222 void emitCOFFSecNumber(MCSymbol
const *Symbol)
override;
223 void emitCOFFSecOffset(MCSymbol
const *Symbol)
override;
224 void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t
Size,
225 MCSymbol *CsectSym, Align Alignment)
override;
226 void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
229 void emitXCOFFRenameDirective(
const MCSymbol *Name,
230 StringRef Rename)
override;
232 void emitXCOFFRefDirective(
const MCSymbol *Symbol)
override;
234 void emitXCOFFExceptDirective(
const MCSymbol *Symbol,
235 const MCSymbol *
Trap,
236 unsigned Lang,
unsigned Reason,
237 unsigned FunctionSize,
bool hasDebug)
override;
238 void emitXCOFFCInfoSym(StringRef Name, StringRef
Metadata)
override;
240 void emitELFSize(MCSymbol *Symbol,
const MCExpr *
Value)
override;
241 void emitCommonSymbol(MCSymbol *Symbol, uint64_t
Size,
242 Align ByteAlignment)
override;
249 void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t
Size,
250 Align ByteAlignment)
override;
252 void emitZerofill(MCSection *Section, MCSymbol *Symbol =
nullptr,
253 uint64_t
Size = 0, Align ByteAlignment =
Align(1),
254 SMLoc Loc = SMLoc())
override;
256 void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t
Size,
257 Align ByteAlignment =
Align(1))
override;
259 void emitBinaryData(StringRef
Data)
override;
261 void emitBytes(StringRef
Data)
override;
263 void emitValueImpl(
const MCExpr *
Value,
unsigned Size,
264 SMLoc Loc = SMLoc())
override;
265 void emitIntValue(uint64_t
Value,
unsigned Size)
override;
266 void emitIntValueInHex(uint64_t
Value,
unsigned Size)
override;
267 void emitIntValueInHexWithPadding(uint64_t
Value,
unsigned Size)
override;
269 void emitULEB128Value(
const MCExpr *
Value)
override;
271 void emitSLEB128Value(
const MCExpr *
Value)
override;
273 void emitFill(
const MCExpr &NumBytes, uint64_t FillValue,
274 SMLoc Loc = SMLoc())
override;
276 void emitFill(
const MCExpr &NumValues, int64_t
Size, int64_t Expr,
277 SMLoc Loc = SMLoc())
override;
279 void emitAlignmentDirective(uint64_t ByteAlignment,
280 std::optional<int64_t>
Value,
unsigned ValueSize,
281 unsigned MaxBytesToEmit);
283 void emitValueToAlignment(Align Alignment, int64_t Fill = 0,
285 unsigned MaxBytesToEmit = 0)
override;
287 void emitCodeAlignment(Align Alignment,
const MCSubtargetInfo *STI,
288 unsigned MaxBytesToEmit = 0)
override;
289 void emitPrefAlign(Align Alignment,
const MCSymbol &End,
bool EmitNops,
290 uint8_t Fill,
const MCSubtargetInfo &STI)
override;
292 void emitValueToOffset(
const MCExpr *
Offset,
296 void emitFileDirective(StringRef
Filename)
override;
297 void emitFileDirective(StringRef
Filename, StringRef CompilerVersion,
298 StringRef TimeStamp, StringRef Description)
override;
299 Expected<unsigned> tryEmitDwarfFileDirective(
300 unsigned FileNo, StringRef Directory, StringRef
Filename,
301 std::optional<MD5::MD5Result> Checksum = std::nullopt,
302 std::optional<StringRef> Source = std::nullopt,
303 unsigned CUID = 0)
override;
304 void emitDwarfFile0Directive(StringRef Directory, StringRef
Filename,
305 std::optional<MD5::MD5Result> Checksum,
306 std::optional<StringRef> Source,
307 unsigned CUID = 0)
override;
308 void emitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
unsigned Column,
309 unsigned Flags,
unsigned Isa,
310 unsigned Discriminator, StringRef FileName,
311 StringRef Location = {})
override;
312 void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name)
override;
316 void emitDwarfLocDirectiveWithInlinedAt(
unsigned FileNo,
unsigned Line,
317 unsigned Column,
unsigned FileIA,
318 unsigned LineIA,
unsigned ColIA,
319 const MCSymbol *Sym,
unsigned Flags,
320 unsigned Isa,
unsigned Discriminator,
322 StringRef Comment = {})
override;
324 MCSymbol *getDwarfLineTableSymbol(
unsigned CUID)
override;
326 bool emitCVFileDirective(
unsigned FileNo, StringRef
Filename,
327 ArrayRef<uint8_t> Checksum,
328 unsigned ChecksumKind)
override;
329 bool emitCVFuncIdDirective(
unsigned FuncId)
override;
330 bool emitCVInlineSiteIdDirective(
unsigned FunctionId,
unsigned IAFunc,
331 unsigned IAFile,
unsigned IALine,
332 unsigned IACol, SMLoc Loc)
override;
333 void emitCVLocDirective(
unsigned FunctionId,
unsigned FileNo,
unsigned Line,
334 unsigned Column,
bool PrologueEnd,
bool IsStmt,
335 StringRef FileName, SMLoc Loc)
override;
336 void emitCVLinetableDirective(
unsigned FunctionId,
const MCSymbol *FnStart,
337 const MCSymbol *FnEnd)
override;
338 void emitCVInlineLinetableDirective(
unsigned PrimaryFunctionId,
339 unsigned SourceFileId,
340 unsigned SourceLineNum,
341 const MCSymbol *FnStartSym,
342 const MCSymbol *FnEndSym)
override;
344 void PrintCVDefRangePrefix(
345 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges);
347 void emitCVDefRangeDirective(
348 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
349 codeview::DefRangeRegisterRelHeader DRHdr)
override;
351 void emitCVDefRangeDirective(
352 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
353 codeview::DefRangeSubfieldRegisterHeader DRHdr)
override;
355 void emitCVDefRangeDirective(
356 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
357 codeview::DefRangeRegisterHeader DRHdr)
override;
359 void emitCVDefRangeDirective(
360 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
361 codeview::DefRangeFramePointerRelHeader DRHdr)
override;
363 void emitCVDefRangeDirective(
364 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
365 codeview::DefRangeRegisterRelIndirHeader DRHdr)
override;
367 void emitCVStringTableDirective()
override;
368 void emitCVFileChecksumsDirective()
override;
369 void emitCVFileChecksumOffsetDirective(
unsigned FileNo)
override;
370 void emitCVFPOData(
const MCSymbol *ProcSym, SMLoc L)
override;
372 void emitIdent(StringRef IdentString)
override;
373 void emitCFIBKeyFrame()
override;
374 void emitCFIMTETaggedFrame()
override;
375 void emitCFISections(
bool EH,
bool Debug,
bool SFrame)
override;
376 void emitCFIDefCfa(int64_t
Register, int64_t
Offset, SMLoc Loc)
override;
377 void emitCFIDefCfaOffset(int64_t
Offset, SMLoc Loc)
override;
378 void emitCFIDefCfaRegister(int64_t
Register, SMLoc Loc)
override;
381 void emitCFIOffset(int64_t
Register, int64_t
Offset, SMLoc Loc)
override;
382 void emitCFIPersonality(
const MCSymbol *Sym,
unsigned Encoding)
override;
383 void emitCFILsda(
const MCSymbol *Sym,
unsigned Encoding)
override;
384 void emitCFIRememberState(SMLoc Loc)
override;
385 void emitCFIRestoreState(SMLoc Loc)
override;
386 void emitCFIRestore(int64_t
Register, SMLoc Loc)
override;
387 void emitCFISameValue(int64_t
Register, SMLoc Loc)
override;
388 void emitCFIRelOffset(int64_t
Register, int64_t
Offset, SMLoc Loc)
override;
389 void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc)
override;
390 void emitCFIEscape(StringRef Values, SMLoc Loc)
override;
391 void emitCFIGnuArgsSize(int64_t
Size, SMLoc Loc)
override;
392 void emitCFISignalFrame()
override;
393 void emitCFIUndefined(int64_t
Register, SMLoc Loc)
override;
394 void emitCFIRegister(int64_t Register1, int64_t Register2,
396 void emitCFIWindowSave(SMLoc Loc)
override;
397 void emitCFINegateRAState(SMLoc Loc)
override;
398 void emitCFINegateRAStateWithPC(SMLoc Loc)
override;
399 void emitCFIReturnColumn(int64_t
Register)
override;
400 void emitCFILLVMRegisterPair(int64_t
Register, int64_t R1, int64_t R1Size,
401 int64_t
R2, int64_t R2Size, SMLoc Loc)
override;
402 void emitCFILLVMVectorRegisters(
405 void emitCFILLVMVectorOffset(int64_t
Register, int64_t RegisterSize,
406 int64_t MaskRegister, int64_t MaskRegisterSize,
407 int64_t
Offset, SMLoc Loc)
override;
408 void emitCFILLVMVectorRegisterMask(int64_t
Register, int64_t SpillRegister,
409 int64_t SpillRegisterLaneSizeInBits,
410 int64_t MaskRegister,
411 int64_t MaskRegisterSizeInBits,
414 void emitCFILabelDirective(SMLoc Loc, StringRef Name)
override;
415 void emitCFIValOffset(int64_t
Register, int64_t
Offset, SMLoc Loc)
override;
417 void emitWinCFIStartProc(
const MCSymbol *Symbol, SMLoc Loc)
override;
418 void emitWinCFIEndProc(SMLoc Loc)
override;
419 void emitWinCFIFuncletOrFuncEnd(SMLoc Loc)
override;
420 void emitWinCFISplitChained(SMLoc Loc)
override;
421 void emitWinCFIPushReg(MCRegister
Register, SMLoc Loc)
override;
422 void emitWinCFIPush2Regs(MCRegister Reg1, MCRegister Reg2,
426 void emitWinCFIAllocStack(
unsigned Size, SMLoc Loc)
override;
431 void emitWinCFIPushFrame(
bool Code, SMLoc Loc)
override;
432 void emitWinCFIEndProlog(SMLoc Loc)
override;
433 void emitWinCFIBeginEpilogue(SMLoc Loc)
override;
434 void emitWinCFIEndEpilogue(SMLoc Loc)
override;
435 void emitWinCFIUnwindV2Start(SMLoc Loc)
override;
436 void emitWinCFIUnwindVersion(uint8_t
Version, SMLoc Loc)
override;
438 void emitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
bool Except,
440 void emitWinEHHandlerData(SMLoc Loc)
override;
442 void emitCGProfileEntry(
const MCSymbolRefExpr *From,
443 const MCSymbolRefExpr *To, uint64_t
Count)
override;
445 void emitInstruction(
const MCInst &Inst,
const MCSubtargetInfo &STI)
override;
447 void emitPseudoProbe(uint64_t
Guid, uint64_t Index, uint64_t
Type,
448 uint64_t Attr, uint64_t Discriminator,
450 MCSymbol *FnSym)
override;
452 void emitRelocDirective(
const MCExpr &
Offset, StringRef Name,
453 const MCExpr *Expr, SMLoc Loc)
override;
455 void emitAddrsig()
override;
456 void emitAddrsigSym(
const MCSymbol *Sym)
override;
461 void emitRawTextImpl(StringRef
String)
override;
463 void finishImpl()
override;
465 void emitDwarfUnitLength(uint64_t
Length,
const Twine &Comment)
override;
467 MCSymbol *emitDwarfUnitLength(
const Twine &Prefix,
468 const Twine &Comment)
override;
470 void emitDwarfLineStartLabel(MCSymbol *StartSym)
override;
472 void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel,
473 MCSymbol *EndLabel =
nullptr)
override;
475 void emitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
476 const MCSymbol *Label,
477 unsigned PointerSize)
override;
482void MCAsmStreamer::AddComment(
const Twine &
T,
bool EOL) {
483 if (!IsVerboseAsm)
return;
485 T.toVector(CommentToEmit);
491void MCAsmStreamer::EmitCommentsAndEOL() {
497 StringRef Comments = CommentToEmit;
500 "Comment array not newline terminated");
504 size_t Position = Comments.
find(
'\n');
507 Comments = Comments.
substr(Position+1);
508 }
while (!Comments.
empty());
510 CommentToEmit.
clear();
514 assert(Bytes > 0 && Bytes <= 8 &&
"Invalid size!");
515 return Value & ((
uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
518void MCAsmStreamer::emitRawComment(
const Twine &
T,
bool TabPrefix) {
525void MCAsmStreamer::addExplicitComment(
const Twine &
T) {
526 StringRef c =
T.getSingleStringRef();
530 ExplicitCommentToEmit.
append(
"\t");
535 size_t p = 2, len = c.
size() - 2;
539 ExplicitCommentToEmit.
append(
"\t");
544 ExplicitCommentToEmit.
append(
"\n");
548 ExplicitCommentToEmit.
append(
"\t");
550 }
else if (c.
front() ==
'#') {
552 ExplicitCommentToEmit.
append(
"\t");
556 assert(
false &&
"Unexpected Assembly Comment");
558 if (c.
back() ==
'\n')
559 emitExplicitComments();
562void MCAsmStreamer::emitExplicitComments() {
563 StringRef Comments = ExplicitCommentToEmit;
564 if (!Comments.
empty())
566 ExplicitCommentToEmit.
clear();
569void MCAsmStreamer::switchSection(MCSection *Section, uint32_t Subsection) {
571 if (!EmittedSectionDirective ||
573 EmittedSectionDirective =
true;
574 if (MCTargetStreamer *TS = getTargetStreamer()) {
575 TS->changeSection(Cur.first, Section, Subsection, OS);
584bool MCAsmStreamer::popSection() {
587 auto [Sec, Subsec] = getCurrentSection();
592void MCAsmStreamer::emitELFSymverDirective(
const MCSymbol *OriginalSym,
594 bool KeepOriginalSym) {
596 OriginalSym->
print(OS, MAI);
598 if (!KeepOriginalSym && !
Name.contains(
"@@@"))
603void MCAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
608 if (!
Symbol->isVariable() &&
623 assert(NbArgs != -1 && ((
size_t)NbArgs) ==
Args.size() &&
"Malformed LOH!");
624 assert(str !=
"" &&
"Invalid LOH name");
629 for (
const MCSymbol *Arg : Args) {
638void MCAsmStreamer::emitGNUAttribute(
unsigned Tag,
unsigned Value) {
639 OS <<
"\t.gnu_attribute " <<
Tag <<
", " <<
Value <<
"\n";
642void MCAsmStreamer::emitSubsectionsViaSymbols() {
643 OS <<
".subsections_via_symbols\n";
646void MCAsmStreamer::emitLinkerOptions(ArrayRef<std::string>
Options) {
647 assert(!
Options.empty() &&
"At least one option is required!");
648 OS <<
"\t.linker_option \"" <<
Options[0] <<
'"';
650 OS <<
", " <<
'"' << Opt <<
'"';
679 if (SDKVersion.
empty())
681 OS <<
'\t' <<
"sdk_version " << SDKVersion.
getMajor();
682 if (
auto Minor = SDKVersion.
getMinor()) {
683 OS <<
", " << *Minor;
685 OS <<
", " << *Subminor;
691 unsigned Minor,
unsigned Update,
692 VersionTuple SDKVersion) {
695 OS <<
", " << Update;
702#define PLATFORM(platform, id, name, build_name, target, tapi_target, \
704 case MachO::PLATFORM_##platform: \
706#include "llvm/BinaryFormat/MachO.def"
711void MCAsmStreamer::emitBuildVersion(
unsigned Platform,
unsigned Major,
712 unsigned Minor,
unsigned Update,
713 VersionTuple SDKVersion) {
715 OS <<
"\t.build_version " << PlatformName <<
", " << Major <<
", " << Minor;
717 OS <<
", " << Update;
722void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(
723 unsigned Platform,
unsigned Major,
unsigned Minor,
unsigned Update,
724 VersionTuple SDKVersion) {
725 emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
728void MCAsmStreamer::emitAssignment(MCSymbol *Symbol,
const MCExpr *
Value) {
733 OS << (UseSet ?
", " :
" = ");
740void MCAsmStreamer::emitConditionalAssignment(MCSymbol *Symbol,
741 const MCExpr *
Value) {
742 OS <<
".lto_set_conditional ";
749void MCAsmStreamer::emitWeakReference(MCSymbol *Alias,
const MCSymbol *Symbol) {
751 Alias->
print(OS, MAI);
757bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
774 default:
return false;
797 OS <<
"\t.no_dead_strip\t";
802 OS <<
"\t.private_extern\t";
811 OS <<
"\t.weak_definition\t";
828 OS <<
"\t.weak_anti_dep\t";
838void MCAsmStreamer::emitSymbolDesc(MCSymbol *Symbol,
unsigned DescValue) {
839 OS <<
".desc" <<
' ';
841 OS <<
',' << DescValue;
845void MCAsmStreamer::emitSyntaxDirective(StringRef Syntax, StringRef
Options) {
846 OS <<
"\t." << Syntax <<
"_syntax";
852void MCAsmStreamer::beginCOFFSymbolDef(
const MCSymbol *Symbol) {
859void MCAsmStreamer::emitCOFFSymbolStorageClass(
int StorageClass) {
864void MCAsmStreamer::emitCOFFSymbolType(
int Type) {
865 OS <<
"\t.type\t" <<
Type <<
';';
869void MCAsmStreamer::endCOFFSymbolDef() {
874void MCAsmStreamer::emitCOFFSafeSEH(MCSymbol
const *Symbol) {
875 OS <<
"\t.safeseh\t";
880void MCAsmStreamer::emitCOFFSymbolIndex(MCSymbol
const *Symbol) {
886void MCAsmStreamer::emitCOFFSectionIndex(MCSymbol
const *Symbol) {
892void MCAsmStreamer::emitCOFFSecRel32(MCSymbol
const *Symbol, uint64_t
Offset) {
893 OS <<
"\t.secrel32\t";
900void MCAsmStreamer::emitCOFFImgRel32(MCSymbol
const *Symbol, int64_t
Offset) {
910void MCAsmStreamer::emitCOFFSecNumber(MCSymbol
const *Symbol) {
916void MCAsmStreamer::emitCOFFSecOffset(MCSymbol
const *Symbol) {
917 OS <<
"\t.secoffset\t";
925void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,
930 "We only support writing log base-2 alignment format with XCOFF.");
933 LabelSym->
print(OS, MAI);
934 OS <<
',' <<
Size <<
',';
935 CsectSym->
print(OS, MAI);
936 OS <<
',' <<
Log2(Alignment);
942 auto *XSym =
static_cast<MCSymbolXCOFF *
>(CsectSym);
943 if (XSym->hasRename())
944 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
947void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
949 auto &Sym =
static_cast<MCSymbolXCOFF &
>(*Symbol);
969 switch (Visibility) {
990 emitXCOFFRenameDirective(&Sym, Sym.getSymbolTableName());
993void MCAsmStreamer::emitXCOFFRenameDirective(
const MCSymbol *Name,
996 Name->print(OS, MAI);
999 for (
char C : Rename) {
1009void MCAsmStreamer::emitXCOFFRefDirective(
const MCSymbol *Symbol) {
1015void MCAsmStreamer::emitXCOFFExceptDirective(
const MCSymbol *Symbol,
1016 const MCSymbol *
Trap,
1019 unsigned FunctionSize,
1021 OS <<
"\t.except\t";
1023 OS <<
", " << Lang <<
", " << Reason;
1027void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef
Metadata) {
1028 const char InfoDirective[] =
"\t.info ";
1029 const char *Separator =
", ";
1030 constexpr int WordSize =
sizeof(uint32_t);
1033 OS << InfoDirective;
1034 PrintQuotedString(Name, OS);
1037 size_t MetadataSize =
Metadata.size();
1040 OS <<
format_hex(MetadataSize, 10) << Separator;
1043 if (MetadataSize == 0) {
1053 uint32_t PaddedSize =
alignTo(MetadataSize, WordSize);
1054 uint32_t PaddingSize = PaddedSize - MetadataSize;
1061 constexpr int WordsPerDirective = 5;
1064 int WordsBeforeNextDirective = 0;
1065 auto PrintWord = [&](
const uint8_t *WordPtr) {
1066 if (WordsBeforeNextDirective-- == 0) {
1068 OS << InfoDirective;
1069 WordsBeforeNextDirective = WordsPerDirective;
1077 for (;
Index + WordSize <= MetadataSize;
Index += WordSize)
1078 PrintWord(
reinterpret_cast<const uint8_t *
>(
Metadata.data()) + Index);
1083 assert(PaddedSize - Index == WordSize);
1084 std::array<uint8_t, WordSize> LastWord = {0};
1085 ::memcpy(LastWord.data(),
Metadata.data() + Index, MetadataSize - Index);
1086 PrintWord(LastWord.data());
1091void MCAsmStreamer::emitELFSize(MCSymbol *Symbol,
const MCExpr *
Value) {
1100void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t
Size,
1101 Align ByteAlignment) {
1109 OS <<
',' <<
Log2(ByteAlignment);
1115 auto *XSym =
static_cast<MCSymbolXCOFF *
>(
Symbol);
1116 if (XSym && XSym->hasRename())
1117 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
1121void MCAsmStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t
Size,
1127 if (ByteAlign > 1) {
1132 OS <<
',' << ByteAlign.
value();
1135 OS <<
',' <<
Log2(ByteAlign);
1142void MCAsmStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
1143 uint64_t
Size, Align ByteAlignment,
1152 ".zerofill is a Mach-O specific directive");
1155 const MCSectionMachO *MOSection = ((
const MCSectionMachO*)Section);
1162 OS <<
',' <<
Log2(ByteAlignment);
1170void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1171 uint64_t
Size, Align ByteAlignment) {
1177 ".zerofill is a Mach-O specific directive");
1186 if (ByteAlignment > 1)
1187 OS <<
", " <<
Log2(ByteAlignment);
1193 const auto BeginPtr =
Data.begin(), EndPtr =
Data.end();
1194 for (
const unsigned char C :
make_range(BeginPtr, EndPtr - 1)) {
1205 assert(!
Data.empty() &&
"Cannot generate an empty list.");
1206 const auto printCharacterInOctal = [&OS](
unsigned char C) {
1212 const auto printOneCharacterFor = [printCharacterInOctal](
1213 auto printOnePrintingCharacter) {
1214 return [printCharacterInOctal, printOnePrintingCharacter](
unsigned char C) {
1216 printOnePrintingCharacter(
static_cast<char>(
C));
1219 printCharacterInOctal(
C);
1222 const auto printCharacterList = [
Data, &OS](
const auto &printOneCharacter) {
1223 const auto BeginPtr =
Data.begin(), EndPtr =
Data.end();
1224 for (
const unsigned char C :
make_range(BeginPtr, EndPtr - 1)) {
1225 printOneCharacter(
C);
1228 printOneCharacter(*(EndPtr - 1));
1232 printCharacterList(printCharacterInOctal);
1235 printCharacterList(printOneCharacterFor([&OS](
char C) {
1236 const char AsmCharLitBuf[2] = {
'\'',
C};
1237 OS <<
StringRef(AsmCharLitBuf,
sizeof(AsmCharLitBuf));
1244void MCAsmStreamer::PrintQuotedString(StringRef
Data, raw_ostream &OS)
const {
1248 for (
unsigned char C :
Data) {
1255 for (
unsigned char C :
Data) {
1256 if (
C ==
'"' ||
C ==
'\\') {
1257 OS <<
'\\' << (char)
C;
1295void MCAsmStreamer::emitBytes(StringRef
Data) {
1296 assert(getCurrentSectionOnly() &&
1297 "Cannot emit contents before setting section!");
1298 if (
Data.empty())
return;
1300 const auto emitAsString = [
this](StringRef
Data) {
1305 if (
Data.back() == 0) {
1306 OS <<
"\t.string\t";
1311 PrintQuotedString(
Data, OS);
1331 PrintQuotedString(
Data, OS);
1336 if (
Data.size() != 1 && emitAsString(
Data))
1341 if (MCTargetStreamer *TS = getTargetStreamer()) {
1342 TS->emitRawBytes(
Data);
1346 for (
const unsigned char C :
Data.bytes()) {
1347 OS << Directive << (unsigned)
C;
1352void MCAsmStreamer::emitBinaryData(StringRef
Data) {
1354 const size_t Cols = 4;
1355 for (
size_t I = 0, EI =
alignTo(
Data.size(), Cols);
I < EI;
I += Cols) {
1356 size_t J =
I, EJ = std::min(
I + Cols,
Data.size());
1359 for (; J < EJ - 1; ++J)
1360 OS <<
format(
"0x%02x", uint8_t(
Data[J])) <<
", ";
1366void MCAsmStreamer::emitIntValue(uint64_t
Value,
unsigned Size) {
1370void MCAsmStreamer::emitIntValueInHex(uint64_t
Value,
unsigned Size) {
1374void MCAsmStreamer::emitIntValueInHexWithPadding(uint64_t
Value,
1379void MCAsmStreamer::emitValueImpl(
const MCExpr *
Value,
unsigned Size,
1382 assert(getCurrentSectionOnly() &&
1383 "Cannot emit contents before setting section!");
1384 const char *Directive =
nullptr;
1395 if (!
Value->evaluateAsAbsolute(IntValue))
1410 unsigned ByteOffset =
1411 IsLittleEndian ?
Emitted : (Remaining - EmissionSize);
1412 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
1416 uint64_t Shift = 64 - EmissionSize * 8;
1417 assert(Shift <
static_cast<uint64_t
>(
1418 std::numeric_limits<unsigned long long>::digits) &&
1419 "undefined behavior");
1420 ValueToEmit &= ~0ULL >> Shift;
1421 emitIntValue(ValueToEmit, EmissionSize);
1427 assert(Directive &&
"Invalid size for machine code value!");
1429 if (MCTargetStreamer *TS = getTargetStreamer()) {
1430 TS->emitValue(
Value);
1437void MCAsmStreamer::emitULEB128Value(
const MCExpr *
Value) {
1439 if (
Value->evaluateAsAbsolute(IntValue)) {
1440 emitULEB128IntValue(IntValue);
1443 OS <<
"\t.uleb128 ";
1448void MCAsmStreamer::emitSLEB128Value(
const MCExpr *
Value) {
1450 if (
Value->evaluateAsAbsolute(IntValue)) {
1451 emitSLEB128IntValue(IntValue);
1454 OS <<
"\t.sleb128 ";
1459void MCAsmStreamer::emitFill(
const MCExpr &NumBytes, uint64_t FillValue,
1461 int64_t IntNumBytes;
1462 const bool IsAbsolute = NumBytes.evaluateAsAbsolute(IntNumBytes);
1463 if (IsAbsolute && IntNumBytes == 0)
1467 if (!MAI->
isAIX() || FillValue == 0) {
1469 OS << ZeroDirective;
1472 OS <<
',' << (int)FillValue;
1477 "Cannot emit non-absolute expression lengths of fill.");
1478 for (
int i = 0; i < IntNumBytes; ++i) {
1489void MCAsmStreamer::emitFill(
const MCExpr &NumValues, int64_t
Size,
1490 int64_t Expr, SMLoc Loc) {
1494 OS <<
", " <<
Size <<
", 0x";
1499void MCAsmStreamer::emitAlignmentDirective(uint64_t ByteAlignment,
1500 std::optional<int64_t>
Value,
1502 unsigned MaxBytesToEmit) {
1516 switch (ValueSize) {
1520 OS <<
"\t.p2align\t";
1534 if (
Value.has_value() || MaxBytesToEmit) {
1535 if (
Value.has_value()) {
1543 OS <<
", " << MaxBytesToEmit;
1551 switch (ValueSize) {
1553 case 1: OS <<
".balign";
break;
1554 case 2: OS <<
".balignw";
break;
1555 case 4: OS <<
".balignl";
break;
1560 if (
Value.has_value())
1562 else if (MaxBytesToEmit)
1565 OS <<
", " << MaxBytesToEmit;
1569void MCAsmStreamer::emitValueToAlignment(Align Alignment, int64_t Fill,
1571 unsigned MaxBytesToEmit) {
1572 emitAlignmentDirective(Alignment.
value(), Fill, FillLen, MaxBytesToEmit);
1575void MCAsmStreamer::emitCodeAlignment(Align Alignment,
1576 const MCSubtargetInfo *STI,
1577 unsigned MaxBytesToEmit) {
1583 emitAlignmentDirective(Alignment.
value(), std::nullopt, 1, MaxBytesToEmit);
1586void MCAsmStreamer::emitPrefAlign(Align Alignment,
const MCSymbol &End,
1587 bool EmitNops, uint8_t Fill,
1588 const MCSubtargetInfo &) {
1589 OS <<
"\t.prefalign\t" <<
Log2(Alignment) <<
", ";
1594 OS <<
", " <<
static_cast<unsigned>(Fill);
1598void MCAsmStreamer::emitValueToOffset(
const MCExpr *
Offset,
1599 unsigned char Value,
1604 OS <<
", " << (unsigned)
Value;
1608void MCAsmStreamer::emitFileDirective(StringRef
Filename) {
1615void MCAsmStreamer::emitFileDirective(StringRef
Filename,
1616 StringRef CompilerVersion,
1617 StringRef TimeStamp,
1618 StringRef Description) {
1622 bool useTimeStamp = !TimeStamp.
empty();
1623 bool useCompilerVersion = !CompilerVersion.
empty();
1624 bool useDescription = !Description.
empty();
1625 if (useTimeStamp || useCompilerVersion || useDescription) {
1628 PrintQuotedString(TimeStamp, OS);
1629 if (useCompilerVersion || useDescription) {
1631 if (useCompilerVersion)
1632 PrintQuotedString(CompilerVersion, OS);
1633 if (useDescription) {
1635 PrintQuotedString(Description, OS);
1642void MCAsmStreamer::printDwarfFileDirective(
1643 unsigned FileNo, StringRef Directory, StringRef
Filename,
1644 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1645 bool UseDwarfDirectory, raw_svector_ostream &OS)
const {
1646 SmallString<128> FullPathName;
1648 if (!UseDwarfDirectory && !Directory.
empty()) {
1652 FullPathName = Directory;
1659 OS <<
"\t.file\t" << FileNo <<
' ';
1660 if (!Directory.
empty()) {
1661 PrintQuotedString(Directory, OS);
1666 OS <<
" md5 0x" << Checksum->digest();
1669 PrintQuotedString(*Source, OS);
1673Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
1674 unsigned FileNo, StringRef Directory, StringRef
Filename,
1675 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1677 assert(CUID == 0 &&
"multiple CUs not supported by MCAsmStreamer");
1679 MCDwarfLineTable &Table =
getContext().getMCDwarfLineTable(CUID);
1681 Expected<unsigned> FileNoOrErr =
1686 FileNo = FileNoOrErr.
get();
1693 SmallString<128> Str;
1694 raw_svector_ostream OS1(Str);
1695 printDwarfFileDirective(FileNo, Directory,
Filename, Checksum, Source,
1696 UseDwarfDirectory, OS1);
1698 if (MCTargetStreamer *TS = getTargetStreamer())
1699 TS->emitDwarfFileDirective(OS1.str());
1701 emitRawText(OS1.str());
1706void MCAsmStreamer::emitDwarfFile0Directive(
1707 StringRef Directory, StringRef
Filename,
1708 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1722 SmallString<128> Str;
1723 raw_svector_ostream OS1(Str);
1724 printDwarfFileDirective(0, Directory,
Filename, Checksum, Source,
1725 UseDwarfDirectory, OS1);
1727 if (MCTargetStreamer *TS = getTargetStreamer())
1728 TS->emitDwarfFileDirective(OS1.str());
1730 emitRawText(OS1.str());
1734void MCAsmStreamer::emitDwarfLocDirectiveFlags(
unsigned Flags,
unsigned Isa,
1735 unsigned Discriminator) {
1740 OS <<
" basic_block";
1742 OS <<
" prologue_end";
1744 OS <<
" epilogue_begin";
1746 const unsigned OldFlags =
getContext().getCurrentDwarfLoc().getFlags();
1753 OS <<
" isa " << Isa;
1759void MCAsmStreamer::emitDwarfLocDirectiveSuffix(
unsigned FileNo,
unsigned Line,
1760 unsigned Column,
unsigned Flags,
1762 unsigned Discriminator,
1764 StringRef Comment) {
1766 emitDwarfLocDirectiveFlags(Flags, Isa, Discriminator);
1773 OS << FileName <<
':' <<
Line <<
':' << Column;
1781 Discriminator, FileName, Comment);
1784void MCAsmStreamer::emitDwarfLocDirective(
unsigned FileNo,
unsigned Line,
1785 unsigned Column,
unsigned Flags,
1786 unsigned Isa,
unsigned Discriminator,
1788 StringRef Comment) {
1796 Discriminator, FileName, Comment);
1801 OS <<
"\t.loc\t" << FileNo <<
" " <<
Line <<
" " << Column;
1804 emitDwarfLocDirectiveSuffix(FileNo, Line, Column, Flags, Isa, Discriminator,
1810void MCAsmStreamer::emitDwarfLocDirectiveWithInlinedAt(
1811 unsigned FileNo,
unsigned Line,
unsigned Column,
unsigned FileIA,
1812 unsigned LineIA,
unsigned ColIA,
const MCSymbol *Sym,
unsigned Flags,
1813 unsigned Isa,
unsigned Discriminator, StringRef FileName,
1814 StringRef Comment) {
1816 OS <<
"\t.loc\t" << FileNo <<
" " <<
Line <<
" " << Column;
1817 OS <<
", function_name " << *Sym;
1818 OS <<
", inlined_at " << FileIA <<
" " << LineIA <<
" " << ColIA;
1821 emitDwarfLocDirectiveSuffix(FileNo, Line, Column, Flags, Isa, Discriminator,
1825void MCAsmStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
1827 OS <<
".loc_label\t" <<
Name;
1831MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(
unsigned CUID) {
1837bool MCAsmStreamer::emitCVFileDirective(
unsigned FileNo, StringRef
Filename,
1838 ArrayRef<uint8_t> Checksum,
1839 unsigned ChecksumKind) {
1844 OS <<
"\t.cv_file\t" << FileNo <<
' ';
1847 if (!ChecksumKind) {
1853 PrintQuotedString(
toHex(Checksum), OS);
1860bool MCAsmStreamer::emitCVFuncIdDirective(
unsigned FuncId) {
1861 OS <<
"\t.cv_func_id " << FuncId <<
'\n';
1865bool MCAsmStreamer::emitCVInlineSiteIdDirective(
unsigned FunctionId,
1868 unsigned IALine,
unsigned IACol,
1870 OS <<
"\t.cv_inline_site_id " << FunctionId <<
" within " << IAFunc
1871 <<
" inlined_at " << IAFile <<
' ' << IALine <<
' ' << IACol <<
'\n';
1873 IALine, IACol, Loc);
1876void MCAsmStreamer::emitCVLocDirective(
unsigned FunctionId,
unsigned FileNo,
1877 unsigned Line,
unsigned Column,
1878 bool PrologueEnd,
bool IsStmt,
1879 StringRef FileName, SMLoc Loc) {
1881 if (!checkCVLocSection(FunctionId, FileNo, Loc))
1884 OS <<
"\t.cv_loc\t" << FunctionId <<
" " << FileNo <<
" " <<
Line <<
" "
1887 OS <<
" prologue_end";
1900void MCAsmStreamer::emitCVLinetableDirective(
unsigned FunctionId,
1901 const MCSymbol *FnStart,
1902 const MCSymbol *FnEnd) {
1903 OS <<
"\t.cv_linetable\t" << FunctionId <<
", ";
1904 FnStart->
print(OS, MAI);
1906 FnEnd->
print(OS, MAI);
1911void MCAsmStreamer::emitCVInlineLinetableDirective(
unsigned PrimaryFunctionId,
1912 unsigned SourceFileId,
1913 unsigned SourceLineNum,
1914 const MCSymbol *FnStartSym,
1915 const MCSymbol *FnEndSym) {
1916 OS <<
"\t.cv_inline_linetable\t" << PrimaryFunctionId <<
' ' << SourceFileId
1917 <<
' ' << SourceLineNum <<
' ';
1918 FnStartSym->
print(OS, MAI);
1920 FnEndSym->
print(OS, MAI);
1923 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1926void MCAsmStreamer::PrintCVDefRangePrefix(
1927 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {
1928 OS <<
"\t.cv_def_range\t";
1929 for (std::pair<const MCSymbol *, const MCSymbol *>
Range : Ranges) {
1937void MCAsmStreamer::emitCVDefRangeDirective(
1938 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1939 codeview::DefRangeRegisterRelHeader DRHdr) {
1940 PrintCVDefRangePrefix(Ranges);
1941 OS <<
", reg_rel, ";
1947void MCAsmStreamer::emitCVDefRangeDirective(
1948 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1949 codeview::DefRangeSubfieldRegisterHeader DRHdr) {
1950 PrintCVDefRangePrefix(Ranges);
1951 OS <<
", subfield_reg, ";
1956void MCAsmStreamer::emitCVDefRangeDirective(
1957 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1958 codeview::DefRangeRegisterHeader DRHdr) {
1959 PrintCVDefRangePrefix(Ranges);
1965void MCAsmStreamer::emitCVDefRangeDirective(
1966 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1967 codeview::DefRangeFramePointerRelHeader DRHdr) {
1968 PrintCVDefRangePrefix(Ranges);
1969 OS <<
", frame_ptr_rel, ";
1974void MCAsmStreamer::emitCVDefRangeDirective(
1975 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1976 codeview::DefRangeRegisterRelIndirHeader DRHdr) {
1977 PrintCVDefRangePrefix(Ranges);
1978 OS <<
", reg_rel_indir, ";
1984void MCAsmStreamer::emitCVStringTableDirective() {
1985 OS <<
"\t.cv_stringtable";
1989void MCAsmStreamer::emitCVFileChecksumsDirective() {
1990 OS <<
"\t.cv_filechecksums";
1994void MCAsmStreamer::emitCVFileChecksumOffsetDirective(
unsigned FileNo) {
1995 OS <<
"\t.cv_filechecksumoffset\t" << FileNo;
1999void MCAsmStreamer::emitCVFPOData(
const MCSymbol *ProcSym, SMLoc L) {
2000 OS <<
"\t.cv_fpo_data\t";
2001 ProcSym->
print(OS, MAI);
2005void MCAsmStreamer::emitIdent(StringRef IdentString) {
2008 PrintQuotedString(IdentString, OS);
2012void MCAsmStreamer::emitCFISections(
bool EH,
bool Debug,
bool SFrame) {
2014 OS <<
"\t.cfi_sections ";
2023 OS <<
".debug_frame";
2035void MCAsmStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
2036 OS <<
"\t.cfi_startproc";
2042void MCAsmStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
2044 OS <<
"\t.cfi_endproc";
2048void MCAsmStreamer::EmitRegisterName(int64_t
Register) {
2053 const MCRegisterInfo *MRI =
getContext().getRegisterInfo();
2054 if (std::optional<MCRegister> LLVMRegister =
2056 InstPrinter->printRegName(OS, *LLVMRegister);
2063void MCAsmStreamer::emitCFIDefCfa(int64_t
Register, int64_t
Offset, SMLoc Loc) {
2065 OS <<
"\t.cfi_def_cfa ";
2071void MCAsmStreamer::emitCFIDefCfaOffset(int64_t
Offset, SMLoc Loc) {
2073 OS <<
"\t.cfi_def_cfa_offset " <<
Offset;
2077void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t
Register, int64_t
Offset,
2080 OS <<
"\t.cfi_llvm_def_aspace_cfa ";
2088 OS <<
"\t.cfi_escape ";
2089 if (!Values.
empty()) {
2090 size_t e = Values.
size() - 1;
2091 for (
size_t i = 0; i < e; ++i)
2097void MCAsmStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
2103void MCAsmStreamer::emitCFIGnuArgsSize(int64_t
Size, SMLoc Loc) {
2106 uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
2113void MCAsmStreamer::emitCFIDefCfaRegister(int64_t
Register, SMLoc Loc) {
2115 OS <<
"\t.cfi_def_cfa_register ";
2120void MCAsmStreamer::emitCFIOffset(int64_t
Register, int64_t
Offset, SMLoc Loc) {
2122 OS <<
"\t.cfi_offset ";
2128void MCAsmStreamer::emitCFIPersonality(
const MCSymbol *Sym,
2129 unsigned Encoding) {
2131 OS <<
"\t.cfi_personality " << Encoding <<
", ";
2132 Sym->
print(OS, MAI);
2136void MCAsmStreamer::emitCFILsda(
const MCSymbol *Sym,
unsigned Encoding) {
2138 OS <<
"\t.cfi_lsda " << Encoding <<
", ";
2139 Sym->
print(OS, MAI);
2143void MCAsmStreamer::emitCFIRememberState(SMLoc Loc) {
2145 OS <<
"\t.cfi_remember_state";
2149void MCAsmStreamer::emitCFIRestoreState(SMLoc Loc) {
2151 OS <<
"\t.cfi_restore_state";
2155void MCAsmStreamer::emitCFIRestore(int64_t
Register, SMLoc Loc) {
2157 OS <<
"\t.cfi_restore ";
2162void MCAsmStreamer::emitCFISameValue(int64_t
Register, SMLoc Loc) {
2164 OS <<
"\t.cfi_same_value ";
2169void MCAsmStreamer::emitCFIRelOffset(int64_t
Register, int64_t
Offset,
2172 OS <<
"\t.cfi_rel_offset ";
2178void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
2180 OS <<
"\t.cfi_adjust_cfa_offset " << Adjustment;
2184void MCAsmStreamer::emitCFISignalFrame() {
2186 OS <<
"\t.cfi_signal_frame";
2190void MCAsmStreamer::emitCFIUndefined(int64_t
Register, SMLoc Loc) {
2192 OS <<
"\t.cfi_undefined ";
2197void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
2200 OS <<
"\t.cfi_register ";
2201 EmitRegisterName(Register1);
2203 EmitRegisterName(Register2);
2207void MCAsmStreamer::emitCFILLVMRegisterPair(int64_t
Register, int64_t R1,
2208 int64_t R1Size, int64_t
R2,
2209 int64_t R2Size, SMLoc Loc) {
2212 OS <<
"\t.cfi_llvm_register_pair ";
2215 EmitRegisterName(R1);
2216 OS <<
", " << R1Size <<
", ";
2217 EmitRegisterName(
R2);
2218 OS <<
", " << R2Size;
2222void MCAsmStreamer::emitCFILLVMVectorRegisters(
2227 OS <<
"\t.cfi_llvm_vector_registers ";
2229 for (
auto [
Reg, Lane,
Size] : VRs)
2230 OS <<
", " <<
Reg <<
", " << Lane <<
", " <<
Size;
2234void MCAsmStreamer::emitCFILLVMVectorOffset(int64_t
Register,
2235 int64_t RegisterSize,
2236 int64_t MaskRegister,
2237 int64_t MaskRegisterSize,
2238 int64_t
Offset, SMLoc Loc) {
2240 MaskRegisterSize,
Offset, Loc);
2242 OS <<
"\t.cfi_llvm_vector_offset ";
2244 OS <<
", " << RegisterSize <<
", ";
2245 EmitRegisterName(MaskRegister);
2246 OS <<
", " << MaskRegisterSize <<
", " <<
Offset;
2250void MCAsmStreamer::emitCFILLVMVectorRegisterMask(
2251 int64_t
Register, int64_t SpillRegister,
2252 int64_t SpillRegisterLaneSizeInBits, int64_t MaskRegister,
2253 int64_t MaskRegisterSizeInBits, SMLoc Loc) {
2255 Register, SpillRegister, SpillRegisterLaneSizeInBits, MaskRegister,
2256 MaskRegisterSizeInBits, Loc);
2258 OS <<
"\t.cfi_llvm_vector_register_mask ";
2261 EmitRegisterName(SpillRegister);
2262 OS <<
", " << SpillRegisterLaneSizeInBits <<
", ";
2263 EmitRegisterName(MaskRegister);
2264 OS <<
", " << MaskRegisterSizeInBits;
2268void MCAsmStreamer::emitCFIWindowSave(SMLoc Loc) {
2270 OS <<
"\t.cfi_window_save";
2274void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) {
2276 OS <<
"\t.cfi_negate_ra_state";
2280void MCAsmStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) {
2282 OS <<
"\t.cfi_negate_ra_state_with_pc";
2286void MCAsmStreamer::emitCFIReturnColumn(int64_t
Register) {
2288 OS <<
"\t.cfi_return_column ";
2293void MCAsmStreamer::emitCFILabelDirective(SMLoc Loc, StringRef Name) {
2295 OS <<
"\t.cfi_label " <<
Name;
2299void MCAsmStreamer::emitCFIBKeyFrame() {
2301 OS <<
"\t.cfi_b_key_frame";
2305void MCAsmStreamer::emitCFIMTETaggedFrame() {
2307 OS <<
"\t.cfi_mte_tagged_frame";
2311void MCAsmStreamer::emitCFIValOffset(int64_t
Register, int64_t
Offset,
2314 OS <<
"\t.cfi_val_offset ";
2320void MCAsmStreamer::emitWinCFIStartProc(
const MCSymbol *Symbol, SMLoc Loc) {
2328void MCAsmStreamer::emitWinCFIEndProc(SMLoc Loc) {
2331 OS <<
"\t.seh_endproc";
2335void MCAsmStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
2338 OS <<
"\t.seh_endfunclet";
2342void MCAsmStreamer::emitWinCFISplitChained(SMLoc Loc) {
2345 OS <<
"\t.seh_splitchained";
2349void MCAsmStreamer::emitWinEHHandler(
const MCSymbol *Sym,
bool Unwind,
2350 bool Except, SMLoc Loc) {
2353 OS <<
"\t.seh_handler ";
2354 Sym->
print(OS, MAI);
2360 OS <<
", " << Marker <<
"unwind";
2362 OS <<
", " << Marker <<
"except";
2366void MCAsmStreamer::emitWinEHHandlerData(SMLoc Loc) {
2373 WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
2381 MCSection *XData = getAssociatedXDataSection(TextSec);
2382 switchSectionNoPrint(XData);
2384 OS <<
"\t.seh_handlerdata";
2388void MCAsmStreamer::emitWinCFIPushReg(MCRegister
Register, SMLoc Loc) {
2391 OS <<
"\t.seh_pushreg ";
2392 InstPrinter->printRegName(OS,
Register);
2396void MCAsmStreamer::emitWinCFIPush2Regs(MCRegister Reg1, MCRegister Reg2,
2400 OS <<
"\t.seh_push2regs ";
2401 InstPrinter->printRegName(OS, Reg1);
2403 InstPrinter->printRegName(OS, Reg2);
2407void MCAsmStreamer::emitWinCFISetFrame(MCRegister
Register,
unsigned Offset,
2411 OS <<
"\t.seh_setframe ";
2412 InstPrinter->printRegName(OS,
Register);
2417void MCAsmStreamer::emitWinCFIAllocStack(
unsigned Size, SMLoc Loc) {
2420 OS <<
"\t.seh_stackalloc " <<
Size;
2424void MCAsmStreamer::emitWinCFISaveReg(MCRegister
Register,
unsigned Offset,
2428 OS <<
"\t.seh_savereg ";
2429 InstPrinter->printRegName(OS,
Register);
2434void MCAsmStreamer::emitWinCFISaveXMM(MCRegister
Register,
unsigned Offset,
2438 OS <<
"\t.seh_savexmm ";
2439 InstPrinter->printRegName(OS,
Register);
2444void MCAsmStreamer::emitWinCFIPushFrame(
bool Code, SMLoc Loc) {
2447 OS <<
"\t.seh_pushframe";
2453void MCAsmStreamer::emitWinCFIEndProlog(SMLoc Loc) {
2456 OS <<
"\t.seh_endprologue";
2460void MCAsmStreamer::emitWinCFIBeginEpilogue(SMLoc Loc) {
2463 OS <<
"\t.seh_startepilogue";
2467void MCAsmStreamer::emitWinCFIEndEpilogue(SMLoc Loc) {
2470 OS <<
"\t.seh_endepilogue";
2474void MCAsmStreamer::emitWinCFIUnwindV2Start(SMLoc Loc) {
2477 OS <<
"\t.seh_unwindv2start";
2481void MCAsmStreamer::emitWinCFIUnwindVersion(uint8_t
Version, SMLoc Loc) {
2484 OS <<
"\t.seh_unwindversion " << (unsigned)
Version;
2488void MCAsmStreamer::emitCGProfileEntry(
const MCSymbolRefExpr *From,
2489 const MCSymbolRefExpr *To,
2491 OS <<
"\t.cg_profile ";
2495 OS <<
", " <<
Count;
2499void MCAsmStreamer::AddEncodingComment(
const MCInst &Inst,
2500 const MCSubtargetInfo &STI) {
2501 raw_ostream &OS = getCommentOS();
2502 SmallString<256>
Code;
2506 if (!getAssembler().getEmitterPtr())
2509 getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
2512 bool ForceLE =
getContext().getTargetTriple().isRISCV();
2519 for (
unsigned i = 0, e =
Code.size() * 8; i != e; ++i)
2522 for (
unsigned i = 0, e =
Fixups.size(); i != e; ++i) {
2524 MCFixupKindInfo
Info =
2525 getAssembler().getBackend().getFixupKindInfo(
F.getKind());
2526 for (
unsigned j = 0;
j !=
Info.TargetSize; ++
j) {
2527 unsigned Index =
F.getOffset() * 8 +
Info.TargetOffset +
j;
2528 assert(Index <
Code.size() * 8 &&
"Invalid offset in fixup!");
2529 FixupMap[
Index] = 1 + i;
2535 OS <<
"encoding: [";
2536 for (
unsigned i = 0, e =
Code.size(); i != e; ++i) {
2541 uint8_t MapEntry = FixupMap[i * 8 + 0];
2542 for (
unsigned j = 1;
j != 8; ++
j) {
2543 if (FixupMap[i * 8 + j] == MapEntry)
2546 MapEntry = uint8_t(~0U);
2550 if (MapEntry != uint8_t(~0U)) {
2551 if (MapEntry == 0) {
2552 OS <<
format(
"0x%02x", uint8_t(Code[i]));
2556 OS <<
format(
"0x%02x", uint8_t(Code[i])) <<
'\''
2557 << char(
'A' + MapEntry - 1) <<
'\'';
2559 OS << char(
'A' + MapEntry - 1);
2564 for (
unsigned j = 8;
j--;) {
2572 FixupBit = i * 8 +
j;
2574 FixupBit = i * 8 + (7-
j);
2576 if (uint8_t MapEntry = FixupMap[FixupBit]) {
2577 assert(Bit == 0 &&
"Encoder wrote into fixed up bit!");
2578 OS << char(
'A' + MapEntry - 1);
2586 for (
unsigned i = 0, e =
Fixups.size(); i != e; ++i) {
2588 OS <<
" fixup " << char(
'A' + i) <<
" - "
2589 <<
"offset: " <<
F.getOffset() <<
", value: ";
2591 auto Kind =
F.getKind();
2593 OS <<
", relocation type: " <<
Kind;
2596 auto Info = getAssembler().getBackend().getFixupKindInfo(Kind);
2597 if (
F.isPCRel() && StringRef(
Info.Name).starts_with(
"FK_Data_"))
2598 OS <<
"FK_PCRel_" << (
Info.TargetSize / 8);
2606void MCAsmStreamer::emitInstruction(
const MCInst &Inst,
2607 const MCSubtargetInfo &STI) {
2608 if (LFIRewriter && LFIRewriter->rewriteInst(Inst, *
this, STI))
2612 MCSection *Sec = getCurrentSectionOnly();
2616 if (MAI->
isAIX() && CurFrag)
2622 AddEncodingComment(Inst, STI);
2627 getCommentOS() <<
"\n";
2630 if(getTargetStreamer())
2631 getTargetStreamer()->prettyPrintAsm(*InstPrinter, 0, Inst, STI, OS);
2633 InstPrinter->printInst(&Inst, 0,
"", STI, OS);
2635 StringRef Comments = CommentToEmit;
2636 if (Comments.
size() && Comments.
back() !=
'\n')
2637 getCommentOS() <<
"\n";
2642void MCAsmStreamer::emitPseudoProbe(uint64_t
Guid, uint64_t Index,
2643 uint64_t
Type, uint64_t Attr,
2644 uint64_t Discriminator,
2647 OS <<
"\t.pseudoprobe\t" <<
Guid <<
" " <<
Index <<
" " <<
Type <<
" " << Attr;
2652 for (
const auto &Site : InlineStack)
2653 OS <<
" @ " << std::get<0>(Site) <<
":" << std::get<1>(Site);
2656 FnSym->
print(OS, MAI);
2661void MCAsmStreamer::emitRelocDirective(
const MCExpr &
Offset, StringRef Name,
2662 const MCExpr *Expr, SMLoc) {
2673void MCAsmStreamer::emitAddrsig() {
2678void MCAsmStreamer::emitAddrsigSym(
const MCSymbol *Sym) {
2679 OS <<
"\t.addrsig_sym ";
2680 Sym->
print(OS, MAI);
2687void MCAsmStreamer::emitRawTextImpl(StringRef
String) {
2688 String.consume_back(
"\n");
2693void MCAsmStreamer::finishImpl() {
2711 const auto &Tables =
getContext().getMCDwarfLineTables();
2712 if (!Tables.empty()) {
2713 assert(Tables.size() == 1 &&
"asm output only supports one line table");
2714 if (
auto *Label = Tables.begin()->second.getLabel()) {
2715 switchSection(
getContext().getObjectFileInfo()->getDwarfLineSection(), 0);
2721void MCAsmStreamer::emitDwarfUnitLength(uint64_t
Length,
const Twine &Comment) {
2733MCSymbol *MCAsmStreamer::emitDwarfUnitLength(
const Twine &Prefix,
2734 const Twine &Comment) {
2742 return getContext().createTempSymbol(Prefix +
"_end");
2746void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
2757 emitLabel(DebugLineSymTmp);
2761 unsigned LengthFieldSize =
2767 emitAssignment(StartSym, OuterSym);
2773void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
2774 MCSymbol *LastLabel,
2775 MCSymbol *EndLabel) {
2782 ".loc should not be generated together with raw data!");
2795 emitDwarfAdvanceLineAddr(
INT64_MAX, LastLabel, EndLabel,
2800void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
2801 const MCSymbol *LastLabel,
2802 const MCSymbol *Label,
2803 unsigned PointerSize) {
2805 ".loc/.file don't need raw data in debug line section!");
2808 AddComment(
"Set address to " +
Label->getName());
2809 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2810 emitULEB128IntValue(PointerSize + 1);
2811 emitIntValue(dwarf::DW_LNE_set_address, 1);
2812 emitSymbolValue(Label, PointerSize);
2816 AddComment(
"Start sequence");
2824 AddComment(
"End sequence");
2825 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2826 emitULEB128IntValue(1);
2827 emitIntValue(dwarf::DW_LNE_end_sequence, 1);
2832 AddComment(
"Advance line " + Twine(LineDelta));
2833 emitIntValue(dwarf::DW_LNS_advance_line, 1);
2834 emitSLEB128IntValue(LineDelta);
2835 emitIntValue(dwarf::DW_LNS_copy, 1);
2839 std::unique_ptr<formatted_raw_ostream> OS,
2840 std::unique_ptr<MCInstPrinter> IP,
2841 std::unique_ptr<MCCodeEmitter> CE,
2842 std::unique_ptr<MCAsmBackend> MAB) {
2843 return new MCAsmStreamer(Context, std::move(OS), std::move(IP), std::move(CE),
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_LIKELY(EXPR)
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values)
static const char * getVersionMinDirective(MCVersionMinType Type)
static bool isPrintableString(StringRef Data)
static void PrintByteList(StringRef Data, raw_ostream &OS, MCAsmInfo::AsmCharLiteralSyntax ACLS)
static char toOctal(int X)
static void EmitSDKVersionSuffix(raw_ostream &OS, const VersionTuple &SDKVersion)
static int64_t truncateToSize(int64_t Value, unsigned Bytes)
static const char * getPlatformName(MachO::PlatformType Type)
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_BASIC_BLOCK
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
This file declares the MCLFIRewriter class, an abstract class that encapsulates the rewriting logic f...
LFI-specific code for MC.
Promote Memory to Register
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static constexpr StringLiteral Filename
This file defines the SmallString class.
StringRef getMnemonic(unsigned Opc)
LLVM_ABI void print(raw_ostream &OS) const
Print out the bounds to a stream.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
const char * getLabelSuffix() const
bool hasDotTypeDotSizeDirective() const
bool isLittleEndian() const
True if the target is little endian.
bool doesSupportDataRegionDirectives() const
bool usesSetToEquateSymbol() const
const char * getData32bitsDirective() const
unsigned getTextAlignFillValue() const
bool useDwarfRegNumForCFI() const
bool supportsExtendedDwarfLocDirective() const
const char * getData8bitsDirective() const
const char * getData64bitsDirective() const
AsmCharLiteralSyntax characterLiteralSyntax() const
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const
void printExpr(raw_ostream &, const MCExpr &) const
virtual void printSwitchToSection(const MCSection &, uint32_t Subsection, const Triple &, raw_ostream &) const
StringRef getCommentString() const
const char * getAscizDirective() const
const char * getZeroDirective() const
const char * getWeakDirective() const
const char * getData16bitsDirective() const
const char * getSeparatorString() const
bool getCOMMDirectiveAlignmentIsInBytes() const
const char * getGlobalDirective() const
unsigned getCommentColumn() const
bool hasSingleParameterDotFile() const
const char * getAsciiDirective() const
AsmCharLiteralSyntax
Assembly character literal syntax types.
@ ACLS_SingleQuotePrefix
Unknown; character literals not used by LLVM for this target.
const char * getWeakRefDirective() const
bool hasNoDeadStrip() const
bool hasIdentDirective() const
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
dwarf::DwarfFormat getDwarfFormat() const
const MCAsmInfo & getAsmInfo() const
static LLVM_ABI void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)
static LLVM_ABI void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)
LLVM_ABI Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles() const
static LLVM_ABI void Emit(MCStreamer *MCOS)
LLVM_ABI void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCContext *Ctx=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
MCSection * getTextSection() const
std::optional< MCRegister > getLLVMRegNum(uint64_t RegNum, bool isEH) const
Map a dwarf register back to a target register.
StringRef getSegmentName() const
MCSymbol * getEndSymbol(MCContext &Ctx)
void setHasInstructions(bool Value)
StringRef getName() const
Streaming machine code generation interface.
virtual void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc={})
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
virtual void emitCFILLVMVectorOffset(int64_t Register, int64_t RegisterSizeInBits, int64_t MaskRegister, int64_t MaskRegisterSizeInBits, int64_t Offset, SMLoc Loc={})
virtual void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc={})
virtual void emitWinCFIUnwindVersion(uint8_t Version, SMLoc Loc=SMLoc())
virtual bool emitCVFuncIdDirective(unsigned FunctionId)
Introduces a function id for use with .cv_loc.
virtual void emitCFIBKeyFrame()
virtual void emitWinCFIPushReg(MCRegister Register, SMLoc Loc=SMLoc())
virtual bool popSection()
Restore the current and previous section from the section stack.
virtual void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except, SMLoc Loc=SMLoc())
virtual void emitCFISections(bool EH, bool Debug, bool SFrame)
virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name)
This implements the '.loc_label Name' directive.
virtual void emitCFINegateRAStateWithPC(SMLoc Loc={})
virtual void emitCFISameValue(int64_t Register, SMLoc Loc={})
virtual void emitCFIReturnColumn(int64_t Register)
virtual void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding)
virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)
Emit a unit length field.
virtual void emitCFIWindowSave(SMLoc Loc={})
virtual void emitCFILLVMRegisterPair(int64_t Register, int64_t R1, int64_t R1SizeInBits, int64_t R2, int64_t R2SizeInBits, SMLoc Loc={})
virtual void emitWinCFIUnwindV2Start(SMLoc Loc=SMLoc())
virtual void emitWinCFIEndEpilogue(SMLoc Loc=SMLoc())
virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc=SMLoc())
virtual void emitWinEHHandlerData(SMLoc Loc=SMLoc())
virtual void emitCFIUndefined(int64_t Register, SMLoc Loc={})
virtual void emitWinCFISaveXMM(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
virtual void emitCFINegateRAState(SMLoc Loc={})
virtual void emitCFILsda(const MCSymbol *Sym, unsigned Encoding)
virtual void emitWinCFIBeginEpilogue(SMLoc Loc=SMLoc())
virtual void emitCFIMTETaggedFrame()
virtual void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc=SMLoc())
virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)
Emit the debug line start label.
virtual void emitCFIEscape(StringRef Values, SMLoc Loc={})
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitCFIRememberState(SMLoc Loc)
virtual void emitCFILabelDirective(SMLoc Loc, StringRef Name)
virtual void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName, StringRef Comment={})
This implements the DWARF2 '.loc fileno lineno ...' assembler directive.
virtual void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart, const MCSymbol *FnEnd)
This implements the CodeView '.cv_linetable' assembler directive.
virtual void emitWinCFISaveReg(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
virtual void emitWinCFIEndProlog(SMLoc Loc=SMLoc())
virtual void emitWinCFIEndProc(SMLoc Loc=SMLoc())
virtual void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame)
virtual void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc={})
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
virtual void emitCFIRegister(int64_t Register1, int64_t Register2, SMLoc Loc={})
virtual void emitWinCFIFuncletOrFuncEnd(SMLoc Loc=SMLoc())
This is used on platforms, such as Windows on ARM64, that require function or funclet sizes to be emi...
virtual void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc={})
virtual void emitWinCFIPush2Regs(MCRegister Reg1, MCRegister Reg2, SMLoc Loc=SMLoc())
virtual void emitCFILLVMVectorRegisterMask(int64_t Register, int64_t SpillRegister, int64_t SpillRegisterLaneSizeInBits, int64_t MaskRegister, int64_t MaskRegisterSizeInBits, SMLoc Loc={})
virtual void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc)
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
virtual void emitCFIRestoreState(SMLoc Loc)
virtual void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc={})
virtual void emitWinCFISetFrame(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
virtual void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc={})
virtual void emitWinCFISplitChained(SMLoc Loc=SMLoc())
virtual void emitWinCFIAllocStack(unsigned Size, SMLoc Loc=SMLoc())
virtual void emitCFIValOffset(int64_t Register, int64_t Offset, SMLoc Loc={})
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.
virtual void emitCFISignalFrame()
virtual void emitCFILLVMVectorRegisters(int64_t Register, ArrayRef< MCCFIInstruction::VectorRegisterWithLane > VRs, SMLoc Loc={})
virtual void emitCFIRestore(int64_t Register, SMLoc Loc={})
virtual void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
This implements the CodeView '.cv_inline_linetable' assembler directive.
void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
virtual void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset, int64_t AddressSpace, SMLoc Loc={})
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
DwarfDirectory MCUseDwarfDirectory
void append(StringRef RHS)
Append from a StringRef.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
char back() const
Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
char front() const
Get the first character in the string.
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.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Represents a version number in the form major[.minor[.subminor[.build]]].
unsigned getMajor() const
Retrieve the major version number.
std::optional< unsigned > getSubminor() const
Retrieve the subminor version number, if provided.
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
std::optional< unsigned > getMinor() const
Retrieve the minor version number, if provided.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
size_t GetNumBytesInBuffer() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
support::ulittle32_t Word
bool isRelocation(MCFixupKind FixupKind)
LLVM_ABI int getDwarfVersion()
@ Emitted
Assigned address, still materializing.
NodeAddr< CodeNode * > Code
Context & getContext() const
uint32_t read32be(const void *P)
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
FunctionAddr VTableAddr Value
@ Debug
Register 'use' is for debugging purpose.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static StringRef MCLOHDirectiveName()
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
LLVM_ABI MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, std::unique_ptr< MCInstPrinter > InstPrint, std::unique_ptr< MCCodeEmitter > CE, std::unique_ptr< MCAsmBackend > TAB)
Create a machine code streamer which will print out assembly for the native target,...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
@ MCDR_DataRegionEnd
.end_data_region
@ MCDR_DataRegion
.data_region
@ MCDR_DataRegionJT8
.data_region jt8
@ MCDR_DataRegionJT32
.data_region jt32
@ MCDR_DataRegionJT16
.data_region jt16
MCLOHDirective::LOHArgs MCLOHArgs
LLVM_ABI void emitLFINoteSection(MCStreamer &Streamer, MCContext &Ctx)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
SmallVector< InlineSite, 8 > MCPseudoProbeInlineStack
@ MCVM_WatchOSVersionMin
.watchos_version_min
@ MCVM_OSXVersionMin
.macosx_version_min
@ MCVM_TvOSVersionMin
.tvos_version_min
@ MCVM_IOSVersionMin
.ios_version_min
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
FunctionAddr VTableAddr Count
LLVM_ABI raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
static int MCLOHIdToNbArgs(MCLOHType Kind)
FunctionAddr VTableAddr uintptr_t uintptr_t Data
MCLOHType
Linker Optimization Hint Type.
ArrayRef(const T &OneElt) -> ArrayRef< T >
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
bool isPrint(char C)
Checks whether character C is printable.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
unsigned Log2(Align A)
Returns the log2 of the alignment.
std::pair< MCSection *, uint32_t > MCSectionSubPair
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
@ MCSA_WeakDefAutoPrivate
.weak_def_can_be_hidden (MachO)
@ MCSA_Memtag
.memtag (ELF)
@ MCSA_Protected
.protected (ELF)
@ MCSA_OSLinkage
symbol uses OS linkage (GOFF)
@ MCSA_Exported
.globl _foo, exported (XCOFF)
@ MCSA_PrivateExtern
.private_extern (MachO)
@ MCSA_Internal
.internal (ELF)
@ MCSA_WeakReference
.weak_reference (MachO)
@ MCSA_AltEntry
.alt_entry (MachO)
@ MCSA_ELF_TypeIndFunction
.type _foo, STT_GNU_IFUNC
@ MCSA_LazyReference
.lazy_reference (MachO)
@ MCSA_ELF_TypeNoType
.type _foo, STT_NOTYPE # aka @notype
@ MCSA_Reference
.reference (MachO)
@ MCSA_SymbolResolver
.symbol_resolver (MachO)
@ MCSA_ELF_TypeTLS
.type _foo, STT_TLS # aka @tls_object
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
@ MCSA_WeakDefinition
.weak_definition (MachO)
@ MCSA_ELF_TypeCommon
.type _foo, STT_COMMON # aka @common
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
@ MCSA_XPLinkage
symbol uses XP linkage (GOFF)
@ MCSA_Extern
.extern (XCOFF)
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
@ MCSA_ELF_TypeGnuUniqueObject
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
@ MCSA_LGlobal
.lglobl (XCOFF)
@ MCSA_Invalid
Not a valid directive.
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
static StringRef MCLOHIdToName(MCLOHType Kind)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
const MCSymbol * Function