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