Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/MC/MCAsmStreamer.cpp
Line
Count
Source (jump to first uncovered line)
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
9
#include "llvm/ADT/Optional.h"
10
#include "llvm/ADT/STLExtras.h"
11
#include "llvm/ADT/SmallString.h"
12
#include "llvm/ADT/StringExtras.h"
13
#include "llvm/ADT/Twine.h"
14
#include "llvm/MC/MCAsmBackend.h"
15
#include "llvm/MC/MCAsmInfo.h"
16
#include "llvm/MC/MCAssembler.h"
17
#include "llvm/MC/MCCodeEmitter.h"
18
#include "llvm/MC/MCCodeView.h"
19
#include "llvm/MC/MCContext.h"
20
#include "llvm/MC/MCExpr.h"
21
#include "llvm/MC/MCFixupKindInfo.h"
22
#include "llvm/MC/MCInst.h"
23
#include "llvm/MC/MCInstPrinter.h"
24
#include "llvm/MC/MCObjectFileInfo.h"
25
#include "llvm/MC/MCObjectWriter.h"
26
#include "llvm/MC/MCRegisterInfo.h"
27
#include "llvm/MC/MCSectionMachO.h"
28
#include "llvm/MC/MCStreamer.h"
29
#include "llvm/Support/ErrorHandling.h"
30
#include "llvm/Support/Format.h"
31
#include "llvm/Support/FormattedStream.h"
32
#include "llvm/Support/LEB128.h"
33
#include "llvm/Support/MathExtras.h"
34
#include "llvm/Support/Path.h"
35
#include "llvm/Support/TargetRegistry.h"
36
#include <cctype>
37
38
using namespace llvm;
39
40
namespace {
41
42
class MCAsmStreamer final : public MCStreamer {
43
  std::unique_ptr<formatted_raw_ostream> OSOwner;
44
  formatted_raw_ostream &OS;
45
  const MCAsmInfo *MAI;
46
  std::unique_ptr<MCInstPrinter> InstPrinter;
47
  std::unique_ptr<MCAssembler> Assembler;
48
49
  SmallString<128> ExplicitCommentToEmit;
50
  SmallString<128> CommentToEmit;
51
  raw_svector_ostream CommentStream;
52
  raw_null_ostream NullStream;
53
54
  unsigned IsVerboseAsm : 1;
55
  unsigned ShowInst : 1;
56
  unsigned UseDwarfDirectory : 1;
57
58
  void EmitRegisterName(int64_t Register);
59
  void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
60
  void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
61
62
public:
63
  MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,
64
                bool isVerboseAsm, bool useDwarfDirectory,
65
                MCInstPrinter *printer, std::unique_ptr<MCCodeEmitter> emitter,
66
                std::unique_ptr<MCAsmBackend> asmbackend, bool showInst)
67
      : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
68
        MAI(Context.getAsmInfo()), InstPrinter(printer),
69
        Assembler(llvm::make_unique<MCAssembler>(
70
            Context, std::move(asmbackend), std::move(emitter),
71
            (asmbackend) ? asmbackend->createObjectWriter(NullStream)
72
                         : nullptr)),
73
        CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
74
26.7k
        ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
75
26.7k
    assert(InstPrinter);
76
26.7k
    if (IsVerboseAsm)
77
26.2k
        InstPrinter->setCommentStream(CommentStream);
78
26.7k
  }
79
80
3.36M
  MCAssembler &getAssembler() { return *Assembler; }
81
520k
  MCAssembler *getAssemblerPtr() override { return nullptr; }
82
83
7.01M
  inline void EmitEOL() {
84
7.01M
    // Dump Explicit Comments here.
85
7.01M
    emitExplicitComments();
86
7.01M
    // If we don't have any comments, just emit a \n.
87
7.01M
    if (!IsVerboseAsm) {
88
132k
      OS << '\n';
89
132k
      return;
90
132k
    }
91
6.88M
    EmitCommentsAndEOL();
92
6.88M
  }
93
94
  void EmitSyntaxDirective() override;
95
96
  void EmitCommentsAndEOL();
97
98
  /// Return true if this streamer supports verbose assembly at all.
99
80.1k
  bool isVerboseAsm() const override { return IsVerboseAsm; }
100
101
  /// Do we support EmitRawText?
102
5.10k
  bool hasRawTextSupport() const override { return true; }
103
104
  /// Add a comment that can be emitted to the generated .s file to make the
105
  /// output of the compiler more readable. This only affects the MCAsmStreamer
106
  /// and only when verbose assembly output is enabled.
107
  void AddComment(const Twine &T, bool EOL = true) override;
108
109
  /// Add a comment showing the encoding of an instruction.
110
  void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);
111
112
  /// Return a raw_ostream that comments can be written to.
113
  /// Unlike AddComment, you are required to terminate comments with \n if you
114
  /// use this method.
115
6.11M
  raw_ostream &GetCommentOS() override {
116
6.11M
    if (!IsVerboseAsm)
117
72.1k
      return nulls();  // Discard comments unless in verbose asm mode.
118
6.04M
    return CommentStream;
119
6.04M
  }
120
121
  void emitRawComment(const Twine &T, bool TabPrefix = true) override;
122
123
  void addExplicitComment(const Twine &T) override;
124
  void emitExplicitComments() override;
125
126
  /// Emit a blank line to a .s file to pretty it up.
127
1.06M
  void AddBlankLine() override {
128
1.06M
    EmitEOL();
129
1.06M
  }
130
131
  /// @name MCStreamer Interface
132
  /// @{
133
134
  void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
135
136
  void emitELFSymverDirective(StringRef AliasName,
137
                              const MCSymbol *Aliasee) override;
138
139
  void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
140
  void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
141
142
  void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
143
  void EmitLinkerOptions(ArrayRef<std::string> Options) override;
144
  void EmitDataRegion(MCDataRegionType Kind) override;
145
  void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
146
                      unsigned Update, VersionTuple SDKVersion) override;
147
  void EmitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
148
                        unsigned Update, VersionTuple SDKVersion) override;
149
  void EmitThumbFunc(MCSymbol *Func) override;
150
151
  void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
152
  void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
153
  bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
154
155
  void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
156
  void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
157
  void EmitCOFFSymbolStorageClass(int StorageClass) override;
158
  void EmitCOFFSymbolType(int Type) override;
159
  void EndCOFFSymbolDef() override;
160
  void EmitCOFFSafeSEH(MCSymbol const *Symbol) override;
161
  void EmitCOFFSymbolIndex(MCSymbol const *Symbol) override;
162
  void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
163
  void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
164
  void EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
165
  void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
166
  void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
167
                        unsigned ByteAlignment) override;
168
169
  /// Emit a local common (.lcomm) symbol.
170
  ///
171
  /// @param Symbol - The common symbol to emit.
172
  /// @param Size - The size of the common symbol.
173
  /// @param ByteAlignment - The alignment of the common symbol in bytes.
174
  void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
175
                             unsigned ByteAlignment) override;
176
177
  void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
178
                    uint64_t Size = 0, unsigned ByteAlignment = 0,
179
                    SMLoc Loc = SMLoc()) override;
180
181
  void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
182
                      unsigned ByteAlignment = 0) override;
183
184
  void EmitBinaryData(StringRef Data) override;
185
186
  void EmitBytes(StringRef Data) override;
187
188
  void EmitValueImpl(const MCExpr *Value, unsigned Size,
189
                     SMLoc Loc = SMLoc()) override;
190
  void EmitIntValue(uint64_t Value, unsigned Size) override;
191
  void EmitIntValueInHex(uint64_t Value, unsigned Size) override;
192
193
  void EmitULEB128Value(const MCExpr *Value) override;
194
195
  void EmitSLEB128Value(const MCExpr *Value) override;
196
197
  void EmitDTPRel32Value(const MCExpr *Value) override;
198
  void EmitDTPRel64Value(const MCExpr *Value) override;
199
  void EmitTPRel32Value(const MCExpr *Value) override;
200
  void EmitTPRel64Value(const MCExpr *Value) override;
201
202
  void EmitGPRel64Value(const MCExpr *Value) override;
203
204
  void EmitGPRel32Value(const MCExpr *Value) override;
205
206
  void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
207
                SMLoc Loc = SMLoc()) override;
208
209
  void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
210
                SMLoc Loc = SMLoc()) override;
211
212
  void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
213
                            unsigned ValueSize = 1,
214
                            unsigned MaxBytesToEmit = 0) override;
215
216
  void EmitCodeAlignment(unsigned ByteAlignment,
217
                         unsigned MaxBytesToEmit = 0) override;
218
219
  void emitValueToOffset(const MCExpr *Offset,
220
                         unsigned char Value,
221
                         SMLoc Loc) override;
222
223
  void EmitFileDirective(StringRef Filename) override;
224
  Expected<unsigned> tryEmitDwarfFileDirective(unsigned FileNo,
225
                                               StringRef Directory,
226
                                               StringRef Filename,
227
                                               Optional<MD5::MD5Result> Checksum = None,
228
                                               Optional<StringRef> Source = None,
229
                                               unsigned CUID = 0) override;
230
  void emitDwarfFile0Directive(StringRef Directory, StringRef Filename,
231
                               Optional<MD5::MD5Result> Checksum,
232
                               Optional<StringRef> Source,
233
                               unsigned CUID = 0) override;
234
  void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
235
                             unsigned Column, unsigned Flags,
236
                             unsigned Isa, unsigned Discriminator,
237
                             StringRef FileName) override;
238
  MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
239
240
  bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
241
                           ArrayRef<uint8_t> Checksum,
242
                           unsigned ChecksumKind) override;
243
  bool EmitCVFuncIdDirective(unsigned FuncId) override;
244
  bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
245
                                   unsigned IAFile, unsigned IALine,
246
                                   unsigned IACol, SMLoc Loc) override;
247
  void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
248
                          unsigned Column, bool PrologueEnd, bool IsStmt,
249
                          StringRef FileName, SMLoc Loc) override;
250
  void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart,
251
                                const MCSymbol *FnEnd) override;
252
  void EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
253
                                      unsigned SourceFileId,
254
                                      unsigned SourceLineNum,
255
                                      const MCSymbol *FnStartSym,
256
                                      const MCSymbol *FnEndSym) override;
257
  void EmitCVDefRangeDirective(
258
      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
259
      StringRef FixedSizePortion) override;
260
  void EmitCVStringTableDirective() override;
261
  void EmitCVFileChecksumsDirective() override;
262
  void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
263
  void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;
