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