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