264
265
  void EmitIdent(StringRef IdentString) override;
266
  void EmitCFIBKeyFrame() override;
267
  void EmitCFISections(bool EH, bool Debug) override;
268
  void EmitCFIDefCfa(int64_t Register, int64_t Offset) override;
269
  void EmitCFIDefCfaOffset(int64_t Offset) override;
270
  void EmitCFIDefCfaRegister(int64_t Register) override;
271
  void EmitCFIOffset(int64_t Register, int64_t Offset) override;
272
  void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
273
  void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
274
  void EmitCFIRememberState() override;
275
  void EmitCFIRestoreState() override;
276
  void EmitCFIRestore(int64_t Register) override;
277
  void EmitCFISameValue(int64_t Register) override;
278
  void EmitCFIRelOffset(int64_t Register, int64_t Offset) override;
279
  void EmitCFIAdjustCfaOffset(int64_t Adjustment) override;
280
  void EmitCFIEscape(StringRef Values) override;
281
  void EmitCFIGnuArgsSize(int64_t Size) override;
282
  void EmitCFISignalFrame() override;
283
  void EmitCFIUndefined(int64_t Register) override;
284
  void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
285
  void EmitCFIWindowSave() override;
286
  void EmitCFINegateRAState() override;
287
  void EmitCFIReturnColumn(int64_t Register) override;
288
289
  void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
290
  void EmitWinCFIEndProc(SMLoc Loc) override;
291
  void EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) override;
292
  void EmitWinCFIStartChained(SMLoc Loc) override;
293
  void EmitWinCFIEndChained(SMLoc Loc) override;
294
  void EmitWinCFIPushReg(unsigned Register, SMLoc Loc) override;
295
  void EmitWinCFISetFrame(unsigned Register, unsigned Offset,
296
                          SMLoc Loc) override;
297
  void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
298
  void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
299
                         SMLoc Loc) override;
300
  void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
301
                         SMLoc Loc) override;
302
  void EmitWinCFIPushFrame(bool Code, SMLoc Loc) override;
303
  void EmitWinCFIEndProlog(SMLoc Loc) override;
304
305
  void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
306
                        SMLoc Loc) override;
307
  void EmitWinEHHandlerData(SMLoc Loc) override;
308
309
  void emitCGProfileEntry(const MCSymbolRefExpr *From,
310
                          const MCSymbolRefExpr *To, uint64_t Count) override;
311
312
  void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
313
314
  void EmitBundleAlignMode(unsigned AlignPow2) override;
315
  void EmitBundleLock(bool AlignToEnd) override;
316
  void EmitBundleUnlock() override;
317
318
  bool EmitRelocDirective(const MCExpr &Offset, StringRef Name,
319
                          const MCExpr *Expr, SMLoc Loc,
320
                          const MCSubtargetInfo &STI) override;
321
322
  void EmitAddrsig() override;
323
  void EmitAddrsigSym(const MCSymbol *Sym) override;
324
325
  /// If this file is backed by an assembly streamer, this dumps the specified
326
  /// string in the output .s file. This capability is indicated by the
327
  /// hasRawTextSupport() predicate.
328
  void EmitRawTextImpl(StringRef String) override;
329
330
  void FinishImpl() override;
331
};
332
333
} // end anonymous namespace.
334
335
179k
void MCAsmStreamer::AddComment(const Twine &T, bool EOL) {
336
179k
  if (!IsVerboseAsm) 
return1.60k
;
337
177k
338
177k
  T.toVector(CommentToEmit);
339
177k
340
177k
  if (EOL)
341
171k
    CommentToEmit.push_back('\n'); // Place comment in a new line.
342
177k
}
343
344
6.88M
void MCAsmStreamer::EmitCommentsAndEOL() {
345
6.88M
  if (CommentToEmit.empty() && 
CommentStream.GetNumBytesInBuffer() == 04.86M
) {
346
4.86M
    OS << '\n';
347
4.86M
    return;
348
4.86M
  }
349
2.01M
350
2.01M
  StringRef Comments = CommentToEmit;
351
2.01M
352
2.01M
  assert(Comments.back() == '\n' &&
353
2.01M
         "Comment array not newline terminated");
354
2.08M
  do {
355
2.08M
    // Emit a line of comments.
356
2.08M
    OS.PadToColumn(MAI->getCommentColumn());
357
2.08M
    size_t Position = Comments.find('\n');
358
2.08M
    OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
359
2.08M
360
2.08M
    Comments = Comments.substr(Position+1);
361
2.08M
  } while (!Comments.empty());
362
2.01M
363
2.01M
  CommentToEmit.clear();
364
2.01M
}
365
366
113k
static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
367
113k
  assert(Bytes > 0 && Bytes <= 8 && "Invalid size!");
368
113k
  return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
369
113k
}
370
371
729k
void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
372
729k
  if (TabPrefix)
373
27.3k
    OS << '\t';
374
729k
  OS << MAI->getCommentString() << T;
375
729k
  EmitEOL();
376
729k
}
377
378
320
void MCAsmStreamer::addExplicitComment(const Twine &T) {
379
320
  StringRef c = T.getSingleStringRef();
380
320
  if (c.equals(StringRef(MAI->getSeparatorString())))
381
64
    return;
382
256
  if (c.startswith(StringRef("//"))) {
383
51
    ExplicitCommentToEmit.append("\t");
384
51
    ExplicitCommentToEmit.append(MAI->getCommentString());
385
51
    // drop //
386
51
    ExplicitCommentToEmit.append(c.slice(2, c.size()).str());
387
205
  } else if (c.startswith(StringRef("/*"))) {
388
13
    size_t p = 2, len = c.size() - 2;
389
13
    // emit each line in comment as separate newline.
390
14
    do {
391
14
      size_t newp = std::min(len, c.find_first_of("\r\n", p));
392
14
      ExplicitCommentToEmit.append("\t");
393
14
      ExplicitCommentToEmit.append(MAI->getCommentString());
394
14
      ExplicitCommentToEmit.append(c.slice(p, newp).str());
395
14
      // If we have another line in this comment add line
396
14
      if (newp < len)
397
1
        ExplicitCommentToEmit.append("\n");
398
14
      p = newp + 1;
399
14
    } while (p < len);
400
192
  } else if (c.startswith(StringRef(MAI->getCommentString()))) {
401
170
    ExplicitCommentToEmit.append("\t");
402
170
    ExplicitCommentToEmit.append(c.str());
403
170
  } else 
if (22
c.front() == '#'22
) {
404
22
405
22
    ExplicitCommentToEmit.append("\t");
406
22
    ExplicitCommentToEmit.append(MAI->getCommentString());
407
22
    ExplicitCommentToEmit.append(c.slice(1, c.size()).str());
408
22
  } else
409
22
    assert(false && "Unexpected Assembly Comment");
410
256
  // full line comments immediately output
411
256
  if (c.back() == '\n')
412
228
    emitExplicitComments();
413
256
}
414
415
7.01M
void MCAsmStreamer::emitExplicitComments() {
416
7.01M
  StringRef Comments = ExplicitCommentToEmit;
417
7.01M
  if (!Comments.empty())
418
252
    OS << Comments;
419
7.01M
  ExplicitCommentToEmit.clear();
420
7.01M
}
421
422
void MCAsmStreamer::ChangeSection(MCSection *Section,
423
205k
                                  const MCExpr *Subsection) {
424
205k
  assert(Section && "Cannot switch to a null section!");
425
205k
  if (MCTargetStreamer *TS = getTargetStreamer()) {
426
194k
    TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS);
427
194k
  } else {
428
11.6k
    Section->PrintSwitchToSection(
429
11.6k
        *MAI, getContext().getObjectFileInfo()->getTargetTriple(), OS,
430
11.6k
        Subsection);
431
11.6k
  }
432
205k
}
433
434
void MCAsmStreamer::emitELFSymverDirective(StringRef AliasName,
435
6
                                           const MCSymbol *Aliasee) {
436
6
  OS << ".symver ";
437
6
  Aliasee->print(OS, MAI);
438
6
  OS << ", " << AliasName;
439
6
  EmitEOL();
440
6
}
441
442
538k
void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
443
538k
  MCStreamer::EmitLabel(Symbol, Loc);
444
538k
445
538k
  Symbol->print(OS, MAI);
446
538k
  OS << MAI->getLabelSuffix();
447
538k
448
538k
  EmitEOL();
449
538k
}
450
451
238
void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
452
238
  StringRef str = MCLOHIdToName(Kind);
453
238
454
#ifndef NDEBUG
455
  int NbArgs = MCLOHIdToNbArgs(Kind);
456
  assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
457
  assert(str != "" && "Invalid LOH name");
458
#endif
459
460
238
  OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
461
238
  bool IsFirst = true;
462
543
  for (const MCSymbol *Arg : Args) {
463
543
    if (!IsFirst)
464
305
      OS << ", ";
465
543
    IsFirst = false;
466
543
    Arg->print(OS, MAI);
467
543
  }
468
238
  EmitEOL();
469
238
}
470
471
22.2k
void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
472
22.2k
  switch (Flag) {
473
22.2k
  
case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break2.89k
;
474
22.2k
  
case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break2.51k
;
475
22.2k
  
case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break7.86k
;
476
22.2k
  
case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break8.93k
;
477
22.2k
  
case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break2
;
478
22.2k
  }
479
22.2k
  EmitEOL();
480
22.2k
}
481
482
5
void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
483
5
  assert(!Options.empty() && "At least one option is required!");
484
5
  OS << "\t.linker_option \"" << Options[0] << '"';
485
5
  for (ArrayRef<std::string>::iterator it = Options.begin() + 1,
486
7
         ie = Options.end(); it != ie; 
++it2
) {
487
2
    OS << ", " << '"' << *it << '"';
488
2
  }
489
5
  EmitEOL();
490
5
}
491
492
3.69k
void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
493
3.69k
  if (!MAI->doesSupportDataRegionDirectives())
494
2.81k
    return;
495
884
  switch (Kind) {
496
884
  
case MCDR_DataRegion: OS << "\t.data_region"; break392
;
497
884
  
case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break15
;
498
884
  
case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break0
;
499
884
  
case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break35
;
500
884
  
case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break442
;
501
884
  }
502
884
  EmitEOL();
