LLVM 18.0.0git
MCAsmStreamer.cpp
Go to the documentation of this file.
1//===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/ADT/Twine.h"
14#include "llvm/MC/MCAsmInfo.h"
15#include "llvm/MC/MCAssembler.h"
17#include "llvm/MC/MCCodeView.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCExpr.h"
21#include "llvm/MC/MCInst.h"
26#include "llvm/MC/MCRegister.h"
29#include "llvm/MC/MCStreamer.h"
34#include "llvm/Support/Format.h"
36#include "llvm/Support/LEB128.h"
38#include "llvm/Support/Path.h"
39#include <algorithm>
40#include <optional>
41
42using namespace llvm;
43
44namespace {
45
46class MCAsmStreamer final : public MCStreamer {
47 std::unique_ptr<formatted_raw_ostream> OSOwner;
49 const MCAsmInfo *MAI;
50 std::unique_ptr<MCInstPrinter> InstPrinter;
51 std::unique_ptr<MCAssembler> Assembler;
52
53 SmallString<128> ExplicitCommentToEmit;
54 SmallString<128> CommentToEmit;
55 raw_svector_ostream CommentStream;
56 raw_null_ostream NullStream;
57
58 unsigned IsVerboseAsm : 1;
59 unsigned ShowInst : 1;
60 unsigned UseDwarfDirectory : 1;
61
62 void EmitRegisterName(int64_t Register);
63 void PrintQuotedString(StringRef Data, raw_ostream &OS) const;
64 void printDwarfFileDirective(unsigned FileNo, StringRef Directory,
65 StringRef Filename,
66 std::optional<MD5::MD5Result> Checksum,
67 std::optional<StringRef> Source,
68 bool UseDwarfDirectory,
69 raw_svector_ostream &OS) const;
70 void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
71 void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
72
73public:
74 MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
75 bool isVerboseAsm, bool useDwarfDirectory,
76 MCInstPrinter *printer, std::unique_ptr<MCCodeEmitter> emitter,
77 std::unique_ptr<MCAsmBackend> asmbackend, bool showInst)
78 : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
79 MAI(Context.getAsmInfo()), InstPrinter(printer),
80 Assembler(std::make_unique<MCAssembler>(
81 Context, std::move(asmbackend), std::move(emitter),
82 (asmbackend) ? asmbackend->createObjectWriter(NullStream)
83 : nullptr)),
84 CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
85 ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
86 assert(InstPrinter);
87 if (IsVerboseAsm)
88 InstPrinter->setCommentStream(CommentStream);
89 if (Assembler->getBackendPtr())
90 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
91
92 Context.setUseNamesOnTempLabels(true);
93 }
94
95 MCAssembler &getAssembler() { return *Assembler; }
96 MCAssembler *getAssemblerPtr() override { return nullptr; }
97
98 inline void EmitEOL() {
99 // Dump Explicit Comments here.
101 // If we don't have any comments, just emit a \n.
102 if (!IsVerboseAsm) {
103 OS << '\n';
104 return;
105 }
106 EmitCommentsAndEOL();
107 }
108
109 void emitSyntaxDirective() override;
110
111 void EmitCommentsAndEOL();
112
113 /// Return true if this streamer supports verbose assembly at all.
114 bool isVerboseAsm() const override { return IsVerboseAsm; }
115
116 /// Do we support EmitRawText?
117 bool hasRawTextSupport() const override { return true; }
118
119 /// Add a comment that can be emitted to the generated .s file to make the
120 /// output of the compiler more readable. This only affects the MCAsmStreamer
121 /// and only when verbose assembly output is enabled.
122 void AddComment(const Twine &T, bool EOL = true) override;
123
124 /// Add a comment showing the encoding of an instruction.
125 void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);
126
127 /// Return a raw_ostream that comments can be written to.
128 /// Unlike AddComment, you are required to terminate comments with \n if you
129 /// use this method.
130 raw_ostream &getCommentOS() override {
131 if (!IsVerboseAsm)
132 return nulls(); // Discard comments unless in verbose asm mode.
133 return CommentStream;
134 }
135
136 void emitRawComment(const Twine &T, bool TabPrefix = true) override;
137
138 void addExplicitComment(const Twine &T) override;
139 void emitExplicitComments() override;
140
141 /// Emit a blank line to a .s file to pretty it up.
142 void addBlankLine() override { EmitEOL(); }
143
144 /// @name MCStreamer Interface
145 /// @{
146
147 void changeSection(MCSection *Section, const MCExpr *Subsection) override;
148
149 void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name,
150 bool KeepOriginalSym) override;
151
152 void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
153
154 void emitGNUAttribute(unsigned Tag, unsigned Value) override;
155
156 StringRef getMnemonic(MCInst &MI) override {
157 return InstPrinter->getMnemonic(&MI).first;
158 }
159
160 void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
161
162 void emitAssemblerFlag(MCAssemblerFlag Flag) override;
164 void emitDataRegion(MCDataRegionType Kind) override;
165 void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
166 unsigned Update, VersionTuple SDKVersion) override;
167 void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
168 unsigned Update, VersionTuple SDKVersion) override;
169 void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major,
170 unsigned Minor, unsigned Update,
171 VersionTuple SDKVersion) override;
172 void emitThumbFunc(MCSymbol *Func) override;
173
174 void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
176 const MCExpr *Value) override;
177 void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
178 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
179
180 void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
181 void beginCOFFSymbolDef(const MCSymbol *Symbol) override;
182 void emitCOFFSymbolStorageClass(int StorageClass) override;
183 void emitCOFFSymbolType(int Type) override;
184 void endCOFFSymbolDef() override;
185 void emitCOFFSafeSEH(MCSymbol const *Symbol) override;
186 void emitCOFFSymbolIndex(MCSymbol const *Symbol) override;
187 void emitCOFFSectionIndex(MCSymbol const *Symbol) override;
188 void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
189 void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
191 MCSymbol *CsectSym, Align Alignment) override;
193 MCSymbolAttr Linkage,
194 MCSymbolAttr Visibility) override;
196 StringRef Rename) override;
197
198 void emitXCOFFRefDirective(const MCSymbol *Symbol) override;
199
200 void emitXCOFFExceptDirective(const MCSymbol *Symbol,
201 const MCSymbol *Trap,
202 unsigned Lang, unsigned Reason,
203 unsigned FunctionSize, bool hasDebug) override;
205
206 void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
208 Align ByteAlignment) override;
209
210 /// Emit a local common (.lcomm) symbol.
211 ///
212 /// @param Symbol - The common symbol to emit.
213 /// @param Size - The size of the common symbol.
214 /// @param ByteAlignment - The alignment of the common symbol in bytes.
216 Align ByteAlignment) override;
217
218 void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
219 uint64_t Size = 0, Align ByteAlignment = Align(1),
220 SMLoc Loc = SMLoc()) override;
221
222 void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
223 Align ByteAlignment = Align(1)) override;
224
225 void emitBinaryData(StringRef Data) override;
226
227 void emitBytes(StringRef Data) override;
228
229 void emitValueImpl(const MCExpr *Value, unsigned Size,
230 SMLoc Loc = SMLoc()) override;
231 void emitIntValue(uint64_t Value, unsigned Size) override;
232 void emitIntValueInHex(uint64_t Value, unsigned Size) override;
233 void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size) override;
234
235 void emitULEB128Value(const MCExpr *Value) override;
236
237 void emitSLEB128Value(const MCExpr *Value) override;
238
239 void emitDTPRel32Value(const MCExpr *Value) override;
240 void emitDTPRel64Value(const MCExpr *Value) override;
241 void emitTPRel32Value(const MCExpr *Value) override;
242 void emitTPRel64Value(const MCExpr *Value) override;
243
244 void emitGPRel64Value(const MCExpr *Value) override;
245
246 void emitGPRel32Value(const MCExpr *Value) override;
247
248 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
249 SMLoc Loc = SMLoc()) override;
250
251 void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
252 SMLoc Loc = SMLoc()) override;
253
254 void emitAlignmentDirective(unsigned ByteAlignment,
255 std::optional<int64_t> Value, unsigned ValueSize,
256 unsigned MaxBytesToEmit);
257
258 void emitValueToAlignment(Align Alignment, int64_t Value = 0,
259 unsigned ValueSize = 1,
260 unsigned MaxBytesToEmit = 0) override;
261
262 void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
263 unsigned MaxBytesToEmit = 0) override;
264
265 void emitValueToOffset(const MCExpr *Offset,
266 unsigned char Value,
267 SMLoc Loc) override;
268
269 void emitFileDirective(StringRef Filename) override;
270 void emitFileDirective(StringRef Filename, StringRef CompilerVerion,
271 StringRef TimeStamp, StringRef Description) override;
273 unsigned FileNo, StringRef Directory, StringRef Filename,
274 std::optional<MD5::MD5Result> Checksum = std::nullopt,
275 std::optional<StringRef> Source = std::nullopt,
276 unsigned CUID = 0) override;
277 void emitDwarfFile0Directive(StringRef Directory, StringRef Filename,
278 std::optional<MD5::MD5Result> Checksum,
279 std::optional<StringRef> Source,
280 unsigned CUID = 0) override;
281 void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
282 unsigned Flags, unsigned Isa,
283 unsigned Discriminator,
284 StringRef FileName) override;
285 MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
286
287 bool emitCVFileDirective(unsigned FileNo, StringRef Filename,
288 ArrayRef<uint8_t> Checksum,
289 unsigned ChecksumKind) override;
290 bool emitCVFuncIdDirective(unsigned FuncId) override;
291 bool emitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
292 unsigned IAFile, unsigned IALine,
293 unsigned IACol, SMLoc Loc) override;
294 void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
295 unsigned Column, bool PrologueEnd, bool IsStmt,
296 StringRef FileName, SMLoc Loc) override;
297 void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart,
298 const MCSymbol *FnEnd) override;
299 void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
300 unsigned SourceFileId,
301 unsigned SourceLineNum,
302 const MCSymbol *FnStartSym,
303 const MCSymbol *FnEndSym) override;
304
305 void PrintCVDefRangePrefix(
306 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges);
307
309 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
311
313 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
315
317 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
318 codeview::DefRangeRegisterHeader DRHdr) override;
319
321 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
323
324 void emitCVStringTableDirective() override;
325 void emitCVFileChecksumsDirective() override;
326 void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
327 void emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;
328
329 void emitIdent(StringRef IdentString) override;
330 void emitCFIBKeyFrame() override;
331 void emitCFIMTETaggedFrame() override;
332 void emitCFISections(bool EH, bool Debug) override;
333 void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) override;
334 void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) override;
335 void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) override;
336 void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
337 int64_t AddressSpace, SMLoc Loc) override;
338 void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
339 void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
340 void emitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
341 void emitCFIRememberState(SMLoc Loc) override;
342 void emitCFIRestoreState(SMLoc Loc) override;
343 void emitCFIRestore(int64_t Register, SMLoc Loc) override;
344 void emitCFISameValue(int64_t Register, SMLoc Loc) override;
345 void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
346 void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) override;
347 void emitCFIEscape(StringRef Values, SMLoc Loc) override;
348 void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) override;
349 void emitCFISignalFrame() override;
350 void emitCFIUndefined(int64_t Register, SMLoc Loc) override;
351 void emitCFIRegister(int64_t Register1, int64_t Register2,
352 SMLoc Loc) override;
353 void emitCFIWindowSave(SMLoc Loc) override;
354 void emitCFINegateRAState(SMLoc Loc) override;
355 void emitCFIReturnColumn(int64_t Register) override;
356
357 void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
358 void emitWinCFIEndProc(SMLoc Loc) override;
359 void emitWinCFIFuncletOrFuncEnd(SMLoc Loc) override;
360 void emitWinCFIStartChained(SMLoc Loc) override;
361 void emitWinCFIEndChained(SMLoc Loc) override;
362 void emitWinCFIPushReg(MCRegister Register, SMLoc Loc) override;
364 SMLoc Loc) override;
365 void emitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
367 SMLoc Loc) override;
369 SMLoc Loc) override;
370 void emitWinCFIPushFrame(bool Code, SMLoc Loc) override;
371 void emitWinCFIEndProlog(SMLoc Loc) override;
372
373 void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
374 SMLoc Loc) override;
375 void emitWinEHHandlerData(SMLoc Loc) override;
376
378 const MCSymbolRefExpr *To, uint64_t Count) override;
379
380 void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
381
383 uint64_t Attr, uint64_t Discriminator,
384 const MCPseudoProbeInlineStack &InlineStack,
385 MCSymbol *FnSym) override;
386
387 void emitBundleAlignMode(Align Alignment) override;
388 void emitBundleLock(bool AlignToEnd) override;
389 void emitBundleUnlock() override;
390
391 std::optional<std::pair<bool, std::string>>
393 SMLoc Loc, const MCSubtargetInfo &STI) override;
394
395 void emitAddrsig() override;
396 void emitAddrsigSym(const MCSymbol *Sym) override;
397
398 /// If this file is backed by an assembly streamer, this dumps the specified
399 /// string in the output .s file. This capability is indicated by the
400 /// hasRawTextSupport() predicate.
401 void emitRawTextImpl(StringRef String) override;
402
403 void finishImpl() override;
404
405 void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) override;
406
407 MCSymbol *emitDwarfUnitLength(const Twine &Prefix,
408 const Twine &Comment) override;
409
410 void emitDwarfLineStartLabel(MCSymbol *StartSym) override;
411
412 void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
413
414 void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
415 const MCSymbol *Label,
416 unsigned PointerSize) override;
417
418 void doFinalizationAtSectionEnd(MCSection *Section) override;
419};
420
421} // end anonymous namespace.
422
423void MCAsmStreamer::AddComment(const Twine &T, bool EOL) {
424 if (!IsVerboseAsm) return;
425
426 T.toVector(CommentToEmit);
427
428 if (EOL)
429 CommentToEmit.push_back('\n'); // Place comment in a new line.
430}
431
432void MCAsmStreamer::EmitCommentsAndEOL() {
433 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
434 OS << '\n';
435 return;
436 }
437
438 StringRef Comments = CommentToEmit;
439
440 assert(Comments.back() == '\n' &&
441 "Comment array not newline terminated");
442 do {
443 // Emit a line of comments.
444 OS.PadToColumn(MAI->getCommentColumn());
445 size_t Position = Comments.find('\n');
446 OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
447
448 Comments = Comments.substr(Position+1);
449 } while (!Comments.empty());
450
451 CommentToEmit.clear();
452}
453
454static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
455 assert(Bytes > 0 && Bytes <= 8 && "Invalid size!");
456 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
457}
458
459void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
460 if (TabPrefix)
461 OS << '\t';
462 OS << MAI->getCommentString() << T;
463 EmitEOL();
464}
465
466void MCAsmStreamer::addExplicitComment(const Twine &T) {
467 StringRef c = T.getSingleStringRef();
468 if (c.equals(StringRef(MAI->getSeparatorString())))
469 return;
470 if (c.startswith(StringRef("//"))) {
471 ExplicitCommentToEmit.append("\t");
472 ExplicitCommentToEmit.append(MAI->getCommentString());
473 // drop //
474 ExplicitCommentToEmit.append(c.slice(2, c.size()).str());
475 } else if (c.startswith(StringRef("/*"))) {
476 size_t p = 2, len = c.size() - 2;
477 // emit each line in comment as separate newline.
478 do {
479 size_t newp = std::min(len, c.find_first_of("\r\n", p));
480 ExplicitCommentToEmit.append("\t");
481 ExplicitCommentToEmit.append(MAI->getCommentString());
482 ExplicitCommentToEmit.append(c.slice(p, newp).str());
483 // If we have another line in this comment add line
484 if (newp < len)
485 ExplicitCommentToEmit.append("\n");
486 p = newp + 1;
487 } while (p < len);
488 } else if (c.startswith(StringRef(MAI->getCommentString()))) {
489 ExplicitCommentToEmit.append("\t");
490 ExplicitCommentToEmit.append(c.str());
491 } else if (c.front() == '#') {
492
493 ExplicitCommentToEmit.append("\t");
494 ExplicitCommentToEmit.append(MAI->getCommentString());
495 ExplicitCommentToEmit.append(c.slice(1, c.size()).str());
496 } else
497 assert(false && "Unexpected Assembly Comment");
498 // full line comments immediately output
499 if (c.back() == '\n')
500 emitExplicitComments();
501}
502
503void MCAsmStreamer::emitExplicitComments() {
504 StringRef Comments = ExplicitCommentToEmit;
505 if (!Comments.empty())
506 OS << Comments;
507 ExplicitCommentToEmit.clear();
508}
509
510void MCAsmStreamer::changeSection(MCSection *Section,
511 const MCExpr *Subsection) {
512 assert(Section && "Cannot switch to a null section!");
513 if (MCTargetStreamer *TS = getTargetStreamer()) {
514 TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS);
515 } else {
516 Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
517 Subsection);
518 }
519}
520
521void MCAsmStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
523 bool KeepOriginalSym) {
524 OS << ".symver ";
525 OriginalSym->print(OS, MAI);
526 OS << ", " << Name;
527 if (!KeepOriginalSym && !Name.contains("@@@"))
528 OS << ", remove";
529 EmitEOL();
530}
531
532void MCAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
533 MCStreamer::emitLabel(Symbol, Loc);
534
535 Symbol->print(OS, MAI);
536 OS << MAI->getLabelSuffix();
537
538 EmitEOL();
539}
540
541void MCAsmStreamer::emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
542 StringRef str = MCLOHIdToName(Kind);
543
544#ifndef NDEBUG
545 int NbArgs = MCLOHIdToNbArgs(Kind);
546 assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
547 assert(str != "" && "Invalid LOH name");
548#endif
549
550 OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
551 bool IsFirst = true;
552 for (const MCSymbol *Arg : Args) {
553 if (!IsFirst)
554 OS << ", ";
555 IsFirst = false;
556 Arg->print(OS, MAI);
557 }
558 EmitEOL();
559}
560
561void MCAsmStreamer::emitGNUAttribute(unsigned Tag, unsigned Value) {
562 OS << "\t.gnu_attribute " << Tag << ", " << Value << "\n";
563}
564
565void MCAsmStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
566 switch (Flag) {
567 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
568 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
569 case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break;
570 case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break;
571 case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break;
572 }
573 EmitEOL();
574}
575
576void MCAsmStreamer::emitLinkerOptions(ArrayRef<std::string> Options) {
577 assert(!Options.empty() && "At least one option is required!");
578 OS << "\t.linker_option \"" << Options[0] << '"';
579 for (const std::string &Opt : llvm::drop_begin(Options))
580 OS << ", " << '"' << Opt << '"';
581 EmitEOL();
582}
583
584void MCAsmStreamer::emitDataRegion(MCDataRegionType Kind) {
586 return;
587 switch (Kind) {
588 case MCDR_DataRegion: OS << "\t.data_region"; break;
589 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
590 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
591 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
592 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
593 }
594 EmitEOL();
595}
596
598 switch (Type) {
599 case MCVM_WatchOSVersionMin: return ".watchos_version_min";
600 case MCVM_TvOSVersionMin: return ".tvos_version_min";
601 case MCVM_IOSVersionMin: return ".ios_version_min";
602 case MCVM_OSXVersionMin: return ".macosx_version_min";
603 }
604 llvm_unreachable("Invalid MC version min type");
605}
606
608 const VersionTuple &SDKVersion) {
609 if (SDKVersion.empty())
610 return;
611 OS << '\t' << "sdk_version " << SDKVersion.getMajor();
612 if (auto Minor = SDKVersion.getMinor()) {
613 OS << ", " << *Minor;
614 if (auto Subminor = SDKVersion.getSubminor()) {
615 OS << ", " << *Subminor;
616 }
617 }
618}
619
620void MCAsmStreamer::emitVersionMin(MCVersionMinType Type, unsigned Major,
621 unsigned Minor, unsigned Update,
622 VersionTuple SDKVersion) {
623 OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
624 if (Update)
625 OS << ", " << Update;
626 EmitSDKVersionSuffix(OS, SDKVersion);
627 EmitEOL();
628}
629
631 switch (Type) {
632#define PLATFORM(platform, id, name, build_name, target, tapi_target, \
633 marketing) \
634 case MachO::PLATFORM_##platform: \
635 return #build_name;
636#include "llvm/BinaryFormat/MachO.def"
637 }
638 llvm_unreachable("Invalid Mach-O platform type");
639}
640
641void MCAsmStreamer::emitBuildVersion(unsigned Platform, unsigned Major,
642 unsigned Minor, unsigned Update,
643 VersionTuple SDKVersion) {
644 const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
645 OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
646 if (Update)
647 OS << ", " << Update;
648 EmitSDKVersionSuffix(OS, SDKVersion);
649 EmitEOL();
650}
651
652void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(
653 unsigned Platform, unsigned Major, unsigned Minor, unsigned Update,
654 VersionTuple SDKVersion) {
655 emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
656}
657
658void MCAsmStreamer::emitThumbFunc(MCSymbol *Func) {
659 // This needs to emit to a temporary string to get properly quoted
660 // MCSymbols when they have spaces in them.
661 OS << "\t.thumb_func";
662 // Only Mach-O hasSubsectionsViaSymbols()
663 if (MAI->hasSubsectionsViaSymbols()) {
664 OS << '\t';
665 Func->print(OS, MAI);
666 }
667 EmitEOL();
668}
669
670void MCAsmStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
671 // Do not emit a .set on inlined target assignments.
672 bool EmitSet = true;
673 if (auto *E = dyn_cast<MCTargetExpr>(Value))
674 if (E->inlineAssignedExpr())
675 EmitSet = false;
676 if (EmitSet) {
677 OS << ".set ";
678 Symbol->print(OS, MAI);
679 OS << ", ";
680 Value->print(OS, MAI);
681
682 EmitEOL();
683 }
684
686}
687
688void MCAsmStreamer::emitConditionalAssignment(MCSymbol *Symbol,
689 const MCExpr *Value) {
690 OS << ".lto_set_conditional ";
691 Symbol->print(OS, MAI);
692 OS << ", ";
693 Value->print(OS, MAI);
694 EmitEOL();
695}
696
697void MCAsmStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
698 OS << ".weakref ";
699 Alias->print(OS, MAI);
700 OS << ", ";
701 Symbol->print(OS, MAI);
702 EmitEOL();
703}
704
705bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
707 switch (Attribute) {
708 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
709 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
710 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
711 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
712 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
713 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
714 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
715 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
716 if (!MAI->hasDotTypeDotSizeDirective())
717 return false; // Symbol attribute not supported
718 OS << "\t.type\t";
719 Symbol->print(OS, MAI);
720 OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%');
721 switch (Attribute) {
722 default: return false;
723 case MCSA_ELF_TypeFunction: OS << "function"; break;
724 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
725 case MCSA_ELF_TypeObject: OS << "object"; break;
726 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
727 case MCSA_ELF_TypeCommon: OS << "common"; break;
728 case MCSA_ELF_TypeNoType: OS << "notype"; break;
729 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
730 }
731 EmitEOL();
732 return true;
733 case MCSA_Global: // .globl/.global
734 OS << MAI->getGlobalDirective();
735 break;
736 case MCSA_LGlobal: OS << "\t.lglobl\t"; break;
737 case MCSA_Hidden: OS << "\t.hidden\t"; break;
738 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
739 case MCSA_Internal: OS << "\t.internal\t"; break;
740 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
741 case MCSA_Local: OS << "\t.local\t"; break;
742 case MCSA_NoDeadStrip:
743 if (!MAI->hasNoDeadStrip())
744 return false;
745 OS << "\t.no_dead_strip\t";
746 break;
747 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
748 case MCSA_AltEntry: OS << "\t.alt_entry\t"; break;
750 OS << "\t.private_extern\t";
751 break;
752 case MCSA_Protected: OS << "\t.protected\t"; break;
753 case MCSA_Reference: OS << "\t.reference\t"; break;
754 case MCSA_Extern:
755 OS << "\t.extern\t";
756 break;
757 case MCSA_Weak: OS << MAI->getWeakDirective(); break;
759 OS << "\t.weak_definition\t";
760 break;
761 // .weak_reference
762 case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
763 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
764 case MCSA_Cold:
765 // Assemblers currently do not support a .cold directive.
766 case MCSA_Exported:
767 // Non-AIX assemblers currently do not support exported visibility.
768 return false;
769 case MCSA_Memtag:
770 OS << "\t.memtag\t";
771 break;
772 case MCSA_WeakAntiDep:
773 OS << "\t.weak_anti_dep\t";
774 break;
775 }
776
777 Symbol->print(OS, MAI);
778 EmitEOL();
779
780 return true;
781}
782
783void MCAsmStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
784 OS << ".desc" << ' ';
785 Symbol->print(OS, MAI);
786 OS << ',' << DescValue;
787 EmitEOL();
788}
789
790void MCAsmStreamer::emitSyntaxDirective() {
791 if (MAI->getAssemblerDialect() == 1) {
792 OS << "\t.intel_syntax noprefix";
793 EmitEOL();
794 }
795 // FIXME: Currently emit unprefix'ed registers.
796 // The intel_syntax directive has one optional argument
797 // with may have a value of prefix or noprefix.
798}
799
800void MCAsmStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {
801 OS << "\t.def\t";
802 Symbol->print(OS, MAI);
803 OS << ';';
804 EmitEOL();
805}
806
807void MCAsmStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
808 OS << "\t.scl\t" << StorageClass << ';';
809 EmitEOL();
810}
811
812void MCAsmStreamer::emitCOFFSymbolType(int Type) {
813 OS << "\t.type\t" << Type << ';';
814 EmitEOL();
815}
816
817void MCAsmStreamer::endCOFFSymbolDef() {
818 OS << "\t.endef";
819 EmitEOL();
820}
821
822void MCAsmStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {
823 OS << "\t.safeseh\t";
824 Symbol->print(OS, MAI);
825 EmitEOL();
826}
827
828void MCAsmStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
829 OS << "\t.symidx\t";
830 Symbol->print(OS, MAI);
831 EmitEOL();
832}
833
834void MCAsmStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {
835 OS << "\t.secidx\t";
836 Symbol->print(OS, MAI);
837 EmitEOL();
838}
839
840void MCAsmStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {
841 OS << "\t.secrel32\t";
842 Symbol->print(OS, MAI);
843 if (Offset != 0)
844 OS << '+' << Offset;
845 EmitEOL();
846}
847
848void MCAsmStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
849 OS << "\t.rva\t";
850 Symbol->print(OS, MAI);
851 if (Offset > 0)
852 OS << '+' << Offset;
853 else if (Offset < 0)
854 OS << '-' << -Offset;
855 EmitEOL();
856}
857
858// We need an XCOFF-specific version of this directive as the AIX syntax
859// requires a QualName argument identifying the csect name and storage mapping
860// class to appear before the alignment if we are specifying it.
861void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,
863 MCSymbol *CsectSym,
864 Align Alignment) {
866 "We only support writing log base-2 alignment format with XCOFF.");
867
868 OS << "\t.lcomm\t";
869 LabelSym->print(OS, MAI);
870 OS << ',' << Size << ',';
871 CsectSym->print(OS, MAI);
872 OS << ',' << Log2(Alignment);
873
874 EmitEOL();
875
876 // Print symbol's rename (original name contains invalid character(s)) if
877 // there is one.
878 MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(CsectSym);
879 if (XSym->hasRename())
880 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
881}
882
883void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
884 MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) {
885
886 switch (Linkage) {
887 case MCSA_Global:
888 OS << MAI->getGlobalDirective();
889 break;
890 case MCSA_Weak:
891 OS << MAI->getWeakDirective();
892 break;
893 case MCSA_Extern:
894 OS << "\t.extern\t";
895 break;
896 case MCSA_LGlobal:
897 OS << "\t.lglobl\t";
898 break;
899 default:
900 report_fatal_error("unhandled linkage type");
901 }
902
903 Symbol->print(OS, MAI);
904
905 switch (Visibility) {
906 case MCSA_Invalid:
907 // Nothing to do.
908 break;
909 case MCSA_Hidden:
910 OS << ",hidden";
911 break;
912 case MCSA_Protected:
913 OS << ",protected";
914 break;
915 case MCSA_Exported:
916 OS << ",exported";
917 break;
918 default:
919 report_fatal_error("unexpected value for Visibility type");
920 }
921 EmitEOL();
922
923 // Print symbol's rename (original name contains invalid character(s)) if
924 // there is one.
925 if (cast<MCSymbolXCOFF>(Symbol)->hasRename())
926 emitXCOFFRenameDirective(Symbol,
927 cast<MCSymbolXCOFF>(Symbol)->getSymbolTableName());
928}
929
930void MCAsmStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
931 StringRef Rename) {
932 OS << "\t.rename\t";
933 Name->print(OS, MAI);
934 const char DQ = '"';
935 OS << ',' << DQ;
936 for (char C : Rename) {
937 // To escape a double quote character, the character should be doubled.
938 if (C == DQ)
939 OS << DQ;
940 OS << C;
941 }
942 OS << DQ;
943 EmitEOL();
944}
945
946void MCAsmStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {
947 OS << "\t.ref ";
948 Symbol->print(OS, MAI);
949 EmitEOL();
950}
951
952void MCAsmStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
953 const MCSymbol *Trap,
954 unsigned Lang,
955 unsigned Reason,
956 unsigned FunctionSize,
957 bool hasDebug) {
958 OS << "\t.except\t";
959 Symbol->print(OS, MAI);
960 OS << ", " << Lang << ", " << Reason;
961 EmitEOL();
962}
963
964void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
965 const char InfoDirective[] = "\t.info ";
966 const char *Separator = ", ";
967 constexpr int WordSize = sizeof(uint32_t);
968
969 // Start by emitting the .info pseudo-op and C_INFO symbol name.
970 OS << InfoDirective;
971 PrintQuotedString(Name, OS);
972 OS << Separator;
973
974 size_t MetadataSize = Metadata.size();
975
976 // Emit the 4-byte length of the metadata.
977 OS << format_hex(MetadataSize, 10) << Separator;
978
979 // Nothing left to do if there's no metadata.
980 if (MetadataSize == 0) {
981 EmitEOL();
982 return;
983 }
984
985 // Metadata needs to be padded out to an even word size when generating
986 // assembly because the .info pseudo-op can only generate words of data. We
987 // apply the same restriction to the object case for consistency, however the
988 // linker doesn't require padding, so it will only save bytes specified by the
989 // length and discard any padding.
990 uint32_t PaddedSize = alignTo(MetadataSize, WordSize);
991 uint32_t PaddingSize = PaddedSize - MetadataSize;
992
993 // Write out the payload a word at a time.
994 //
995 // The assembler has a limit on the number of operands in an expression,
996 // so we need multiple .info pseudo-ops. We choose a small number of words
997 // per pseudo-op to keep the assembly readable.
998 constexpr int WordsPerDirective = 5;
999 // Force emitting a new directive to keep the first directive purely about the
1000 // name and size of the note.
1001 int WordsBeforeNextDirective = 0;
1002 auto PrintWord = [&](const uint8_t *WordPtr) {
1003 if (WordsBeforeNextDirective-- == 0) {
1004 EmitEOL();
1005 OS << InfoDirective;
1006 WordsBeforeNextDirective = WordsPerDirective;
1007 }
1008 OS << Separator;
1010 OS << format_hex(Word, 10);
1011 };
1012
1013 size_t Index = 0;
1014 for (; Index + WordSize <= MetadataSize; Index += WordSize)
1015 PrintWord(reinterpret_cast<const uint8_t *>(Metadata.data()) + Index);
1016
1017 // If there is padding, then we have at least one byte of payload left
1018 // to emit.
1019 if (PaddingSize) {
1020 assert(PaddedSize - Index == WordSize);
1021 std::array<uint8_t, WordSize> LastWord = {0};
1022 ::memcpy(LastWord.data(), Metadata.data() + Index, MetadataSize - Index);
1023 PrintWord(LastWord.data());
1024 }
1025 EmitEOL();
1026}
1027
1028void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
1030 OS << "\t.size\t";
1031 Symbol->print(OS, MAI);
1032 OS << ", ";
1033 Value->print(OS, MAI);
1034 EmitEOL();
1035}
1036
1037void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1038 Align ByteAlignment) {
1039 OS << "\t.comm\t";
1040 Symbol->print(OS, MAI);
1041 OS << ',' << Size;
1042
1044 OS << ',' << ByteAlignment.value();
1045 else
1046 OS << ',' << Log2(ByteAlignment);
1047 EmitEOL();
1048
1049 // Print symbol's rename (original name contains invalid character(s)) if
1050 // there is one.
1051 MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(Symbol);
1052 if (XSym && XSym->hasRename())
1053 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
1054}
1055
1056void MCAsmStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1057 Align ByteAlign) {
1058 OS << "\t.lcomm\t";
1059 Symbol->print(OS, MAI);
1060 OS << ',' << Size;
1061
1062 if (ByteAlign > 1) {
1063 switch (MAI->getLCOMMDirectiveAlignmentType()) {
1064 case LCOMM::NoAlignment:
1065 llvm_unreachable("alignment not supported on .lcomm!");
1067 OS << ',' << ByteAlign.value();
1068 break;
1070 OS << ',' << Log2(ByteAlign);
1071 break;
1072 }
1073 }
1074 EmitEOL();
1075}
1076
1077void MCAsmStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
1078 uint64_t Size, Align ByteAlignment,
1079 SMLoc Loc) {
1080 if (Symbol)
1081 assignFragment(Symbol, &Section->getDummyFragment());
1082
1083 // Note: a .zerofill directive does not switch sections.
1084 OS << ".zerofill ";
1085
1086 assert(Section->getVariant() == MCSection::SV_MachO &&
1087 ".zerofill is a Mach-O specific directive");
1088 // This is a mach-o specific directive.
1089
1090 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
1091 OS << MOSection->getSegmentName() << "," << MOSection->getName();
1092
1093 if (Symbol) {
1094 OS << ',';
1095 Symbol->print(OS, MAI);
1096 OS << ',' << Size;
1097 OS << ',' << Log2(ByteAlignment);
1098 }
1099 EmitEOL();
1100}
1101
1102// .tbss sym, size, align
1103// This depends that the symbol has already been mangled from the original,
1104// e.g. _a.
1105void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1106 uint64_t Size, Align ByteAlignment) {
1107 assignFragment(Symbol, &Section->getDummyFragment());
1108
1109 assert(Symbol && "Symbol shouldn't be NULL!");
1110 // Instead of using the Section we'll just use the shortcut.
1111
1112 assert(Section->getVariant() == MCSection::SV_MachO &&
1113 ".zerofill is a Mach-O specific directive");
1114 // This is a mach-o specific directive and section.
1115
1116 OS << ".tbss ";
1117 Symbol->print(OS, MAI);
1118 OS << ", " << Size;
1119
1120 // Output align if we have it. We default to 1 so don't bother printing
1121 // that.
1122 if (ByteAlignment > 1)
1123 OS << ", " << Log2(ByteAlignment);
1124
1125 EmitEOL();
1126}
1127
1128static inline bool isPrintableString(StringRef Data) {
1129 const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1130 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1131 if (!isPrint(C))
1132 return false;
1133 }
1134 return isPrint(Data.back()) || Data.back() == 0;
1135}
1136
1137static inline char toOctal(int X) { return (X&7)+'0'; }
1138
1141 assert(!Data.empty() && "Cannot generate an empty list.");
1142 const auto printCharacterInOctal = [&OS](unsigned char C) {
1143 OS << '0';
1144 OS << toOctal(C >> 6);
1145 OS << toOctal(C >> 3);
1146 OS << toOctal(C >> 0);
1147 };
1148 const auto printOneCharacterFor = [printCharacterInOctal](
1149 auto printOnePrintingCharacter) {
1150 return [printCharacterInOctal, printOnePrintingCharacter](unsigned char C) {
1151 if (isPrint(C)) {
1152 printOnePrintingCharacter(static_cast<char>(C));
1153 return;
1154 }
1155 printCharacterInOctal(C);
1156 };
1157 };
1158 const auto printCharacterList = [Data, &OS](const auto &printOneCharacter) {
1159 const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1160 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1161 printOneCharacter(C);
1162 OS << ',';
1163 }
1164 printOneCharacter(*(EndPtr - 1));
1165 };
1166 switch (ACLS) {
1168 printCharacterList(printCharacterInOctal);
1169 return;
1171 printCharacterList(printOneCharacterFor([&OS](char C) {
1172 const char AsmCharLitBuf[2] = {'\'', C};
1173 OS << StringRef(AsmCharLitBuf, sizeof(AsmCharLitBuf));
1174 }));
1175 return;
1176 }
1177 llvm_unreachable("Invalid AsmCharLiteralSyntax value!");
1178}
1179
1180void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) const {
1181 OS << '"';
1182
1184 for (unsigned char C : Data) {
1185 if (C == '"')
1186 OS << "\"\"";
1187 else
1188 OS << (char)C;
1189 }
1190 } else {
1191 for (unsigned char C : Data) {
1192 if (C == '"' || C == '\\') {
1193 OS << '\\' << (char)C;
1194 continue;
1195 }
1196
1197 if (isPrint((unsigned char)C)) {
1198 OS << (char)C;
1199 continue;
1200 }
1201
1202 switch (C) {
1203 case '\b':
1204 OS << "\\b";
1205 break;
1206 case '\f':
1207 OS << "\\f";
1208 break;
1209 case '\n':
1210 OS << "\\n";
1211 break;
1212 case '\r':
1213 OS << "\\r";
1214 break;
1215 case '\t':
1216 OS << "\\t";
1217 break;
1218 default:
1219 OS << '\\';
1220 OS << toOctal(C >> 6);
1221 OS << toOctal(C >> 3);
1222 OS << toOctal(C >> 0);
1223 break;
1224 }
1225 }
1226 }
1227
1228 OS << '"';
1229}
1230
1231void MCAsmStreamer::emitBytes(StringRef Data) {
1232 assert(getCurrentSectionOnly() &&
1233 "Cannot emit contents before setting section!");
1234 if (Data.empty()) return;
1235
1236 const auto emitAsString = [this](StringRef Data) {
1237 // If the data ends with 0 and the target supports .asciz, use it, otherwise
1238 // use .ascii or a byte-list directive
1239 if (MAI->getAscizDirective() && Data.back() == 0) {
1240 OS << MAI->getAscizDirective();
1241 Data = Data.substr(0, Data.size() - 1);
1242 } else if (LLVM_LIKELY(MAI->getAsciiDirective())) {
1243 OS << MAI->getAsciiDirective();
1244 } else if (MAI->hasPairedDoubleQuoteStringConstants() &&
1245 isPrintableString(Data)) {
1246 // For target with DoubleQuoteString constants, .string and .byte are used
1247 // as replacement of .asciz and .ascii.
1249 "hasPairedDoubleQuoteStringConstants target must support "
1250 "PlainString Directive");
1252 "hasPairedDoubleQuoteStringConstants target must support ByteList "
1253 "Directive");
1254 if (Data.back() == 0) {
1255 OS << MAI->getPlainStringDirective();
1256 Data = Data.substr(0, Data.size() - 1);
1257 } else {
1258 OS << MAI->getByteListDirective();
1259 }
1260 } else if (MAI->getByteListDirective()) {
1261 OS << MAI->getByteListDirective();
1263 EmitEOL();
1264 return true;
1265 } else {
1266 return false;
1267 }
1268
1269 PrintQuotedString(Data, OS);
1270 EmitEOL();
1271 return true;
1272 };
1273
1274 if (Data.size() != 1 && emitAsString(Data))
1275 return;
1276
1277 // Only single byte is provided or no ascii, asciz, or byte-list directives
1278 // are applicable. Emit as vector of individual 8bits data elements.
1279 if (MCTargetStreamer *TS = getTargetStreamer()) {
1280 TS->emitRawBytes(Data);
1281 return;
1282 }
1283 const char *Directive = MAI->getData8bitsDirective();
1284 for (const unsigned char C : Data.bytes()) {
1285 OS << Directive << (unsigned)C;
1286 EmitEOL();
1287 }
1288}
1289
1290void MCAsmStreamer::emitBinaryData(StringRef Data) {
1291 // This is binary data. Print it in a grid of hex bytes for readability.
1292 const size_t Cols = 4;
1293 for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; I += Cols) {
1294 size_t J = I, EJ = std::min(I + Cols, Data.size());
1295 assert(EJ > 0);
1296 OS << MAI->getData8bitsDirective();
1297 for (; J < EJ - 1; ++J)
1298 OS << format("0x%02x", uint8_t(Data[J])) << ", ";
1299 OS << format("0x%02x", uint8_t(Data[J]));
1300 EmitEOL();
1301 }
1302}
1303
1304void MCAsmStreamer::emitIntValue(uint64_t Value, unsigned Size) {
1305 emitValue(MCConstantExpr::create(Value, getContext()), Size);
1306}
1307
1308void MCAsmStreamer::emitIntValueInHex(uint64_t Value, unsigned Size) {
1309 emitValue(MCConstantExpr::create(Value, getContext(), true), Size);
1310}
1311
1312void MCAsmStreamer::emitIntValueInHexWithPadding(uint64_t Value,
1313 unsigned Size) {
1314 emitValue(MCConstantExpr::create(Value, getContext(), true, Size), Size);
1315}
1316
1317void MCAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
1318 SMLoc Loc) {
1319 assert(Size <= 8 && "Invalid size");
1320 assert(getCurrentSectionOnly() &&
1321 "Cannot emit contents before setting section!");
1322 const char *Directive = nullptr;
1323 switch (Size) {
1324 default: break;
1325 case 1: Directive = MAI->getData8bitsDirective(); break;
1326 case 2: Directive = MAI->getData16bitsDirective(); break;
1327 case 4: Directive = MAI->getData32bitsDirective(); break;
1328 case 8: Directive = MAI->getData64bitsDirective(); break;
1329 }
1330
1331 if (!Directive) {
1332 int64_t IntValue;
1333 if (!Value->evaluateAsAbsolute(IntValue))
1334 report_fatal_error("Don't know how to emit this value.");
1335
1336 // We couldn't handle the requested integer size so we fallback by breaking
1337 // the request down into several, smaller, integers.
1338 // Since sizes greater or equal to "Size" are invalid, we use the greatest
1339 // power of 2 that is less than "Size" as our largest piece of granularity.
1340 bool IsLittleEndian = MAI->isLittleEndian();
1341 for (unsigned Emitted = 0; Emitted != Size;) {
1342 unsigned Remaining = Size - Emitted;
1343 // The size of our partial emission must be a power of two less than
1344 // Size.
1345 unsigned EmissionSize = llvm::bit_floor(std::min(Remaining, Size - 1));
1346 // Calculate the byte offset of our partial emission taking into account
1347 // the endianness of the target.
1348 unsigned ByteOffset =
1349 IsLittleEndian ? Emitted : (Remaining - EmissionSize);
1350 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
1351 // We truncate our partial emission to fit within the bounds of the
1352 // emission domain. This produces nicer output and silences potential
1353 // truncation warnings when round tripping through another assembler.
1354 uint64_t Shift = 64 - EmissionSize * 8;
1355 assert(Shift < static_cast<uint64_t>(
1356 std::numeric_limits<unsigned long long>::digits) &&
1357 "undefined behavior");
1358 ValueToEmit &= ~0ULL >> Shift;
1359 emitIntValue(ValueToEmit, EmissionSize);
1360 Emitted += EmissionSize;
1361 }
1362 return;
1363 }
1364
1365 assert(Directive && "Invalid size for machine code value!");
1366 OS << Directive;
1367 if (MCTargetStreamer *TS = getTargetStreamer()) {
1368 TS->emitValue(Value);
1369 } else {
1370 Value->print(OS, MAI);
1371 EmitEOL();
1372 }
1373}
1374
1375void MCAsmStreamer::emitULEB128Value(const MCExpr *Value) {
1376 int64_t IntValue;
1377 if (Value->evaluateAsAbsolute(IntValue)) {
1378 emitULEB128IntValue(IntValue);
1379 return;
1380 }
1381 OS << "\t.uleb128 ";
1382 Value->print(OS, MAI);
1383 EmitEOL();
1384}
1385
1386void MCAsmStreamer::emitSLEB128Value(const MCExpr *Value) {
1387 int64_t IntValue;
1388 if (Value->evaluateAsAbsolute(IntValue)) {
1389 emitSLEB128IntValue(IntValue);
1390 return;
1391 }
1392 OS << "\t.sleb128 ";
1393 Value->print(OS, MAI);
1394 EmitEOL();
1395}
1396
1397void MCAsmStreamer::emitDTPRel64Value(const MCExpr *Value) {
1398 assert(MAI->getDTPRel64Directive() != nullptr);
1399 OS << MAI->getDTPRel64Directive();
1400 Value->print(OS, MAI);
1401 EmitEOL();
1402}
1403
1404void MCAsmStreamer::emitDTPRel32Value(const MCExpr *Value) {
1405 assert(MAI->getDTPRel32Directive() != nullptr);
1406 OS << MAI->getDTPRel32Directive();
1407 Value->print(OS, MAI);
1408 EmitEOL();
1409}
1410
1411void MCAsmStreamer::emitTPRel64Value(const MCExpr *Value) {
1412 assert(MAI->getTPRel64Directive() != nullptr);
1413 OS << MAI->getTPRel64Directive();
1414 Value->print(OS, MAI);
1415 EmitEOL();
1416}
1417
1418void MCAsmStreamer::emitTPRel32Value(const MCExpr *Value) {
1419 assert(MAI->getTPRel32Directive() != nullptr);
1420 OS << MAI->getTPRel32Directive();
1421 Value->print(OS, MAI);
1422 EmitEOL();
1423}
1424
1425void MCAsmStreamer::emitGPRel64Value(const MCExpr *Value) {
1426 assert(MAI->getGPRel64Directive() != nullptr);
1427 OS << MAI->getGPRel64Directive();
1428 Value->print(OS, MAI);
1429 EmitEOL();
1430}
1431
1432void MCAsmStreamer::emitGPRel32Value(const MCExpr *Value) {
1433 assert(MAI->getGPRel32Directive() != nullptr);
1434 OS << MAI->getGPRel32Directive();
1435 Value->print(OS, MAI);
1436 EmitEOL();
1437}
1438
1439void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
1440 SMLoc Loc) {
1441 int64_t IntNumBytes;
1442 const bool IsAbsolute = NumBytes.evaluateAsAbsolute(IntNumBytes);
1443 if (IsAbsolute && IntNumBytes == 0)
1444 return;
1445
1446 if (const char *ZeroDirective = MAI->getZeroDirective()) {
1447 if (MAI->doesZeroDirectiveSupportNonZeroValue() || FillValue == 0) {
1448 // FIXME: Emit location directives
1449 OS << ZeroDirective;
1450 NumBytes.print(OS, MAI);
1451 if (FillValue != 0)
1452 OS << ',' << (int)FillValue;
1453 EmitEOL();
1454 } else {
1455 if (!IsAbsolute)
1457 "Cannot emit non-absolute expression lengths of fill.");
1458 for (int i = 0; i < IntNumBytes; ++i) {
1459 OS << MAI->getData8bitsDirective() << (int)FillValue;
1460 EmitEOL();
1461 }
1462 }
1463 return;
1464 }
1465
1466 MCStreamer::emitFill(NumBytes, FillValue);
1467}
1468
1469void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
1470 int64_t Expr, SMLoc Loc) {
1471 // FIXME: Emit location directives
1472 OS << "\t.fill\t";
1473 NumValues.print(OS, MAI);
1474 OS << ", " << Size << ", 0x";
1475 OS.write_hex(truncateToSize(Expr, 4));
1476 EmitEOL();
1477}
1478
1479void MCAsmStreamer::emitAlignmentDirective(unsigned ByteAlignment,
1480 std::optional<int64_t> Value,
1481 unsigned ValueSize,
1482 unsigned MaxBytesToEmit) {
1483 if (MAI->useDotAlignForAlignment()) {
1484 if (!isPowerOf2_32(ByteAlignment))
1485 report_fatal_error("Only power-of-two alignments are supported "
1486 "with .align.");
1487 OS << "\t.align\t";
1488 OS << Log2_32(ByteAlignment);
1489 EmitEOL();
1490 return;
1491 }
1492
1493 // Some assemblers don't support non-power of two alignments, so we always
1494 // emit alignments as a power of two if possible.
1495 if (isPowerOf2_32(ByteAlignment)) {
1496 switch (ValueSize) {
1497 default:
1498 llvm_unreachable("Invalid size for machine code value!");
1499 case 1:
1500 OS << "\t.p2align\t";
1501 break;
1502 case 2:
1503 OS << ".p2alignw ";
1504 break;
1505 case 4:
1506 OS << ".p2alignl ";
1507 break;
1508 case 8:
1509 llvm_unreachable("Unsupported alignment size!");
1510 }
1511
1512 OS << Log2_32(ByteAlignment);
1513
1514 if (Value.has_value() || MaxBytesToEmit) {
1515 if (Value.has_value()) {
1516 OS << ", 0x";
1517 OS.write_hex(truncateToSize(*Value, ValueSize));
1518 } else {
1519 OS << ", ";
1520 }
1521
1522 if (MaxBytesToEmit)
1523 OS << ", " << MaxBytesToEmit;
1524 }
1525 EmitEOL();
1526 return;
1527 }
1528
1529 // Non-power of two alignment. This is not widely supported by assemblers.
1530 // FIXME: Parameterize this based on MAI.
1531 switch (ValueSize) {
1532 default: llvm_unreachable("Invalid size for machine code value!");
1533 case 1: OS << ".balign"; break;
1534 case 2: OS << ".balignw"; break;
1535 case 4: OS << ".balignl"; break;
1536 case 8: llvm_unreachable("Unsupported alignment size!");
1537 }
1538
1539 OS << ' ' << ByteAlignment;
1540 if (Value.has_value())
1541 OS << ", " << truncateToSize(*Value, ValueSize);
1542 else if (MaxBytesToEmit)
1543 OS << ", ";
1544 if (MaxBytesToEmit)
1545 OS << ", " << MaxBytesToEmit;
1546 EmitEOL();
1547}
1548
1549void MCAsmStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
1550 unsigned ValueSize,
1551 unsigned MaxBytesToEmit) {
1552 emitAlignmentDirective(Alignment.value(), Value, ValueSize, MaxBytesToEmit);
1553}
1554
1555void MCAsmStreamer::emitCodeAlignment(Align Alignment,
1556 const MCSubtargetInfo *STI,
1557 unsigned MaxBytesToEmit) {
1558 // Emit with a text fill value.
1559 if (MAI->getTextAlignFillValue())
1560 emitAlignmentDirective(Alignment.value(), MAI->getTextAlignFillValue(), 1,
1561 MaxBytesToEmit);
1562 else
1563 emitAlignmentDirective(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
1564}
1565
1566void MCAsmStreamer::emitValueToOffset(const MCExpr *Offset,
1567 unsigned char Value,
1568 SMLoc Loc) {
1569 // FIXME: Verify that Offset is associated with the current section.
1570 OS << ".org ";
1571 Offset->print(OS, MAI);
1572 OS << ", " << (unsigned)Value;
1573 EmitEOL();
1574}
1575
1576void MCAsmStreamer::emitFileDirective(StringRef Filename) {
1578 OS << "\t.file\t";
1579 PrintQuotedString(Filename, OS);
1580 EmitEOL();
1581}
1582
1583void MCAsmStreamer::emitFileDirective(StringRef Filename,
1584 StringRef CompilerVerion,
1585 StringRef TimeStamp,
1586 StringRef Description) {
1588 OS << "\t.file\t";
1589 PrintQuotedString(Filename, OS);
1590 OS << ",";
1591 if (!CompilerVerion.empty()) {
1592 PrintQuotedString(CompilerVerion, OS);
1593 }
1594 if (!TimeStamp.empty()) {
1595 OS << ",";
1596 PrintQuotedString(TimeStamp, OS);
1597 }
1598 if (!Description.empty()) {
1599 OS << ",";
1600 PrintQuotedString(Description, OS);
1601 }
1602 EmitEOL();
1603}
1604
1605void MCAsmStreamer::printDwarfFileDirective(
1606 unsigned FileNo, StringRef Directory, StringRef Filename,
1607 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1608 bool UseDwarfDirectory, raw_svector_ostream &OS) const {
1609 SmallString<128> FullPathName;
1610
1611 if (!UseDwarfDirectory && !Directory.empty()) {
1612 if (sys::path::is_absolute(Filename))
1613 Directory = "";
1614 else {
1615 FullPathName = Directory;
1616 sys::path::append(FullPathName, Filename);
1617 Directory = "";
1618 Filename = FullPathName;
1619 }
1620 }
1621
1622 OS << "\t.file\t" << FileNo << ' ';
1623 if (!Directory.empty()) {
1624 PrintQuotedString(Directory, OS);
1625 OS << ' ';
1626 }
1627 PrintQuotedString(Filename, OS);
1628 if (Checksum)
1629 OS << " md5 0x" << Checksum->digest();
1630 if (Source) {
1631 OS << " source ";
1632 PrintQuotedString(*Source, OS);
1633 }
1634}
1635
1636Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
1637 unsigned FileNo, StringRef Directory, StringRef Filename,
1638 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1639 unsigned CUID) {
1640 assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer");
1641
1642 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
1643 unsigned NumFiles = Table.getMCDwarfFiles().size();
1644 Expected<unsigned> FileNoOrErr =
1645 Table.tryGetFile(Directory, Filename, Checksum, Source,
1646 getContext().getDwarfVersion(), FileNo);
1647 if (!FileNoOrErr)
1648 return FileNoOrErr.takeError();
1649 FileNo = FileNoOrErr.get();
1650
1651 // Return early if this file is already emitted before or if target doesn't
1652 // support .file directive.
1653 if (NumFiles == Table.getMCDwarfFiles().size() ||
1655 return FileNo;
1656
1657 SmallString<128> Str;
1658 raw_svector_ostream OS1(Str);
1659 printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source,
1660 UseDwarfDirectory, OS1);
1661
1662 if (MCTargetStreamer *TS = getTargetStreamer())
1663 TS->emitDwarfFileDirective(OS1.str());
1664 else
1665 emitRawText(OS1.str());
1666
1667 return FileNo;
1668}
1669
1670void MCAsmStreamer::emitDwarfFile0Directive(
1671 StringRef Directory, StringRef Filename,
1672 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1673 unsigned CUID) {
1674 assert(CUID == 0);
1675 // .file 0 is new for DWARF v5.
1676 if (getContext().getDwarfVersion() < 5)
1677 return;
1678 // Inform MCDwarf about the root file.
1679 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
1680 Source);
1681
1682 // Target doesn't support .loc/.file directives, return early.
1684 return;
1685
1686 SmallString<128> Str;
1687 raw_svector_ostream OS1(Str);
1688 printDwarfFileDirective(0, Directory, Filename, Checksum, Source,
1689 UseDwarfDirectory, OS1);
1690
1691 if (MCTargetStreamer *TS = getTargetStreamer())
1692 TS->emitDwarfFileDirective(OS1.str());
1693 else
1694 emitRawText(OS1.str());
1695}
1696
1697void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
1698 unsigned Column, unsigned Flags,
1699 unsigned Isa, unsigned Discriminator,
1700 StringRef FileName) {
1701 // If target doesn't support .loc/.file directive, we need to record the lines
1702 // same way like we do in object mode.
1703 if (!MAI->usesDwarfFileAndLocDirectives()) {
1704 // In case we see two .loc directives in a row, make sure the
1705 // first one gets a line entry.
1706 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
1707 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1708 Discriminator, FileName);
1709 return;
1710 }
1711
1712 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
1714 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
1715 OS << " basic_block";
1716 if (Flags & DWARF2_FLAG_PROLOGUE_END)
1717 OS << " prologue_end";
1718 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
1719 OS << " epilogue_begin";
1720
1721 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
1722 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
1723 OS << " is_stmt ";
1724
1725 if (Flags & DWARF2_FLAG_IS_STMT)
1726 OS << "1";
1727 else
1728 OS << "0";
1729 }
1730
1731 if (Isa)
1732 OS << " isa " << Isa;
1733 if (Discriminator)
1734 OS << " discriminator " << Discriminator;
1735 }
1736
1737 if (IsVerboseAsm) {
1738 OS.PadToColumn(MAI->getCommentColumn());
1739 OS << MAI->getCommentString() << ' ' << FileName << ':'
1740 << Line << ':' << Column;
1741 }
1742 EmitEOL();
1743 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1744 Discriminator, FileName);
1745}
1746
1747MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
1748 // Always use the zeroth line table, since asm syntax only supports one line
1749 // table for now.
1751}
1752
1753bool MCAsmStreamer::emitCVFileDirective(unsigned FileNo, StringRef Filename,
1754 ArrayRef<uint8_t> Checksum,
1755 unsigned ChecksumKind) {
1756 if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
1757 ChecksumKind))
1758 return false;
1759
1760 OS << "\t.cv_file\t" << FileNo << ' ';
1761 PrintQuotedString(Filename, OS);
1762
1763 if (!ChecksumKind) {
1764 EmitEOL();
1765 return true;
1766 }
1767
1768 OS << ' ';
1769 PrintQuotedString(toHex(Checksum), OS);
1770 OS << ' ' << ChecksumKind;
1771
1772 EmitEOL();
1773 return true;
1774}
1775
1776bool MCAsmStreamer::emitCVFuncIdDirective(unsigned FuncId) {
1777 OS << "\t.cv_func_id " << FuncId << '\n';
1779}
1780
1781bool MCAsmStreamer::emitCVInlineSiteIdDirective(unsigned FunctionId,
1782 unsigned IAFunc,
1783 unsigned IAFile,
1784 unsigned IALine, unsigned IACol,
1785 SMLoc Loc) {
1786 OS << "\t.cv_inline_site_id " << FunctionId << " within " << IAFunc
1787 << " inlined_at " << IAFile << ' ' << IALine << ' ' << IACol << '\n';
1789 IALine, IACol, Loc);
1790}
1791
1792void MCAsmStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
1793 unsigned Line, unsigned Column,
1794 bool PrologueEnd, bool IsStmt,
1795 StringRef FileName, SMLoc Loc) {
1796 // Validate the directive.
1797 if (!checkCVLocSection(FunctionId, FileNo, Loc))
1798 return;
1799
1800 OS << "\t.cv_loc\t" << FunctionId << " " << FileNo << " " << Line << " "
1801 << Column;
1802 if (PrologueEnd)
1803 OS << " prologue_end";
1804
1805 if (IsStmt)
1806 OS << " is_stmt 1";
1807
1808 if (IsVerboseAsm) {
1809 OS.PadToColumn(MAI->getCommentColumn());
1810 OS << MAI->getCommentString() << ' ' << FileName << ':' << Line << ':'
1811 << Column;
1812 }
1813 EmitEOL();
1814}
1815
1816void MCAsmStreamer::emitCVLinetableDirective(unsigned FunctionId,
1817 const MCSymbol *FnStart,
1818 const MCSymbol *FnEnd) {
1819 OS << "\t.cv_linetable\t" << FunctionId << ", ";
1820 FnStart->print(OS, MAI);
1821 OS << ", ";
1822 FnEnd->print(OS, MAI);
1823 EmitEOL();
1824 this->MCStreamer::emitCVLinetableDirective(FunctionId, FnStart, FnEnd);
1825}
1826
1827void MCAsmStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
1828 unsigned SourceFileId,
1829 unsigned SourceLineNum,
1830 const MCSymbol *FnStartSym,
1831 const MCSymbol *FnEndSym) {
1832 OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId
1833 << ' ' << SourceLineNum << ' ';
1834 FnStartSym->print(OS, MAI);
1835 OS << ' ';
1836 FnEndSym->print(OS, MAI);
1837 EmitEOL();
1839 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1840}
1841
1842void MCAsmStreamer::PrintCVDefRangePrefix(
1843 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {
1844 OS << "\t.cv_def_range\t";
1845 for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
1846 OS << ' ';
1847 Range.first->print(OS, MAI);
1848 OS << ' ';
1849 Range.second->print(OS, MAI);
1850 }
1851}
1852
1853void MCAsmStreamer::emitCVDefRangeDirective(
1854 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1856 PrintCVDefRangePrefix(Ranges);
1857 OS << ", reg_rel, ";
1858 OS << DRHdr.Register << ", " << DRHdr.Flags << ", "
1859 << DRHdr.BasePointerOffset;
1860 EmitEOL();
1861}
1862
1863void MCAsmStreamer::emitCVDefRangeDirective(
1864 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1866 PrintCVDefRangePrefix(Ranges);
1867 OS << ", subfield_reg, ";
1868 OS << DRHdr.Register << ", " << DRHdr.OffsetInParent;
1869 EmitEOL();
1870}
1871
1872void MCAsmStreamer::emitCVDefRangeDirective(
1873 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1875 PrintCVDefRangePrefix(Ranges);
1876 OS << ", reg, ";
1877 OS << DRHdr.Register;
1878 EmitEOL();
1879}
1880
1881void MCAsmStreamer::emitCVDefRangeDirective(
1882 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1884 PrintCVDefRangePrefix(Ranges);
1885 OS << ", frame_ptr_rel, ";
1886 OS << DRHdr.Offset;
1887 EmitEOL();
1888}
1889
1890void MCAsmStreamer::emitCVStringTableDirective() {
1891 OS << "\t.cv_stringtable";
1892 EmitEOL();
1893}
1894
1895void MCAsmStreamer::emitCVFileChecksumsDirective() {
1896 OS << "\t.cv_filechecksums";
1897 EmitEOL();
1898}
1899
1900void MCAsmStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
1901 OS << "\t.cv_filechecksumoffset\t" << FileNo;
1902 EmitEOL();
1903}
1904
1905void MCAsmStreamer::emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) {
1906 OS << "\t.cv_fpo_data\t";
1907 ProcSym->print(OS, MAI);
1908 EmitEOL();
1909}
1910
1911void MCAsmStreamer::emitIdent(StringRef IdentString) {
1912 assert(MAI->hasIdentDirective() && ".ident directive not supported");
1913 OS << "\t.ident\t";
1914 PrintQuotedString(IdentString, OS);
1915 EmitEOL();
1916}
1917
1918void MCAsmStreamer::emitCFISections(bool EH, bool Debug) {
1920 OS << "\t.cfi_sections ";
1921 if (EH) {
1922 OS << ".eh_frame";
1923 if (Debug)
1924 OS << ", .debug_frame";
1925 } else if (Debug) {
1926 OS << ".debug_frame";
1927 }
1928
1929 EmitEOL();
1930}
1931
1932void MCAsmStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
1933 OS << "\t.cfi_startproc";
1934 if (Frame.IsSimple)
1935 OS << " simple";
1936 EmitEOL();
1937}
1938
1939void MCAsmStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
1941 OS << "\t.cfi_endproc";
1942 EmitEOL();
1943}
1944
1945void MCAsmStreamer::EmitRegisterName(int64_t Register) {
1946 if (!MAI->useDwarfRegNumForCFI()) {
1947 // User .cfi_* directives can use arbitrary DWARF register numbers, not
1948 // just ones that map to LLVM register numbers and have known names.
1949 // Fall back to using the original number directly if no name is known.
1950 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1951 if (std::optional<unsigned> LLVMRegister =
1952 MRI->getLLVMRegNum(Register, true)) {
1953 InstPrinter->printRegName(OS, *LLVMRegister);
1954 return;
1955 }
1956 }
1957 OS << Register;
1958}
1959
1960void MCAsmStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) {
1962 OS << "\t.cfi_def_cfa ";
1963 EmitRegisterName(Register);
1964 OS << ", " << Offset;
1965 EmitEOL();
1966}
1967
1968void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) {
1970 OS << "\t.cfi_def_cfa_offset " << Offset;
1971 EmitEOL();
1972}
1973
1974void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
1975 int64_t AddressSpace, SMLoc Loc) {
1977 OS << "\t.cfi_llvm_def_aspace_cfa ";
1978 EmitRegisterName(Register);
1979 OS << ", " << Offset;
1980 OS << ", " << AddressSpace;
1981 EmitEOL();
1982}
1983
1985 OS << "\t.cfi_escape ";
1986 if (!Values.empty()) {
1987 size_t e = Values.size() - 1;
1988 for (size_t i = 0; i < e; ++i)
1989 OS << format("0x%02x", uint8_t(Values[i])) << ", ";
1990 OS << format("0x%02x", uint8_t(Values[e]));
1991 }
1992}
1993
1994void MCAsmStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
1995 MCStreamer::emitCFIEscape(Values, Loc);
1996 PrintCFIEscape(OS, Values);
1997 EmitEOL();
1998}
1999
2000void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {
2002
2003 uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
2004 unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
2005
2006 PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));
2007 EmitEOL();
2008}
2009
2010void MCAsmStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {
2012 OS << "\t.cfi_def_cfa_register ";
2013 EmitRegisterName(Register);
2014 EmitEOL();
2015}
2016
2017void MCAsmStreamer::emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
2019 OS << "\t.cfi_offset ";
2020 EmitRegisterName(Register);
2021 OS << ", " << Offset;
2022 EmitEOL();
2023}
2024
2025void MCAsmStreamer::emitCFIPersonality(const MCSymbol *Sym,
2026 unsigned Encoding) {
2028 OS << "\t.cfi_personality " << Encoding << ", ";
2029 Sym->print(OS, MAI);
2030 EmitEOL();
2031}
2032
2033void MCAsmStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
2034 MCStreamer::emitCFILsda(Sym, Encoding);
2035 OS << "\t.cfi_lsda " << Encoding << ", ";
2036 Sym->print(OS, MAI);
2037 EmitEOL();
2038}
2039
2040void MCAsmStreamer::emitCFIRememberState(SMLoc Loc) {
2042 OS << "\t.cfi_remember_state";
2043 EmitEOL();
2044}
2045
2046void MCAsmStreamer::emitCFIRestoreState(SMLoc Loc) {
2048 OS << "\t.cfi_restore_state";
2049 EmitEOL();
2050}
2051
2052void MCAsmStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {
2054 OS << "\t.cfi_restore ";
2055 EmitRegisterName(Register);
2056 EmitEOL();
2057}
2058
2059void MCAsmStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {
2061 OS << "\t.cfi_same_value ";
2062 EmitRegisterName(Register);
2063 EmitEOL();
2064}
2065
2066void MCAsmStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset,
2067 SMLoc Loc) {
2069 OS << "\t.cfi_rel_offset ";
2070 EmitRegisterName(Register);
2071 OS << ", " << Offset;
2072 EmitEOL();
2073}
2074
2075void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
2076 MCStreamer::emitCFIAdjustCfaOffset(Adjustment, Loc);
2077 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
2078 EmitEOL();
2079}
2080
2081void MCAsmStreamer::emitCFISignalFrame() {
2083 OS << "\t.cfi_signal_frame";
2084 EmitEOL();
2085}
2086
2087void MCAsmStreamer::emitCFIUndefined(int64_t Register, SMLoc Loc) {
2089 OS << "\t.cfi_undefined ";
2090 EmitRegisterName(Register);
2091 EmitEOL();
2092}
2093
2094void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
2095 SMLoc Loc) {
2096 MCStreamer::emitCFIRegister(Register1, Register2, Loc);
2097 OS << "\t.cfi_register ";
2098 EmitRegisterName(Register1);
2099 OS << ", ";
2100 EmitRegisterName(Register2);
2101 EmitEOL();
2102}
2103
2104void MCAsmStreamer::emitCFIWindowSave(SMLoc Loc) {
2106 OS << "\t.cfi_window_save";
2107 EmitEOL();
2108}
2109
2110void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) {
2112 OS << "\t.cfi_negate_ra_state";
2113 EmitEOL();
2114}
2115
2116void MCAsmStreamer::emitCFIReturnColumn(int64_t Register) {
2118 OS << "\t.cfi_return_column ";
2119 EmitRegisterName(Register);
2120 EmitEOL();
2121}
2122
2123void MCAsmStreamer::emitCFIBKeyFrame() {
2125 OS << "\t.cfi_b_key_frame";
2126 EmitEOL();
2127}
2128
2129void MCAsmStreamer::emitCFIMTETaggedFrame() {
2131 OS << "\t.cfi_mte_tagged_frame";
2132 EmitEOL();
2133}
2134
2135void MCAsmStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
2137
2138 OS << ".seh_proc ";
2139 Symbol->print(OS, MAI);
2140 EmitEOL();
2141}
2142
2143void MCAsmStreamer::emitWinCFIEndProc(SMLoc Loc) {
2145
2146 OS << "\t.seh_endproc";
2147 EmitEOL();
2148}
2149
2150void MCAsmStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
2152
2153 OS << "\t.seh_endfunclet";
2154 EmitEOL();
2155}
2156
2157void MCAsmStreamer::emitWinCFIStartChained(SMLoc Loc) {
2159
2160 OS << "\t.seh_startchained";
2161 EmitEOL();
2162}
2163
2164void MCAsmStreamer::emitWinCFIEndChained(SMLoc Loc) {
2166
2167 OS << "\t.seh_endchained";
2168 EmitEOL();
2169}
2170
2171void MCAsmStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind,
2172 bool Except, SMLoc Loc) {
2173 MCStreamer::emitWinEHHandler(Sym, Unwind, Except, Loc);
2174
2175 OS << "\t.seh_handler ";
2176 Sym->print(OS, MAI);
2177 char Marker = '@';
2178 const Triple &T = getContext().getTargetTriple();
2179 if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
2180 Marker = '%';
2181 if (Unwind)
2182 OS << ", " << Marker << "unwind";
2183 if (Except)
2184 OS << ", " << Marker << "except";
2185 EmitEOL();
2186}
2187
2188void MCAsmStreamer::emitWinEHHandlerData(SMLoc Loc) {
2190
2191 // Switch sections. Don't call switchSection directly, because that will
2192 // cause the section switch to be visible in the emitted assembly.
2193 // We only do this so the section switch that terminates the handler
2194 // data block is visible.
2195 WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
2196
2197 // Do nothing if no frame is open. MCStreamer should've already reported an
2198 // error.
2199 if (!CurFrame)
2200 return;
2201
2202 MCSection *TextSec = &CurFrame->Function->getSection();
2203 MCSection *XData = getAssociatedXDataSection(TextSec);
2204 switchSectionNoChange(XData);
2205
2206 OS << "\t.seh_handlerdata";
2207 EmitEOL();
2208}
2209
2210void MCAsmStreamer::emitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
2212
2213 OS << "\t.seh_pushreg ";
2214 InstPrinter->printRegName(OS, Register);
2215 EmitEOL();
2216}
2217
2218void MCAsmStreamer::emitWinCFISetFrame(MCRegister Register, unsigned Offset,
2219 SMLoc Loc) {
2221
2222 OS << "\t.seh_setframe ";
2223 InstPrinter->printRegName(OS, Register);
2224 OS << ", " << Offset;
2225 EmitEOL();
2226}
2227
2228void MCAsmStreamer::emitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
2230
2231 OS << "\t.seh_stackalloc " << Size;
2232 EmitEOL();
2233}
2234
2235void MCAsmStreamer::emitWinCFISaveReg(MCRegister Register, unsigned Offset,
2236 SMLoc Loc) {
2238
2239 OS << "\t.seh_savereg ";
2240 InstPrinter->printRegName(OS, Register);
2241 OS << ", " << Offset;
2242 EmitEOL();
2243}
2244
2245void MCAsmStreamer::emitWinCFISaveXMM(MCRegister Register, unsigned Offset,
2246 SMLoc Loc) {
2248
2249 OS << "\t.seh_savexmm ";
2250 InstPrinter->printRegName(OS, Register);
2251 OS << ", " << Offset;
2252 EmitEOL();
2253}
2254
2255void MCAsmStreamer::emitWinCFIPushFrame(bool Code, SMLoc Loc) {
2257
2258 OS << "\t.seh_pushframe";
2259 if (Code)
2260 OS << " @code";
2261 EmitEOL();
2262}
2263
2264void MCAsmStreamer::emitWinCFIEndProlog(SMLoc Loc) {
2266
2267 OS << "\t.seh_endprologue";
2268 EmitEOL();
2269}
2270
2271void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
2272 const MCSymbolRefExpr *To,
2273 uint64_t Count) {
2274 OS << "\t.cg_profile ";
2275 From->getSymbol().print(OS, MAI);
2276 OS << ", ";
2277 To->getSymbol().print(OS, MAI);
2278 OS << ", " << Count;
2279 EmitEOL();
2280}
2281
2282void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
2283 const MCSubtargetInfo &STI) {
2284 raw_ostream &OS = getCommentOS();
2287
2288 // If we have no code emitter, don't emit code.
2289 if (!getAssembler().getEmitterPtr())
2290 return;
2291
2292 getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
2293
2294 // If we are showing fixups, create symbolic markers in the encoded
2295 // representation. We do this by making a per-bit map to the fixup item index,
2296 // then trying to display it as nicely as possible.
2297 SmallVector<uint8_t, 64> FixupMap;
2298 FixupMap.resize(Code.size() * 8);
2299 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
2300 FixupMap[i] = 0;
2301
2302 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
2303 MCFixup &F = Fixups[i];
2304 const MCFixupKindInfo &Info =
2305 getAssembler().getBackend().getFixupKindInfo(F.getKind());
2306 for (unsigned j = 0; j != Info.TargetSize; ++j) {
2307 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
2308 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
2309 FixupMap[Index] = 1 + i;
2310 }
2311 }
2312
2313 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
2314 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
2315 OS << "encoding: [";
2316 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
2317 if (i)
2318 OS << ',';
2319
2320 // See if all bits are the same map entry.
2321 uint8_t MapEntry = FixupMap[i * 8 + 0];
2322 for (unsigned j = 1; j != 8; ++j) {
2323 if (FixupMap[i * 8 + j] == MapEntry)
2324 continue;
2325
2326 MapEntry = uint8_t(~0U);
2327 break;
2328 }
2329
2330 if (MapEntry != uint8_t(~0U)) {
2331 if (MapEntry == 0) {
2332 OS << format("0x%02x", uint8_t(Code[i]));
2333 } else {
2334 if (Code[i]) {
2335 // FIXME: Some of the 8 bits require fix up.
2336 OS << format("0x%02x", uint8_t(Code[i])) << '\''
2337 << char('A' + MapEntry - 1) << '\'';
2338 } else
2339 OS << char('A' + MapEntry - 1);
2340 }
2341 } else {
2342 // Otherwise, write out in binary.
2343 OS << "0b";
2344 for (unsigned j = 8; j--;) {
2345 unsigned Bit = (Code[i] >> j) & 1;
2346
2347 unsigned FixupBit;
2348 if (MAI->isLittleEndian())
2349 FixupBit = i * 8 + j;
2350 else
2351 FixupBit = i * 8 + (7-j);
2352
2353 if (uint8_t MapEntry = FixupMap[FixupBit]) {
2354 assert(Bit == 0 && "Encoder wrote into fixed up bit!");
2355 OS << char('A' + MapEntry - 1);
2356 } else
2357 OS << Bit;
2358 }
2359 }
2360 }
2361 OS << "]\n";
2362
2363 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
2364 MCFixup &F = Fixups[i];
2365 const MCFixupKindInfo &Info =
2366 getAssembler().getBackend().getFixupKindInfo(F.getKind());
2367 OS << " fixup " << char('A' + i) << " - "
2368 << "offset: " << F.getOffset() << ", value: ";
2369 F.getValue()->print(OS, MAI);
2370 OS << ", kind: " << Info.Name << "\n";
2371 }
2372}
2373
2374void MCAsmStreamer::emitInstruction(const MCInst &Inst,
2375 const MCSubtargetInfo &STI) {
2376 assert(getCurrentSectionOnly() &&
2377 "Cannot emit contents before setting section!");
2378
2380 // Now that a machine instruction has been assembled into this section, make
2381 // a line entry for any .loc directive that has been seen.
2382 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
2383
2384 // Show the encoding in a comment if we have a code emitter.
2385 AddEncodingComment(Inst, STI);
2386
2387 // Show the MCInst if enabled.
2388 if (ShowInst) {
2389 Inst.dump_pretty(getCommentOS(), InstPrinter.get(), "\n ");
2390 getCommentOS() << "\n";
2391 }
2392
2393 if(getTargetStreamer())
2394 getTargetStreamer()->prettyPrintAsm(*InstPrinter, 0, Inst, STI, OS);
2395 else
2396 InstPrinter->printInst(&Inst, 0, "", STI, OS);
2397
2398 StringRef Comments = CommentToEmit;
2399 if (Comments.size() && Comments.back() != '\n')
2400 getCommentOS() << "\n";
2401
2402 EmitEOL();
2403}
2404
2405void MCAsmStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index,
2406 uint64_t Type, uint64_t Attr,
2407 uint64_t Discriminator,
2408 const MCPseudoProbeInlineStack &InlineStack,
2409 MCSymbol *FnSym) {
2410 OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " " << Attr;
2411 if (Discriminator)
2412 OS << " " << Discriminator;
2413 // Emit inline stack like
2414 // @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11
2415 for (const auto &Site : InlineStack)
2416 OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site);
2417
2418 OS << " " << FnSym->getName();
2419
2420 EmitEOL();
2421}
2422
2423void MCAsmStreamer::emitBundleAlignMode(Align Alignment) {
2424 OS << "\t.bundle_align_mode " << Log2(Alignment);
2425 EmitEOL();
2426}
2427
2428void MCAsmStreamer::emitBundleLock(bool AlignToEnd) {
2429 OS << "\t.bundle_lock";
2430 if (AlignToEnd)
2431 OS << " align_to_end";
2432 EmitEOL();
2433}
2434
2435void MCAsmStreamer::emitBundleUnlock() {
2436 OS << "\t.bundle_unlock";
2437 EmitEOL();
2438}
2439
2440std::optional<std::pair<bool, std::string>>
2441MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
2442 const MCExpr *Expr, SMLoc,
2443 const MCSubtargetInfo &STI) {
2444 OS << "\t.reloc ";
2445 Offset.print(OS, MAI);
2446 OS << ", " << Name;
2447 if (Expr) {
2448 OS << ", ";
2449 Expr->print(OS, MAI);
2450 }
2451 EmitEOL();
2452 return std::nullopt;
2453}
2454
2455void MCAsmStreamer::emitAddrsig() {
2456 OS << "\t.addrsig";
2457 EmitEOL();
2458}
2459
2460void MCAsmStreamer::emitAddrsigSym(const MCSymbol *Sym) {
2461 OS << "\t.addrsig_sym ";
2462 Sym->print(OS, MAI);
2463 EmitEOL();
2464}
2465
2466/// EmitRawText - If this file is backed by an assembly streamer, this dumps
2467/// the specified string in the output .s file. This capability is
2468/// indicated by the hasRawTextSupport() predicate.
2469void MCAsmStreamer::emitRawTextImpl(StringRef String) {
2470 if (!String.empty() && String.back() == '\n')
2471 String = String.substr(0, String.size()-1);
2472 OS << String;
2473 EmitEOL();
2474}
2475
2476void MCAsmStreamer::finishImpl() {
2477 // If we are generating dwarf for assembly source files dump out the sections.
2478 if (getContext().getGenDwarfForAssembly())
2480
2481 // Now it is time to emit debug line sections if target doesn't support .loc
2482 // and .line directives.
2483 if (!MAI->usesDwarfFileAndLocDirectives()) {
2484 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
2485 return;
2486 }
2487
2488 // Emit the label for the line table, if requested - since the rest of the
2489 // line table will be defined by .loc/.file directives, and not emitted
2490 // directly, the label is the only work required here.
2491 const auto &Tables = getContext().getMCDwarfLineTables();
2492 if (!Tables.empty()) {
2493 assert(Tables.size() == 1 && "asm output only supports one line table");
2494 if (auto *Label = Tables.begin()->second.getLabel()) {
2495 switchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
2496 emitLabel(Label);
2497 }
2498 }
2499}
2500
2501void MCAsmStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
2502 // If the assembler on some target fills in the DWARF unit length, we
2503 // don't want to emit the length in the compiler. For example, the AIX
2504 // assembler requires the assembly file with the unit length omitted from
2505 // the debug section headers. In such cases, any label we placed occurs
2506 // after the implied length field. We need to adjust the reference here
2507 // to account for the offset introduced by the inserted length field.
2509 return;
2511}
2512
2513MCSymbol *MCAsmStreamer::emitDwarfUnitLength(const Twine &Prefix,
2514 const Twine &Comment) {
2515 // If the assembler on some target fills in the DWARF unit length, we
2516 // don't want to emit the length in the compiler. For example, the AIX
2517 // assembler requires the assembly file with the unit length omitted from
2518 // the debug section headers. In such cases, any label we placed occurs
2519 // after the implied length field. We need to adjust the reference here
2520 // to account for the offset introduced by the inserted length field.
2522 return getContext().createTempSymbol(Prefix + "_end");
2523 return MCStreamer::emitDwarfUnitLength(Prefix, Comment);
2524}
2525
2526void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
2527 // If the assembler on some target fills in the DWARF unit length, we
2528 // don't want to emit the length in the compiler. For example, the AIX
2529 // assembler requires the assembly file with the unit length omitted from
2530 // the debug section headers. In such cases, any label we placed occurs
2531 // after the implied length field. We need to adjust the reference here
2532 // to account for the offset introduced by the inserted length field.
2533 MCContext &Ctx = getContext();
2534 if (!MAI->needsDwarfSectionSizeInHeader()) {
2535 MCSymbol *DebugLineSymTmp = Ctx.createTempSymbol("debug_line_");
2536 // Emit the symbol which does not contain the unit length field.
2537 emitLabel(DebugLineSymTmp);
2538
2539 // Adjust the outer reference to account for the offset introduced by the
2540 // inserted length field.
2541 unsigned LengthFieldSize =
2543 const MCExpr *EntrySize = MCConstantExpr::create(LengthFieldSize, Ctx);
2544 const MCExpr *OuterSym = MCBinaryExpr::createSub(
2545 MCSymbolRefExpr::create(DebugLineSymTmp, Ctx), EntrySize, Ctx);
2546
2547 emitAssignment(StartSym, OuterSym);
2548 return;
2549 }
2551}
2552
2553void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
2554 MCSymbol *LastLabel) {
2555 // If the targets write the raw debug line data for assembly output (We can
2556 // not switch to Section and add the end symbol there for assembly output)
2557 // we currently use the .text end label as any section end. This will not
2558 // impact the debugability as we will jump to the caller of the last function
2559 // in the section before we come into the .text end address.
2561 ".loc should not be generated together with raw data!");
2562
2563 MCContext &Ctx = getContext();
2564
2565 // FIXME: use section end symbol as end of the Section. We need to consider
2566 // the explicit sections and -ffunction-sections when we try to generate or
2567 // find section end symbol for the Section.
2568 MCSection *TextSection = Ctx.getObjectFileInfo()->getTextSection();
2569 assert(TextSection->hasEnded() && ".text section is not end!");
2570
2571 MCSymbol *SectionEnd = TextSection->getEndSymbol(Ctx);
2572 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
2573 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
2574 AsmInfo->getCodePointerSize());
2575}
2576
2577// Generate DWARF line sections for assembly mode without .loc/.file
2578void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
2579 const MCSymbol *LastLabel,
2580 const MCSymbol *Label,
2581 unsigned PointerSize) {
2583 ".loc/.file don't need raw data in debug line section!");
2584
2585 // Set to new address.
2586 AddComment("Set address to " + Label->getName());
2587 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2588 emitULEB128IntValue(PointerSize + 1);
2589 emitIntValue(dwarf::DW_LNE_set_address, 1);
2590 emitSymbolValue(Label, PointerSize);
2591
2592 if (!LastLabel) {
2593 // Emit the sequence for the LineDelta (from 1) and a zero address delta.
2594 AddComment("Start sequence");
2595 MCDwarfLineAddr::Emit(this, MCDwarfLineTableParams(), LineDelta, 0);
2596 return;
2597 }
2598
2599 // INT64_MAX is a signal of the end of the section. Emit DW_LNE_end_sequence
2600 // for the end of the section.
2601 if (LineDelta == INT64_MAX) {
2602 AddComment("End sequence");
2603 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2604 emitULEB128IntValue(1);
2605 emitIntValue(dwarf::DW_LNE_end_sequence, 1);
2606 return;
2607 }
2608
2609 // Advance line.
2610 AddComment("Advance line " + Twine(LineDelta));
2611 emitIntValue(dwarf::DW_LNS_advance_line, 1);
2612 emitSLEB128IntValue(LineDelta);
2613 emitIntValue(dwarf::DW_LNS_copy, 1);
2614}
2615
2616void MCAsmStreamer::doFinalizationAtSectionEnd(MCSection *Section) {
2617 // Emit section end. This is used to tell the debug line section where the end
2618 // is for a text section if we don't use .loc to represent the debug line.
2620 return;
2621
2622 switchSectionNoChange(Section);
2623
2624 MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());
2625
2626 if (!Sym->isInSection())
2627 emitLabel(Sym);
2628}
2629
2631 std::unique_ptr<formatted_raw_ostream> OS,
2632 bool isVerboseAsm, bool useDwarfDirectory,
2633 MCInstPrinter *IP,
2634 std::unique_ptr<MCCodeEmitter> &&CE,
2635 std::unique_ptr<MCAsmBackend> &&MAB,
2636 bool ShowInst) {
2637 return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
2638 useDwarfDirectory, IP, std::move(CE), std::move(MAB),
2639 ShowInst);
2640}
unsigned const MachineRegisterInfo * MRI
BlockVerifier::State From
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:221
dxil pretty printer
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:477
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
static LVOptions Options
Definition: LVOptions.cpp:25
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
Definition: MCDwarf.h:117
#define DWARF2_FLAG_BASIC_BLOCK
Definition: MCDwarf.h:118
#define DWARF2_FLAG_PROLOGUE_END
Definition: MCDwarf.h:119
#define DWARF2_FLAG_EPILOGUE_BEGIN
Definition: MCDwarf.h:120
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
LLVMContext & Context
bool Debug
Profile::FuncID FuncId
Definition: Profile.cpp:321
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallString class.
This file contains some functions that are useful when dealing with strings.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Tagged union holding either a T or a Error.
Definition: Error.h:474
Error takeError()
Take ownership of the stored error.
Definition: Error.h:601
reference get()
Returns a reference to the stored T value.
Definition: Error.h:571
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
const char * getPlainStringDirective() const
Definition: MCAsmInfo.h:726
const char * getLabelSuffix() const
Definition: MCAsmInfo.h:666
bool hasDotTypeDotSizeDirective() const
Definition: MCAsmInfo.h:755
bool isLittleEndian() const
True if the target is little endian.
Definition: MCAsmInfo.h:562
bool doesSupportDataRegionDirectives() const
Definition: MCAsmInfo.h:706
const char * getTPRel64Directive() const
Definition: MCAsmInfo.h:580
const char * getData32bitsDirective() const
Definition: MCAsmInfo.h:573
bool hasFourStringsDotFile() const
Definition: MCAsmInfo.h:757
unsigned getAssemblerDialect() const
Definition: MCAsmInfo.h:689
unsigned getTextAlignFillValue() const
Definition: MCAsmInfo.h:731
bool useDwarfRegNumForCFI() const
Definition: MCAsmInfo.h:816
bool supportsExtendedDwarfLocDirective() const
Definition: MCAsmInfo.h:821
const char * getData8bitsDirective() const
Definition: MCAsmInfo.h:571
const char * getTPRel32Directive() const
Definition: MCAsmInfo.h:581
const char * getData64bitsDirective() const
Definition: MCAsmInfo.h:574
AsmCharLiteralSyntax characterLiteralSyntax() const
Definition: MCAsmInfo.h:727
const char * getByteListDirective() const
Definition: MCAsmInfo.h:725
const char * getCode16Directive() const
Definition: MCAsmInfo.h:686
const char * getGPRel64Directive() const
Definition: MCAsmInfo.h:576
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const
Definition: MCAsmInfo.h:744
StringRef getCommentString() const
Definition: MCAsmInfo.h:658
const char * getAscizDirective() const
Definition: MCAsmInfo.h:724
const char * getDTPRel64Directive() const
Definition: MCAsmInfo.h:578
const char * getZeroDirective() const
Definition: MCAsmInfo.h:719
const char * getWeakDirective() const
Definition: MCAsmInfo.h:761
bool hasSubsectionsViaSymbols() const
Definition: MCAsmInfo.h:567
const char * getData16bitsDirective() const
Definition: MCAsmInfo.h:572
const char * getSeparatorString() const
Definition: MCAsmInfo.h:652
bool getCOMMDirectiveAlignmentIsInBytes() const
Definition: MCAsmInfo.h:740
bool hasPairedDoubleQuoteStringConstants() const
Definition: MCAsmInfo.h:751
bool needsDwarfSectionSizeInHeader() const
Definition: MCAsmInfo.h:829
const char * getGlobalDirective() const
Definition: MCAsmInfo.h:732
const char * getCode32Directive() const
Definition: MCAsmInfo.h:687
unsigned getCommentColumn() const
This indicates the column (zero-based) at which asm comments should be printed.
Definition: MCAsmInfo.h:656
const char * getCode64Directive() const
Definition: MCAsmInfo.h:688
bool hasSingleParameterDotFile() const
Definition: MCAsmInfo.h:756
bool doesZeroDirectiveSupportNonZeroValue() const
Definition: MCAsmInfo.h:720
const char * getAsciiDirective() const
Definition: MCAsmInfo.h:723
AsmCharLiteralSyntax
Assembly character literal syntax types.
Definition: MCAsmInfo.h:59
@ ACLS_SingleQuotePrefix
Unknown; character literals not used by LLVM for this target.
Definition: MCAsmInfo.h:62
bool useDotAlignForAlignment() const
Definition: MCAsmInfo.h:710
const char * getGPRel32Directive() const
Definition: MCAsmInfo.h:577
const char * getWeakRefDirective() const
Definition: MCAsmInfo.h:762
const char * getDTPRel32Directive() const
Definition: MCAsmInfo.h:579
bool hasNoDeadStrip() const
Definition: MCAsmInfo.h:759
bool usesDwarfFileAndLocDirectives() const
Definition: MCAsmInfo.h:825
bool hasIdentDirective() const
Definition: MCAsmInfo.h:758
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition: MCAsmInfo.h:553
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:613
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
Context object for machine code objects.
Definition: MCContext.h:76
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:450
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:321
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:446
dwarf::DwarfFormat getDwarfFormat() const
Definition: MCContext.h:828
static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
Definition: MCDwarf.cpp:668
static void make(MCStreamer *MCOS, MCSection *Section)
Definition: MCDwarf.cpp:94
static void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)
Definition: MCDwarf.cpp:259
Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
Definition: MCDwarf.cpp:569
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles() const
Definition: MCDwarf.h:418
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
static void Emit(MCStreamer *MCOS)
Definition: MCDwarf.cpp:1137
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:45
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCRegisterInfo *RegInfo=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
Definition: MCInst.cpp:81
MCSection * getTextSection() const
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
This represents a section on a Mach-O system (used by Mac OS X).
StringRef getSegmentName() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
MCSymbol * getEndSymbol(MCContext &Ctx)
Definition: MCSection.cpp:29
StringRef getName() const
Definition: MCSection.h:124
bool hasEnded() const
Definition: MCSection.cpp:35
Streaming machine code generation interface.
Definition: MCStreamer.h:212
virtual void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc={})
Definition: MCStreamer.cpp:638
virtual void emitAddrsig()
Definition: MCStreamer.h:1102
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
virtual void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc={})
Definition: MCStreamer.cpp:496
virtual void addBlankLine()
Emit a blank line to a .s file to pretty it up.
Definition: MCStreamer.h:380
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel)
Emit the debug line end entry.
Definition: MCStreamer.h:1156
virtual bool emitCVFuncIdDirective(unsigned FunctionId)
Introduces a function id for use with .cv_loc.
Definition: MCStreamer.cpp:302
virtual void finishImpl()
Streamer specific finalization.
virtual void emitDTPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (64-bit DTP relative) value.
Definition: MCStreamer.cpp:195
virtual void emitCFIBKeyFrame()
Definition: MCStreamer.cpp:249
virtual void beginCOFFSymbolDef(const MCSymbol *Symbol)
Start emitting COFF symbol definition.
virtual void emitSyntaxDirective()
Definition: MCStreamer.cpp:866
virtual void emitWinCFIPushReg(MCRegister Register, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:872
virtual void emitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
virtual StringRef getMnemonic(MCInst &MI)
Returns the mnemonic for MI, if the streamer has access to a instruction printer and returns an empty...
Definition: MCStreamer.h:479
virtual void emitGNUAttribute(unsigned Tag, unsigned Value)
Emit a .gnu_attribute directive.
Definition: MCStreamer.h:674
virtual raw_ostream & getCommentOS()
Return a raw_ostream that comments can be written to.
Definition: MCStreamer.cpp:111
virtual void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:791
virtual void emitBundleLock(bool AlignToEnd)
The following instructions are a bundle-locked group.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitGPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a gprel64 (64-bit GP relative) value.
Definition: MCStreamer.cpp:211
virtual void emitCFISameValue(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:608
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
virtual bool emitCVFileDirective(unsigned FileNo, StringRef Filename, ArrayRef< uint8_t > Checksum, unsigned ChecksumKind)
Associate a filename with a specified logical file number, and also specify that file's checksum info...
Definition: MCStreamer.cpp:295
virtual void emitCFIReturnColumn(int64_t Register)
Definition: MCStreamer.cpp:695
virtual void emitCOFFSymbolType(int Type)
Emit the type of the symbol.
virtual void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding)
Definition: MCStreamer.cpp:570
virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)
Emit a unit length field.
virtual void emitCFIWindowSave(SMLoc Loc={})
Definition: MCStreamer.cpp:676
virtual void emitCOFFSymbolIndex(MCSymbol const *Symbol)
Emits the symbol table index of a Symbol into the current section.
Definition: MCStreamer.cpp:981
virtual void emitCVStringTableDirective()
This implements the CodeView '.cv_stringtable' assembler directive.
Definition: MCStreamer.h:1008
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
Definition: MCStreamer.h:340
virtual void emitIntValueInHex(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers & p...
Definition: MCStreamer.h:748
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.
Definition: MCStreamer.cpp:263
virtual bool isVerboseAsm() const
Return true if this streamer supports verbose assembly and if it is enabled.
Definition: MCStreamer.h:336
virtual void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset)
Emits a COFF image relative relocation.
Definition: MCStreamer.cpp:987
virtual void endCOFFSymbolDef()
Marks the end of the symbol definition.
virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:955
virtual void emitWinEHHandlerData(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:808
virtual void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment)=0
Emit a common symbol.
virtual MCAssembler * getAssemblerPtr()
Definition: MCStreamer.h:299
virtual void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility)
Emit a symbol's linkage and visibility with a linkage directive for XCOFF.
virtual void emitCFIUndefined(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:655
virtual void emitWinCFISaveXMM(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:940
virtual void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame)
Definition: MCStreamer.cpp:473
virtual void emitCVFileChecksumOffsetDirective(unsigned FileNo)
This implements the CodeView '.cv_filechecksumoffset' assembler directive.
Definition: MCStreamer.h:1015
virtual void emitCFINegateRAState(SMLoc Loc={})
Definition: MCStreamer.cpp:685
virtual void emitGPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a gprel32 (32-bit GP relative) value.
Definition: MCStreamer.cpp:215
virtual void emitCFILsda(const MCSymbol *Sym, unsigned Encoding)
Definition: MCStreamer.cpp:579
virtual void emitBundleUnlock()
Ends a bundle-locked group.
virtual Expected< unsigned > tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, std::optional< MD5::MD5Result > Checksum=std::nullopt, std::optional< StringRef > Source=std::nullopt, unsigned CUID=0)
Associate a filename with a specified logical file number.
Definition: MCStreamer.cpp:232
virtual void addExplicitComment(const Twine &T)
Add explicit comment T.
Definition: MCStreamer.cpp:123
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:359
virtual void emitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc={})
This implements the CodeView '.cv_fpo_data' assembler directive.
Definition: MCStreamer.h:1018
virtual void emitELFSize(MCSymbol *Symbol, const MCExpr *Value)
Emit an ELF .size directive.
virtual void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size, MCSymbol *CsectSym, Align Alignment)
Emits an lcomm directive with XCOFF csect information.
virtual void emitCFIMTETaggedFrame()
Definition: MCStreamer.cpp:256
virtual void emitTPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a tprel (32-bit TP relative) value.
Definition: MCStreamer.cpp:207
virtual void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
Definition: MCStreamer.cpp:985
virtual void doFinalizationAtSectionEnd(MCSection *Section)
Do finalization for the streamer at the end of a section.
Definition: MCStreamer.h:1167
virtual void emitRawComment(const Twine &T, bool TabPrefix=true)
Print T and prefix it with the comment string (normally #) and optionally a tab.
Definition: MCStreamer.cpp:121
virtual std::optional< std::pair< bool, std::string > > emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI)
Record a relocation described by the .reloc directive.
Definition: MCStreamer.h:1097
virtual void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:717
virtual void emitIdent(StringRef IdentString)
Emit the "identifiers" directive.
Definition: MCStreamer.h:911
virtual void emitCVFileChecksumsDirective()
This implements the CodeView '.cv_filechecksums' assembler directive.
Definition: MCStreamer.h:1011
virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)
Emit the debug line start label.
virtual void emitCFIEscape(StringRef Values, SMLoc Loc={})
Definition: MCStreamer.cpp:628
virtual void emitXCOFFExceptDirective(const MCSymbol *Symbol, const MCSymbol *Trap, unsigned Lang, unsigned Reason, unsigned FunctionSize, bool hasDebug)
Emit an XCOFF .except directive which adds information about a trap instruction to the object file ex...
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:424
virtual void emitCOFFSectionIndex(MCSymbol const *Symbol)
Emits a COFF section index.
Definition: MCStreamer.cpp:983
void setAllowAutoPadding(bool v)
Definition: MCStreamer.h:308
virtual void emitCFIRememberState(SMLoc Loc)
Definition: MCStreamer.cpp:587
virtual void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart, const MCSymbol *FnEnd)
This implements the CodeView '.cv_linetable' assembler directive.
Definition: MCStreamer.cpp:347
virtual void emitTPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a tprel (64-bit TP relative) value.
Definition: MCStreamer.cpp:203
virtual void emitCFISections(bool EH, bool Debug)
Definition: MCStreamer.cpp:446
virtual void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers & p...
Definition: MCStreamer.h:760
virtual void emitAssemblerFlag(MCAssemblerFlag Flag)
Note in the output the specified Flag.
virtual void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Definition: MCStreamer.h:516
virtual void emitValueToAlignment(Align Alignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Definition: MCStreamer.cpp:134
virtual void emitWinCFISaveReg(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:923
virtual void emitWinCFIEndChained(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:777
virtual void emitWinCFIEndProlog(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:969
virtual void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize)
If targets does not support representing debug line section by .loc/.file directives in assembly outp...
Definition: MCStreamer.h:1161
virtual void emitWinCFIEndProc(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:735
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
virtual void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame)
Definition: MCStreamer.cpp:484
virtual void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue)
Set the DescValue for the Symbol.
virtual void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:527
virtual void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment)
Emit a local common (.lcomm) symbol.
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
Definition: MCStreamer.cpp:271
virtual void emitCFIRegister(int64_t Register1, int64_t Register2, SMLoc Loc={})
Definition: MCStreamer.cpp:665
virtual void emitCOFFSafeSEH(MCSymbol const *Symbol)
Definition: MCStreamer.cpp:979
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...
Definition: MCStreamer.cpp:753
virtual void changeSection(MCSection *, const MCExpr *)
Update streamer for a new active section.
virtual void emitXCOFFRenameDirective(const MCSymbol *Name, StringRef Rename)
Emit a XCOFF .rename directive which creates a synonym for an illegal or undesirable name.
virtual void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, uint64_t Discriminator, const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym)
Emit the a pseudo probe into the current section.
virtual void emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count)
Definition: MCStreamer.cpp:816
virtual void emitDataRegion(MCDataRegionType Kind)
Note in the output the specified region Kind.
Definition: MCStreamer.h:503
virtual void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc={})
Definition: MCStreamer.cpp:517
virtual void emitULEB128Value(const MCExpr *Value)
virtual void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc)
Definition: MCStreamer.cpp:560
virtual void emitLinkerOptions(ArrayRef< std::string > Kind)
Emit the given list Options of strings as linker options into the output.
Definition: MCStreamer.h:500
virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value, SMLoc Loc)
Emit some number of copies of Value until the byte offset Offset is reached.
virtual void emitExplicitComments()
Emit added explicit comments.
Definition: MCStreamer.cpp:124
virtual void emitThumbFunc(MCSymbol *Func)
Note in the output that the specified Func is a Thumb mode function (ARM target only).
virtual void emitCFIRestoreState(SMLoc Loc)
Definition: MCStreamer.cpp:597
virtual void emitXCOFFRefDirective(const MCSymbol *Symbol)
Emit a XCOFF .ref directive which creates R_REF type entry in the relocation table for one or more sy...
virtual void emitCVDefRangeDirective(ArrayRef< std::pair< const MCSymbol *, const MCSymbol * > > Ranges, StringRef FixedSizePortion)
This implements the CodeView '.cv_def_range' assembler directive.
Definition: MCStreamer.cpp:369
virtual void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc={})
Definition: MCStreamer.cpp:550
virtual void emitWinCFISetFrame(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:884
virtual void emitDTPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (32-bit DTP relative) value.
Definition: MCStreamer.cpp:199
virtual void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc={})
Definition: MCStreamer.cpp:507
virtual void emitZerofill(MCSection *Section, MCSymbol *Symbol=nullptr, uint64_t Size=0, Align ByteAlignment=Align(1), SMLoc Loc=SMLoc())=0
Emit the zerofill section and an optional symbol.
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.
Definition: MCStreamer.cpp:320
virtual void emitWinCFIAllocStack(unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:906
virtual void emitFileDirective(StringRef Filename)
Switch to a new logical file.
virtual void emitSLEB128Value(const MCExpr *Value)
virtual void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name, bool KeepOriginalSym)
Emit an ELF .symver directive.
virtual void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata)
Emit a C_INFO symbol with XCOFF embedded metadata to the .info section.
virtual void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Emit the expression Value into the output as a native integer of the given Size bytes.
virtual void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args)
Emit a Linker Optimization Hint (LOH) directive.
Definition: MCStreamer.h:671
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.
Definition: MCStreamer.cpp:306
virtual void emitCFISignalFrame()
Definition: MCStreamer.cpp:648
virtual void emitVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Specify the Mach-O minimum deployment target version.
Definition: MCStreamer.h:506
virtual void emitCOFFSymbolStorageClass(int StorageClass)
Emit the storage class of the symbol.
virtual void emitConditionalAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol, but only if Value is also emitted.
Definition: MCStreamer.cpp:443
virtual void emitWinCFIStartChained(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:764
virtual void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, Align ByteAlignment=Align(1))
Emit a thread local bss (.tbss) symbol.
virtual void emitCFIRestore(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:618
virtual void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
This implements the CodeView '.cv_inline_linetable' assembler directive.
Definition: MCStreamer.cpp:351
void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
Definition: MCStreamer.cpp:221
virtual void emitBundleAlignMode(Align Alignment)
Set the bundle alignment mode from now on in the section.
virtual void emitRawTextImpl(StringRef String)
EmitRawText - If this file is backed by an assembly streamer, this dumps the specified string in the ...
Definition: MCStreamer.cpp:992
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
virtual void emitAddrsigSym(const MCSymbol *Sym)
Definition: MCStreamer.h:1103
virtual void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol)
Emit an weak reference from Alias to Symbol.
virtual void emitDwarfFile0Directive(StringRef Directory, StringRef Filename, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, unsigned CUID=0)
Specify the "root" file of the compilation, using the ".file 0" extension.
Definition: MCStreamer.cpp:240
virtual void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Emit/Specify Mach-O build version command.
Definition: MCStreamer.h:512
virtual void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset, int64_t AddressSpace, SMLoc Loc={})
Definition: MCStreamer.cpp:538
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:402
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:389
StringRef getSymbolTableName() const
Definition: MCSymbolXCOFF.h:59
bool hasRename() const
Definition: MCSymbolXCOFF.h:55
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:269
Target specific streamer interface.
Definition: MCStreamer.h:93
Root of the metadata hierarchy.
Definition: Metadata.h:62
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Represents a location in source code.
Definition: SMLoc.h:23
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:68
bool empty() const
Definition: SmallVector.h:94
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
void resize(size_type N)
Definition: SmallVector.h:642
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:575
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
char back() const
back - Get the last character in the string.
Definition: StringRef.h:146
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:688
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
char front() const
front - Get the first character in the string.
Definition: StringRef.h:140
bool startswith(StringRef Prefix) const
Definition: StringRef.h:261
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.
Definition: StringRef.h:381
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:164
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:301
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:4832
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:29
unsigned getMajor() const
Retrieve the major version number.
Definition: VersionTuple.h:71
std::optional< unsigned > getSubminor() const
Retrieve the subminor version number, if provided.
Definition: VersionTuple.h:81
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
Definition: VersionTuple.h:66
std::optional< unsigned > getMinor() const
Retrieve the minor version number, if provided.
Definition: VersionTuple.h:74
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
A raw_ostream that discards all output.
Definition: raw_ostream.h:705
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
size_t GetNumBytesInBuffer() const
Definition: raw_ostream.h:177
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:672
This class represents a function that is read from a sample profile.
Definition: FunctionId.h:36
#define INT64_MAX
Definition: DataTypes.h:71
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ ByteAlignment
Definition: MCAsmInfo.h:50
@ Log2Alignment
Definition: MCAsmInfo.h:50
PlatformType
Definition: MachO.h:500
StorageClass
Definition: XCOFF.h:169
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
Definition: Dwarf.h:769
support::ulittle32_t Word
Definition: IRSymtab.h:52
@ ChecksumKind
Definition: LLToken.h:478
int getDwarfVersion()
@ Emitted
Assigned address, still materializing.
NodeAddr< FuncNode * > Func
Definition: RDFGraph.h:393
NodeAddr< CodeNode * > Code
Definition: RDFGraph.h:388
uint32_t read32be(const void *P)
Definition: Endian.h:418
bool isPrint(int c)
Definition: Locale.cpp:13
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:673
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:458
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp:456
@ Length
Definition: DWP.cpp:456
AddressSpace
Definition: NVPTXBaseInfo.h:21
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static StringRef MCLOHDirectiveName()
MCDataRegionType
Definition: MCDirectives.h:61
@ MCDR_DataRegionEnd
.end_data_region
Definition: MCDirectives.h:66
@ MCDR_DataRegion
.data_region
Definition: MCDirectives.h:62
@ MCDR_DataRegionJT8
.data_region jt8
Definition: MCDirectives.h:63
@ MCDR_DataRegionJT32
.data_region jt32
Definition: MCDirectives.h:65
@ MCDR_DataRegionJT16
.data_region jt16
Definition: MCDirectives.h:64
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:313
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:264
MCVersionMinType
Definition: MCDirectives.h:69
@ MCVM_WatchOSVersionMin
.watchos_version_min
Definition: MCDirectives.h:73
@ MCVM_OSXVersionMin
.macosx_version_min
Definition: MCDirectives.h:71
@ MCVM_TvOSVersionMin
.tvos_version_min
Definition: MCDirectives.h:72
@ MCVM_IOSVersionMin
.ios_version_min
Definition: MCDirectives.h:70
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition: Format.h:187
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:125
static int MCLOHIdToNbArgs(MCLOHType Kind)
MCAssemblerFlag
Definition: MCDirectives.h:53
@ MCAF_SyntaxUnified
.syntax (ARM/ELF)
Definition: MCDirectives.h:54
@ MCAF_Code64
.code64 (X86)
Definition: MCDirectives.h:58
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:56
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:57
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:55
MCLOHType
Linker Optimization Hint Type.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *InstPrint, std::unique_ptr< MCCodeEmitter > &&CE, std::unique_ptr< MCAsmBackend > &&TAB, bool ShowInst)
Create a machine code streamer which will print out assembly for the native target,...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1853
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition: Alignment.h:208
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition: bit.h:327
MCSymbolAttr
Definition: MCDirectives.h:18
@ MCSA_Local
.local (ELF)
Definition: MCDirectives.h:38
@ MCSA_WeakDefAutoPrivate
.weak_def_can_be_hidden (MachO)
Definition: MCDirectives.h:48
@ MCSA_Memtag
.memtag (ELF)
Definition: MCDirectives.h:50
@ MCSA_Protected
.protected (ELF)
Definition: MCDirectives.h:43
@ MCSA_Exported
.globl _foo, exported (XCOFF)
Definition: MCDirectives.h:34
@ MCSA_PrivateExtern
.private_extern (MachO)
Definition: MCDirectives.h:42
@ MCSA_Internal
.internal (ELF)
Definition: MCDirectives.h:36
@ MCSA_WeakReference
.weak_reference (MachO)
Definition: MCDirectives.h:47
@ MCSA_AltEntry
.alt_entry (MachO)
Definition: MCDirectives.h:41
@ MCSA_ELF_TypeIndFunction
.type _foo, STT_GNU_IFUNC
Definition: MCDirectives.h:24
@ MCSA_LazyReference
.lazy_reference (MachO)
Definition: MCDirectives.h:37
@ MCSA_ELF_TypeNoType
.type _foo, STT_NOTYPE # aka @notype
Definition: MCDirectives.h:28
@ MCSA_Reference
.reference (MachO)
Definition: MCDirectives.h:44
@ MCSA_SymbolResolver
.symbol_resolver (MachO)
Definition: MCDirectives.h:40
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
@ MCSA_ELF_TypeTLS
.type _foo, STT_TLS # aka @tls_object
Definition: MCDirectives.h:26
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
Definition: MCDirectives.h:35
@ MCSA_WeakDefinition
.weak_definition (MachO)
Definition: MCDirectives.h:46
@ MCSA_ELF_TypeCommon
.type _foo, STT_COMMON # aka @common
Definition: MCDirectives.h:27
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
Definition: MCDirectives.h:49
@ MCSA_Extern
.extern (XCOFF)
Definition: MCDirectives.h:32
@ MCSA_Cold
.cold (MachO)
Definition: MCDirectives.h:22
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
Definition: MCDirectives.h:25
@ MCSA_ELF_TypeGnuUniqueObject
Definition: MCDirectives.h:29
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
@ MCSA_Hidden
.hidden (ELF)
Definition: MCDirectives.h:33
@ MCSA_LGlobal
.lglobl (XCOFF)
Definition: MCDirectives.h:31
@ MCSA_Invalid
Not a valid directive.
Definition: MCDirectives.h:19
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
Definition: MCDirectives.h:39
static StringRef MCLOHIdToName(MCLOHType Kind)
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Target independent information on a fixup kind.
const MCSymbol * Function
Definition: MCWinEH.h:44