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, uint64_t Discriminator,
381 const MCPseudoProbeInlineStack &InlineStack,
382 MCSymbol *FnSym) override;
383
384 void emitBundleAlignMode(Align Alignment) override;
385 void emitBundleLock(bool AlignToEnd) override;
386 void emitBundleUnlock() override;
387
388 std::optional<std::pair<bool, std::string>>
390 SMLoc Loc, const MCSubtargetInfo &STI) override;
391
392 void emitAddrsig() override;
393 void emitAddrsigSym(const MCSymbol *Sym) override;
394
395 /// If this file is backed by an assembly streamer, this dumps the specified
396 /// string in the output .s file. This capability is indicated by the
397 /// hasRawTextSupport() predicate.
398 void emitRawTextImpl(StringRef String) override;
399
400 void finishImpl() override;
401
402 void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) override;
403
404 MCSymbol *emitDwarfUnitLength(const Twine &Prefix,
405 const Twine &Comment) override;
406
407 void emitDwarfLineStartLabel(MCSymbol *StartSym) override;
408
409 void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
410
411 void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
412 const MCSymbol *Label,
413 unsigned PointerSize) override;
414
415 void doFinalizationAtSectionEnd(MCSection *Section) override;
416};
417
418} // end anonymous namespace.
419
420void MCAsmStreamer::AddComment(const Twine &T, bool EOL) {
421 if (!IsVerboseAsm) return;
422
423 T.toVector(CommentToEmit);
424
425 if (EOL)
426 CommentToEmit.push_back('\n'); // Place comment in a new line.
427}
428
429void MCAsmStreamer::EmitCommentsAndEOL() {
430 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
431 OS << '\n';
432 return;
433 }
434
435 StringRef Comments = CommentToEmit;
436
437 assert(Comments.back() == '\n' &&
438 "Comment array not newline terminated");
439 do {
440 // Emit a line of comments.
441 OS.PadToColumn(MAI->getCommentColumn());
442 size_t Position = Comments.find('\n');
443 OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
444
445 Comments = Comments.substr(Position+1);
446 } while (!Comments.empty());
447
448 CommentToEmit.clear();
449}
450
451static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
452 assert(Bytes > 0 && Bytes <= 8 && "Invalid size!");
453 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
454}
455
456void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
457 if (TabPrefix)
458 OS << '\t';
459 OS << MAI->getCommentString() << T;
460 EmitEOL();
461}
462
463void MCAsmStreamer::addExplicitComment(const Twine &T) {
464 StringRef c = T.getSingleStringRef();
465 if (c.equals(StringRef(MAI->getSeparatorString())))
466 return;
467 if (c.startswith(StringRef("//"))) {
468 ExplicitCommentToEmit.append("\t");
469 ExplicitCommentToEmit.append(MAI->getCommentString());
470 // drop //
471 ExplicitCommentToEmit.append(c.slice(2, c.size()).str());
472 } else if (c.startswith(StringRef("/*"))) {
473 size_t p = 2, len = c.size() - 2;
474 // emit each line in comment as separate newline.
475 do {
476 size_t newp = std::min(len, c.find_first_of("\r\n", p));
477 ExplicitCommentToEmit.append("\t");
478 ExplicitCommentToEmit.append(MAI->getCommentString());
479 ExplicitCommentToEmit.append(c.slice(p, newp).str());
480 // If we have another line in this comment add line
481 if (newp < len)
482 ExplicitCommentToEmit.append("\n");
483 p = newp + 1;
484 } while (p < len);
485 } else if (c.startswith(StringRef(MAI->getCommentString()))) {
486 ExplicitCommentToEmit.append("\t");
487 ExplicitCommentToEmit.append(c.str());
488 } else if (c.front() == '#') {
489
490 ExplicitCommentToEmit.append("\t");
491 ExplicitCommentToEmit.append(MAI->getCommentString());
492 ExplicitCommentToEmit.append(c.slice(1, c.size()).str());
493 } else
494 assert(false && "Unexpected Assembly Comment");
495 // full line comments immediately output
496 if (c.back() == '\n')
497 emitExplicitComments();
498}
499
500void MCAsmStreamer::emitExplicitComments() {
501 StringRef Comments = ExplicitCommentToEmit;
502 if (!Comments.empty())
503 OS << Comments;
504 ExplicitCommentToEmit.clear();
505}
506
507void MCAsmStreamer::changeSection(MCSection *Section,
508 const MCExpr *Subsection) {
509 assert(Section && "Cannot switch to a null section!");
510 if (MCTargetStreamer *TS = getTargetStreamer()) {
511 TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS);
512 } else {
513 Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
514 Subsection);
515 }
516}
517
518void MCAsmStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
520 bool KeepOriginalSym) {
521 OS << ".symver ";
522 OriginalSym->print(OS, MAI);
523 OS << ", " << Name;
524 if (!KeepOriginalSym && !Name.contains("@@@"))
525 OS << ", remove";
526 EmitEOL();
527}
528
529void MCAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
530 MCStreamer::emitLabel(Symbol, Loc);
531
532 Symbol->print(OS, MAI);
533 OS << MAI->getLabelSuffix();
534
535 EmitEOL();
536}
537
538void MCAsmStreamer::emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
539 StringRef str = MCLOHIdToName(Kind);
540
541#ifndef NDEBUG
542 int NbArgs = MCLOHIdToNbArgs(Kind);
543 assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
544 assert(str != "" && "Invalid LOH name");
545#endif
546
547 OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
548 bool IsFirst = true;
549 for (const MCSymbol *Arg : Args) {
550 if (!IsFirst)
551 OS << ", ";
552 IsFirst = false;
553 Arg->print(OS, MAI);
554 }
555 EmitEOL();
556}
557
558void MCAsmStreamer::emitGNUAttribute(unsigned Tag, unsigned Value) {
559 OS << "\t.gnu_attribute " << Tag << ", " << Value << "\n";
560}
561
562void MCAsmStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
563 switch (Flag) {
564 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
565 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
566 case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break;
567 case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break;
568 case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break;
569 }
570 EmitEOL();
571}
572
573void MCAsmStreamer::emitLinkerOptions(ArrayRef<std::string> Options) {
574 assert(!Options.empty() && "At least one option is required!");
575 OS << "\t.linker_option \"" << Options[0] << '"';
576 for (const std::string &Opt : llvm::drop_begin(Options))
577 OS << ", " << '"' << Opt << '"';
578 EmitEOL();
579}
580
581void MCAsmStreamer::emitDataRegion(MCDataRegionType Kind) {
583 return;
584 switch (Kind) {
585 case MCDR_DataRegion: OS << "\t.data_region"; break;
586 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
587 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
588 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
589 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
590 }
591 EmitEOL();
592}
593
595 switch (Type) {
596 case MCVM_WatchOSVersionMin: return ".watchos_version_min";
597 case MCVM_TvOSVersionMin: return ".tvos_version_min";
598 case MCVM_IOSVersionMin: return ".ios_version_min";
599 case MCVM_OSXVersionMin: return ".macosx_version_min";
600 }
601 llvm_unreachable("Invalid MC version min type");
602}
603
605 const VersionTuple &SDKVersion) {
606 if (SDKVersion.empty())
607 return;
608 OS << '\t' << "sdk_version " << SDKVersion.getMajor();
609 if (auto Minor = SDKVersion.getMinor()) {
610 OS << ", " << *Minor;
611 if (auto Subminor = SDKVersion.getSubminor()) {
612 OS << ", " << *Subminor;
613 }
614 }
615}
616
617void MCAsmStreamer::emitVersionMin(MCVersionMinType Type, unsigned Major,
618 unsigned Minor, unsigned Update,
619 VersionTuple SDKVersion) {
620 OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
621 if (Update)
622 OS << ", " << Update;
623 EmitSDKVersionSuffix(OS, SDKVersion);
624 EmitEOL();
625}
626
628 switch (Type) {
629 case MachO::PLATFORM_UNKNOWN: /* silence warning*/
630 break;
631 case MachO::PLATFORM_MACOS: return "macos";
632 case MachO::PLATFORM_IOS: return "ios";
633 case MachO::PLATFORM_TVOS: return "tvos";
634 case MachO::PLATFORM_WATCHOS: return "watchos";
635 case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
636 case MachO::PLATFORM_MACCATALYST: return "macCatalyst";
637 case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator";
638 case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator";
639 case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator";
640 case MachO::PLATFORM_DRIVERKIT: return "driverkit";
641 }
642 llvm_unreachable("Invalid Mach-O platform type");
643}
644
645void MCAsmStreamer::emitBuildVersion(unsigned Platform, unsigned Major,
646 unsigned Minor, unsigned Update,
647 VersionTuple SDKVersion) {
648 const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
649 OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
650 if (Update)
651 OS << ", " << Update;
652 EmitSDKVersionSuffix(OS, SDKVersion);
653 EmitEOL();
654}
655
656void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(
657 unsigned Platform, unsigned Major, unsigned Minor, unsigned Update,
658 VersionTuple SDKVersion) {
659 emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
660}
661
662void MCAsmStreamer::emitThumbFunc(MCSymbol *Func) {
663 // This needs to emit to a temporary string to get properly quoted
664 // MCSymbols when they have spaces in them.
665 OS << "\t.thumb_func";
666 // Only Mach-O hasSubsectionsViaSymbols()
667 if (MAI->hasSubsectionsViaSymbols()) {
668 OS << '\t';
669 Func->print(OS, MAI);
670 }
671 EmitEOL();
672}
673
674void MCAsmStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
675 // Do not emit a .set on inlined target assignments.
676 bool EmitSet = true;
677 if (auto *E = dyn_cast<MCTargetExpr>(Value))
678 if (E->inlineAssignedExpr())
679 EmitSet = false;
680 if (EmitSet) {
681 OS << ".set ";
682 Symbol->print(OS, MAI);
683 OS << ", ";
684 Value->print(OS, MAI);
685
686 EmitEOL();
687 }
688
690}
691
692void MCAsmStreamer::emitConditionalAssignment(MCSymbol *Symbol,
693 const MCExpr *Value) {
694 OS << ".lto_set_conditional ";
695 Symbol->print(OS, MAI);
696 OS << ", ";
697 Value->print(OS, MAI);
698 EmitEOL();
699}
700
701void MCAsmStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
702 OS << ".weakref ";
703 Alias->print(OS, MAI);
704 OS << ", ";
705 Symbol->print(OS, MAI);
706 EmitEOL();
707}
708
709bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
711 switch (Attribute) {
712 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
713 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
714 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
715 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
716 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
717 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
718 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
719 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
720 if (!MAI->hasDotTypeDotSizeDirective())
721 return false; // Symbol attribute not supported
722 OS << "\t.type\t";
723 Symbol->print(OS, MAI);
724 OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%');
725 switch (Attribute) {
726 default: return false;
727 case MCSA_ELF_TypeFunction: OS << "function"; break;
728 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
729 case MCSA_ELF_TypeObject: OS << "object"; break;
730 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
731 case MCSA_ELF_TypeCommon: OS << "common"; break;
732 case MCSA_ELF_TypeNoType: OS << "notype"; break;
733 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
734 }
735 EmitEOL();
736 return true;
737 case MCSA_Global: // .globl/.global
738 OS << MAI->getGlobalDirective();
739 break;
740 case MCSA_LGlobal: OS << "\t.lglobl\t"; break;
741 case MCSA_Hidden: OS << "\t.hidden\t"; break;
742 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
743 case MCSA_Internal: OS << "\t.internal\t"; break;
744 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
745 case MCSA_Local: OS << "\t.local\t"; break;
746 case MCSA_NoDeadStrip:
747 if (!MAI->hasNoDeadStrip())
748 return false;
749 OS << "\t.no_dead_strip\t";
750 break;
751 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
752 case MCSA_AltEntry: OS << "\t.alt_entry\t"; break;
754 OS << "\t.private_extern\t";
755 break;
756 case MCSA_Protected: OS << "\t.protected\t"; break;
757 case MCSA_Reference: OS << "\t.reference\t"; break;
758 case MCSA_Extern:
759 OS << "\t.extern\t";
760 break;
761 case MCSA_Weak: OS << MAI->getWeakDirective(); break;
763 OS << "\t.weak_definition\t";
764 break;
765 // .weak_reference
766 case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
767 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
768 case MCSA_Cold:
769 // Assemblers currently do not support a .cold directive.
770 case MCSA_Exported:
771 // Non-AIX assemblers currently do not support exported visibility.
772 return false;
773 case MCSA_Memtag:
774 OS << "\t.memtag\t";
775 break;
776 }
777
778 Symbol->print(OS, MAI);
779 EmitEOL();
780
781 return true;
782}
783
784void MCAsmStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
785 OS << ".desc" << ' ';
786 Symbol->print(OS, MAI);
787 OS << ',' << DescValue;
788 EmitEOL();
789}
790
791void MCAsmStreamer::emitSyntaxDirective() {
792 if (MAI->getAssemblerDialect() == 1) {
793 OS << "\t.intel_syntax noprefix";
794 EmitEOL();
795 }
796 // FIXME: Currently emit unprefix'ed registers.
797 // The intel_syntax directive has one optional argument
798 // with may have a value of prefix or noprefix.
799}
800
801void MCAsmStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {
802 OS << "\t.def\t";
803 Symbol->print(OS, MAI);
804 OS << ';';
805 EmitEOL();
806}
807
808void MCAsmStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
809 OS << "\t.scl\t" << StorageClass << ';';
810 EmitEOL();
811}
812
813void MCAsmStreamer::emitCOFFSymbolType(int Type) {
814 OS << "\t.type\t" << Type << ';';
815 EmitEOL();
816}
817
818void MCAsmStreamer::endCOFFSymbolDef() {
819 OS << "\t.endef";
820 EmitEOL();
821}
822
823void MCAsmStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {
824 OS << "\t.safeseh\t";
825 Symbol->print(OS, MAI);
826 EmitEOL();
827}
828
829void MCAsmStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
830 OS << "\t.symidx\t";
831 Symbol->print(OS, MAI);
832 EmitEOL();
833}
834
835void MCAsmStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {
836 OS << "\t.secidx\t";
837 Symbol->print(OS, MAI);
838 EmitEOL();
839}
840
841void MCAsmStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {
842 OS << "\t.secrel32\t";
843 Symbol->print(OS, MAI);
844 if (Offset != 0)
845 OS << '+' << Offset;
846 EmitEOL();
847}
848
849void MCAsmStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
850 OS << "\t.rva\t";
851 Symbol->print(OS, MAI);
852 if (Offset > 0)
853 OS << '+' << Offset;
854 else if (Offset < 0)
855 OS << '-' << -Offset;
856 EmitEOL();
857}
858
859// We need an XCOFF-specific version of this directive as the AIX syntax
860// requires a QualName argument identifying the csect name and storage mapping
861// class to appear before the alignment if we are specifying it.
862void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,
864 MCSymbol *CsectSym,
865 Align Alignment) {
867 "We only support writing log base-2 alignment format with XCOFF.");
868
869 OS << "\t.lcomm\t";
870 LabelSym->print(OS, MAI);
871 OS << ',' << Size << ',';
872 CsectSym->print(OS, MAI);
873 OS << ',' << Log2(Alignment);
874
875 EmitEOL();
876
877 // Print symbol's rename (original name contains invalid character(s)) if
878 // there is one.
879 MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(CsectSym);
880 if (XSym->hasRename())
881 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
882}
883
884void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
885 MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) {
886
887 switch (Linkage) {
888 case MCSA_Global:
889 OS << MAI->getGlobalDirective();
890 break;
891 case MCSA_Weak:
892 OS << MAI->getWeakDirective();
893 break;
894 case MCSA_Extern:
895 OS << "\t.extern\t";
896 break;
897 case MCSA_LGlobal:
898 OS << "\t.lglobl\t";
899 break;
900 default:
901 report_fatal_error("unhandled linkage type");
902 }
903
904 Symbol->print(OS, MAI);
905
906 switch (Visibility) {
907 case MCSA_Invalid:
908 // Nothing to do.
909 break;
910 case MCSA_Hidden:
911 OS << ",hidden";
912 break;
913 case MCSA_Protected:
914 OS << ",protected";
915 break;
916 case MCSA_Exported:
917 OS << ",exported";
918 break;
919 default:
920 report_fatal_error("unexpected value for Visibility type");
921 }
922 EmitEOL();
923
924 // Print symbol's rename (original name contains invalid character(s)) if
925 // there is one.
926 if (cast<MCSymbolXCOFF>(Symbol)->hasRename())
927 emitXCOFFRenameDirective(Symbol,
928 cast<MCSymbolXCOFF>(Symbol)->getSymbolTableName());
929}
930
931void MCAsmStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
932 StringRef Rename) {
933 OS << "\t.rename\t";
934 Name->print(OS, MAI);
935 const char DQ = '"';
936 OS << ',' << DQ;
937 for (char C : Rename) {
938 // To escape a double quote character, the character should be doubled.
939 if (C == DQ)
940 OS << DQ;
941 OS << C;
942 }
943 OS << DQ;
944 EmitEOL();
945}
946
947void MCAsmStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {
948 OS << "\t.ref ";
949 Symbol->print(OS, MAI);
950 EmitEOL();
951}
952
953void MCAsmStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
954 const MCSymbol *Trap,
955 unsigned Lang,
956 unsigned Reason,
957 unsigned FunctionSize,
958 bool hasDebug) {
959 OS << "\t.except\t";
960 Symbol->print(OS, MAI);
961 OS << ", " << Lang << ", " << Reason;
962 EmitEOL();
963}
964
965void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
967 OS << "\t.size\t";
968 Symbol->print(OS, MAI);
969 OS << ", ";
970 Value->print(OS, MAI);
971 EmitEOL();
972}
973
974void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
975 Align ByteAlignment) {
976 OS << "\t.comm\t";
977 Symbol->print(OS, MAI);
978 OS << ',' << Size;
979
981 OS << ',' << ByteAlignment.value();
982 else
983 OS << ',' << Log2(ByteAlignment);
984 EmitEOL();
985
986 // Print symbol's rename (original name contains invalid character(s)) if
987 // there is one.
988 MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(Symbol);
989 if (XSym && XSym->hasRename())
990 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
991}
992
993void MCAsmStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
994 Align ByteAlign) {
995 OS << "\t.lcomm\t";
996 Symbol->print(OS, MAI);
997 OS << ',' << Size;
998
999 if (ByteAlign > 1) {
1000 switch (MAI->getLCOMMDirectiveAlignmentType()) {
1001 case LCOMM::NoAlignment:
1002 llvm_unreachable("alignment not supported on .lcomm!");
1004 OS << ',' << ByteAlign.value();
1005 break;
1007 OS << ',' << Log2(ByteAlign);
1008 break;
1009 }
1010 }
1011 EmitEOL();
1012}
1013
1014void MCAsmStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
1015 uint64_t Size, Align ByteAlignment,
1016 SMLoc Loc) {
1017 if (Symbol)
1018 assignFragment(Symbol, &Section->getDummyFragment());
1019
1020 // Note: a .zerofill directive does not switch sections.
1021 OS << ".zerofill ";
1022
1023 assert(Section->getVariant() == MCSection::SV_MachO &&
1024 ".zerofill is a Mach-O specific directive");
1025 // This is a mach-o specific directive.
1026
1027 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
1028 OS << MOSection->getSegmentName() << "," << MOSection->getName();
1029
1030 if (Symbol) {
1031 OS << ',';
1032 Symbol->print(OS, MAI);
1033 OS << ',' << Size;
1034 OS << ',' << Log2(ByteAlignment);
1035 }
1036 EmitEOL();
1037}
1038
1039// .tbss sym, size, align
1040// This depends that the symbol has already been mangled from the original,
1041// e.g. _a.
1042void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1043 uint64_t Size, Align ByteAlignment) {
1044 assignFragment(Symbol, &Section->getDummyFragment());
1045
1046 assert(Symbol && "Symbol shouldn't be NULL!");
1047 // Instead of using the Section we'll just use the shortcut.
1048
1049 assert(Section->getVariant() == MCSection::SV_MachO &&
1050 ".zerofill is a Mach-O specific directive");
1051 // This is a mach-o specific directive and section.
1052
1053 OS << ".tbss ";
1054 Symbol->print(OS, MAI);
1055 OS << ", " << Size;
1056
1057 // Output align if we have it. We default to 1 so don't bother printing
1058 // that.
1059 if (ByteAlignment > 1)
1060 OS << ", " << Log2(ByteAlignment);
1061
1062 EmitEOL();
1063}
1064
1065static inline bool isPrintableString(StringRef Data) {
1066 const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1067 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1068 if (!isPrint(C))
1069 return false;
1070 }
1071 return isPrint(Data.back()) || Data.back() == 0;
1072}
1073
1074static inline char toOctal(int X) { return (X&7)+'0'; }
1075
1078 assert(!Data.empty() && "Cannot generate an empty list.");
1079 const auto printCharacterInOctal = [&OS](unsigned char C) {
1080 OS << '0';
1081 OS << toOctal(C >> 6);
1082 OS << toOctal(C >> 3);
1083 OS << toOctal(C >> 0);
1084 };
1085 const auto printOneCharacterFor = [printCharacterInOctal](
1086 auto printOnePrintingCharacter) {
1087 return [printCharacterInOctal, printOnePrintingCharacter](unsigned char C) {
1088 if (isPrint(C)) {
1089 printOnePrintingCharacter(static_cast<char>(C));
1090 return;
1091 }
1092 printCharacterInOctal(C);
1093 };
1094 };
1095 const auto printCharacterList = [Data, &OS](const auto &printOneCharacter) {
1096 const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1097 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1098 printOneCharacter(C);
1099 OS << ',';
1100 }
1101 printOneCharacter(*(EndPtr - 1));
1102 };
1103 switch (ACLS) {
1105 printCharacterList(printCharacterInOctal);
1106 return;
1108 printCharacterList(printOneCharacterFor([&OS](char C) {
1109 const char AsmCharLitBuf[2] = {'\'', C};
1110 OS << StringRef(AsmCharLitBuf, sizeof(AsmCharLitBuf));
1111 }));
1112 return;
1113 }
1114 llvm_unreachable("Invalid AsmCharLiteralSyntax value!");
1115}
1116
1117void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) const {
1118 OS << '"';
1119
1121 for (unsigned char C : Data) {
1122 if (C == '"')
1123 OS << "\"\"";
1124 else
1125 OS << (char)C;
1126 }
1127 } else {
1128 for (unsigned char C : Data) {
1129 if (C == '"' || C == '\\') {
1130 OS << '\\' << (char)C;
1131 continue;
1132 }
1133
1134 if (isPrint((unsigned char)C)) {
1135 OS << (char)C;
1136 continue;
1137 }
1138
1139 switch (C) {
1140 case '\b':
1141 OS << "\\b";
1142 break;
1143 case '\f':
1144 OS << "\\f";
1145 break;
1146 case '\n':
1147 OS << "\\n";
1148 break;
1149 case '\r':
1150 OS << "\\r";
1151 break;
1152 case '\t':
1153 OS << "\\t";
1154 break;
1155 default:
1156 OS << '\\';
1157 OS << toOctal(C >> 6);
1158 OS << toOctal(C >> 3);
1159 OS << toOctal(C >> 0);
1160 break;
1161 }
1162 }
1163 }
1164
1165 OS << '"';
1166}
1167
1168void MCAsmStreamer::emitBytes(StringRef Data) {
1169 assert(getCurrentSectionOnly() &&
1170 "Cannot emit contents before setting section!");
1171 if (Data.empty()) return;
1172
1173 const auto emitAsString = [this](StringRef Data) {
1174 // If the data ends with 0 and the target supports .asciz, use it, otherwise
1175 // use .ascii or a byte-list directive
1176 if (MAI->getAscizDirective() && Data.back() == 0) {
1177 OS << MAI->getAscizDirective();
1178 Data = Data.substr(0, Data.size() - 1);
1179 } else if (LLVM_LIKELY(MAI->getAsciiDirective())) {
1180 OS << MAI->getAsciiDirective();
1181 } else if (MAI->hasPairedDoubleQuoteStringConstants() &&
1183 // For target with DoubleQuoteString constants, .string and .byte are used
1184 // as replacement of .asciz and .ascii.
1186 "hasPairedDoubleQuoteStringConstants target must support "
1187 "PlainString Directive");
1189 "hasPairedDoubleQuoteStringConstants target must support ByteList "
1190 "Directive");
1191 if (Data.back() == 0) {
1192 OS << MAI->getPlainStringDirective();
1193 Data = Data.substr(0, Data.size() - 1);
1194 } else {
1195 OS << MAI->getByteListDirective();
1196 }
1197 } else if (MAI->getByteListDirective()) {
1198 OS << MAI->getByteListDirective();
1200 EmitEOL();
1201 return true;
1202 } else {
1203 return false;
1204 }
1205
1206 PrintQuotedString(Data, OS);
1207 EmitEOL();
1208 return true;
1209 };
1210
1211 if (Data.size() != 1 && emitAsString(Data))
1212 return;
1213
1214 // Only single byte is provided or no ascii, asciz, or byte-list directives
1215 // are applicable. Emit as vector of individual 8bits data elements.
1216 if (MCTargetStreamer *TS = getTargetStreamer()) {
1217 TS->emitRawBytes(Data);
1218 return;
1219 }
1220 const char *Directive = MAI->getData8bitsDirective();
1221 for (const unsigned char C : Data.bytes()) {
1222 OS << Directive << (unsigned)C;
1223 EmitEOL();
1224 }
1225}
1226
1227void MCAsmStreamer::emitBinaryData(StringRef Data) {
1228 // This is binary data. Print it in a grid of hex bytes for readability.
1229 const size_t Cols = 4;
1230 for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; I += Cols) {
1231 size_t J = I, EJ = std::min(I + Cols, Data.size());
1232 assert(EJ > 0);
1233 OS << MAI->getData8bitsDirective();
1234 for (; J < EJ - 1; ++J)
1235 OS << format("0x%02x", uint8_t(Data[J])) << ", ";
1236 OS << format("0x%02x", uint8_t(Data[J]));
1237 EmitEOL();
1238 }
1239}
1240
1241void MCAsmStreamer::emitIntValue(uint64_t Value, unsigned Size) {
1242 emitValue(MCConstantExpr::create(Value, getContext()), Size);
1243}
1244
1245void MCAsmStreamer::emitIntValueInHex(uint64_t Value, unsigned Size) {
1246 emitValue(MCConstantExpr::create(Value, getContext(), true), Size);
1247}
1248
1249void MCAsmStreamer::emitIntValueInHexWithPadding(uint64_t Value,
1250 unsigned Size) {
1251 emitValue(MCConstantExpr::create(Value, getContext(), true, Size), Size);
1252}
1253
1254void MCAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
1255 SMLoc Loc) {
1256 assert(Size <= 8 && "Invalid size");
1257 assert(getCurrentSectionOnly() &&
1258 "Cannot emit contents before setting section!");
1259 const char *Directive = nullptr;
1260 switch (Size) {
1261 default: break;
1262 case 1: Directive = MAI->getData8bitsDirective(); break;
1263 case 2: Directive = MAI->getData16bitsDirective(); break;
1264 case 4: Directive = MAI->getData32bitsDirective(); break;
1265 case 8: Directive = MAI->getData64bitsDirective(); break;
1266 }
1267
1268 if (!Directive) {
1269 int64_t IntValue;
1270 if (!Value->evaluateAsAbsolute(IntValue))
1271 report_fatal_error("Don't know how to emit this value.");
1272
1273 // We couldn't handle the requested integer size so we fallback by breaking
1274 // the request down into several, smaller, integers.
1275 // Since sizes greater or equal to "Size" are invalid, we use the greatest
1276 // power of 2 that is less than "Size" as our largest piece of granularity.
1277 bool IsLittleEndian = MAI->isLittleEndian();
1278 for (unsigned Emitted = 0; Emitted != Size;) {
1279 unsigned Remaining = Size - Emitted;
1280 // The size of our partial emission must be a power of two less than
1281 // Size.
1282 unsigned EmissionSize = llvm::bit_floor(std::min(Remaining, Size - 1));
1283 // Calculate the byte offset of our partial emission taking into account
1284 // the endianness of the target.
1285 unsigned ByteOffset =
1286 IsLittleEndian ? Emitted : (Remaining - EmissionSize);
1287 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
1288 // We truncate our partial emission to fit within the bounds of the
1289 // emission domain. This produces nicer output and silences potential
1290 // truncation warnings when round tripping through another assembler.
1291 uint64_t Shift = 64 - EmissionSize * 8;
1292 assert(Shift < static_cast<uint64_t>(
1293 std::numeric_limits<unsigned long long>::digits) &&
1294 "undefined behavior");
1295 ValueToEmit &= ~0ULL >> Shift;
1296 emitIntValue(ValueToEmit, EmissionSize);
1297 Emitted += EmissionSize;
1298 }
1299 return;
1300 }
1301
1302 assert(Directive && "Invalid size for machine code value!");
1303 OS << Directive;
1304 if (MCTargetStreamer *TS = getTargetStreamer()) {
1305 TS->emitValue(Value);
1306 } else {
1307 Value->print(OS, MAI);
1308 EmitEOL();
1309 }
1310}
1311
1312void MCAsmStreamer::emitULEB128Value(const MCExpr *Value) {
1313 int64_t IntValue;
1314 if (Value->evaluateAsAbsolute(IntValue)) {
1315 emitULEB128IntValue(IntValue);
1316 return;
1317 }
1318 OS << "\t.uleb128 ";
1319 Value->print(OS, MAI);
1320 EmitEOL();
1321}
1322
1323void MCAsmStreamer::emitSLEB128Value(const MCExpr *Value) {
1324 int64_t IntValue;
1325 if (Value->evaluateAsAbsolute(IntValue)) {
1326 emitSLEB128IntValue(IntValue);
1327 return;
1328 }
1329 OS << "\t.sleb128 ";
1330 Value->print(OS, MAI);
1331 EmitEOL();
1332}
1333
1334void MCAsmStreamer::emitDTPRel64Value(const MCExpr *Value) {
1335 assert(MAI->getDTPRel64Directive() != nullptr);
1336 OS << MAI->getDTPRel64Directive();
1337 Value->print(OS, MAI);
1338 EmitEOL();
1339}
1340
1341void MCAsmStreamer::emitDTPRel32Value(const MCExpr *Value) {
1342 assert(MAI->getDTPRel32Directive() != nullptr);
1343 OS << MAI->getDTPRel32Directive();
1344 Value->print(OS, MAI);
1345 EmitEOL();
1346}
1347
1348void MCAsmStreamer::emitTPRel64Value(const MCExpr *Value) {
1349 assert(MAI->getTPRel64Directive() != nullptr);
1350 OS << MAI->getTPRel64Directive();
1351 Value->print(OS, MAI);
1352 EmitEOL();
1353}
1354
1355void MCAsmStreamer::emitTPRel32Value(const MCExpr *Value) {
1356 assert(MAI->getTPRel32Directive() != nullptr);
1357 OS << MAI->getTPRel32Directive();
1358 Value->print(OS, MAI);
1359 EmitEOL();
1360}
1361
1362void MCAsmStreamer::emitGPRel64Value(const MCExpr *Value) {
1363 assert(MAI->getGPRel64Directive() != nullptr);
1364 OS << MAI->getGPRel64Directive();
1365 Value->print(OS, MAI);
1366 EmitEOL();
1367}
1368
1369void MCAsmStreamer::emitGPRel32Value(const MCExpr *Value) {
1370 assert(MAI->getGPRel32Directive() != nullptr);
1371 OS << MAI->getGPRel32Directive();
1372 Value->print(OS, MAI);
1373 EmitEOL();
1374}
1375
1376void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
1377 SMLoc Loc) {
1378 int64_t IntNumBytes;
1379 const bool IsAbsolute = NumBytes.evaluateAsAbsolute(IntNumBytes);
1380 if (IsAbsolute && IntNumBytes == 0)
1381 return;
1382
1383 if (const char *ZeroDirective = MAI->getZeroDirective()) {
1384 if (MAI->doesZeroDirectiveSupportNonZeroValue() || FillValue == 0) {
1385 // FIXME: Emit location directives
1386 OS << ZeroDirective;
1387 NumBytes.print(OS, MAI);
1388 if (FillValue != 0)
1389 OS << ',' << (int)FillValue;
1390 EmitEOL();
1391 } else {
1392 if (!IsAbsolute)
1394 "Cannot emit non-absolute expression lengths of fill.");
1395 for (int i = 0; i < IntNumBytes; ++i) {
1396 OS << MAI->getData8bitsDirective() << (int)FillValue;
1397 EmitEOL();
1398 }
1399 }
1400 return;
1401 }
1402
1403 MCStreamer::emitFill(NumBytes, FillValue);
1404}
1405
1406void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
1407 int64_t Expr, SMLoc Loc) {
1408 // FIXME: Emit location directives
1409 OS << "\t.fill\t";
1410 NumValues.print(OS, MAI);
1411 OS << ", " << Size << ", 0x";
1412 OS.write_hex(truncateToSize(Expr, 4));
1413 EmitEOL();
1414}
1415
1416void MCAsmStreamer::emitAlignmentDirective(unsigned ByteAlignment,
1417 std::optional<int64_t> Value,
1418 unsigned ValueSize,
1419 unsigned MaxBytesToEmit) {
1420 if (MAI->useDotAlignForAlignment()) {
1421 if (!isPowerOf2_32(ByteAlignment))
1422 report_fatal_error("Only power-of-two alignments are supported "
1423 "with .align.");
1424 OS << "\t.align\t";
1425 OS << Log2_32(ByteAlignment);
1426 EmitEOL();
1427 return;
1428 }
1429
1430 // Some assemblers don't support non-power of two alignments, so we always
1431 // emit alignments as a power of two if possible.
1432 if (isPowerOf2_32(ByteAlignment)) {
1433 switch (ValueSize) {
1434 default:
1435 llvm_unreachable("Invalid size for machine code value!");
1436 case 1:
1437 OS << "\t.p2align\t";
1438 break;
1439 case 2:
1440 OS << ".p2alignw ";
1441 break;
1442 case 4:
1443 OS << ".p2alignl ";
1444 break;
1445 case 8:
1446 llvm_unreachable("Unsupported alignment size!");
1447 }
1448
1449 OS << Log2_32(ByteAlignment);
1450
1451 if (Value.has_value() || MaxBytesToEmit) {
1452 if (Value.has_value()) {
1453 OS << ", 0x";
1454 OS.write_hex(truncateToSize(*Value, ValueSize));
1455 } else {
1456 OS << ", ";
1457 }
1458
1459 if (MaxBytesToEmit)
1460 OS << ", " << MaxBytesToEmit;
1461 }
1462 EmitEOL();
1463 return;
1464 }
1465
1466 // Non-power of two alignment. This is not widely supported by assemblers.
1467 // FIXME: Parameterize this based on MAI.
1468 switch (ValueSize) {
1469 default: llvm_unreachable("Invalid size for machine code value!");
1470 case 1: OS << ".balign"; break;
1471 case 2: OS << ".balignw"; break;
1472 case 4: OS << ".balignl"; break;
1473 case 8: llvm_unreachable("Unsupported alignment size!");
1474 }
1475
1476 OS << ' ' << ByteAlignment;
1477 if (Value.has_value())
1478 OS << ", " << truncateToSize(*Value, ValueSize);
1479 else if (MaxBytesToEmit)
1480 OS << ", ";
1481 if (MaxBytesToEmit)
1482 OS << ", " << MaxBytesToEmit;
1483 EmitEOL();
1484}
1485
1486void MCAsmStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
1487 unsigned ValueSize,
1488 unsigned MaxBytesToEmit) {
1489 emitAlignmentDirective(Alignment.value(), Value, ValueSize, MaxBytesToEmit);
1490}
1491
1492void MCAsmStreamer::emitCodeAlignment(Align Alignment,
1493 const MCSubtargetInfo *STI,
1494 unsigned MaxBytesToEmit) {
1495 // Emit with a text fill value.
1496 if (MAI->getTextAlignFillValue())
1497 emitAlignmentDirective(Alignment.value(), MAI->getTextAlignFillValue(), 1,
1498 MaxBytesToEmit);
1499 else
1500 emitAlignmentDirective(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
1501}
1502
1503void MCAsmStreamer::emitValueToOffset(const MCExpr *Offset,
1504 unsigned char Value,
1505 SMLoc Loc) {
1506 // FIXME: Verify that Offset is associated with the current section.
1507 OS << ".org ";
1508 Offset->print(OS, MAI);
1509 OS << ", " << (unsigned)Value;
1510 EmitEOL();
1511}
1512
1513void MCAsmStreamer::emitFileDirective(StringRef Filename) {
1515 OS << "\t.file\t";
1516 PrintQuotedString(Filename, OS);
1517 EmitEOL();
1518}
1519
1520void MCAsmStreamer::emitFileDirective(StringRef Filename,
1521 StringRef CompilerVerion,
1522 StringRef TimeStamp,
1523 StringRef Description) {
1525 OS << "\t.file\t";
1526 PrintQuotedString(Filename, OS);
1527 OS << ",";
1528 if (!CompilerVerion.empty()) {
1529 PrintQuotedString(CompilerVerion, OS);
1530 }
1531 if (!TimeStamp.empty()) {
1532 OS << ",";
1533 PrintQuotedString(TimeStamp, OS);
1534 }
1535 if (!Description.empty()) {
1536 OS << ",";
1537 PrintQuotedString(Description, OS);
1538 }
1539 EmitEOL();
1540}
1541
1542void MCAsmStreamer::printDwarfFileDirective(
1543 unsigned FileNo, StringRef Directory, StringRef Filename,
1544 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1545 bool UseDwarfDirectory, raw_svector_ostream &OS) const {
1546 SmallString<128> FullPathName;
1547
1548 if (!UseDwarfDirectory && !Directory.empty()) {
1549 if (sys::path::is_absolute(Filename))
1550 Directory = "";
1551 else {
1552 FullPathName = Directory;
1553 sys::path::append(FullPathName, Filename);
1554 Directory = "";
1555 Filename = FullPathName;
1556 }
1557 }
1558
1559 OS << "\t.file\t" << FileNo << ' ';
1560 if (!Directory.empty()) {
1561 PrintQuotedString(Directory, OS);
1562 OS << ' ';
1563 }
1564 PrintQuotedString(Filename, OS);
1565 if (Checksum)
1566 OS << " md5 0x" << Checksum->digest();
1567 if (Source) {
1568 OS << " source ";
1569 PrintQuotedString(*Source, OS);
1570 }
1571}
1572
1573Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
1574 unsigned FileNo, StringRef Directory, StringRef Filename,
1575 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1576 unsigned CUID) {
1577 assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer");
1578
1579 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
1580 unsigned NumFiles = Table.getMCDwarfFiles().size();
1581 Expected<unsigned> FileNoOrErr =
1582 Table.tryGetFile(Directory, Filename, Checksum, Source,
1583 getContext().getDwarfVersion(), FileNo);
1584 if (!FileNoOrErr)
1585 return FileNoOrErr.takeError();
1586 FileNo = FileNoOrErr.get();
1587
1588 // Return early if this file is already emitted before or if target doesn't
1589 // support .file directive.
1590 if (NumFiles == Table.getMCDwarfFiles().size() ||
1592 return FileNo;
1593
1594 SmallString<128> Str;
1595 raw_svector_ostream OS1(Str);
1596 printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source,
1597 UseDwarfDirectory, OS1);
1598
1599 if (MCTargetStreamer *TS = getTargetStreamer())
1600 TS->emitDwarfFileDirective(OS1.str());
1601 else
1602 emitRawText(OS1.str());
1603
1604 return FileNo;
1605}
1606
1607void MCAsmStreamer::emitDwarfFile0Directive(
1608 StringRef Directory, StringRef Filename,
1609 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1610 unsigned CUID) {
1611 assert(CUID == 0);
1612 // .file 0 is new for DWARF v5.
1613 if (getContext().getDwarfVersion() < 5)
1614 return;
1615 // Inform MCDwarf about the root file.
1616 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
1617 Source);
1618
1619 // Target doesn't support .loc/.file directives, return early.
1621 return;
1622
1623 SmallString<128> Str;
1624 raw_svector_ostream OS1(Str);
1625 printDwarfFileDirective(0, Directory, Filename, Checksum, Source,
1626 UseDwarfDirectory, OS1);
1627
1628 if (MCTargetStreamer *TS = getTargetStreamer())
1629 TS->emitDwarfFileDirective(OS1.str());
1630 else
1631 emitRawText(OS1.str());
1632}
1633
1634void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
1635 unsigned Column, unsigned Flags,
1636 unsigned Isa, unsigned Discriminator,
1637 StringRef FileName) {
1638 // If target doesn't support .loc/.file directive, we need to record the lines
1639 // same way like we do in object mode.
1640 if (!MAI->usesDwarfFileAndLocDirectives()) {
1641 // In case we see two .loc directives in a row, make sure the
1642 // first one gets a line entry.
1643 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
1644 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1645 Discriminator, FileName);
1646 return;
1647 }
1648
1649 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
1651 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
1652 OS << " basic_block";
1653 if (Flags & DWARF2_FLAG_PROLOGUE_END)
1654 OS << " prologue_end";
1655 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
1656 OS << " epilogue_begin";
1657
1658 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
1659 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
1660 OS << " is_stmt ";
1661
1662 if (Flags & DWARF2_FLAG_IS_STMT)
1663 OS << "1";
1664 else
1665 OS << "0";
1666 }
1667
1668 if (Isa)
1669 OS << " isa " << Isa;
1670 if (Discriminator)
1671 OS << " discriminator " << Discriminator;
1672 }
1673
1674 if (IsVerboseAsm) {
1675 OS.PadToColumn(MAI->getCommentColumn());
1676 OS << MAI->getCommentString() << ' ' << FileName << ':'
1677 << Line << ':' << Column;
1678 }
1679 EmitEOL();
1680 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1681 Discriminator, FileName);
1682}
1683
1684MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
1685 // Always use the zeroth line table, since asm syntax only supports one line
1686 // table for now.
1688}
1689
1690bool MCAsmStreamer::emitCVFileDirective(unsigned FileNo, StringRef Filename,
1691 ArrayRef<uint8_t> Checksum,
1692 unsigned ChecksumKind) {
1693 if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
1694 ChecksumKind))
1695 return false;
1696
1697 OS << "\t.cv_file\t" << FileNo << ' ';
1698 PrintQuotedString(Filename, OS);
1699
1700 if (!ChecksumKind) {
1701 EmitEOL();
1702 return true;
1703 }
1704
1705 OS << ' ';
1706 PrintQuotedString(toHex(Checksum), OS);
1707 OS << ' ' << ChecksumKind;
1708
1709 EmitEOL();
1710 return true;
1711}
1712
1713bool MCAsmStreamer::emitCVFuncIdDirective(unsigned FuncId) {
1714 OS << "\t.cv_func_id " << FuncId << '\n';
1716}
1717
1718bool MCAsmStreamer::emitCVInlineSiteIdDirective(unsigned FunctionId,
1719 unsigned IAFunc,
1720 unsigned IAFile,
1721 unsigned IALine, unsigned IACol,
1722 SMLoc Loc) {
1723 OS << "\t.cv_inline_site_id " << FunctionId << " within " << IAFunc
1724 << " inlined_at " << IAFile << ' ' << IALine << ' ' << IACol << '\n';
1725 return MCStreamer::emitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
1726 IALine, IACol, Loc);
1727}
1728
1729void MCAsmStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
1730 unsigned Line, unsigned Column,
1731 bool PrologueEnd, bool IsStmt,
1732 StringRef FileName, SMLoc Loc) {
1733 // Validate the directive.
1734 if (!checkCVLocSection(FunctionId, FileNo, Loc))
1735 return;
1736
1737 OS << "\t.cv_loc\t" << FunctionId << " " << FileNo << " " << Line << " "
1738 << Column;
1739 if (PrologueEnd)
1740 OS << " prologue_end";
1741
1742 if (IsStmt)
1743 OS << " is_stmt 1";
1744
1745 if (IsVerboseAsm) {
1746 OS.PadToColumn(MAI->getCommentColumn());
1747 OS << MAI->getCommentString() << ' ' << FileName << ':' << Line << ':'
1748 << Column;
1749 }
1750 EmitEOL();
1751}
1752
1753void MCAsmStreamer::emitCVLinetableDirective(unsigned FunctionId,
1754 const MCSymbol *FnStart,
1755 const MCSymbol *FnEnd) {
1756 OS << "\t.cv_linetable\t" << FunctionId << ", ";
1757 FnStart->print(OS, MAI);
1758 OS << ", ";
1759 FnEnd->print(OS, MAI);
1760 EmitEOL();
1761 this->MCStreamer::emitCVLinetableDirective(FunctionId, FnStart, FnEnd);
1762}
1763
1764void MCAsmStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
1765 unsigned SourceFileId,
1766 unsigned SourceLineNum,
1767 const MCSymbol *FnStartSym,
1768 const MCSymbol *FnEndSym) {
1769 OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId
1770 << ' ' << SourceLineNum << ' ';
1771 FnStartSym->print(OS, MAI);
1772 OS << ' ';
1773 FnEndSym->print(OS, MAI);
1774 EmitEOL();
1776 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1777}
1778
1779void MCAsmStreamer::PrintCVDefRangePrefix(
1780 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {
1781 OS << "\t.cv_def_range\t";
1782 for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
1783 OS << ' ';
1784 Range.first->print(OS, MAI);
1785 OS << ' ';
1786 Range.second->print(OS, MAI);
1787 }
1788}
1789
1790void MCAsmStreamer::emitCVDefRangeDirective(
1791 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1793 PrintCVDefRangePrefix(Ranges);
1794 OS << ", reg_rel, ";
1795 OS << DRHdr.Register << ", " << DRHdr.Flags << ", "
1796 << DRHdr.BasePointerOffset;
1797 EmitEOL();
1798}
1799
1800void MCAsmStreamer::emitCVDefRangeDirective(
1801 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1803 PrintCVDefRangePrefix(Ranges);
1804 OS << ", subfield_reg, ";
1805 OS << DRHdr.Register << ", " << DRHdr.OffsetInParent;
1806 EmitEOL();
1807}
1808
1809void MCAsmStreamer::emitCVDefRangeDirective(
1810 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1812 PrintCVDefRangePrefix(Ranges);
1813 OS << ", reg, ";
1814 OS << DRHdr.Register;
1815 EmitEOL();
1816}
1817
1818void MCAsmStreamer::emitCVDefRangeDirective(
1819 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1821 PrintCVDefRangePrefix(Ranges);
1822 OS << ", frame_ptr_rel, ";
1823 OS << DRHdr.Offset;
1824 EmitEOL();
1825}
1826
1827void MCAsmStreamer::emitCVStringTableDirective() {
1828 OS << "\t.cv_stringtable";
1829 EmitEOL();
1830}
1831
1832void MCAsmStreamer::emitCVFileChecksumsDirective() {
1833 OS << "\t.cv_filechecksums";
1834 EmitEOL();
1835}
1836
1837void MCAsmStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
1838 OS << "\t.cv_filechecksumoffset\t" << FileNo;
1839 EmitEOL();
1840}
1841
1842void MCAsmStreamer::emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) {
1843 OS << "\t.cv_fpo_data\t";
1844 ProcSym->print(OS, MAI);
1845 EmitEOL();
1846}
1847
1848void MCAsmStreamer::emitIdent(StringRef IdentString) {
1849 assert(MAI->hasIdentDirective() && ".ident directive not supported");
1850 OS << "\t.ident\t";
1851 PrintQuotedString(IdentString, OS);
1852 EmitEOL();
1853}
1854
1855void MCAsmStreamer::emitCFISections(bool EH, bool Debug) {
1857 OS << "\t.cfi_sections ";
1858 if (EH) {
1859 OS << ".eh_frame";
1860 if (Debug)
1861 OS << ", .debug_frame";
1862 } else if (Debug) {
1863 OS << ".debug_frame";
1864 }
1865
1866 EmitEOL();
1867}
1868
1869void MCAsmStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
1870 OS << "\t.cfi_startproc";
1871 if (Frame.IsSimple)
1872 OS << " simple";
1873 EmitEOL();
1874}
1875
1876void MCAsmStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
1878 OS << "\t.cfi_endproc";
1879 EmitEOL();
1880}
1881
1882void MCAsmStreamer::EmitRegisterName(int64_t Register) {
1883 if (!MAI->useDwarfRegNumForCFI()) {
1884 // User .cfi_* directives can use arbitrary DWARF register numbers, not
1885 // just ones that map to LLVM register numbers and have known names.
1886 // Fall back to using the original number directly if no name is known.
1887 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1888 if (std::optional<unsigned> LLVMRegister =
1889 MRI->getLLVMRegNum(Register, true)) {
1890 InstPrinter->printRegName(OS, *LLVMRegister);
1891 return;
1892 }
1893 }
1894 OS << Register;
1895}
1896
1897void MCAsmStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset) {
1899 OS << "\t.cfi_def_cfa ";
1900 EmitRegisterName(Register);
1901 OS << ", " << Offset;
1902 EmitEOL();
1903}
1904
1905void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset) {
1907 OS << "\t.cfi_def_cfa_offset " << Offset;
1908 EmitEOL();
1909}
1910
1911void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
1912 int64_t AddressSpace) {
1914 OS << "\t.cfi_llvm_def_aspace_cfa ";
1915 EmitRegisterName(Register);
1916 OS << ", " << Offset;
1917 OS << ", " << AddressSpace;
1918 EmitEOL();
1919}
1920
1922 OS << "\t.cfi_escape ";
1923 if (!Values.empty()) {
1924 size_t e = Values.size() - 1;
1925 for (size_t i = 0; i < e; ++i)
1926 OS << format("0x%02x", uint8_t(Values[i])) << ", ";
1927 OS << format("0x%02x", uint8_t(Values[e]));
1928 }
1929}
1930
1931void MCAsmStreamer::emitCFIEscape(StringRef Values) {
1933 PrintCFIEscape(OS, Values);
1934 EmitEOL();
1935}
1936
1937void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size) {
1939
1940 uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
1941 unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
1942
1943 PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));
1944 EmitEOL();
1945}
1946
1947void MCAsmStreamer::emitCFIDefCfaRegister(int64_t Register) {
1949 OS << "\t.cfi_def_cfa_register ";
1950 EmitRegisterName(Register);
1951 EmitEOL();
1952}
1953
1954void MCAsmStreamer::emitCFIOffset(int64_t Register, int64_t Offset) {
1955 this->MCStreamer::emitCFIOffset(Register, Offset);
1956 OS << "\t.cfi_offset ";
1957 EmitRegisterName(Register);
1958 OS << ", " << Offset;
1959 EmitEOL();
1960}
1961
1962void MCAsmStreamer::emitCFIPersonality(const MCSymbol *Sym,
1963 unsigned Encoding) {
1965 OS << "\t.cfi_personality " << Encoding << ", ";
1966 Sym->print(OS, MAI);
1967 EmitEOL();
1968}
1969
1970void MCAsmStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
1971 MCStreamer::emitCFILsda(Sym, Encoding);
1972 OS << "\t.cfi_lsda " << Encoding << ", ";
1973 Sym->print(OS, MAI);
1974 EmitEOL();
1975}
1976
1977void MCAsmStreamer::emitCFIRememberState() {
1979 OS << "\t.cfi_remember_state";
1980 EmitEOL();
1981}
1982
1983void MCAsmStreamer::emitCFIRestoreState() {
1985 OS << "\t.cfi_restore_state";
1986 EmitEOL();
1987}
1988
1989void MCAsmStreamer::emitCFIRestore(int64_t Register) {
1991 OS << "\t.cfi_restore ";
1992 EmitRegisterName(Register);
1993 EmitEOL();
1994}
1995
1996void MCAsmStreamer::emitCFISameValue(int64_t Register) {
1998 OS << "\t.cfi_same_value ";
1999 EmitRegisterName(Register);
2000 EmitEOL();
2001}
2002
2003void MCAsmStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset) {
2005 OS << "\t.cfi_rel_offset ";
2006 EmitRegisterName(Register);
2007 OS << ", " << Offset;
2008 EmitEOL();
2009}
2010
2011void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment) {
2013 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
2014 EmitEOL();
2015}
2016
2017void MCAsmStreamer::emitCFISignalFrame() {
2019 OS << "\t.cfi_signal_frame";
2020 EmitEOL();
2021}
2022
2023void MCAsmStreamer::emitCFIUndefined(int64_t Register) {
2025 OS << "\t.cfi_undefined ";
2026 EmitRegisterName(Register);
2027 EmitEOL();
2028}
2029
2030void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
2031 MCStreamer::emitCFIRegister(Register1, Register2);
2032 OS << "\t.cfi_register ";
2033 EmitRegisterName(Register1);
2034 OS << ", ";
2035 EmitRegisterName(Register2);
2036 EmitEOL();
2037}
2038
2039void MCAsmStreamer::emitCFIWindowSave() {
2041 OS << "\t.cfi_window_save";
2042 EmitEOL();
2043}
2044
2045void MCAsmStreamer::emitCFINegateRAState() {
2047 OS << "\t.cfi_negate_ra_state";
2048 EmitEOL();
2049}
2050
2051void MCAsmStreamer::emitCFIReturnColumn(int64_t Register) {
2053 OS << "\t.cfi_return_column ";
2054 EmitRegisterName(Register);
2055 EmitEOL();
2056}
2057
2058void MCAsmStreamer::emitCFIBKeyFrame() {
2060 OS << "\t.cfi_b_key_frame";
2061 EmitEOL();
2062}
2063
2064void MCAsmStreamer::emitCFIMTETaggedFrame() {
2066 OS << "\t.cfi_mte_tagged_frame";
2067 EmitEOL();
2068}
2069
2070void MCAsmStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
2072
2073 OS << ".seh_proc ";
2074 Symbol->print(OS, MAI);
2075 EmitEOL();
2076}
2077
2078void MCAsmStreamer::emitWinCFIEndProc(SMLoc Loc) {
2080
2081 OS << "\t.seh_endproc";
2082 EmitEOL();
2083}
2084
2085void MCAsmStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
2087
2088 OS << "\t.seh_endfunclet";
2089 EmitEOL();
2090}
2091
2092void MCAsmStreamer::emitWinCFIStartChained(SMLoc Loc) {
2094
2095 OS << "\t.seh_startchained";
2096 EmitEOL();
2097}
2098
2099void MCAsmStreamer::emitWinCFIEndChained(SMLoc Loc) {
2101
2102 OS << "\t.seh_endchained";
2103 EmitEOL();
2104}
2105
2106void MCAsmStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind,
2107 bool Except, SMLoc Loc) {
2108 MCStreamer::emitWinEHHandler(Sym, Unwind, Except, Loc);
2109
2110 OS << "\t.seh_handler ";
2111 Sym->print(OS, MAI);
2112 char Marker = '@';
2113 const Triple &T = getContext().getTargetTriple();
2114 if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
2115 Marker = '%';
2116 if (Unwind)
2117 OS << ", " << Marker << "unwind";
2118 if (Except)
2119 OS << ", " << Marker << "except";
2120 EmitEOL();
2121}
2122
2123void MCAsmStreamer::emitWinEHHandlerData(SMLoc Loc) {
2125
2126 // Switch sections. Don't call switchSection directly, because that will
2127 // cause the section switch to be visible in the emitted assembly.
2128 // We only do this so the section switch that terminates the handler
2129 // data block is visible.
2130 WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
2131
2132 // Do nothing if no frame is open. MCStreamer should've already reported an
2133 // error.
2134 if (!CurFrame)
2135 return;
2136
2137 MCSection *TextSec = &CurFrame->Function->getSection();
2138 MCSection *XData = getAssociatedXDataSection(TextSec);
2139 switchSectionNoChange(XData);
2140
2141 OS << "\t.seh_handlerdata";
2142 EmitEOL();
2143}
2144
2145void MCAsmStreamer::emitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
2147
2148 OS << "\t.seh_pushreg ";
2149 InstPrinter->printRegName(OS, Register);
2150 EmitEOL();
2151}
2152
2153void MCAsmStreamer::emitWinCFISetFrame(MCRegister Register, unsigned Offset,
2154 SMLoc Loc) {
2156
2157 OS << "\t.seh_setframe ";
2158 InstPrinter->printRegName(OS, Register);
2159 OS << ", " << Offset;
2160 EmitEOL();
2161}
2162
2163void MCAsmStreamer::emitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
2165
2166 OS << "\t.seh_stackalloc " << Size;
2167 EmitEOL();
2168}
2169
2170void MCAsmStreamer::emitWinCFISaveReg(MCRegister Register, unsigned Offset,
2171 SMLoc Loc) {
2173
2174 OS << "\t.seh_savereg ";
2175 InstPrinter->printRegName(OS, Register);
2176 OS << ", " << Offset;
2177 EmitEOL();
2178}
2179
2180void MCAsmStreamer::emitWinCFISaveXMM(MCRegister Register, unsigned Offset,
2181 SMLoc Loc) {
2183
2184 OS << "\t.seh_savexmm ";
2185 InstPrinter->printRegName(OS, Register);
2186 OS << ", " << Offset;
2187 EmitEOL();
2188}
2189
2190void MCAsmStreamer::emitWinCFIPushFrame(bool Code, SMLoc Loc) {
2192
2193 OS << "\t.seh_pushframe";
2194 if (Code)
2195 OS << " @code";
2196 EmitEOL();
2197}
2198
2199void MCAsmStreamer::emitWinCFIEndProlog(SMLoc Loc) {
2201
2202 OS << "\t.seh_endprologue";
2203 EmitEOL();
2204}
2205
2206void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
2207 const MCSymbolRefExpr *To,
2208 uint64_t Count) {
2209 OS << "\t.cg_profile ";
2210 From->getSymbol().print(OS, MAI);
2211 OS << ", ";
2212 To->getSymbol().print(OS, MAI);
2213 OS << ", " << Count;
2214 EmitEOL();
2215}
2216
2217void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
2218 const MCSubtargetInfo &STI) {
2219 raw_ostream &OS = getCommentOS();
2222
2223 // If we have no code emitter, don't emit code.
2224 if (!getAssembler().getEmitterPtr())
2225 return;
2226
2227 getAssembler().getEmitter().encodeInstruction(Inst, Code, 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(uint64_t Guid, uint64_t Index,
2341 uint64_t Type, uint64_t Attr,
2342 uint64_t Discriminator,
2343 const MCPseudoProbeInlineStack &InlineStack,
2344 MCSymbol *FnSym) {
2345 OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " " << Attr;
2346 if (Discriminator)
2347 OS << " " << Discriminator;
2348 // Emit inline stack like
2349 // @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11
2350 for (const auto &Site : InlineStack)
2351 OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site);
2352
2353 OS << " " << FnSym->getName();
2354
2355 EmitEOL();
2356}
2357
2358void MCAsmStreamer::emitBundleAlignMode(Align Alignment) {
2359 OS << "\t.bundle_align_mode " << Log2(Alignment);
2360 EmitEOL();
2361}
2362
2363void MCAsmStreamer::emitBundleLock(bool AlignToEnd) {
2364 OS << "\t.bundle_lock";
2365 if (AlignToEnd)
2366 OS << " align_to_end";
2367 EmitEOL();
2368}
2369
2370void MCAsmStreamer::emitBundleUnlock() {
2371 OS << "\t.bundle_unlock";
2372 EmitEOL();
2373}
2374
2375std::optional<std::pair<bool, std::string>>
2376MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
2377 const MCExpr *Expr, SMLoc,
2378 const MCSubtargetInfo &STI) {
2379 OS << "\t.reloc ";
2380 Offset.print(OS, MAI);
2381 OS << ", " << Name;
2382 if (Expr) {
2383 OS << ", ";
2384 Expr->print(OS, MAI);
2385 }
2386 EmitEOL();
2387 return std::nullopt;
2388}
2389
2390void MCAsmStreamer::emitAddrsig() {
2391 OS << "\t.addrsig";
2392 EmitEOL();
2393}
2394
2395void MCAsmStreamer::emitAddrsigSym(const MCSymbol *Sym) {
2396 OS << "\t.addrsig_sym ";
2397 Sym->print(OS, MAI);
2398 EmitEOL();
2399}
2400
2401/// EmitRawText - If this file is backed by an assembly streamer, this dumps
2402/// the specified string in the output .s file. This capability is
2403/// indicated by the hasRawTextSupport() predicate.
2404void MCAsmStreamer::emitRawTextImpl(StringRef String) {
2405 if (!String.empty() && String.back() == '\n')
2406 String = String.substr(0, String.size()-1);
2407 OS << String;
2408 EmitEOL();
2409}
2410
2411void MCAsmStreamer::finishImpl() {
2412 // If we are generating dwarf for assembly source files dump out the sections.
2413 if (getContext().getGenDwarfForAssembly())
2415
2416 // Now it is time to emit debug line sections if target doesn't support .loc
2417 // and .line directives.
2418 if (!MAI->usesDwarfFileAndLocDirectives()) {
2419 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
2420 return;
2421 }
2422
2423 // Emit the label for the line table, if requested - since the rest of the
2424 // line table will be defined by .loc/.file directives, and not emitted
2425 // directly, the label is the only work required here.
2426 const auto &Tables = getContext().getMCDwarfLineTables();
2427 if (!Tables.empty()) {
2428 assert(Tables.size() == 1 && "asm output only supports one line table");
2429 if (auto *Label = Tables.begin()->second.getLabel()) {
2430 switchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
2431 emitLabel(Label);
2432 }
2433 }
2434}
2435
2436void MCAsmStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
2437 // If the assembler on some target fills in the DWARF unit length, we
2438 // don't want to emit the length in the compiler. For example, the AIX
2439 // assembler requires the assembly file with the unit length omitted from
2440 // the debug section headers. In such cases, any label we placed occurs
2441 // after the implied length field. We need to adjust the reference here
2442 // to account for the offset introduced by the inserted length field.
2444 return;
2446}
2447
2448MCSymbol *MCAsmStreamer::emitDwarfUnitLength(const Twine &Prefix,
2449 const Twine &Comment) {
2450 // If the assembler on some target fills in the DWARF unit length, we
2451 // don't want to emit the length in the compiler. For example, the AIX
2452 // assembler requires the assembly file with the unit length omitted from
2453 // the debug section headers. In such cases, any label we placed occurs
2454 // after the implied length field. We need to adjust the reference here
2455 // to account for the offset introduced by the inserted length field.
2457 return getContext().createTempSymbol(Prefix + "_end");
2458 return MCStreamer::emitDwarfUnitLength(Prefix, Comment);
2459}
2460
2461void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
2462 // If the assembler on some target fills in the DWARF unit length, we
2463 // don't want to emit the length in the compiler. For example, the AIX
2464 // assembler requires the assembly file with the unit length omitted from
2465 // the debug section headers. In such cases, any label we placed occurs
2466 // after the implied length field. We need to adjust the reference here
2467 // to account for the offset introduced by the inserted length field.
2468 MCContext &Ctx = getContext();
2469 if (!MAI->needsDwarfSectionSizeInHeader()) {
2470 MCSymbol *DebugLineSymTmp = Ctx.createTempSymbol("debug_line_");
2471 // Emit the symbol which does not contain the unit length field.
2472 emitLabel(DebugLineSymTmp);
2473
2474 // Adjust the outer reference to account for the offset introduced by the
2475 // inserted length field.
2476 unsigned LengthFieldSize =
2478 const MCExpr *EntrySize = MCConstantExpr::create(LengthFieldSize, Ctx);
2479 const MCExpr *OuterSym = MCBinaryExpr::createSub(
2480 MCSymbolRefExpr::create(DebugLineSymTmp, Ctx), EntrySize, Ctx);
2481
2482 emitAssignment(StartSym, OuterSym);
2483 return;
2484 }
2486}
2487
2488void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
2489 MCSymbol *LastLabel) {
2490 // If the targets write the raw debug line data for assembly output (We can
2491 // not switch to Section and add the end symbol there for assembly output)
2492 // we currently use the .text end label as any section end. This will not
2493 // impact the debugability as we will jump to the caller of the last function
2494 // in the section before we come into the .text end address.
2496 ".loc should not be generated together with raw data!");
2497
2498 MCContext &Ctx = getContext();
2499
2500 // FIXME: use section end symbol as end of the Section. We need to consider
2501 // the explicit sections and -ffunction-sections when we try to generate or
2502 // find section end symbol for the Section.
2503 MCSection *TextSection = Ctx.getObjectFileInfo()->getTextSection();
2504 assert(TextSection->hasEnded() && ".text section is not end!");
2505
2506 MCSymbol *SectionEnd = TextSection->getEndSymbol(Ctx);
2507 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
2508 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
2509 AsmInfo->getCodePointerSize());
2510}
2511
2512// Generate DWARF line sections for assembly mode without .loc/.file
2513void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
2514 const MCSymbol *LastLabel,
2515 const MCSymbol *Label,
2516 unsigned PointerSize) {
2518 ".loc/.file don't need raw data in debug line section!");
2519
2520 // Set to new address.
2521 AddComment("Set address to " + Label->getName());
2522 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2523 emitULEB128IntValue(PointerSize + 1);
2524 emitIntValue(dwarf::DW_LNE_set_address, 1);
2525 emitSymbolValue(Label, PointerSize);
2526
2527 if (!LastLabel) {
2528 // Emit the sequence for the LineDelta (from 1) and a zero address delta.
2529 AddComment("Start sequence");
2530 MCDwarfLineAddr::Emit(this, MCDwarfLineTableParams(), LineDelta, 0);
2531 return;
2532 }
2533
2534 // INT64_MAX is a signal of the end of the section. Emit DW_LNE_end_sequence
2535 // for the end of the section.
2536 if (LineDelta == INT64_MAX) {
2537 AddComment("End sequence");
2538 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2539 emitULEB128IntValue(1);
2540 emitIntValue(dwarf::DW_LNE_end_sequence, 1);
2541 return;
2542 }
2543
2544 // Advance line.
2545 AddComment("Advance line " + Twine(LineDelta));
2546 emitIntValue(dwarf::DW_LNS_advance_line, 1);
2547 emitSLEB128IntValue(LineDelta);
2548 emitIntValue(dwarf::DW_LNS_copy, 1);
2549}
2550
2551void MCAsmStreamer::doFinalizationAtSectionEnd(MCSection *Section) {
2552 // Emit section end. This is used to tell the debug line section where the end
2553 // is for a text section if we don't use .loc to represent the debug line.
2555 return;
2556
2557 switchSectionNoChange(Section);
2558
2559 MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());
2560
2561 if (!Sym->isInSection())
2562 emitLabel(Sym);
2563}
2564
2566 std::unique_ptr<formatted_raw_ostream> OS,
2567 bool isVerboseAsm, bool useDwarfDirectory,
2568 MCInstPrinter *IP,
2569 std::unique_ptr<MCCodeEmitter> &&CE,
2570 std::unique_ptr<MCAsmBackend> &&MAB,
2571 bool ShowInst) {
2572 return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
2573 useDwarfDirectory, IP, std::move(CE), std::move(MAB),
2574 ShowInst);
2575}
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
Symbol * Sym
Definition: ELF_riscv.cpp:463
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:669
static void make(MCStreamer *MCOS, MCSection *Section)
Definition: MCDwarf.cpp:94
static void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)
Definition: MCDwarf.cpp:259
Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
Definition: MCDwarf.cpp:565
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:1138
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:302
virtual void finishImpl()
Streamer specific finalization.
virtual void emitDTPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (64-bit DTP relative) value.
Definition: MCStreamer.cpp:195
virtual void emitCFIDefCfaOffset(int64_t Offset)
Definition: MCStreamer.cpp:507
virtual void emitCFIBKeyFrame()
Definition: MCStreamer.cpp:249
virtual void beginCOFFSymbolDef(const MCSymbol *Symbol)
Start emitting COFF symbol definition.
virtual void emitSyntaxDirective()
Definition: MCStreamer.cpp:862
virtual void emitWinCFIPushReg(MCRegister Register, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:868
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:635
virtual void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:787
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:538
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:662
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
virtual bool emitCVFileDirective(unsigned FileNo, StringRef Filename, ArrayRef< uint8_t > Checksum, unsigned ChecksumKind)
Associate a filename with a specified logical file number, and also specify that file's checksum info...
Definition: MCStreamer.cpp:295
virtual void emitCFIReturnColumn(int64_t Register)
Definition: MCStreamer.cpp:691
virtual void emitCOFFSymbolType(int Type)
Emit the type of the symbol.
virtual void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding)
Definition: MCStreamer.cpp:570
virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)
Emit a unit length field.
virtual void emitCOFFSymbolIndex(MCSymbol const *Symbol)
Emits the symbol table index of a Symbol into the current section.
Definition: MCStreamer.cpp:977
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:263
virtual bool isVerboseAsm() const
Return true if this streamer supports verbose assembly and if it is enabled.
Definition: MCStreamer.h:336
virtual void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset)
Emits a COFF image relative relocation.
Definition: MCStreamer.cpp:983
virtual void endCOFFSymbolDef()
Marks the end of the symbol definition.
virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:951
virtual void emitWinEHHandlerData(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:804
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:936
virtual void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame)
Definition: MCStreamer.cpp:473
virtual void emitCVFileChecksumOffsetDirective(unsigned FileNo)
This implements the CodeView '.cv_filechecksumoffset' assembler directive.
Definition: MCStreamer.h: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:579
virtual void emitCFIRememberState()
Definition: MCStreamer.cpp:587
virtual void emitBundleUnlock()
Ends a bundle-locked group.
virtual Expected< unsigned > tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, std::optional< MD5::MD5Result > Checksum=std::nullopt, std::optional< StringRef > Source=std::nullopt, unsigned CUID=0)
Associate a filename with a specified logical file number.
Definition: MCStreamer.cpp:232
virtual void addExplicitComment(const Twine &T)
Add explicit comment T.
Definition: MCStreamer.cpp:123
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:359
virtual void emitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc={})
This implements the CodeView '.cv_fpo_data' assembler directive.
Definition: MCStreamer.h: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:256
virtual void emitTPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a tprel (32-bit TP relative) value.
Definition: MCStreamer.cpp:207
virtual void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
Definition: MCStreamer.cpp:981
virtual void emitCFIOffset(int64_t Register, int64_t Offset)
Definition: MCStreamer.cpp:550
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:713
virtual void emitIdent(StringRef IdentString)
Emit the "identifiers" directive.
Definition: MCStreamer.h:905
virtual void emitCFIWindowSave()
Definition: MCStreamer.cpp:672
virtual void emitCVFileChecksumsDirective()
This implements the CodeView '.cv_filechecksums' assembler directive.
Definition: MCStreamer.h:1005
virtual void emitCFIRestoreState()
Definition: MCStreamer.cpp:596
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:424
virtual void emitCOFFSectionIndex(MCSymbol const *Symbol)
Emits a COFF section index.
Definition: MCStreamer.cpp:979
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:347
virtual void emitCFIRestore(int64_t Register)
Definition: MCStreamer.cpp:616
virtual void emitTPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a tprel (64-bit TP relative) value.
Definition: MCStreamer.cpp:203
virtual void emitCFISections(bool EH, bool Debug)
Definition: MCStreamer.cpp:446
virtual void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers & p...
Definition: MCStreamer.h: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:919
virtual void emitWinCFIEndChained(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:773
virtual void emitWinCFIEndProlog(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:965
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:731
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
virtual void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame)
Definition: MCStreamer.cpp:484
virtual void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue)
Set the DescValue for the Symbol.
virtual void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment)
Emit a local common (.lcomm) symbol.
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
Definition: MCStreamer.cpp:271
virtual void emitCOFFSafeSEH(MCSymbol const *Symbol)
Definition: MCStreamer.cpp:975
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:749
virtual void changeSection(MCSection *, const MCExpr *)
Update streamer for a new active section.
virtual void emitXCOFFRenameDirective(const MCSymbol *Name, StringRef Rename)
Emit a XCOFF .rename directive which creates a synonym for an illegal or undesirable name.
virtual void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, uint64_t Discriminator, const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym)
Emit the a pseudo probe into the current section.
virtual void emitCFIUndefined(int64_t Register)
Definition: MCStreamer.cpp:652
virtual void emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count)
Definition: MCStreamer.cpp:812
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:527
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:369
virtual void emitWinCFISetFrame(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:880
virtual void emitCFINegateRAState()
Definition: MCStreamer.cpp:682
virtual void emitCFIAdjustCfaOffset(int64_t Adjustment)
Definition: MCStreamer.cpp:517
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:320
virtual void emitCFISameValue(int64_t Register)
Definition: MCStreamer.cpp:606
virtual void emitWinCFIAllocStack(unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:902
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:306
virtual void emitCFISignalFrame()
Definition: MCStreamer.cpp:645
virtual void emitCFIDefCfa(int64_t Register, int64_t Offset)
Definition: MCStreamer.cpp:496
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:560
virtual void emitConditionalAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol, but only if Value is also emitted.
Definition: MCStreamer.cpp:443
virtual void emitWinCFIStartChained(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:760
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:351
void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
Definition: MCStreamer.cpp:221
virtual void emitBundleAlignMode(Align Alignment)
Set the bundle alignment mode from now on in the section.
virtual void emitRawTextImpl(StringRef String)
EmitRawText - If this file is backed by an assembly streamer, this dumps the specified string in the ...
Definition: MCStreamer.cpp:988
virtual void emitCFIEscape(StringRef Values)
Definition: MCStreamer.cpp:626
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:240
virtual void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Emit/Specify Mach-O build version command.
Definition: MCStreamer.h:512
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
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:569
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:682
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:4695
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:499
@ PLATFORM_MACCATALYST
Definition: MachO.h:506
@ PLATFORM_DRIVERKIT
Definition: MachO.h:510
@ PLATFORM_WATCHOS
Definition: MachO.h:504
@ PLATFORM_UNKNOWN
Definition: MachO.h:500
@ PLATFORM_WATCHOSSIMULATOR
Definition: MachO.h:509
@ PLATFORM_IOS
Definition: MachO.h:502
@ PLATFORM_TVOS
Definition: MachO.h:503
@ PLATFORM_TVOSSIMULATOR
Definition: MachO.h:508
@ PLATFORM_BRIDGEOS
Definition: MachO.h:505
@ PLATFORM_MACOS
Definition: MachO.h:501
@ PLATFORM_IOSSIMULATOR
Definition: MachO.h:507
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:473
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:672
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:457
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:440
@ Length
Definition: DWP.cpp:440
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