503
884
}
504
505
1.07k
static const char *getVersionMinDirective(MCVersionMinType Type) {
506
1.07k
  switch (Type) {
507
1.07k
  
case MCVM_WatchOSVersionMin: return ".watchos_version_min"26
;
508
1.07k
  
case MCVM_TvOSVersionMin: return ".tvos_version_min"18
;
509
1.07k
  
case MCVM_IOSVersionMin: return ".ios_version_min"185
;
510
1.07k
  
case MCVM_OSXVersionMin: return ".macosx_version_min"848
;
511
0
  }
512
0
  llvm_unreachable("Invalid MC version min type");
513
0
}
514
515
static void EmitSDKVersionSuffix(raw_ostream &OS,
516
1.09k
                                 const VersionTuple &SDKVersion) {
517
1.09k
  if (SDKVersion.empty())
518
1.08k
    return;
519
11
  OS << '\t' << "sdk_version " << SDKVersion.getMajor();
520
11
  if (auto Minor = SDKVersion.getMinor()) {
521
11
    OS << ", " << *Minor;
522
11
    if (auto Subminor = SDKVersion.getSubminor()) {
523
3
      OS << ", " << *Subminor;
524
3
    }
525
11
  }
526
11
}
527
528
void MCAsmStreamer::EmitVersionMin(MCVersionMinType Type, unsigned Major,
529
                                   unsigned Minor, unsigned Update,
530
1.07k
                                   VersionTuple SDKVersion) {
531
1.07k
  OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
532
1.07k
  if (Update)
533
43
    OS << ", " << Update;
534
1.07k
  EmitSDKVersionSuffix(OS, SDKVersion);
535
1.07k
  EmitEOL();
536
1.07k
}
537
538
14
static const char *getPlatformName(MachO::PlatformType Type) {
539
14
  switch (Type) {
540
14
  
case MachO::PLATFORM_MACOS: return "macos"5
;
541
14
  
case MachO::PLATFORM_IOS: return "ios"2
;
542
14
  
case MachO::PLATFORM_TVOS: return "tvos"3
;
543
14
  
case MachO::PLATFORM_WATCHOS: return "watchos"2
;
544
14
  
case MachO::PLATFORM_BRIDGEOS: return "bridgeos"0
;
545
14
  
case MachO::PLATFORM_MACCATALYST: return "macCatalyst"2
;
546
14
  
case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator"0
;
547
14
  
case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator"0
;
548
14
  
case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator"0
;
549
0
  }
550
0
  llvm_unreachable("Invalid Mach-O platform type");
551
0
}
552
553
void MCAsmStreamer::EmitBuildVersion(unsigned Platform, unsigned Major,
554
                                     unsigned Minor, unsigned Update,
555
14
                                     VersionTuple SDKVersion) {
556
14
  const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
557
14
  OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
558
14
  if (Update)
559
4
    OS << ", " << Update;
560
14
  EmitSDKVersionSuffix(OS, SDKVersion);
561
14
  EmitEOL();
562
14
}
563
564
7.67k
void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
565
7.67k
  // This needs to emit to a temporary string to get properly quoted
566
7.67k
  // MCSymbols when they have spaces in them.
567
7.67k
  OS << "\t.thumb_func";
568
7.67k
  // Only Mach-O hasSubsectionsViaSymbols()
569
7.67k
  if (MAI->hasSubsectionsViaSymbols()) {
570
1.33k
    OS << '\t';
571
1.33k
    Func->print(OS, MAI);
572
1.33k
  }
573
7.67k
  EmitEOL();
574
7.67k
}
575
576
2.93k
void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
577
2.93k
  // Do not emit a .set on inlined target assignments.
578
2.93k
  bool EmitSet = true;
579
2.93k
  if (auto *E = dyn_cast<MCTargetExpr>(Value))
580
12
    if (E->inlineAssignedExpr())
581
12
      EmitSet = false;
582
2.93k
  if (EmitSet) {
583
2.92k
    OS << ".set ";
584
2.92k
    Symbol->print(OS, MAI);
585
2.92k
    OS << ", ";
586
2.92k
    Value->print(OS, MAI);
587
2.92k
588
2.92k
    EmitEOL();
589
2.92k
  }
590
2.93k
591
2.93k
  MCStreamer::EmitAssignment(Symbol, Value);
592
2.93k
}
593
594
0
void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
595
0
  OS << ".weakref ";
596
0
  Alias->print(OS, MAI);
597
0
  OS << ", ";
598
0
  Symbol->print(OS, MAI);
599
0
  EmitEOL();
600
0
}
601
602
bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
603
441k
                                        MCSymbolAttr Attribute) {
604
441k
  switch (Attribute) {
605
441k
  
case MCSA_Invalid: 0
llvm_unreachable0
("Invalid symbol attribute");
606
441k
  case MCSA_ELF_TypeFunction:    /// .type _foo, STT_FUNC  # aka @function
607
208k
  case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
608
208k
  case MCSA_ELF_TypeObject:      /// .type _foo, STT_OBJECT  # aka @object
609
208k
  case MCSA_ELF_TypeTLS:         /// .type _foo, STT_TLS     # aka @tls_object
610
208k
  case MCSA_ELF_TypeCommon:      /// .type _foo, STT_COMMON  # aka @common
611
208k
  case MCSA_ELF_TypeNoType:      /// .type _foo, STT_NOTYPE  # aka @notype
612
208k
  case MCSA_ELF_TypeGnuUniqueObject:  /// .type _foo, @gnu_unique_object
613
208k
    if (!MAI->hasDotTypeDotSizeDirective())
614
83
      return false; // Symbol attribute not supported
615
208k
    OS << "\t.type\t";
616
208k
    Symbol->print(OS, MAI);
617
208k
    OS << ',' << ((MAI->getCommentString()[0] != '@') ? 
'@'193k
:
'%'14.7k
);
618
208k
    switch (Attribute) {
619
208k
    
default: return false0
;
620
208k
    
case MCSA_ELF_TypeFunction: OS << "function"; break197k
;
621
208k
    
case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break7
;
622
208k
    
case MCSA_ELF_TypeObject: OS << "object"; break11.3k
;
623
208k
    
case MCSA_ELF_TypeTLS: OS << "tls_object"; break1
;
624
208k
    
case MCSA_ELF_TypeCommon: OS << "common"; break1
;
625
208k
    
case MCSA_ELF_TypeNoType: OS << "notype"; break1
;
626
208k
    
case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break3
;
627
208k
    }
628
208k
    EmitEOL();
629
208k
    return true;
630
230k
  case MCSA_Global: // .globl/.global
631
230k
    OS << MAI->getGlobalDirective();
632
230k
    break;
633
208k
  
case MCSA_Hidden: OS << "\t.hidden\t"; break877
;
634
208k
  
case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break587
;
635
208k
  
case MCSA_Internal: OS << "\t.internal\t"; break0
;
636
208k
  
case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break9
;
637
208k
  
case MCSA_Local: OS << "\t.local\t"; break260
;
638
208k
  case MCSA_NoDeadStrip:
639
145
    if (!MAI->hasNoDeadStrip())
640
68
      return false;
641
77
    OS << "\t.no_dead_strip\t";
642
77
    break;
643
77
  
case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break4
;
644
77
  
case MCSA_AltEntry: OS << "\t.alt_entry\t"; break8
;
645
88
  case MCSA_PrivateExtern:
646
88
    OS << "\t.private_extern\t";
647
88
    break;
648
77
  
case MCSA_Protected: OS << "\t.protected\t"; break50
;
649
77
  
case MCSA_Reference: OS << "\t.reference\t"; break4
;
650
447
  case MCSA_Weak:           OS << MAI->getWeakDirective(); break;
651
176
  case MCSA_WeakDefinition:
652
176
    OS << "\t.weak_definition\t";
653
176
    break;
654
77
      // .weak_reference
655
155
  case MCSA_WeakReference:  OS << MAI->getWeakRefDirective(); break;
656
77
  
case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break20
;
657
77
  case MCSA_Cold:
658
0
    // Assemblers currently do not support a .cold directive.
659
0
    return false;
660
232k
  }
661
232k
662
232k
  Symbol->print(OS, MAI);
663
232k
  EmitEOL();
664
232k
665
232k
  return true;
666
232k
}
667
668
3
void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
669
3
  OS << ".desc" << ' ';
670
3
  Symbol->print(OS, MAI);
671
3
  OS << ',' << DescValue;
672
3
  EmitEOL();
673
3
}
674
675
7.86k
void MCAsmStreamer::EmitSyntaxDirective() {
676
7.86k
  if (MAI->getAssemblerDialect() == 1) {
677
19
    OS << "\t.intel_syntax noprefix";
678
19
    EmitEOL();
679
19
  }
680
7.86k
  // FIXME: Currently emit unprefix'ed registers.
681
7.86k
  // The intel_syntax directive has one optional argument
682
7.86k
  // with may have a value of prefix or noprefix.
683
7.86k
}
684
685
3.55k
void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
686
3.55k
  OS << "\t.def\t ";
687
3.55k
  Symbol->print(OS, MAI);
688
3.55k
  OS << ';';
689
3.55k
  EmitEOL();
690
3.55k
}
691
692
3.55k
void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
693
3.55k
  OS << "\t.scl\t" << StorageClass << ';';
694
3.55k
  EmitEOL();
695
3.55k
}
696
697
3.55k
void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
698
3.55k
  OS << "\t.type\t" << Type << ';';
699
3.55k
  EmitEOL();
700
3.55k
}
701
702
3.55k
void MCAsmStreamer::EndCOFFSymbolDef() {
703
3.55k
  OS << "\t.endef";
704
3.55k
  EmitEOL();
705
3.55k
}
706
707
30
void MCAsmStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
708
30
  OS << "\t.safeseh\t";
709
30
  Symbol->print(OS, MAI);
710
30
  EmitEOL();
711
30
}
712
713
4
void MCAsmStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {
714
4
  OS << "\t.symidx\t";
715
4
  Symbol->print(OS, MAI);
716
4
  EmitEOL();
717
4
}
718
719
269
void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
720
269
  OS << "\t.secidx\t";
721
269
  Symbol->print(OS, MAI);
722
269
  EmitEOL();
723
269
}
724
725
456
void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {
726
456
  OS << "\t.secrel32\t";
727
456
  Symbol->print(OS, MAI);
728
456
  if (Offset != 0)
729
2
    OS << '+' << Offset;
730
456
  EmitEOL();
731
456
}
732
733
0
void MCAsmStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
734
0
  OS << "\t.rva\t";
735
0
  Symbol->print(OS, MAI);
736
0
  if (Offset > 0)
737
0
    OS << '+' << Offset;
