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