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