738
0
  else if (Offset < 0)
739
0
    OS << '-' << -Offset;
740
0
  EmitEOL();
741
0
}
742
743
205k
void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
744
205k
  assert(MAI->hasDotTypeDotSizeDirective());
745
205k
  OS << "\t.size\t";
746
205k
  Symbol->print(OS, MAI);
747
205k
  OS << ", ";
748
205k
  Value->print(OS, MAI);
749
205k
  EmitEOL();
750
205k
}
751
752
void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
753
3.09k
                                     unsigned ByteAlignment) {
754
3.09k
  OS << "\t.comm\t";
755
3.09k
  Symbol->print(OS, MAI);
756
3.09k
  OS << ',' << Size;
757
3.09k
758
3.09k
  if (ByteAlignment != 0) {
759
2.98k
    if (MAI->getCOMMDirectiveAlignmentIsInBytes())
760
2.74k
      OS << ',' << ByteAlignment;
761
240
    else
762
240
      OS << ',' << Log2_32(ByteAlignment);
763
2.98k
  }
764
3.09k
  EmitEOL();
765
3.09k
}
766
767
void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
768
49
                                          unsigned ByteAlign) {
769
49
  OS << "\t.lcomm\t";
770
49
  Symbol->print(OS, MAI);
771
49
  OS << ',' << Size;
772
49
773
49
  if (ByteAlign > 1) {
774
39
    switch (MAI->getLCOMMDirectiveAlignmentType()) {
775
39
    case LCOMM::NoAlignment:
776
0
      llvm_unreachable("alignment not supported on .lcomm!");
777
39
    case LCOMM::ByteAlignment:
778
38
      OS << ',' << ByteAlign;
779
38
      break;
780
39
    case LCOMM::Log2Alignment:
781
1
      assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
782
1
      OS << ',' << Log2_32(ByteAlign);
783
1
      break;
784
49
    }
785
49
  }
786
49
  EmitEOL();
787
49
}
788
789
void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
790
                                 uint64_t Size, unsigned ByteAlignment,
791
303
                                 SMLoc Loc) {
792
303
  if (Symbol)
793
302
    AssignFragment(Symbol, &Section->getDummyFragment());
794
303
795
303
  // Note: a .zerofill directive does not switch sections.
796
303
  OS << ".zerofill ";
797
303
798
303
  assert(Section->getVariant() == MCSection::SV_MachO &&
799
303
         ".zerofill is a Mach-O specific directive");
800
303
  // This is a mach-o specific directive.
801
303
802
303
  const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
803
303
  OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
804
303
805
303
  if (Symbol) {
806
302
    OS << ',';
807
302
    Symbol->print(OS, MAI);
808
302
    OS << ',' << Size;
809
302
    if (ByteAlignment != 0)
810
302
      OS << ',' << Log2_32(ByteAlignment);
811
302
  }
812
303
  EmitEOL();
813
303
}
814
815
// .tbss sym, size, align
816
// This depends that the symbol has already been mangled from the original,
817
// e.g. _a.
818
void MCAsmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
819
73
                                   uint64_t Size, unsigned ByteAlignment) {
820
73
  AssignFragment(Symbol, &Section->getDummyFragment());
821
73
822
73
  assert(Symbol && "Symbol shouldn't be NULL!");
823
73
  // Instead of using the Section we'll just use the shortcut.
824
73
825
73
  assert(Section->getVariant() == MCSection::SV_MachO &&
826
73
         ".zerofill is a Mach-O specific directive");
827
73
  // This is a mach-o specific directive and section.
828
73
829
73
  OS << ".tbss ";
830
73
  Symbol->print(OS, MAI);
831
73
  OS << ", " << Size;
832
73
833
73
  // Output align if we have it.  We default to 1 so don't bother printing
834
73
  // that.
835
73
  if (ByteAlignment > 1) 
OS << ", " << Log2_32(ByteAlignment)42
;
836
73
837
73
  EmitEOL();
838
73
}
839
840
12.6k
static inline char toOctal(int X) { return (X&7)+'0'; }
841
842
33.0k
static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
843
33.0k
  OS << '"';
844
33.0k
845
724k
  for (unsigned i = 0, e = Data.size(); i != e; 
++i691k
) {
846
691k
    unsigned char C = Data[i];
847
691k
    if (C == '"' || 
C == '\\'691k
) {
848
833
      OS << '\\' << (char)C;
849
833
      continue;
850
833
    }
851
690k
852
690k
    if (isPrint((unsigned char)C)) {
853
685k
      OS << (char)C;
854
685k
      continue;
855
685k
    }
856
4.78k
857
4.78k
    switch (C) {
858
4.78k
      
case '\b': OS << "\\b"; break73
;
859
4.78k
      
case '\f': OS << "\\f"; break11
;
860
4.78k
      
case '\n': OS << "\\n"; break405
;
861
4.78k
      
case '\r': OS << "\\r"; break7
;
862
4.78k
      
case '\t': OS << "\\t"; break68
;
863
4.78k
      default:
864
4.21k
        OS << '\\';
865
4.21k
        OS << toOctal(C >> 6);
866
4.21k
        OS << toOctal(C >> 3);
867
4.21k
        OS << toOctal(C >> 0);
868
4.21k
        break;
869
4.78k
    }
870
4.78k
  }
871
33.0k
872
33.0k
  OS << '"';
873
33.0k
}
874
875
67.4k
void MCAsmStreamer::EmitBytes(StringRef Data) {
876
67.4k
  assert(getCurrentSectionOnly() &&
877
67.4k
         "Cannot emit contents before setting section!");
878
67.4k
  if (Data.empty()) 
return139
;
879
67.3k
880
67.3k
  // If only single byte is provided or no ascii or asciz directives is
881
67.3k
  // supported, emit as vector of 8bits data.
882
67.3k
  if (Data.size() == 1 ||
883
67.3k
      
!(15.7k
MAI->getAscizDirective()15.7k
||
MAI->getAsciiDirective()449
)) {
884
52.0k
    if (MCTargetStreamer *TS = getTargetStreamer()) {
885
40.0k
      TS->emitRawBytes(Data);
886
40.0k
    } else {
887
11.9k
      const char *Directive = MAI->getData8bitsDirective();
888
11.9k
      for (const unsigned char C : Data.bytes()) {
889
11.9k
        OS << Directive << (unsigned)C;
890
11.9k
        EmitEOL();
891
11.9k
      }
892
11.9k
    }
893
52.0k
    return;
894
52.0k
  }
895
15.3k
896
15.3k
  // If the data ends with 0 and the target supports .asciz, use it, otherwise
897
15.3k
  // use .ascii
898
15.3k
  if (MAI->getAscizDirective() && Data.back() == 0) {
899
13.2k
    OS << MAI->getAscizDirective();
900
13.2k
    Data = Data.substr(0, Data.size()-1);
901
13.2k
  } else {
902
2.07k
    OS << MAI->getAsciiDirective();
903
2.07k
  }
904
15.3k
905
15.3k
  PrintQuotedString(Data, OS);
906
15.3k
  EmitEOL();
907
15.3k
}
908
909
423
void MCAsmStreamer::EmitBinaryData(StringRef Data) {
910
423
  // This is binary data. Print it in a grid of hex bytes for readability.
911
423
  const size_t Cols = 4;
912
875
  for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; 
I += Cols452
) {
913
452
    size_t J = I, EJ = std::min(I + Cols, Data.size());
914
452
    assert(EJ > 0);
915
452
    OS << MAI->getData8bitsDirective();
916
624
    for (; J < EJ - 1; 
++J172
)
917
172
      OS << format("0x%02x", uint8_t(Data[J])) << ", ";
918
452
    OS << format("0x%02x", uint8_t(Data[J]));
919
452
    EmitEOL();
920
452
  }
921
423
}
922
923
575k
void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
924
575k
  EmitValue(MCConstantExpr::create(Value, getContext()), Size);
925
575k
}
926
927
26.3k
void MCAsmStreamer::EmitIntValueInHex(uint64_t Value, unsigned Size) {
928
26.3k
  EmitValue(MCConstantExpr::create(Value, getContext(), true), Size);
929
26.3k
}
930
931
void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
932
632k
                                  SMLoc Loc) {
933
632k
  assert(Size <= 8 && "Invalid size");
934
632k
  assert(getCurrentSectionOnly() &&
935
632k
         "Cannot emit contents before setting section!");
936
632k
  const char *Directive = nullptr;
937
632k
  switch (Size) {
938
632k
  
default: break0
;
939
632k
  
case 1: Directive = MAI->getData8bitsDirective(); break153k
;
940
632k
  
case 2: Directive = MAI->getData16bitsDirective(); break99.2k
;
941
632k
  
case 4: Directive = MAI->getData32bitsDirective(); break331k
;
942
632k
  
case 8: Directive = MAI->getData64bitsDirective(); break47.7k
;
943
632k
  }
944
632k
945
632k
  if (!Directive) {
946
823
    int64_t IntValue;
947
823
    if (!Value->evaluateAsAbsolute(IntValue))
948
0
      report_fatal_error("Don't know how to emit this value.");
949
823
950
823
    // We couldn't handle the requested integer size so we fallback by breaking
951
823
    // the request down into several, smaller, integers.
952
823
    // Since sizes greater or equal to "Size" are invalid, we use the greatest
953
823
    // power of 2 that is less than "Size" as our largest piece of granularity.
954
823
    bool IsLittleEndian = MAI->isLittleEndian();
955
2.46k
    for (unsigned Emitted = 0; Emitted != Size;) {
956
1.64k
      unsigned Remaining = Size - Emitted;
957
1.64k
      // The size of our partial emission must be a power of two less than
958
1.64k
      // Size.
959
1.64k
      unsigned EmissionSize = PowerOf2Floor(std::min(Remaining, Size - 1));
960
1.64k
      // Calculate the byte offset of our partial emission taking into account
961
1.64k
      // the endianness of the target.
962
1.64k
      unsigned ByteOffset =
963
1.64k
          IsLittleEndian ? 
Emitted1.49k
:
(Remaining - EmissionSize)154
;
964
1.64k
      uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
965
1.64k
      // We truncate our partial emission to fit within the bounds of the
966
1.64k
      // emission domain.  This produces nicer output and silences potential
967
1.64k
      // truncation warnings when round tripping through another assembler.
968
1.64k
      uint64_t Shift = 64 - EmissionSize * 8;
969
1.64k
      assert(Shift < static_cast<uint64_t>(
970
1.64k
                         std::numeric_limits<unsigned long long>::digits) &&
971
1.64k
             "undefined behavior");
972
1.64k
      ValueToEmit &= ~0ULL >> Shift;
973
1.64k
      EmitIntValue(ValueToEmit, EmissionSize);
974
1.64k
      Emitted += EmissionSize;
975
1.64k
    }
976
823
    return;
977
823
  }
978
631k
979
631k
  assert(Directive && "Invalid size for machine code value!");
980
631k
  OS << Directive;
981
631k
  if (MCTargetStreamer *TS = getTargetStreamer()) {
982
604k
    TS->emitValue(Value);
983
604k
  } else {
984
26.8k
    Value->print(OS, MAI);
985
26.8k
    EmitEOL();
986
26.8k
  }
987
631k
}
988
989
2.23k
void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
990
2.23k
  int64_t IntValue;
