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