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