991
2.23k
  if (Value->evaluateAsAbsolute(IntValue)) {
992
4
    EmitULEB128IntValue(IntValue);
993
4
    return;
994
4
  }
995
2.23k
  OS << "\t.uleb128 ";
996
2.23k
  Value->print(OS, MAI);
997
2.23k
  EmitEOL();
998
2.23k
}
999
1000
4
void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
1001
4
  int64_t IntValue;
1002
4
  if (Value->evaluateAsAbsolute(IntValue)) {
1003
4
    EmitSLEB128IntValue(IntValue);
1004
4
    return;
1005
4
  }
1006
0
  OS << "\t.sleb128 ";
1007
0
  Value->print(OS, MAI);
1008
0
  EmitEOL();
1009
0
}
1010
1011
3
void MCAsmStreamer::EmitDTPRel64Value(const MCExpr *Value) {
1012
3
  assert(MAI->getDTPRel64Directive() != nullptr);
1013
3
  OS << MAI->getDTPRel64Directive();
1014
3
  Value->print(OS, MAI);
1015
3
  EmitEOL();
1016
3
}
1017
1018
3
void MCAsmStreamer::EmitDTPRel32Value(const MCExpr *Value) {
1019
3
  assert(MAI->getDTPRel32Directive() != nullptr);
1020
3
  OS << MAI->getDTPRel32Directive();
1021
3
  Value->print(OS, MAI);
1022
3
  EmitEOL();
1023
3
}
1024
1025
2
void MCAsmStreamer::EmitTPRel64Value(const MCExpr *Value) {
1026
2
  assert(MAI->getTPRel64Directive() != nullptr);
1027
2
  OS << MAI->getTPRel64Directive();
1028
2
  Value->print(OS, MAI);
1029
2
  EmitEOL();
1030
2
}
1031
1032
2
void MCAsmStreamer::EmitTPRel32Value(const MCExpr *Value) {
1033
2
  assert(MAI->getTPRel32Directive() != nullptr);
1034
2
  OS << MAI->getTPRel32Directive();
1035
2
  Value->print(OS, MAI);
1036
2
  EmitEOL();
1037
2
}
1038
1039
33
void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
1040
33
  assert(MAI->getGPRel64Directive() != nullptr);
1041
33
  OS << MAI->getGPRel64Directive();
1042
33
  Value->print(OS, MAI);
1043
33
  EmitEOL();
1044
33
}
1045
1046
23
void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
1047
23
  assert(MAI->getGPRel32Directive() != nullptr);
1048
23
  OS << MAI->getGPRel32Directive();
1049
23
  Value->print(OS, MAI);
1050
23
  EmitEOL();
1051
23
}
1052
1053
void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
1054
74.5k
                             SMLoc Loc) {
1055
74.5k
  int64_t IntNumBytes;
1056
74.5k
  if (NumBytes.evaluateAsAbsolute(IntNumBytes) && 
IntNumBytes == 074.5k
)
1057
52.2k
    return;
1058
22.3k
1059
22.3k
  if (const char *ZeroDirective = MAI->getZeroDirective()) {
1060
22.3k
    // FIXME: Emit location directives
1061
22.3k
    OS << ZeroDirective;
1062
22.3k
    NumBytes.print(OS, MAI);
1063
22.3k
    if (FillValue != 0)
1064
3.43k
      OS << ',' << (int)FillValue;
1065
22.3k
    EmitEOL();
1066
22.3k
    return;
1067
22.3k
  }
1068
0
1069
0
  MCStreamer::emitFill(NumBytes, FillValue);
1070
0
}
1071
1072
void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
1073
24
                             int64_t Expr, SMLoc Loc) {
1074
24
  // FIXME: Emit location directives
1075
24
  OS << "\t.fill\t";
1076
24
  NumValues.print(OS, MAI);
1077
24
  OS << ", " << Size << ", 0x";
1078
24
  OS.write_hex(truncateToSize(Expr, 4));
1079
24
  EmitEOL();
1080
24
}
1081
1082
void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1083
                                         unsigned ValueSize,
1084
264k
                                         unsigned MaxBytesToEmit) {
1085
264k
  // Some assemblers don't support non-power of two alignments, so we always
1086
264k
  // emit alignments as a power of two if possible.
1087
264k
  if (isPowerOf2_32(ByteAlignment)) {
1088
264k
    switch (ValueSize) {
1089
264k
    default:
1090
0
      llvm_unreachable("Invalid size for machine code value!");
1091
264k
    case 1:
1092
263k
      OS << "\t.p2align\t";
1093
263k
      break;
1094
264k
    case 2:
1095
4
      OS << ".p2alignw ";
1096
4
      break;
1097
264k
    case 4:
1098
7
      OS << ".p2alignl ";
1099
7
      break;
1100
264k
    case 8:
1101
0
      llvm_unreachable("Unsupported alignment size!");
1102
264k
    }
1103
264k
1104
264k
    OS << Log2_32(ByteAlignment);
1105
264k
1106
264k
    if (Value || 
MaxBytesToEmit150k
) {
1107
113k
      OS << ", 0x";
1108
113k
      OS.write_hex(truncateToSize(Value, ValueSize));
1109
113k
1110
113k
      if (MaxBytesToEmit)
1111
1
        OS << ", " << MaxBytesToEmit;
1112
113k
    }
1113
264k
    EmitEOL();
1114
264k
    return;
1115
264k
  }
1116
2
1117
2
  // Non-power of two alignment.  This is not widely supported by assemblers.
1118
2
  // FIXME: Parameterize this based on MAI.
1119
2
  switch (ValueSize) {
1120
2
  
default: 0
llvm_unreachable0
("Invalid size for machine code value!");
1121
2
  case 1: OS << ".balign";  break;
1122
2
  
case 2: OS << ".balignw"; break0
;
1123
2
  
case 4: OS << ".balignl"; break0
;
1124
2
  
case 8: 0
llvm_unreachable0
("Unsupported alignment size!");
1125
2
  }
1126
2
1127
2
  OS << ' ' << ByteAlignment;
1128
2
  OS << ", " << truncateToSize(Value, ValueSize);
1129
2
  if (MaxBytesToEmit)
1130
0
    OS << ", " << MaxBytesToEmit;
1131
2
  EmitEOL();
1132
2
}
1133
1134
void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
1135
220k
                                      unsigned MaxBytesToEmit) {
1136
220k
  // Emit with a text fill value.
1137
220k
  EmitValueToAlignment(ByteAlignment, MAI->getTextAlignFillValue(),
1138
220k
                       1, MaxBytesToEmit);
1139
220k
}
1140
1141
void MCAsmStreamer::emitValueToOffset(const MCExpr *Offset,
1142
                                      unsigned char Value,
1143
9
                                      SMLoc Loc) {
1144
9
  // FIXME: Verify that Offset is associated with the current section.
1145
9
  OS << ".org ";
1146
9
  Offset->print(OS, MAI);
1147
9
  OS << ", " << (unsigned)Value;
1148
9
  EmitEOL();
1149
9
}
1150
1151
16.2k
void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
1152
16.2k
  assert(MAI->hasSingleParameterDotFile());
1153
16.2k
  OS << "\t.file\t";
1154
16.2k
  PrintQuotedString(Filename, OS);
1155
16.2k
  EmitEOL();
1156
16.2k
}
1157
1158
static void printDwarfFileDirective(unsigned FileNo, StringRef Directory,
1159
                                    StringRef Filename,
1160
                                    Optional<MD5::MD5Result> Checksum,
1161
                                    Optional<StringRef> Source,
1162
                                    bool UseDwarfDirectory,
1163
536
                                    raw_svector_ostream &OS) {
1164
536
  SmallString<128> FullPathName;
1165
536
1166
536
  if (!UseDwarfDirectory && 
!Directory.empty()486
) {
1167
450
    if (sys::path::is_absolute(Filename))
1168
52
      Directory = "";
1169
398
    else {
1170
398
      FullPathName = Directory;
1171
398
      sys::path::append(FullPathName, Filename);
1172
398
      Directory = "";
1173
398
      Filename = FullPathName;
1174
398
    }
1175
450
  }
1176
536
1177
536
  OS << "\t.file\t" << FileNo << ' ';
1178
536
  if (!Directory.empty()) {
1179
42
    PrintQuotedString(Directory, OS);
1180
42
    OS << ' ';
1181
42
  }
1182
536
  PrintQuotedString(Filename, OS);
1183
536
  if (Checksum)
1184
11
    OS << " md5 0x" << Checksum->digest();
1185
536
  if (Source) {
1186
8
    OS << " source ";
1187
8
    PrintQuotedString(*Source, OS);
1188
8
  }
1189
536
}
1190
1191
Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
1192
    unsigned FileNo, StringRef Directory, StringRef Filename,
1193
4.14k
    Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source, unsigned CUID) {
1194
4.14k
  assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer");
1195
4.14k
1196
4.14k
  MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
1197
4.14k
  unsigned NumFiles = Table.getMCDwarfFiles().size();
1198
4.14k
  Expected<unsigned> FileNoOrErr =
1199
4.14k
      Table.tryGetFile(Directory, Filename, Checksum, Source,
1200
4.14k
                       getContext().getDwarfVersion(), FileNo);
1201
4.14k
  if (!FileNoOrErr)
1202
0
    return FileNoOrErr.takeError();
1203
4.14k
  FileNo = FileNoOrErr.get();
1204
4.14k
  if (NumFiles == Table.getMCDwarfFiles().size())
1205
3.62k
    return FileNo;
1206
525
1207
525
  SmallString<128> Str;
1208
525
  raw_svector_ostream OS1(Str);
1209
525
  printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source,
1210
525
                          UseDwarfDirectory, OS1);
1211
525
1212
525
  if (MCTargetStreamer *TS = getTargetStreamer())
1213
400
    TS->emitDwarfFileDirective(OS1.str());
1214
125
  else
1215
125
    EmitRawText(OS1.str());
1216
525
1217
525
  return FileNo;
1218
525
}
1219
1220
void MCAsmStreamer::emitDwarfFile0Directive(StringRef Directory,
1221
                                            StringRef Filename,
1222
                                            Optional<MD5::MD5Result> Checksum,
1223
                                            Optional<StringRef> Source,
1224
438
                                            unsigned CUID) {
1225
438
  assert(CUID == 0);
1226
438
  // .file 0 is new for DWARF v5.
1227
438
  if (getContext().getDwarfVersion() < 5)
1228
427
    return;
1229
11
  // Inform MCDwarf about the root file.
1230
11
  getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
1231
11
                                      Source);
1232
11
1233
11
  SmallString<128> Str;
1234
11
  raw_svector_ostream OS1(Str);
1235
11
  printDwarfFileDirective(0, Directory, Filename, Checksum, Source,
1236
11
                          UseDwarfDirectory, OS1);
1237
11
1238
11
  if (MCTargetStreamer *TS = getTargetStreamer())
1239
9
    TS->emitDwarfFileDirective(OS1.str());
1240
2
  else
1241
2
    EmitRawText(OS1.str());
1242
11
}
1243
1244
void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
1245
                                          unsigned Column, unsigned Flags,
1246
                                          unsigned Isa,
1247
                                          unsigned Discriminator,
1248
1.83k
                                          StringRef FileName) {
1249
1.83k
  OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
1250
1.83k
  if (MAI->supportsExtendedDwarfLocDirective()) {
1251
1.76k
    if (Flags & DWARF2_FLAG_BASIC_BLOCK)
1252
1.76k
      
OS << " basic_block"0
;
1253
1.76k
    if (Flags & DWARF2_FLAG_PROLOGUE_END)
1254
1.76k
      
OS << " prologue_end"407
;
1255
1.76k
    if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
1256
1.76k
      
OS << " epilogue_begin"0
;
1257
1.76k
1258
1.76k
    unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
1259
1.76k
    if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
1260
387
      OS << " is_stmt ";
1261
387
1262
387
      if (Flags & DWARF2_FLAG_IS_STMT)
1263
387
        
OS << "1"153
;
1264
234
      else
1265
234
        OS << "0";
1266
387
    }
1267
1.76k
1268
1.76k
    if (Isa)
1269
1
      OS << " isa " << Isa;
1270
1.76k
    if (Discriminator)
1271
15
      OS << " discriminator " << Discriminator;
1272
1.76k
  }
1273
1.83k
1274
1.83k
  if (IsVerboseAsm) {
1275
1.68k
    OS.PadToColumn(MAI->getCommentColumn());
1276
1.68k
    OS << MAI->getCommentString() << ' ' << FileName << ':'
1277
1.68k
       << Line << ':' << Column;
1278
1.68k
  }
1279
1.83k
  EmitEOL();
1280
1.83k
  this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
1281
1.83k
                                          Isa, Discriminator, FileName);
1282
1.83k
}
1283
1284
461
MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
1285
461
  // Always use the zeroth line table, since asm syntax only supports one line
1286
461
  // table for now.
1287
461
  return MCStreamer::getDwarfLineTableSymbol(0);
1288
461
}
1289
1290
bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
1291
                                        ArrayRef<uint8_t> Checksum,
1292
106
                                        unsigned ChecksumKind) {
1293
106
  if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
1294
106
                                           ChecksumKind))
1295
0
    return false;
1296
106
1297
106
  OS << "\t.cv_file\t" << FileNo << ' ';
1298
106
  PrintQuotedString(Filename, OS);
1299
106
1300
106
  if (!ChecksumKind) {
1301
50
    EmitEOL();
1302
50
    return true;
1303
50
  }
1304
56
1305
56
  OS << ' ';
1306
56
  PrintQuotedString(toHex(Checksum), OS);
1307
56
  OS << ' ' << ChecksumKind;
1308
56
1309
56
  EmitEOL();
1310
56
  return true;
1311
56
}
1312
1313
210
bool MCAsmStreamer::EmitCVFuncIdDirective(unsigned FuncId) {
1314
210
  OS << "\t.cv_func_id " << FuncId << '\n';
1315
210
  return MCStreamer::EmitCVFuncIdDirective(FuncId);
1316
210
}
1317
1318
bool MCAsmStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
1319
                                                unsigned IAFunc,
1320
                                                unsigned IAFile,
1321
                                                unsigned IALine, unsigned IACol,
1322
15
                                                SMLoc Loc) {
1323
15
  OS << "\t.cv_inline_site_id " << FunctionId << " within " << IAFunc
1324
15
     << " inlined_at " << IAFile << ' ' << IALine << ' ' << IACol << '\n';
1325
15
  return MCStreamer::EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
1326
15
                                                 IALine, IACol, Loc);
1327
15
}
1328
1329
void MCAsmStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
1330
                                       unsigned Line, unsigned Column,
1331
                                       bool PrologueEnd, bool IsStmt,
1332
696
                                       StringRef FileName, SMLoc Loc) {
1333
696
  // Validate the directive.
1334
696
  if (!checkCVLocSection(FunctionId, FileNo, Loc))
1335
1
    return;
1336
695
1337
695
  OS << "\t.cv_loc\t" << FunctionId << " " << FileNo << " " << Line << " "
1338
695
     << Column;
1339
695
  if (PrologueEnd)
1340
0
    OS << " prologue_end";
1341
695
1342
695
  if (IsStmt)
1343
0
    OS << " is_stmt 1";
1344
695
1345
695
  if (IsVerboseAsm) {
1346
695
    OS.PadToColumn(MAI->getCommentColumn());
1347
695
    OS << MAI->getCommentString() << ' ' << FileName << ':' << Line << ':'
1348
695
       << Column;
1349
695
  }
1350
695
  EmitEOL();
1351
695
}
1352
1353
void MCAsmStreamer::EmitCVLinetableDirective(unsigned FunctionId,
1354
                                             const MCSymbol *FnStart,
1355
204
                                             const MCSymbol *FnEnd) {
1356
204
  OS << "\t.cv_linetable\t" << FunctionId << ", ";
1357
204
  FnStart->print(OS, MAI);
1358
204
  OS << ", ";
1359
204
  FnEnd->print(OS, MAI);
1360
204
  EmitEOL();
1361
204
  this->MCStreamer::EmitCVLinetableDirective(FunctionId, FnStart, FnEnd);
1362
204
}
1363
1364
void MCAsmStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
1365
                                                   unsigned SourceFileId,
1366
                                                   unsigned SourceLineNum,
1367
                                                   const MCSymbol *FnStartSym,
1368
13
                                                   const MCSymbol *FnEndSym) {
1369
13
  OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId
1370
13
     << ' ' << SourceLineNum << ' ';
1371
13
  FnStartSym->print(OS, MAI);
1372
13
  OS << ' ';
1373
13
  FnEndSym->print(OS, MAI);
1374
13
  EmitEOL();
1375
13
  this->MCStreamer::EmitCVInlineLinetableDirective(
1376
13
      PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1377
13
}
1378
1379
void MCAsmStreamer::EmitCVDefRangeDirective(
1380
    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1381
270
    StringRef FixedSizePortion) {
1382
270
  OS << "\t.cv_def_range\t";
1383
272
  for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
1384
272
    OS << ' ';
1385
272
    Range.first->print(OS, MAI);
1386
272
    OS << ' ';
1387
272
    Range.second->print(OS, MAI);
1388
272
  }
1389
270
  OS << ", ";
1390
270
  PrintQuotedString(FixedSizePortion, OS);
1391
270
  EmitEOL();
1392
270
  this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
1393
270
}
1394
1395
112
void MCAsmStreamer::EmitCVStringTableDirective() {
1396
112
  OS << "\t.cv_stringtable";
1397
112
  EmitEOL();
1398
112
}
1399
1400
110
void MCAsmStreamer::EmitCVFileChecksumsDirective() {
1401
110
  OS << "\t.cv_filechecksums";
1402
110
  EmitEOL();
1403
110
}
1404
1405
12
void MCAsmStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
1406
12
  OS << "\t.cv_filechecksumoffset\t" << FileNo;
1407
12
  EmitEOL();
1408
12
}
1409
1410
83
void MCAsmStreamer::EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) {
1411
83
  OS << "\t.cv_fpo_data\t";
1412
83
  ProcSym->print(OS, MAI);
1413
83
  EmitEOL();
1414
83
}
1415
1416
356
void MCAsmStreamer::EmitIdent(StringRef IdentString) {
1417
356
  assert(MAI->hasIdentDirective() && ".ident directive not supported");
1418
356
  OS << "\t.ident\t";
1419
356
  PrintQuotedString(IdentString, OS);
1420
356
  EmitEOL();
1421
356
}
1422
1423
177
void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
1424
177
  MCStreamer::EmitCFISections(EH, Debug);
1425
177
  OS << "\t.cfi_sections ";
1426
177
  if (EH) {
1427
0
    OS << ".eh_frame";
1428
0
    if (Debug)
1429
0
      OS << ", .debug_frame";
1430
177
  } else if (Debug) {
1431
177
    OS << ".debug_frame";
1432
177
  }
1433
177
1434
177
  EmitEOL();
1435
177
}
1436
1437
114k
void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
1438
114k
  OS << "\t.cfi_startproc";
1439
114k
  if (Frame.IsSimple)
1440
2
    OS << " simple";
1441
114k
  EmitEOL();
1442
114k
}
1443
1444
114k
void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
1445
114k
  MCStreamer::EmitCFIEndProcImpl(Frame);
1446
114k
  OS << "\t.cfi_endproc";
1447
114k
  EmitEOL();
1448
114k
}
1449
1450
25.8k
void MCAsmStreamer::EmitRegisterName(int64_t Register) {
1451
25.8k
  if (!MAI->useDwarfRegNumForCFI()) {
1452
22.7k
    // User .cfi_* directives can use arbitrary DWARF register numbers, not
1453
22.7k
    // just ones that map to LLVM register numbers and have known names.
1454
22.7k
    // Fall back to using the original number directly if no name is known.
1455
22.7k
    const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1456
22.7k
    int LLVMRegister = MRI->getLLVMRegNumFromEH(Register);
1457
22.7k
    if (LLVMRegister != -1) {
1458
22.7k
      InstPrinter->printRegName(OS, LLVMRegister);
1459
22.7k
      return;
1460
22.7k
    }
1461
3.09k
  }
1462
3.09k
  OS << Register;
1463
3.09k
}
1464
1465
2.42k
void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
1466
2.42k
  MCStreamer::EmitCFIDefCfa(Register, Offset);
1467
2.42k
  OS << "\t.cfi_def_cfa ";
1468
2.42k
  EmitRegisterName(Register);
1469
2.42k
  OS << ", " << Offset;
1470
2.42k
  EmitEOL();
1471
2.42k
}
1472
1473
17.1k
void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
1474
17.1k
  MCStreamer::EmitCFIDefCfaOffset(Offset);
1475
17.1k
  OS << "\t.cfi_def_cfa_offset " << Offset;
1476
17.1k
  EmitEOL();
1477
17.1k
}
1478
1479
33
static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values) {
1480
33
  OS << "\t.cfi_escape ";
1481
33
  if (!Values.empty()) {
1482
33
    size_t e = Values.size() - 1;
1483
72
    for (size_t i = 0; i < e; 
++i39
)
1484
39
      OS << format("0x%02x", uint8_t(Values[i])) << ", ";
1485
33
    OS << format("0x%02x", uint8_t(Values[e]));
1486
33
  }
1487
33
}
1488
1489
2
void MCAsmStreamer::EmitCFIEscape(StringRef Values) {
1490
2
  MCStreamer::EmitCFIEscape(Values);
1491
2
  PrintCFIEscape(OS, Values);
1492
2
  EmitEOL();
1493
2
}
1494
1495
31
void MCAsmStreamer::EmitCFIGnuArgsSize(int64_t Size) {
1496
31
  MCStreamer::EmitCFIGnuArgsSize(Size);
1497
31
1498
31
  uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
1499
31
  unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
1500
31
1501
31
  PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));
1502
31
  EmitEOL();
1503
31
}
1504
1505
1.58k
void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
1506
1.58k
  MCStreamer::EmitCFIDefCfaRegister(Register);
1507
1.58k
  OS << "\t.cfi_def_cfa_register ";
1508
1.58k
  EmitRegisterName(Register);
1509
1.58k
  EmitEOL();
1510
1.58k
}
1511
1512
21.7k
void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
1513
21.7k
  this->MCStreamer::EmitCFIOffset(Register, Offset);
1514
21.7k
  OS << "\t.cfi_offset ";
1515
21.7k
  EmitRegisterName(Register);
1516
21.7k
  OS << ", " << Offset;
1517
21.7k
  EmitEOL();
1518
21.7k
}
1519
1520
void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
1521
225
                                       unsigned Encoding) {
1522
225
  MCStreamer::EmitCFIPersonality(Sym, Encoding);
1523
225
  OS << "\t.cfi_personality " << Encoding << ", ";
1524
225
  Sym->print(OS, MAI);
1525
225
  EmitEOL();
1526
225
}
1527
1528
225
void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
1529
225
  MCStreamer::EmitCFILsda(Sym, Encoding);
1530
225
  OS << "\t.cfi_lsda " << Encoding << ", ";
1531
225
  Sym->print(OS, MAI);
1532
225
  EmitEOL();
1533
225
}
1534
1535
0
void MCAsmStreamer::EmitCFIRememberState() {
1536
0
  MCStreamer::EmitCFIRememberState();
1537
0
  OS << "\t.cfi_remember_state";
1538
0
  EmitEOL();
1539
0
}
1540
1541
0
void MCAsmStreamer::EmitCFIRestoreState() {
1542
0
  MCStreamer::EmitCFIRestoreState();
1543
0
  OS << "\t.cfi_restore_state";
1544
0
  EmitEOL();
1545
0
}
1546
1547
69
void MCAsmStreamer::EmitCFIRestore(int64_t Register) {
1548
69
  MCStreamer::EmitCFIRestore(Register);
1549
69
  OS << "\t.cfi_restore ";
1550
69
  EmitRegisterName(Register);
1551
69
  EmitEOL();
1552
69
}
1553
1554
2
void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
1555
2
  MCStreamer::EmitCFISameValue(Register);
1556
2
  OS << "\t.cfi_same_value ";
1557
2
  EmitRegisterName(Register);
1558
2
  EmitEOL();
1559
2
}
1560
1561
1
void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1562
1
  MCStreamer::EmitCFIRelOffset(Register, Offset);
1563
1
  OS << "\t.cfi_rel_offset ";
1564
1
  EmitRegisterName(Register);
1565
1
  OS << ", " << Offset;
1566
1
  EmitEOL();
1567
1
}
1568
1569
1.97k
void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1570
1.97k
  MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1571
1.97k
  OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1572
1.97k
  EmitEOL();
1573
1.97k
}
1574
1575
0
void MCAsmStreamer::EmitCFISignalFrame() {
1576
0
  MCStreamer::EmitCFISignalFrame();
1577
0
  OS << "\t.cfi_signal_frame";
1578
0
  EmitEOL();
1579
0
}
1580
1581
0
void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1582
0
  MCStreamer::EmitCFIUndefined(Register);
1583
0
  OS << "\t.cfi_undefined " << Register;
1584
0
  EmitEOL();
1585
0
}
1586
1587
366
void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1588
366
  MCStreamer::EmitCFIRegister(Register1, Register2);
1589
366
  OS << "\t.cfi_register " << Register1 << ", " << Register2;
1590
366
  EmitEOL();
1591
366
}
1592
1593
364
void MCAsmStreamer::EmitCFIWindowSave() {
1594
364
  MCStreamer::EmitCFIWindowSave();
1595
364
  OS << "\t.cfi_window_save";
1596
364
  EmitEOL();
1597
364
}
1598
1599
9
void MCAsmStreamer::EmitCFINegateRAState() {
1600
9
  MCStreamer::EmitCFINegateRAState();
1601
9
  OS << "\t.cfi_negate_ra_state";
1602
9
  EmitEOL();
1603
9
}
1604
1605
3
void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
1606
3
  MCStreamer::EmitCFIReturnColumn(Register);
1607
3
  OS << "\t.cfi_return_column " << Register;
1608
3
  EmitEOL();
1609
3
}
1610
1611
2
void MCAsmStreamer::EmitCFIBKeyFrame() {
1612
2
  MCStreamer::EmitCFIBKeyFrame();
1613
2
  OS << "\t.cfi_b_key_frame";
1614
2
  EmitEOL();
1615
2
}
1616
1617
686
void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
1618
686
  MCStreamer::EmitWinCFIStartProc(Symbol, Loc);
1619
686
1620
686
  OS << ".seh_proc ";
1621
686
  Symbol->print(OS, MAI);
1622
686
  EmitEOL();
1623
686
}
1624
1625
685
void MCAsmStreamer::EmitWinCFIEndProc(SMLoc Loc) {
1626
685
  MCStreamer::EmitWinCFIEndProc(Loc);
1627
685
1628
685
  OS << "\t.seh_endproc";
1629
685
  EmitEOL();
1630
685
}
1631
1632
// TODO: Implement
1633
141
void MCAsmStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
1634
141
}
1635
1636
1
void MCAsmStreamer::EmitWinCFIStartChained(SMLoc Loc) {
1637
1
  MCStreamer::EmitWinCFIStartChained(Loc);
1638
1
1639
1
  OS << "\t.seh_startchained";
1640
1
  EmitEOL();
1641
1
}
1642
1643
1
void MCAsmStreamer::EmitWinCFIEndChained(SMLoc Loc) {
1644
1
  MCStreamer::EmitWinCFIEndChained(Loc);
1645
1
1646
1
  OS << "\t.seh_endchained";
1647
1
  EmitEOL();
1648
1
}
1649
1650
void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
1651
153
                                     bool Except, SMLoc Loc) {
1652
153
  MCStreamer::EmitWinEHHandler(Sym, Unwind, Except, Loc);
1653
153
1654
153
  OS << "\t.seh_handler ";
1655
153
  Sym->print(OS, MAI);
1656
153
  if (Unwind)
1657
152
    OS << ", @unwind";
1658
153
  if (Except)
1659
153
    OS << ", @except";
1660
153
  EmitEOL();
1661
153
}
1662
1663
685
void MCAsmStreamer::EmitWinEHHandlerData(SMLoc Loc) {
1664
685
  MCStreamer::EmitWinEHHandlerData(Loc);
1665
685
1666
685
  // Switch sections. Don't call SwitchSection directly, because that will
1667
685
  // cause the section switch to be visible in the emitted assembly.
1668
685
  // We only do this so the section switch that terminates the handler
1669
685
  // data block is visible.
1670
685
  WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
1671
685
  MCSection *TextSec = &CurFrame->Function->getSection();
1672
685
  MCSection *XData = getAssociatedXDataSection(TextSec);
1673
685
  SwitchSectionNoChange(XData);
1674
685
1675
685
  OS << "\t.seh_handlerdata";
1676
685
  EmitEOL();
1677
685
}
1678
1679
425
void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
1680
425
  MCStreamer::EmitWinCFIPushReg(Register, Loc);
1681
425
1682
425
  OS << "\t.seh_pushreg " << Register;
1683
425
  EmitEOL();
1684
425
}
1685
1686
void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
1687
94
                                       SMLoc Loc) {
1688
94
  MCStreamer::EmitWinCFISetFrame(Register, Offset, Loc);
1689
94
1690
94
  OS << "\t.seh_setframe " << Register << ", " << Offset;
1691
94
  EmitEOL();
1692
94
}
1693
1694
517
void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
1695
517
  MCStreamer::EmitWinCFIAllocStack(Size, Loc);
1696
517
1697
517
  OS << "\t.seh_stackalloc " << Size;
1698
517
  EmitEOL();
1699
517
}
1700
1701
void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
1702
1
                                      SMLoc Loc) {
1703
1
  MCStreamer::EmitWinCFISaveReg(Register, Offset, Loc);
1704
1
1705
1
  OS << "\t.seh_savereg " << Register << ", " << Offset;
1706
1
  EmitEOL();
1707
1
}
1708
1709
void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
1710
191
                                      SMLoc Loc) {
1711
191
  MCStreamer::EmitWinCFISaveXMM(Register, Offset, Loc);
1712
191
1713
191
  OS << "\t.seh_savexmm " << Register << ", " << Offset;
1714
191
  EmitEOL();
1715
191
}
1716
1717
1
void MCAsmStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
1718
1
  MCStreamer::EmitWinCFIPushFrame(Code, Loc);
1719
1
1720
1
  OS << "\t.seh_pushframe";
1721
1
  if (Code)
1722
1
    OS << " @code";
1723
1
  EmitEOL();
1724
1
}
1725
1726
545
void MCAsmStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
1727
545
  MCStreamer::EmitWinCFIEndProlog(Loc);
1728
545
1729
545
  OS << "\t.seh_endprologue";
1730
545
  EmitEOL();
1731
545
}
1732
1733
void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
1734
                                       const MCSymbolRefExpr *To,
1735
6
                                       uint64_t Count) {
1736
6
  OS << "\t.cg_profile ";
1737
6
  From->getSymbol().print(OS, MAI);
1738
6
  OS << ", ";
1739
6
  To->getSymbol().print(OS, MAI);
1740
6
  OS << ", " << Count;
1741
6
  EmitEOL();
1742
6
}
1743
1744
void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
1745
2.67M
                                       const MCSubtargetInfo &STI) {
1746
2.67M
  raw_ostream &OS = GetCommentOS();
1747
2.67M
  SmallString<256> Code;
1748
2.67M
  SmallVector<MCFixup, 4> Fixups;
1749
2.67M
  raw_svector_ostream VecOS(Code);
1750
2.67M
1751
2.67M
  // If we have no code emitter, don't emit code.
1752
2.67M
  if (!getAssembler().getEmitterPtr())
1753
1.99M
    return;
1754
676k
1755
676k
  getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
1756
676k
1757
676k
  // If we are showing fixups, create symbolic markers in the encoded
1758
676k
  // representation. We do this by making a per-bit map to the fixup item index,
1759
676k
  // then trying to display it as nicely as possible.
1760
676k
  SmallVector<uint8_t, 64> FixupMap;
1761
676k
  FixupMap.resize(Code.size() * 8);
1762
35.5M
  for (unsigned i = 0, e = Code.size() * 8; i != e; 
++i34.8M
)
1763
34.8M
    FixupMap[i] = 0;
1764
676k
1765
682k
  for (unsigned i = 0, e = Fixups.size(); i != e; 
++i6.02k
) {
1766
6.02k
    MCFixup &F = Fixups[i];
1767
6.02k
    const MCFixupKindInfo &Info =
1768
6.02k
        getAssembler().getBackend().getFixupKindInfo(F.getKind());
1769
119k
    for (unsigned j = 0; j != Info.TargetSize; 
++j113k
) {
1770
113k
      unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1771
113k
      assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1772
113k
      FixupMap[Index] = 1 + i;
1773
113k
    }
1774
6.02k
  }
1775
676k
1776
676k
  // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1777
676k
  // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1778
676k
  OS << "encoding: [";
1779
5.03M
  for (unsigned i = 0, e = Code.size(); i != e; 
++i4.35M
) {
1780
4.35M
    if (i)
1781
3.68M
      OS << ',';
1782
4.35M
1783
4.35M
    // See if all bits are the same map entry.
1784
4.35M
    uint8_t MapEntry = FixupMap[i * 8 + 0];
1785
34.8M
    for (unsigned j = 1; j != 8; 
++j30.5M
) {
1786
30.5M
      if (FixupMap[i * 8 + j] == MapEntry)
1787
30.5M
        continue;
1788
2.31k
1789
2.31k
      MapEntry = uint8_t(~0U);
1790
2.31k
      break;
1791
2.31k
    }
1792
4.35M
1793
4.35M
    if (MapEntry != uint8_t(~0U)) {
1794
4.35M
      if (MapEntry == 0) {
1795
4.34M
        OS << format("0x%02x", uint8_t(Code[i]));
1796
4.34M
      } else {
1797
12.6k
        if (Code[i]) {
1798
681
          // FIXME: Some of the 8 bits require fix up.
1799
681
          OS << format("0x%02x", uint8_t(Code[i])) << '\''
1800
681
             << char('A' + MapEntry - 1) << '\'';
1801
681
        } else
1802
11.9k
          OS << char('A' + MapEntry - 1);
1803
12.6k
      }
1804
4.35M
    } else {
1805
2.31k
      // Otherwise, write out in binary.
1806
2.31k
      OS << "0b";
1807
20.8k
      for (unsigned j = 8; j--;) {
1808
18.5k
        unsigned Bit = (Code[i] >> j) & 1;
1809
18.5k
1810
18.5k
        unsigned FixupBit;
1811
18.5k
        if (MAI->isLittleEndian())
1812
9.83k
          FixupBit = i * 8 + j;
1813
8.70k
        else
1814
8.70k
          FixupBit = i * 8 + (7-j);
1815
18.5k
1816
18.5k
        if (uint8_t MapEntry = FixupMap[FixupBit]) {
1817
11.6k
          assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1818
11.6k
          OS << char('A' + MapEntry - 1);
1819
11.6k
        } else
1820
6.85k
          OS << Bit;
1821
18.5k
      }
1822
2.31k
    }
1823
4.35M
  }
1824
676k
  OS << "]\n";
1825
676k
1826
682k
  for (unsigned i = 0, e = Fixups.size(); i != e; 
++i6.02k
) {
1827
6.02k
    MCFixup &F = Fixups[i];
1828
6.02k
    const MCFixupKindInfo &Info =
1829
6.02k
        getAssembler().getBackend().getFixupKindInfo(F.getKind());
1830
6.02k
    OS << "  fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1831
6.02k
       << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1832
6.02k
  }
1833
676k
}
1834
1835
void MCAsmStreamer::EmitInstruction(const MCInst &Inst,
1836
2.67M
                                    const MCSubtargetInfo &STI) {
1837
2.67M
  assert(getCurrentSectionOnly() &&
1838
2.67M
         "Cannot emit contents before setting section!");
1839
2.67M
1840
2.67M
  // Show the encoding in a comment if we have a code emitter.
1841
2.67M
  AddEncodingComment(Inst, STI);
1842
2.67M
1843
2.67M
  // Show the MCInst if enabled.
1844
2.67M
  if (ShowInst) {
1845
8.73k
    Inst.dump_pretty(GetCommentOS(), InstPrinter.get(), "\n ");
1846
8.73k
    GetCommentOS() << "\n";
1847
8.73k
  }
1848
2.67M
1849
2.67M
  if(getTargetStreamer())
1850
2.49M
    getTargetStreamer()->prettyPrintAsm(*InstPrinter, OS, Inst, STI);
1851
178k
  else
1852
178k
    InstPrinter->printInst(&Inst, OS, "", STI);
1853
2.67M
1854
2.67M
  StringRef Comments = CommentToEmit;
1855
2.67M
  if (Comments.size() && 
Comments.back() != '\n'833k
)
1856
12.4k
    GetCommentOS() << "\n";
1857
2.67M
1858
2.67M
  EmitEOL();
1859
2.67M
}
1860
1861
1
void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
1862
1
  OS << "\t.bundle_align_mode " << AlignPow2;
1863
1
  EmitEOL();
1864
1
}
1865
1866
4
void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
1867
4
  OS << "\t.bundle_lock";
1868
4
  if (AlignToEnd)
1869
3
    OS << " align_to_end";
1870
4
  EmitEOL();
1871
4
}
1872
1873
2
void MCAsmStreamer::EmitBundleUnlock() {
1874
2
  OS << "\t.bundle_unlock";
1875
2
  EmitEOL();
1876
2
}
1877
1878
bool MCAsmStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
1879
                                       const MCExpr *Expr, SMLoc,
1880
1.11k
                                       const MCSubtargetInfo &STI) {
1881
1.11k
  OS << "\t.reloc ";
1882
1.11k
  Offset.print(OS, MAI);
1883
1.11k
  OS << ", " << Name;
1884
1.11k
  if (Expr) {
1885
1.11k
    OS << ", ";
1886
1.11k
    Expr->print(OS, MAI);
1887
1.11k
  }
1888
1.11k
  EmitEOL();
1889
1.11k
  return false;
1890
1.11k
}
1891
1892
40
void MCAsmStreamer::EmitAddrsig() {
1893
40
  OS << "\t.addrsig";
1894
40
  EmitEOL();
1895
40
}
1896
1897
10
void MCAsmStreamer::EmitAddrsigSym(const MCSymbol *Sym) {
1898
10
  OS << "\t.addrsig_sym ";
1899
10
  Sym->print(OS, MAI);
1900
10
  EmitEOL();
1901
10
}
1902
1903
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
1904
/// the specified string in the output .s file.  This capability is
1905
/// indicated by the hasRawTextSupport() predicate.
1906
660k
void MCAsmStreamer::EmitRawTextImpl(StringRef String) {
1907
660k
  if (!String.empty() && 
String.back() == '\n'658k
)
1908
9.36k
    String = String.substr(0, String.size()-1);
1909
660k
  OS << String;
1910
660k
  EmitEOL();
1911
660k
}
1912
1913
23.5k
void MCAsmStreamer::FinishImpl() {
1914
23.5k
  // If we are generating dwarf for assembly source files dump out the sections.
1915
23.5k
  if (getContext().getGenDwarfForAssembly())
1916
10
    MCGenDwarfInfo::Emit(this);
1917
23.5k
1918
23.5k
  // Emit the label for the line table, if requested - since the rest of the
1919
23.5k
  // line table will be defined by .loc/.file directives, and not emitted
1920
23.5k
  // directly, the label is the only work required here.
1921
23.5k
  const auto &Tables = getContext().getMCDwarfLineTables();
1922
23.5k
  if (!Tables.empty()) {
1923
466
    assert(Tables.size() == 1 && "asm output only supports one line table");
1924
466
    if (auto *Label = Tables.begin()->second.getLabel()) {
1925
448
      SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
1926
448
      EmitLabel(Label);
1927
448
    }
1928
466
  }
1929
23.5k
}
1930
1931
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1932
                                    std::unique_ptr<formatted_raw_ostream> OS,
1933
                                    bool isVerboseAsm, bool useDwarfDirectory,
1934
                                    MCInstPrinter *IP,
1935
                                    std::unique_ptr<MCCodeEmitter> &&CE,
1936
                                    std::unique_ptr<MCAsmBackend> &&MAB,
1937
26.7k
                                    bool ShowInst) {
1938
26.7k
  return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm,
1939
26.7k
                           useDwarfDirectory, IP, std::move(CE), std::move(MAB),
1940
26.7k
                           ShowInst);
1941
26.7k
}