1f4a2713aSLionel Sambuc //===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output --------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc
10f4a2713aSLionel Sambuc #include "llvm/MC/MCStreamer.h"
11*0a6a1f1dSLionel Sambuc #include "llvm/ADT/STLExtras.h"
12f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
13f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
14f4a2713aSLionel Sambuc #include "llvm/ADT/Twine.h"
15f4a2713aSLionel Sambuc #include "llvm/MC/MCAsmBackend.h"
16f4a2713aSLionel Sambuc #include "llvm/MC/MCAsmInfo.h"
17f4a2713aSLionel Sambuc #include "llvm/MC/MCCodeEmitter.h"
18f4a2713aSLionel Sambuc #include "llvm/MC/MCContext.h"
19f4a2713aSLionel Sambuc #include "llvm/MC/MCExpr.h"
20f4a2713aSLionel Sambuc #include "llvm/MC/MCFixupKindInfo.h"
21f4a2713aSLionel Sambuc #include "llvm/MC/MCInst.h"
22f4a2713aSLionel Sambuc #include "llvm/MC/MCInstPrinter.h"
23f4a2713aSLionel Sambuc #include "llvm/MC/MCObjectFileInfo.h"
24f4a2713aSLionel Sambuc #include "llvm/MC/MCRegisterInfo.h"
25f4a2713aSLionel Sambuc #include "llvm/MC/MCSectionCOFF.h"
26f4a2713aSLionel Sambuc #include "llvm/MC/MCSectionMachO.h"
27f4a2713aSLionel Sambuc #include "llvm/MC/MCSymbol.h"
28f4a2713aSLionel Sambuc #include "llvm/Support/CommandLine.h"
29f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
30f4a2713aSLionel Sambuc #include "llvm/Support/Format.h"
31f4a2713aSLionel Sambuc #include "llvm/Support/FormattedStream.h"
32f4a2713aSLionel Sambuc #include "llvm/Support/MathExtras.h"
33f4a2713aSLionel Sambuc #include "llvm/Support/Path.h"
34f4a2713aSLionel Sambuc #include <cctype>
35f4a2713aSLionel Sambuc using namespace llvm;
36f4a2713aSLionel Sambuc
37f4a2713aSLionel Sambuc namespace {
38f4a2713aSLionel Sambuc
39f4a2713aSLionel Sambuc class MCAsmStreamer : public MCStreamer {
40f4a2713aSLionel Sambuc protected:
41f4a2713aSLionel Sambuc formatted_raw_ostream &OS;
42f4a2713aSLionel Sambuc const MCAsmInfo *MAI;
43f4a2713aSLionel Sambuc private:
44*0a6a1f1dSLionel Sambuc std::unique_ptr<MCInstPrinter> InstPrinter;
45*0a6a1f1dSLionel Sambuc std::unique_ptr<MCCodeEmitter> Emitter;
46*0a6a1f1dSLionel Sambuc std::unique_ptr<MCAsmBackend> AsmBackend;
47f4a2713aSLionel Sambuc
48f4a2713aSLionel Sambuc SmallString<128> CommentToEmit;
49f4a2713aSLionel Sambuc raw_svector_ostream CommentStream;
50f4a2713aSLionel Sambuc
51f4a2713aSLionel Sambuc unsigned IsVerboseAsm : 1;
52f4a2713aSLionel Sambuc unsigned ShowInst : 1;
53f4a2713aSLionel Sambuc unsigned UseDwarfDirectory : 1;
54f4a2713aSLionel Sambuc
55f4a2713aSLionel Sambuc void EmitRegisterName(int64_t Register);
56*0a6a1f1dSLionel Sambuc void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
57*0a6a1f1dSLionel Sambuc void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
58f4a2713aSLionel Sambuc
59f4a2713aSLionel Sambuc public:
MCAsmStreamer(MCContext & Context,formatted_raw_ostream & os,bool isVerboseAsm,bool useDwarfDirectory,MCInstPrinter * printer,MCCodeEmitter * emitter,MCAsmBackend * asmbackend,bool showInst)60*0a6a1f1dSLionel Sambuc MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
61*0a6a1f1dSLionel Sambuc bool isVerboseAsm, bool useDwarfDirectory,
62*0a6a1f1dSLionel Sambuc MCInstPrinter *printer, MCCodeEmitter *emitter,
63*0a6a1f1dSLionel Sambuc MCAsmBackend *asmbackend, bool showInst)
64*0a6a1f1dSLionel Sambuc : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
65f4a2713aSLionel Sambuc InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
66f4a2713aSLionel Sambuc CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
67*0a6a1f1dSLionel Sambuc ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
68f4a2713aSLionel Sambuc if (InstPrinter && IsVerboseAsm)
69f4a2713aSLionel Sambuc InstPrinter->setCommentStream(CommentStream);
70f4a2713aSLionel Sambuc }
71f4a2713aSLionel Sambuc
EmitEOL()72f4a2713aSLionel Sambuc inline void EmitEOL() {
73f4a2713aSLionel Sambuc // If we don't have any comments, just emit a \n.
74f4a2713aSLionel Sambuc if (!IsVerboseAsm) {
75f4a2713aSLionel Sambuc OS << '\n';
76f4a2713aSLionel Sambuc return;
77f4a2713aSLionel Sambuc }
78f4a2713aSLionel Sambuc EmitCommentsAndEOL();
79f4a2713aSLionel Sambuc }
80f4a2713aSLionel Sambuc void EmitCommentsAndEOL();
81f4a2713aSLionel Sambuc
82f4a2713aSLionel Sambuc /// isVerboseAsm - Return true if this streamer supports verbose assembly at
83f4a2713aSLionel Sambuc /// all.
isVerboseAsm() const84*0a6a1f1dSLionel Sambuc bool isVerboseAsm() const override { return IsVerboseAsm; }
85f4a2713aSLionel Sambuc
86f4a2713aSLionel Sambuc /// hasRawTextSupport - We support EmitRawText.
hasRawTextSupport() const87*0a6a1f1dSLionel Sambuc bool hasRawTextSupport() const override { return true; }
88f4a2713aSLionel Sambuc
89f4a2713aSLionel Sambuc /// AddComment - Add a comment that can be emitted to the generated .s
90f4a2713aSLionel Sambuc /// file if applicable as a QoI issue to make the output of the compiler
91f4a2713aSLionel Sambuc /// more readable. This only affects the MCAsmStreamer, and only when
92f4a2713aSLionel Sambuc /// verbose assembly output is enabled.
93*0a6a1f1dSLionel Sambuc void AddComment(const Twine &T) override;
94f4a2713aSLionel Sambuc
95f4a2713aSLionel Sambuc /// AddEncodingComment - Add a comment showing the encoding of an instruction.
96*0a6a1f1dSLionel Sambuc void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);
97f4a2713aSLionel Sambuc
98f4a2713aSLionel Sambuc /// GetCommentOS - Return a raw_ostream that comments can be written to.
99f4a2713aSLionel Sambuc /// Unlike AddComment, you are required to terminate comments with \n if you
100f4a2713aSLionel Sambuc /// use this method.
GetCommentOS()101*0a6a1f1dSLionel Sambuc raw_ostream &GetCommentOS() override {
102f4a2713aSLionel Sambuc if (!IsVerboseAsm)
103f4a2713aSLionel Sambuc return nulls(); // Discard comments unless in verbose asm mode.
104f4a2713aSLionel Sambuc return CommentStream;
105f4a2713aSLionel Sambuc }
106f4a2713aSLionel Sambuc
107*0a6a1f1dSLionel Sambuc void emitRawComment(const Twine &T, bool TabPrefix = true) override;
108*0a6a1f1dSLionel Sambuc
109f4a2713aSLionel Sambuc /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
AddBlankLine()110*0a6a1f1dSLionel Sambuc void AddBlankLine() override {
111f4a2713aSLionel Sambuc EmitEOL();
112f4a2713aSLionel Sambuc }
113f4a2713aSLionel Sambuc
114f4a2713aSLionel Sambuc /// @name MCStreamer Interface
115f4a2713aSLionel Sambuc /// @{
116f4a2713aSLionel Sambuc
117*0a6a1f1dSLionel Sambuc void ChangeSection(const MCSection *Section,
118*0a6a1f1dSLionel Sambuc const MCExpr *Subsection) override;
119f4a2713aSLionel Sambuc
120*0a6a1f1dSLionel Sambuc void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
121*0a6a1f1dSLionel Sambuc void EmitLabel(MCSymbol *Symbol) override;
122f4a2713aSLionel Sambuc
123*0a6a1f1dSLionel Sambuc void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
124*0a6a1f1dSLionel Sambuc void EmitLinkerOptions(ArrayRef<std::string> Options) override;
125*0a6a1f1dSLionel Sambuc void EmitDataRegion(MCDataRegionType Kind) override;
126*0a6a1f1dSLionel Sambuc void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
127*0a6a1f1dSLionel Sambuc unsigned Update) override;
128*0a6a1f1dSLionel Sambuc void EmitThumbFunc(MCSymbol *Func) override;
129f4a2713aSLionel Sambuc
130*0a6a1f1dSLionel Sambuc void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
131*0a6a1f1dSLionel Sambuc void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
132*0a6a1f1dSLionel Sambuc bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
133f4a2713aSLionel Sambuc
134*0a6a1f1dSLionel Sambuc void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
135*0a6a1f1dSLionel Sambuc void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
136*0a6a1f1dSLionel Sambuc void EmitCOFFSymbolStorageClass(int StorageClass) override;
137*0a6a1f1dSLionel Sambuc void EmitCOFFSymbolType(int Type) override;
138*0a6a1f1dSLionel Sambuc void EndCOFFSymbolDef() override;
139*0a6a1f1dSLionel Sambuc void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
140*0a6a1f1dSLionel Sambuc void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
141*0a6a1f1dSLionel Sambuc void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
142*0a6a1f1dSLionel Sambuc void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
143*0a6a1f1dSLionel Sambuc unsigned ByteAlignment) override;
144f4a2713aSLionel Sambuc
145f4a2713aSLionel Sambuc /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
146f4a2713aSLionel Sambuc ///
147f4a2713aSLionel Sambuc /// @param Symbol - The common symbol to emit.
148f4a2713aSLionel Sambuc /// @param Size - The size of the common symbol.
149f4a2713aSLionel Sambuc /// @param ByteAlignment - The alignment of the common symbol in bytes.
150*0a6a1f1dSLionel Sambuc void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
151*0a6a1f1dSLionel Sambuc unsigned ByteAlignment) override;
152f4a2713aSLionel Sambuc
153*0a6a1f1dSLionel Sambuc void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
154*0a6a1f1dSLionel Sambuc uint64_t Size = 0, unsigned ByteAlignment = 0) override;
155f4a2713aSLionel Sambuc
156*0a6a1f1dSLionel Sambuc void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
157*0a6a1f1dSLionel Sambuc uint64_t Size, unsigned ByteAlignment = 0) override;
158f4a2713aSLionel Sambuc
159*0a6a1f1dSLionel Sambuc void EmitBytes(StringRef Data) override;
160f4a2713aSLionel Sambuc
161*0a6a1f1dSLionel Sambuc void EmitValueImpl(const MCExpr *Value, unsigned Size,
162*0a6a1f1dSLionel Sambuc const SMLoc &Loc = SMLoc()) override;
163*0a6a1f1dSLionel Sambuc void EmitIntValue(uint64_t Value, unsigned Size) override;
164f4a2713aSLionel Sambuc
165*0a6a1f1dSLionel Sambuc void EmitULEB128Value(const MCExpr *Value) override;
166f4a2713aSLionel Sambuc
167*0a6a1f1dSLionel Sambuc void EmitSLEB128Value(const MCExpr *Value) override;
168f4a2713aSLionel Sambuc
169*0a6a1f1dSLionel Sambuc void EmitGPRel64Value(const MCExpr *Value) override;
170f4a2713aSLionel Sambuc
171*0a6a1f1dSLionel Sambuc void EmitGPRel32Value(const MCExpr *Value) override;
172f4a2713aSLionel Sambuc
173f4a2713aSLionel Sambuc
174*0a6a1f1dSLionel Sambuc void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
175f4a2713aSLionel Sambuc
176*0a6a1f1dSLionel Sambuc void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
177f4a2713aSLionel Sambuc unsigned ValueSize = 1,
178*0a6a1f1dSLionel Sambuc unsigned MaxBytesToEmit = 0) override;
179f4a2713aSLionel Sambuc
180*0a6a1f1dSLionel Sambuc void EmitCodeAlignment(unsigned ByteAlignment,
181*0a6a1f1dSLionel Sambuc unsigned MaxBytesToEmit = 0) override;
182f4a2713aSLionel Sambuc
183*0a6a1f1dSLionel Sambuc bool EmitValueToOffset(const MCExpr *Offset,
184*0a6a1f1dSLionel Sambuc unsigned char Value = 0) override;
185f4a2713aSLionel Sambuc
186*0a6a1f1dSLionel Sambuc void EmitFileDirective(StringRef Filename) override;
187*0a6a1f1dSLionel Sambuc unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
188*0a6a1f1dSLionel Sambuc StringRef Filename,
189*0a6a1f1dSLionel Sambuc unsigned CUID = 0) override;
190*0a6a1f1dSLionel Sambuc void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
191f4a2713aSLionel Sambuc unsigned Column, unsigned Flags,
192f4a2713aSLionel Sambuc unsigned Isa, unsigned Discriminator,
193*0a6a1f1dSLionel Sambuc StringRef FileName) override;
194*0a6a1f1dSLionel Sambuc MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
195f4a2713aSLionel Sambuc
196*0a6a1f1dSLionel Sambuc void EmitIdent(StringRef IdentString) override;
197*0a6a1f1dSLionel Sambuc void EmitCFISections(bool EH, bool Debug) override;
198*0a6a1f1dSLionel Sambuc void EmitCFIDefCfa(int64_t Register, int64_t Offset) override;
199*0a6a1f1dSLionel Sambuc void EmitCFIDefCfaOffset(int64_t Offset) override;
200*0a6a1f1dSLionel Sambuc void EmitCFIDefCfaRegister(int64_t Register) override;
201*0a6a1f1dSLionel Sambuc void EmitCFIOffset(int64_t Register, int64_t Offset) override;
202*0a6a1f1dSLionel Sambuc void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
203*0a6a1f1dSLionel Sambuc void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
204*0a6a1f1dSLionel Sambuc void EmitCFIRememberState() override;
205*0a6a1f1dSLionel Sambuc void EmitCFIRestoreState() override;
206*0a6a1f1dSLionel Sambuc void EmitCFISameValue(int64_t Register) override;
207*0a6a1f1dSLionel Sambuc void EmitCFIRelOffset(int64_t Register, int64_t Offset) override;
208*0a6a1f1dSLionel Sambuc void EmitCFIAdjustCfaOffset(int64_t Adjustment) override;
209*0a6a1f1dSLionel Sambuc void EmitCFISignalFrame() override;
210*0a6a1f1dSLionel Sambuc void EmitCFIUndefined(int64_t Register) override;
211*0a6a1f1dSLionel Sambuc void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
212*0a6a1f1dSLionel Sambuc void EmitCFIWindowSave() override;
213f4a2713aSLionel Sambuc
214*0a6a1f1dSLionel Sambuc void EmitWinCFIStartProc(const MCSymbol *Symbol) override;
215*0a6a1f1dSLionel Sambuc void EmitWinCFIEndProc() override;
216*0a6a1f1dSLionel Sambuc void EmitWinCFIStartChained() override;
217*0a6a1f1dSLionel Sambuc void EmitWinCFIEndChained() override;
218*0a6a1f1dSLionel Sambuc void EmitWinCFIPushReg(unsigned Register) override;
219*0a6a1f1dSLionel Sambuc void EmitWinCFISetFrame(unsigned Register, unsigned Offset) override;
220*0a6a1f1dSLionel Sambuc void EmitWinCFIAllocStack(unsigned Size) override;
221*0a6a1f1dSLionel Sambuc void EmitWinCFISaveReg(unsigned Register, unsigned Offset) override;
222*0a6a1f1dSLionel Sambuc void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) override;
223*0a6a1f1dSLionel Sambuc void EmitWinCFIPushFrame(bool Code) override;
224*0a6a1f1dSLionel Sambuc void EmitWinCFIEndProlog() override;
225f4a2713aSLionel Sambuc
226*0a6a1f1dSLionel Sambuc void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override;
227*0a6a1f1dSLionel Sambuc void EmitWinEHHandlerData() override;
228f4a2713aSLionel Sambuc
229*0a6a1f1dSLionel Sambuc void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
230*0a6a1f1dSLionel Sambuc
231*0a6a1f1dSLionel Sambuc void EmitBundleAlignMode(unsigned AlignPow2) override;
232*0a6a1f1dSLionel Sambuc void EmitBundleLock(bool AlignToEnd) override;
233*0a6a1f1dSLionel Sambuc void EmitBundleUnlock() override;
234f4a2713aSLionel Sambuc
235f4a2713aSLionel Sambuc /// EmitRawText - If this file is backed by an assembly streamer, this dumps
236f4a2713aSLionel Sambuc /// the specified string in the output .s file. This capability is
237f4a2713aSLionel Sambuc /// indicated by the hasRawTextSupport() predicate.
238*0a6a1f1dSLionel Sambuc void EmitRawTextImpl(StringRef String) override;
239f4a2713aSLionel Sambuc
240*0a6a1f1dSLionel Sambuc void FinishImpl() override;
241f4a2713aSLionel Sambuc };
242f4a2713aSLionel Sambuc
243f4a2713aSLionel Sambuc } // end anonymous namespace.
244f4a2713aSLionel Sambuc
245f4a2713aSLionel Sambuc /// AddComment - Add a comment that can be emitted to the generated .s
246f4a2713aSLionel Sambuc /// file if applicable as a QoI issue to make the output of the compiler
247f4a2713aSLionel Sambuc /// more readable. This only affects the MCAsmStreamer, and only when
248f4a2713aSLionel Sambuc /// verbose assembly output is enabled.
AddComment(const Twine & T)249f4a2713aSLionel Sambuc void MCAsmStreamer::AddComment(const Twine &T) {
250f4a2713aSLionel Sambuc if (!IsVerboseAsm) return;
251f4a2713aSLionel Sambuc
252f4a2713aSLionel Sambuc // Make sure that CommentStream is flushed.
253f4a2713aSLionel Sambuc CommentStream.flush();
254f4a2713aSLionel Sambuc
255f4a2713aSLionel Sambuc T.toVector(CommentToEmit);
256f4a2713aSLionel Sambuc // Each comment goes on its own line.
257f4a2713aSLionel Sambuc CommentToEmit.push_back('\n');
258f4a2713aSLionel Sambuc
259f4a2713aSLionel Sambuc // Tell the comment stream that the vector changed underneath it.
260f4a2713aSLionel Sambuc CommentStream.resync();
261f4a2713aSLionel Sambuc }
262f4a2713aSLionel Sambuc
EmitCommentsAndEOL()263f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCommentsAndEOL() {
264f4a2713aSLionel Sambuc if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
265f4a2713aSLionel Sambuc OS << '\n';
266f4a2713aSLionel Sambuc return;
267f4a2713aSLionel Sambuc }
268f4a2713aSLionel Sambuc
269f4a2713aSLionel Sambuc CommentStream.flush();
270f4a2713aSLionel Sambuc StringRef Comments = CommentToEmit.str();
271f4a2713aSLionel Sambuc
272f4a2713aSLionel Sambuc assert(Comments.back() == '\n' &&
273f4a2713aSLionel Sambuc "Comment array not newline terminated");
274f4a2713aSLionel Sambuc do {
275f4a2713aSLionel Sambuc // Emit a line of comments.
276f4a2713aSLionel Sambuc OS.PadToColumn(MAI->getCommentColumn());
277f4a2713aSLionel Sambuc size_t Position = Comments.find('\n');
278f4a2713aSLionel Sambuc OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
279f4a2713aSLionel Sambuc
280f4a2713aSLionel Sambuc Comments = Comments.substr(Position+1);
281f4a2713aSLionel Sambuc } while (!Comments.empty());
282f4a2713aSLionel Sambuc
283f4a2713aSLionel Sambuc CommentToEmit.clear();
284f4a2713aSLionel Sambuc // Tell the comment stream that the vector changed underneath it.
285f4a2713aSLionel Sambuc CommentStream.resync();
286f4a2713aSLionel Sambuc }
287f4a2713aSLionel Sambuc
truncateToSize(int64_t Value,unsigned Bytes)288f4a2713aSLionel Sambuc static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
289f4a2713aSLionel Sambuc assert(Bytes && "Invalid size!");
290f4a2713aSLionel Sambuc return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
291f4a2713aSLionel Sambuc }
292f4a2713aSLionel Sambuc
emitRawComment(const Twine & T,bool TabPrefix)293*0a6a1f1dSLionel Sambuc void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
294*0a6a1f1dSLionel Sambuc if (TabPrefix)
295*0a6a1f1dSLionel Sambuc OS << '\t';
296*0a6a1f1dSLionel Sambuc OS << MAI->getCommentString() << T;
297*0a6a1f1dSLionel Sambuc EmitEOL();
298*0a6a1f1dSLionel Sambuc }
299*0a6a1f1dSLionel Sambuc
ChangeSection(const MCSection * Section,const MCExpr * Subsection)300f4a2713aSLionel Sambuc void MCAsmStreamer::ChangeSection(const MCSection *Section,
301f4a2713aSLionel Sambuc const MCExpr *Subsection) {
302f4a2713aSLionel Sambuc assert(Section && "Cannot switch to a null section!");
303f4a2713aSLionel Sambuc Section->PrintSwitchToSection(*MAI, OS, Subsection);
304f4a2713aSLionel Sambuc }
305f4a2713aSLionel Sambuc
EmitLabel(MCSymbol * Symbol)306f4a2713aSLionel Sambuc void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
307f4a2713aSLionel Sambuc assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
308f4a2713aSLionel Sambuc MCStreamer::EmitLabel(Symbol);
309f4a2713aSLionel Sambuc
310f4a2713aSLionel Sambuc OS << *Symbol << MAI->getLabelSuffix();
311f4a2713aSLionel Sambuc EmitEOL();
312f4a2713aSLionel Sambuc }
313f4a2713aSLionel Sambuc
EmitLOHDirective(MCLOHType Kind,const MCLOHArgs & Args)314*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
315*0a6a1f1dSLionel Sambuc StringRef str = MCLOHIdToName(Kind);
316f4a2713aSLionel Sambuc
317*0a6a1f1dSLionel Sambuc #ifndef NDEBUG
318*0a6a1f1dSLionel Sambuc int NbArgs = MCLOHIdToNbArgs(Kind);
319*0a6a1f1dSLionel Sambuc assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
320*0a6a1f1dSLionel Sambuc assert(str != "" && "Invalid LOH name");
321*0a6a1f1dSLionel Sambuc #endif
322*0a6a1f1dSLionel Sambuc
323*0a6a1f1dSLionel Sambuc OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
324*0a6a1f1dSLionel Sambuc bool IsFirst = true;
325*0a6a1f1dSLionel Sambuc for (MCLOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();
326*0a6a1f1dSLionel Sambuc It != EndIt; ++It) {
327*0a6a1f1dSLionel Sambuc if (!IsFirst)
328*0a6a1f1dSLionel Sambuc OS << ", ";
329*0a6a1f1dSLionel Sambuc IsFirst = false;
330*0a6a1f1dSLionel Sambuc OS << **It;
331*0a6a1f1dSLionel Sambuc }
332f4a2713aSLionel Sambuc EmitEOL();
333f4a2713aSLionel Sambuc }
334f4a2713aSLionel Sambuc
EmitAssemblerFlag(MCAssemblerFlag Flag)335f4a2713aSLionel Sambuc void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
336f4a2713aSLionel Sambuc switch (Flag) {
337f4a2713aSLionel Sambuc case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
338f4a2713aSLionel Sambuc case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
339f4a2713aSLionel Sambuc case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break;
340f4a2713aSLionel Sambuc case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break;
341f4a2713aSLionel Sambuc case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break;
342f4a2713aSLionel Sambuc }
343f4a2713aSLionel Sambuc EmitEOL();
344f4a2713aSLionel Sambuc }
345f4a2713aSLionel Sambuc
EmitLinkerOptions(ArrayRef<std::string> Options)346f4a2713aSLionel Sambuc void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
347f4a2713aSLionel Sambuc assert(!Options.empty() && "At least one option is required!");
348f4a2713aSLionel Sambuc OS << "\t.linker_option \"" << Options[0] << '"';
349f4a2713aSLionel Sambuc for (ArrayRef<std::string>::iterator it = Options.begin() + 1,
350f4a2713aSLionel Sambuc ie = Options.end(); it != ie; ++it) {
351f4a2713aSLionel Sambuc OS << ", " << '"' << *it << '"';
352f4a2713aSLionel Sambuc }
353f4a2713aSLionel Sambuc OS << "\n";
354f4a2713aSLionel Sambuc }
355f4a2713aSLionel Sambuc
EmitDataRegion(MCDataRegionType Kind)356f4a2713aSLionel Sambuc void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
357f4a2713aSLionel Sambuc if (!MAI->doesSupportDataRegionDirectives())
358f4a2713aSLionel Sambuc return;
359f4a2713aSLionel Sambuc switch (Kind) {
360f4a2713aSLionel Sambuc case MCDR_DataRegion: OS << "\t.data_region"; break;
361f4a2713aSLionel Sambuc case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
362f4a2713aSLionel Sambuc case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
363f4a2713aSLionel Sambuc case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
364f4a2713aSLionel Sambuc case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
365f4a2713aSLionel Sambuc }
366f4a2713aSLionel Sambuc EmitEOL();
367f4a2713aSLionel Sambuc }
368f4a2713aSLionel Sambuc
EmitVersionMin(MCVersionMinType Kind,unsigned Major,unsigned Minor,unsigned Update)369*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
370*0a6a1f1dSLionel Sambuc unsigned Minor, unsigned Update) {
371*0a6a1f1dSLionel Sambuc switch (Kind) {
372*0a6a1f1dSLionel Sambuc case MCVM_IOSVersionMin: OS << "\t.ios_version_min"; break;
373*0a6a1f1dSLionel Sambuc case MCVM_OSXVersionMin: OS << "\t.macosx_version_min"; break;
374*0a6a1f1dSLionel Sambuc }
375*0a6a1f1dSLionel Sambuc OS << " " << Major << ", " << Minor;
376*0a6a1f1dSLionel Sambuc if (Update)
377*0a6a1f1dSLionel Sambuc OS << ", " << Update;
378*0a6a1f1dSLionel Sambuc EmitEOL();
379*0a6a1f1dSLionel Sambuc }
380*0a6a1f1dSLionel Sambuc
EmitThumbFunc(MCSymbol * Func)381f4a2713aSLionel Sambuc void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
382f4a2713aSLionel Sambuc // This needs to emit to a temporary string to get properly quoted
383f4a2713aSLionel Sambuc // MCSymbols when they have spaces in them.
384f4a2713aSLionel Sambuc OS << "\t.thumb_func";
385f4a2713aSLionel Sambuc // Only Mach-O hasSubsectionsViaSymbols()
386f4a2713aSLionel Sambuc if (MAI->hasSubsectionsViaSymbols())
387f4a2713aSLionel Sambuc OS << '\t' << *Func;
388f4a2713aSLionel Sambuc EmitEOL();
389f4a2713aSLionel Sambuc }
390f4a2713aSLionel Sambuc
EmitAssignment(MCSymbol * Symbol,const MCExpr * Value)391f4a2713aSLionel Sambuc void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
392f4a2713aSLionel Sambuc OS << *Symbol << " = " << *Value;
393f4a2713aSLionel Sambuc EmitEOL();
394f4a2713aSLionel Sambuc
395*0a6a1f1dSLionel Sambuc MCStreamer::EmitAssignment(Symbol, Value);
396f4a2713aSLionel Sambuc }
397f4a2713aSLionel Sambuc
EmitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)398f4a2713aSLionel Sambuc void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
399f4a2713aSLionel Sambuc OS << ".weakref " << *Alias << ", " << *Symbol;
400f4a2713aSLionel Sambuc EmitEOL();
401f4a2713aSLionel Sambuc }
402f4a2713aSLionel Sambuc
EmitSymbolAttribute(MCSymbol * Symbol,MCSymbolAttr Attribute)403f4a2713aSLionel Sambuc bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
404f4a2713aSLionel Sambuc MCSymbolAttr Attribute) {
405f4a2713aSLionel Sambuc switch (Attribute) {
406f4a2713aSLionel Sambuc case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
407f4a2713aSLionel Sambuc case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
408f4a2713aSLionel Sambuc case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
409f4a2713aSLionel Sambuc case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
410f4a2713aSLionel Sambuc case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
411f4a2713aSLionel Sambuc case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
412f4a2713aSLionel Sambuc case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
413f4a2713aSLionel Sambuc case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
414f4a2713aSLionel Sambuc if (!MAI->hasDotTypeDotSizeDirective())
415f4a2713aSLionel Sambuc return false; // Symbol attribute not supported
416f4a2713aSLionel Sambuc OS << "\t.type\t" << *Symbol << ','
417f4a2713aSLionel Sambuc << ((MAI->getCommentString()[0] != '@') ? '@' : '%');
418f4a2713aSLionel Sambuc switch (Attribute) {
419f4a2713aSLionel Sambuc default: return false;
420f4a2713aSLionel Sambuc case MCSA_ELF_TypeFunction: OS << "function"; break;
421f4a2713aSLionel Sambuc case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
422f4a2713aSLionel Sambuc case MCSA_ELF_TypeObject: OS << "object"; break;
423f4a2713aSLionel Sambuc case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
424f4a2713aSLionel Sambuc case MCSA_ELF_TypeCommon: OS << "common"; break;
425f4a2713aSLionel Sambuc case MCSA_ELF_TypeNoType: OS << "no_type"; break;
426f4a2713aSLionel Sambuc case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
427f4a2713aSLionel Sambuc }
428f4a2713aSLionel Sambuc EmitEOL();
429f4a2713aSLionel Sambuc return true;
430f4a2713aSLionel Sambuc case MCSA_Global: // .globl/.global
431f4a2713aSLionel Sambuc OS << MAI->getGlobalDirective();
432f4a2713aSLionel Sambuc break;
433f4a2713aSLionel Sambuc case MCSA_Hidden: OS << "\t.hidden\t"; break;
434f4a2713aSLionel Sambuc case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
435f4a2713aSLionel Sambuc case MCSA_Internal: OS << "\t.internal\t"; break;
436f4a2713aSLionel Sambuc case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
437f4a2713aSLionel Sambuc case MCSA_Local: OS << "\t.local\t"; break;
438*0a6a1f1dSLionel Sambuc case MCSA_NoDeadStrip:
439*0a6a1f1dSLionel Sambuc if (!MAI->hasNoDeadStrip())
440*0a6a1f1dSLionel Sambuc return false;
441*0a6a1f1dSLionel Sambuc OS << "\t.no_dead_strip\t";
442*0a6a1f1dSLionel Sambuc break;
443f4a2713aSLionel Sambuc case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
444f4a2713aSLionel Sambuc case MCSA_PrivateExtern:
445f4a2713aSLionel Sambuc OS << "\t.private_extern\t";
446f4a2713aSLionel Sambuc break;
447f4a2713aSLionel Sambuc case MCSA_Protected: OS << "\t.protected\t"; break;
448f4a2713aSLionel Sambuc case MCSA_Reference: OS << "\t.reference\t"; break;
449*0a6a1f1dSLionel Sambuc case MCSA_Weak: OS << MAI->getWeakDirective(); break;
450f4a2713aSLionel Sambuc case MCSA_WeakDefinition:
451f4a2713aSLionel Sambuc OS << "\t.weak_definition\t";
452f4a2713aSLionel Sambuc break;
453f4a2713aSLionel Sambuc // .weak_reference
454f4a2713aSLionel Sambuc case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
455f4a2713aSLionel Sambuc case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
456f4a2713aSLionel Sambuc }
457f4a2713aSLionel Sambuc
458f4a2713aSLionel Sambuc OS << *Symbol;
459f4a2713aSLionel Sambuc EmitEOL();
460f4a2713aSLionel Sambuc
461f4a2713aSLionel Sambuc return true;
462f4a2713aSLionel Sambuc }
463f4a2713aSLionel Sambuc
EmitSymbolDesc(MCSymbol * Symbol,unsigned DescValue)464f4a2713aSLionel Sambuc void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
465f4a2713aSLionel Sambuc OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
466f4a2713aSLionel Sambuc EmitEOL();
467f4a2713aSLionel Sambuc }
468f4a2713aSLionel Sambuc
BeginCOFFSymbolDef(const MCSymbol * Symbol)469f4a2713aSLionel Sambuc void MCAsmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
470f4a2713aSLionel Sambuc OS << "\t.def\t " << *Symbol << ';';
471f4a2713aSLionel Sambuc EmitEOL();
472f4a2713aSLionel Sambuc }
473f4a2713aSLionel Sambuc
EmitCOFFSymbolStorageClass(int StorageClass)474f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCOFFSymbolStorageClass (int StorageClass) {
475f4a2713aSLionel Sambuc OS << "\t.scl\t" << StorageClass << ';';
476f4a2713aSLionel Sambuc EmitEOL();
477f4a2713aSLionel Sambuc }
478f4a2713aSLionel Sambuc
EmitCOFFSymbolType(int Type)479f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCOFFSymbolType (int Type) {
480f4a2713aSLionel Sambuc OS << "\t.type\t" << Type << ';';
481f4a2713aSLionel Sambuc EmitEOL();
482f4a2713aSLionel Sambuc }
483f4a2713aSLionel Sambuc
EndCOFFSymbolDef()484f4a2713aSLionel Sambuc void MCAsmStreamer::EndCOFFSymbolDef() {
485f4a2713aSLionel Sambuc OS << "\t.endef";
486f4a2713aSLionel Sambuc EmitEOL();
487f4a2713aSLionel Sambuc }
488f4a2713aSLionel Sambuc
EmitCOFFSectionIndex(MCSymbol const * Symbol)489*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
490*0a6a1f1dSLionel Sambuc OS << "\t.secidx\t" << *Symbol;
491*0a6a1f1dSLionel Sambuc EmitEOL();
492*0a6a1f1dSLionel Sambuc }
493*0a6a1f1dSLionel Sambuc
EmitCOFFSecRel32(MCSymbol const * Symbol)494f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
495*0a6a1f1dSLionel Sambuc OS << "\t.secrel32\t" << *Symbol;
496f4a2713aSLionel Sambuc EmitEOL();
497f4a2713aSLionel Sambuc }
498f4a2713aSLionel Sambuc
EmitELFSize(MCSymbol * Symbol,const MCExpr * Value)499f4a2713aSLionel Sambuc void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
500f4a2713aSLionel Sambuc assert(MAI->hasDotTypeDotSizeDirective());
501f4a2713aSLionel Sambuc OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
502f4a2713aSLionel Sambuc }
503f4a2713aSLionel Sambuc
EmitCommonSymbol(MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)504f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
505f4a2713aSLionel Sambuc unsigned ByteAlignment) {
506f4a2713aSLionel Sambuc // Common symbols do not belong to any actual section.
507*0a6a1f1dSLionel Sambuc AssignSection(Symbol, nullptr);
508f4a2713aSLionel Sambuc
509f4a2713aSLionel Sambuc OS << "\t.comm\t" << *Symbol << ',' << Size;
510f4a2713aSLionel Sambuc if (ByteAlignment != 0) {
511f4a2713aSLionel Sambuc if (MAI->getCOMMDirectiveAlignmentIsInBytes())
512f4a2713aSLionel Sambuc OS << ',' << ByteAlignment;
513f4a2713aSLionel Sambuc else
514f4a2713aSLionel Sambuc OS << ',' << Log2_32(ByteAlignment);
515f4a2713aSLionel Sambuc }
516f4a2713aSLionel Sambuc EmitEOL();
517f4a2713aSLionel Sambuc }
518f4a2713aSLionel Sambuc
519f4a2713aSLionel Sambuc /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
520f4a2713aSLionel Sambuc ///
521f4a2713aSLionel Sambuc /// @param Symbol - The common symbol to emit.
522f4a2713aSLionel Sambuc /// @param Size - The size of the common symbol.
EmitLocalCommonSymbol(MCSymbol * Symbol,uint64_t Size,unsigned ByteAlign)523f4a2713aSLionel Sambuc void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
524f4a2713aSLionel Sambuc unsigned ByteAlign) {
525f4a2713aSLionel Sambuc // Common symbols do not belong to any actual section.
526*0a6a1f1dSLionel Sambuc AssignSection(Symbol, nullptr);
527f4a2713aSLionel Sambuc
528f4a2713aSLionel Sambuc OS << "\t.lcomm\t" << *Symbol << ',' << Size;
529f4a2713aSLionel Sambuc if (ByteAlign > 1) {
530f4a2713aSLionel Sambuc switch (MAI->getLCOMMDirectiveAlignmentType()) {
531f4a2713aSLionel Sambuc case LCOMM::NoAlignment:
532f4a2713aSLionel Sambuc llvm_unreachable("alignment not supported on .lcomm!");
533f4a2713aSLionel Sambuc case LCOMM::ByteAlignment:
534f4a2713aSLionel Sambuc OS << ',' << ByteAlign;
535f4a2713aSLionel Sambuc break;
536f4a2713aSLionel Sambuc case LCOMM::Log2Alignment:
537f4a2713aSLionel Sambuc assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
538f4a2713aSLionel Sambuc OS << ',' << Log2_32(ByteAlign);
539f4a2713aSLionel Sambuc break;
540f4a2713aSLionel Sambuc }
541f4a2713aSLionel Sambuc }
542f4a2713aSLionel Sambuc EmitEOL();
543f4a2713aSLionel Sambuc }
544f4a2713aSLionel Sambuc
EmitZerofill(const MCSection * Section,MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)545f4a2713aSLionel Sambuc void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
546f4a2713aSLionel Sambuc uint64_t Size, unsigned ByteAlignment) {
547f4a2713aSLionel Sambuc if (Symbol)
548f4a2713aSLionel Sambuc AssignSection(Symbol, Section);
549f4a2713aSLionel Sambuc
550f4a2713aSLionel Sambuc // Note: a .zerofill directive does not switch sections.
551f4a2713aSLionel Sambuc OS << ".zerofill ";
552f4a2713aSLionel Sambuc
553f4a2713aSLionel Sambuc // This is a mach-o specific directive.
554f4a2713aSLionel Sambuc const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
555f4a2713aSLionel Sambuc OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
556f4a2713aSLionel Sambuc
557*0a6a1f1dSLionel Sambuc if (Symbol) {
558f4a2713aSLionel Sambuc OS << ',' << *Symbol << ',' << Size;
559f4a2713aSLionel Sambuc if (ByteAlignment != 0)
560f4a2713aSLionel Sambuc OS << ',' << Log2_32(ByteAlignment);
561f4a2713aSLionel Sambuc }
562f4a2713aSLionel Sambuc EmitEOL();
563f4a2713aSLionel Sambuc }
564f4a2713aSLionel Sambuc
565f4a2713aSLionel Sambuc // .tbss sym, size, align
566f4a2713aSLionel Sambuc // This depends that the symbol has already been mangled from the original,
567f4a2713aSLionel Sambuc // e.g. _a.
EmitTBSSSymbol(const MCSection * Section,MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)568f4a2713aSLionel Sambuc void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
569f4a2713aSLionel Sambuc uint64_t Size, unsigned ByteAlignment) {
570f4a2713aSLionel Sambuc AssignSection(Symbol, Section);
571f4a2713aSLionel Sambuc
572*0a6a1f1dSLionel Sambuc assert(Symbol && "Symbol shouldn't be NULL!");
573f4a2713aSLionel Sambuc // Instead of using the Section we'll just use the shortcut.
574f4a2713aSLionel Sambuc // This is a mach-o specific directive and section.
575f4a2713aSLionel Sambuc OS << ".tbss " << *Symbol << ", " << Size;
576f4a2713aSLionel Sambuc
577f4a2713aSLionel Sambuc // Output align if we have it. We default to 1 so don't bother printing
578f4a2713aSLionel Sambuc // that.
579f4a2713aSLionel Sambuc if (ByteAlignment > 1) OS << ", " << Log2_32(ByteAlignment);
580f4a2713aSLionel Sambuc
581f4a2713aSLionel Sambuc EmitEOL();
582f4a2713aSLionel Sambuc }
583f4a2713aSLionel Sambuc
toOctal(int X)584f4a2713aSLionel Sambuc static inline char toOctal(int X) { return (X&7)+'0'; }
585f4a2713aSLionel Sambuc
PrintQuotedString(StringRef Data,raw_ostream & OS)586f4a2713aSLionel Sambuc static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
587f4a2713aSLionel Sambuc OS << '"';
588f4a2713aSLionel Sambuc
589f4a2713aSLionel Sambuc for (unsigned i = 0, e = Data.size(); i != e; ++i) {
590f4a2713aSLionel Sambuc unsigned char C = Data[i];
591f4a2713aSLionel Sambuc if (C == '"' || C == '\\') {
592f4a2713aSLionel Sambuc OS << '\\' << (char)C;
593f4a2713aSLionel Sambuc continue;
594f4a2713aSLionel Sambuc }
595f4a2713aSLionel Sambuc
596f4a2713aSLionel Sambuc if (isprint((unsigned char)C)) {
597f4a2713aSLionel Sambuc OS << (char)C;
598f4a2713aSLionel Sambuc continue;
599f4a2713aSLionel Sambuc }
600f4a2713aSLionel Sambuc
601f4a2713aSLionel Sambuc switch (C) {
602f4a2713aSLionel Sambuc case '\b': OS << "\\b"; break;
603f4a2713aSLionel Sambuc case '\f': OS << "\\f"; break;
604f4a2713aSLionel Sambuc case '\n': OS << "\\n"; break;
605f4a2713aSLionel Sambuc case '\r': OS << "\\r"; break;
606f4a2713aSLionel Sambuc case '\t': OS << "\\t"; break;
607f4a2713aSLionel Sambuc default:
608f4a2713aSLionel Sambuc OS << '\\';
609f4a2713aSLionel Sambuc OS << toOctal(C >> 6);
610f4a2713aSLionel Sambuc OS << toOctal(C >> 3);
611f4a2713aSLionel Sambuc OS << toOctal(C >> 0);
612f4a2713aSLionel Sambuc break;
613f4a2713aSLionel Sambuc }
614f4a2713aSLionel Sambuc }
615f4a2713aSLionel Sambuc
616f4a2713aSLionel Sambuc OS << '"';
617f4a2713aSLionel Sambuc }
618f4a2713aSLionel Sambuc
619f4a2713aSLionel Sambuc
EmitBytes(StringRef Data)620f4a2713aSLionel Sambuc void MCAsmStreamer::EmitBytes(StringRef Data) {
621f4a2713aSLionel Sambuc assert(getCurrentSection().first &&
622f4a2713aSLionel Sambuc "Cannot emit contents before setting section!");
623f4a2713aSLionel Sambuc if (Data.empty()) return;
624f4a2713aSLionel Sambuc
625f4a2713aSLionel Sambuc if (Data.size() == 1) {
626f4a2713aSLionel Sambuc OS << MAI->getData8bitsDirective();
627f4a2713aSLionel Sambuc OS << (unsigned)(unsigned char)Data[0];
628f4a2713aSLionel Sambuc EmitEOL();
629f4a2713aSLionel Sambuc return;
630f4a2713aSLionel Sambuc }
631f4a2713aSLionel Sambuc
632f4a2713aSLionel Sambuc // If the data ends with 0 and the target supports .asciz, use it, otherwise
633f4a2713aSLionel Sambuc // use .ascii
634f4a2713aSLionel Sambuc if (MAI->getAscizDirective() && Data.back() == 0) {
635f4a2713aSLionel Sambuc OS << MAI->getAscizDirective();
636f4a2713aSLionel Sambuc Data = Data.substr(0, Data.size()-1);
637f4a2713aSLionel Sambuc } else {
638f4a2713aSLionel Sambuc OS << MAI->getAsciiDirective();
639f4a2713aSLionel Sambuc }
640f4a2713aSLionel Sambuc
641f4a2713aSLionel Sambuc PrintQuotedString(Data, OS);
642f4a2713aSLionel Sambuc EmitEOL();
643f4a2713aSLionel Sambuc }
644f4a2713aSLionel Sambuc
EmitIntValue(uint64_t Value,unsigned Size)645f4a2713aSLionel Sambuc void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
646f4a2713aSLionel Sambuc EmitValue(MCConstantExpr::Create(Value, getContext()), Size);
647f4a2713aSLionel Sambuc }
648f4a2713aSLionel Sambuc
EmitValueImpl(const MCExpr * Value,unsigned Size,const SMLoc & Loc)649*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
650*0a6a1f1dSLionel Sambuc const SMLoc &Loc) {
651*0a6a1f1dSLionel Sambuc assert(Size <= 8 && "Invalid size");
652f4a2713aSLionel Sambuc assert(getCurrentSection().first &&
653f4a2713aSLionel Sambuc "Cannot emit contents before setting section!");
654*0a6a1f1dSLionel Sambuc const char *Directive = nullptr;
655f4a2713aSLionel Sambuc switch (Size) {
656f4a2713aSLionel Sambuc default: break;
657f4a2713aSLionel Sambuc case 1: Directive = MAI->getData8bitsDirective(); break;
658f4a2713aSLionel Sambuc case 2: Directive = MAI->getData16bitsDirective(); break;
659f4a2713aSLionel Sambuc case 4: Directive = MAI->getData32bitsDirective(); break;
660*0a6a1f1dSLionel Sambuc case 8: Directive = MAI->getData64bitsDirective(); break;
661*0a6a1f1dSLionel Sambuc }
662*0a6a1f1dSLionel Sambuc
663*0a6a1f1dSLionel Sambuc if (!Directive) {
664f4a2713aSLionel Sambuc int64_t IntValue;
665f4a2713aSLionel Sambuc if (!Value->EvaluateAsAbsolute(IntValue))
666f4a2713aSLionel Sambuc report_fatal_error("Don't know how to emit this value.");
667*0a6a1f1dSLionel Sambuc
668*0a6a1f1dSLionel Sambuc // We couldn't handle the requested integer size so we fallback by breaking
669*0a6a1f1dSLionel Sambuc // the request down into several, smaller, integers. Since sizes greater
670*0a6a1f1dSLionel Sambuc // than eight are invalid and size equivalent to eight should have been
671*0a6a1f1dSLionel Sambuc // handled earlier, we use four bytes as our largest piece of granularity.
672*0a6a1f1dSLionel Sambuc bool IsLittleEndian = MAI->isLittleEndian();
673*0a6a1f1dSLionel Sambuc for (unsigned Emitted = 0; Emitted != Size;) {
674*0a6a1f1dSLionel Sambuc unsigned Remaining = Size - Emitted;
675*0a6a1f1dSLionel Sambuc // The size of our partial emission must be a power of two less than
676*0a6a1f1dSLionel Sambuc // eight.
677*0a6a1f1dSLionel Sambuc unsigned EmissionSize = PowerOf2Floor(Remaining);
678*0a6a1f1dSLionel Sambuc if (EmissionSize > 4)
679*0a6a1f1dSLionel Sambuc EmissionSize = 4;
680*0a6a1f1dSLionel Sambuc // Calculate the byte offset of our partial emission taking into account
681*0a6a1f1dSLionel Sambuc // the endianness of the target.
682*0a6a1f1dSLionel Sambuc unsigned ByteOffset =
683*0a6a1f1dSLionel Sambuc IsLittleEndian ? Emitted : (Remaining - EmissionSize);
684*0a6a1f1dSLionel Sambuc uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
685*0a6a1f1dSLionel Sambuc // We truncate our partial emission to fit within the bounds of the
686*0a6a1f1dSLionel Sambuc // emission domain. This produces nicer output and silences potential
687*0a6a1f1dSLionel Sambuc // truncation warnings when round tripping through another assembler.
688*0a6a1f1dSLionel Sambuc uint64_t Shift = 64 - EmissionSize * 8;
689*0a6a1f1dSLionel Sambuc assert(Shift < static_cast<uint64_t>(
690*0a6a1f1dSLionel Sambuc std::numeric_limits<unsigned long long>::digits) &&
691*0a6a1f1dSLionel Sambuc "undefined behavior");
692*0a6a1f1dSLionel Sambuc ValueToEmit &= ~0ULL >> Shift;
693*0a6a1f1dSLionel Sambuc EmitIntValue(ValueToEmit, EmissionSize);
694*0a6a1f1dSLionel Sambuc Emitted += EmissionSize;
695f4a2713aSLionel Sambuc }
696f4a2713aSLionel Sambuc return;
697f4a2713aSLionel Sambuc }
698f4a2713aSLionel Sambuc
699f4a2713aSLionel Sambuc assert(Directive && "Invalid size for machine code value!");
700f4a2713aSLionel Sambuc OS << Directive << *Value;
701f4a2713aSLionel Sambuc EmitEOL();
702f4a2713aSLionel Sambuc }
703f4a2713aSLionel Sambuc
EmitULEB128Value(const MCExpr * Value)704f4a2713aSLionel Sambuc void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
705f4a2713aSLionel Sambuc int64_t IntValue;
706f4a2713aSLionel Sambuc if (Value->EvaluateAsAbsolute(IntValue)) {
707f4a2713aSLionel Sambuc EmitULEB128IntValue(IntValue);
708f4a2713aSLionel Sambuc return;
709f4a2713aSLionel Sambuc }
710f4a2713aSLionel Sambuc OS << ".uleb128 " << *Value;
711f4a2713aSLionel Sambuc EmitEOL();
712f4a2713aSLionel Sambuc }
713f4a2713aSLionel Sambuc
EmitSLEB128Value(const MCExpr * Value)714f4a2713aSLionel Sambuc void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
715f4a2713aSLionel Sambuc int64_t IntValue;
716f4a2713aSLionel Sambuc if (Value->EvaluateAsAbsolute(IntValue)) {
717f4a2713aSLionel Sambuc EmitSLEB128IntValue(IntValue);
718f4a2713aSLionel Sambuc return;
719f4a2713aSLionel Sambuc }
720f4a2713aSLionel Sambuc OS << ".sleb128 " << *Value;
721f4a2713aSLionel Sambuc EmitEOL();
722f4a2713aSLionel Sambuc }
723f4a2713aSLionel Sambuc
EmitGPRel64Value(const MCExpr * Value)724f4a2713aSLionel Sambuc void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
725*0a6a1f1dSLionel Sambuc assert(MAI->getGPRel64Directive() != nullptr);
726f4a2713aSLionel Sambuc OS << MAI->getGPRel64Directive() << *Value;
727f4a2713aSLionel Sambuc EmitEOL();
728f4a2713aSLionel Sambuc }
729f4a2713aSLionel Sambuc
EmitGPRel32Value(const MCExpr * Value)730f4a2713aSLionel Sambuc void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
731*0a6a1f1dSLionel Sambuc assert(MAI->getGPRel32Directive() != nullptr);
732f4a2713aSLionel Sambuc OS << MAI->getGPRel32Directive() << *Value;
733f4a2713aSLionel Sambuc EmitEOL();
734f4a2713aSLionel Sambuc }
735f4a2713aSLionel Sambuc
736f4a2713aSLionel Sambuc
737f4a2713aSLionel Sambuc /// EmitFill - Emit NumBytes bytes worth of the value specified by
738f4a2713aSLionel Sambuc /// FillValue. This implements directives such as '.space'.
EmitFill(uint64_t NumBytes,uint8_t FillValue)739f4a2713aSLionel Sambuc void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
740f4a2713aSLionel Sambuc if (NumBytes == 0) return;
741f4a2713aSLionel Sambuc
742f4a2713aSLionel Sambuc if (const char *ZeroDirective = MAI->getZeroDirective()) {
743f4a2713aSLionel Sambuc OS << ZeroDirective << NumBytes;
744f4a2713aSLionel Sambuc if (FillValue != 0)
745f4a2713aSLionel Sambuc OS << ',' << (int)FillValue;
746f4a2713aSLionel Sambuc EmitEOL();
747f4a2713aSLionel Sambuc return;
748f4a2713aSLionel Sambuc }
749f4a2713aSLionel Sambuc
750f4a2713aSLionel Sambuc // Emit a byte at a time.
751f4a2713aSLionel Sambuc MCStreamer::EmitFill(NumBytes, FillValue);
752f4a2713aSLionel Sambuc }
753f4a2713aSLionel Sambuc
EmitValueToAlignment(unsigned ByteAlignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)754f4a2713aSLionel Sambuc void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
755f4a2713aSLionel Sambuc unsigned ValueSize,
756f4a2713aSLionel Sambuc unsigned MaxBytesToEmit) {
757f4a2713aSLionel Sambuc // Some assemblers don't support non-power of two alignments, so we always
758f4a2713aSLionel Sambuc // emit alignments as a power of two if possible.
759f4a2713aSLionel Sambuc if (isPowerOf2_32(ByteAlignment)) {
760f4a2713aSLionel Sambuc switch (ValueSize) {
761*0a6a1f1dSLionel Sambuc default:
762*0a6a1f1dSLionel Sambuc llvm_unreachable("Invalid size for machine code value!");
763*0a6a1f1dSLionel Sambuc case 1:
764*0a6a1f1dSLionel Sambuc OS << "\t.align\t";
765*0a6a1f1dSLionel Sambuc break;
766*0a6a1f1dSLionel Sambuc case 2:
767*0a6a1f1dSLionel Sambuc OS << ".p2alignw ";
768*0a6a1f1dSLionel Sambuc break;
769*0a6a1f1dSLionel Sambuc case 4:
770*0a6a1f1dSLionel Sambuc OS << ".p2alignl ";
771*0a6a1f1dSLionel Sambuc break;
772*0a6a1f1dSLionel Sambuc case 8:
773*0a6a1f1dSLionel Sambuc llvm_unreachable("Unsupported alignment size!");
774f4a2713aSLionel Sambuc }
775f4a2713aSLionel Sambuc
776f4a2713aSLionel Sambuc if (MAI->getAlignmentIsInBytes())
777f4a2713aSLionel Sambuc OS << ByteAlignment;
778f4a2713aSLionel Sambuc else
779f4a2713aSLionel Sambuc OS << Log2_32(ByteAlignment);
780f4a2713aSLionel Sambuc
781f4a2713aSLionel Sambuc if (Value || MaxBytesToEmit) {
782f4a2713aSLionel Sambuc OS << ", 0x";
783f4a2713aSLionel Sambuc OS.write_hex(truncateToSize(Value, ValueSize));
784f4a2713aSLionel Sambuc
785f4a2713aSLionel Sambuc if (MaxBytesToEmit)
786f4a2713aSLionel Sambuc OS << ", " << MaxBytesToEmit;
787f4a2713aSLionel Sambuc }
788f4a2713aSLionel Sambuc EmitEOL();
789f4a2713aSLionel Sambuc return;
790f4a2713aSLionel Sambuc }
791f4a2713aSLionel Sambuc
792f4a2713aSLionel Sambuc // Non-power of two alignment. This is not widely supported by assemblers.
793f4a2713aSLionel Sambuc // FIXME: Parameterize this based on MAI.
794f4a2713aSLionel Sambuc switch (ValueSize) {
795f4a2713aSLionel Sambuc default: llvm_unreachable("Invalid size for machine code value!");
796f4a2713aSLionel Sambuc case 1: OS << ".balign"; break;
797f4a2713aSLionel Sambuc case 2: OS << ".balignw"; break;
798f4a2713aSLionel Sambuc case 4: OS << ".balignl"; break;
799f4a2713aSLionel Sambuc case 8: llvm_unreachable("Unsupported alignment size!");
800f4a2713aSLionel Sambuc }
801f4a2713aSLionel Sambuc
802f4a2713aSLionel Sambuc OS << ' ' << ByteAlignment;
803f4a2713aSLionel Sambuc OS << ", " << truncateToSize(Value, ValueSize);
804f4a2713aSLionel Sambuc if (MaxBytesToEmit)
805f4a2713aSLionel Sambuc OS << ", " << MaxBytesToEmit;
806f4a2713aSLionel Sambuc EmitEOL();
807f4a2713aSLionel Sambuc }
808f4a2713aSLionel Sambuc
EmitCodeAlignment(unsigned ByteAlignment,unsigned MaxBytesToEmit)809f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
810f4a2713aSLionel Sambuc unsigned MaxBytesToEmit) {
811f4a2713aSLionel Sambuc // Emit with a text fill value.
812f4a2713aSLionel Sambuc EmitValueToAlignment(ByteAlignment, MAI->getTextAlignFillValue(),
813f4a2713aSLionel Sambuc 1, MaxBytesToEmit);
814f4a2713aSLionel Sambuc }
815f4a2713aSLionel Sambuc
EmitValueToOffset(const MCExpr * Offset,unsigned char Value)816f4a2713aSLionel Sambuc bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
817f4a2713aSLionel Sambuc unsigned char Value) {
818f4a2713aSLionel Sambuc // FIXME: Verify that Offset is associated with the current section.
819f4a2713aSLionel Sambuc OS << ".org " << *Offset << ", " << (unsigned) Value;
820f4a2713aSLionel Sambuc EmitEOL();
821f4a2713aSLionel Sambuc return false;
822f4a2713aSLionel Sambuc }
823f4a2713aSLionel Sambuc
824f4a2713aSLionel Sambuc
EmitFileDirective(StringRef Filename)825f4a2713aSLionel Sambuc void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
826f4a2713aSLionel Sambuc assert(MAI->hasSingleParameterDotFile());
827f4a2713aSLionel Sambuc OS << "\t.file\t";
828f4a2713aSLionel Sambuc PrintQuotedString(Filename, OS);
829f4a2713aSLionel Sambuc EmitEOL();
830f4a2713aSLionel Sambuc }
831f4a2713aSLionel Sambuc
EmitDwarfFileDirective(unsigned FileNo,StringRef Directory,StringRef Filename,unsigned CUID)832*0a6a1f1dSLionel Sambuc unsigned MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo,
833*0a6a1f1dSLionel Sambuc StringRef Directory,
834*0a6a1f1dSLionel Sambuc StringRef Filename,
835*0a6a1f1dSLionel Sambuc unsigned CUID) {
836*0a6a1f1dSLionel Sambuc assert(CUID == 0);
837*0a6a1f1dSLionel Sambuc
838*0a6a1f1dSLionel Sambuc MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
839*0a6a1f1dSLionel Sambuc unsigned NumFiles = Table.getMCDwarfFiles().size();
840*0a6a1f1dSLionel Sambuc FileNo = Table.getFile(Directory, Filename, FileNo);
841*0a6a1f1dSLionel Sambuc if (FileNo == 0)
842*0a6a1f1dSLionel Sambuc return 0;
843*0a6a1f1dSLionel Sambuc if (NumFiles == Table.getMCDwarfFiles().size())
844*0a6a1f1dSLionel Sambuc return FileNo;
845*0a6a1f1dSLionel Sambuc
846*0a6a1f1dSLionel Sambuc SmallString<128> FullPathName;
847*0a6a1f1dSLionel Sambuc
848f4a2713aSLionel Sambuc if (!UseDwarfDirectory && !Directory.empty()) {
849f4a2713aSLionel Sambuc if (sys::path::is_absolute(Filename))
850*0a6a1f1dSLionel Sambuc Directory = "";
851*0a6a1f1dSLionel Sambuc else {
852*0a6a1f1dSLionel Sambuc FullPathName = Directory;
853f4a2713aSLionel Sambuc sys::path::append(FullPathName, Filename);
854*0a6a1f1dSLionel Sambuc Directory = "";
855*0a6a1f1dSLionel Sambuc Filename = FullPathName;
856*0a6a1f1dSLionel Sambuc }
857f4a2713aSLionel Sambuc }
858f4a2713aSLionel Sambuc
859f4a2713aSLionel Sambuc OS << "\t.file\t" << FileNo << ' ';
860f4a2713aSLionel Sambuc if (!Directory.empty()) {
861f4a2713aSLionel Sambuc PrintQuotedString(Directory, OS);
862f4a2713aSLionel Sambuc OS << ' ';
863f4a2713aSLionel Sambuc }
864f4a2713aSLionel Sambuc PrintQuotedString(Filename, OS);
865f4a2713aSLionel Sambuc EmitEOL();
866*0a6a1f1dSLionel Sambuc
867*0a6a1f1dSLionel Sambuc return FileNo;
868f4a2713aSLionel Sambuc }
869f4a2713aSLionel Sambuc
EmitDwarfLocDirective(unsigned FileNo,unsigned Line,unsigned Column,unsigned Flags,unsigned Isa,unsigned Discriminator,StringRef FileName)870f4a2713aSLionel Sambuc void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
871f4a2713aSLionel Sambuc unsigned Column, unsigned Flags,
872f4a2713aSLionel Sambuc unsigned Isa,
873f4a2713aSLionel Sambuc unsigned Discriminator,
874f4a2713aSLionel Sambuc StringRef FileName) {
875f4a2713aSLionel Sambuc OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
876f4a2713aSLionel Sambuc if (Flags & DWARF2_FLAG_BASIC_BLOCK)
877f4a2713aSLionel Sambuc OS << " basic_block";
878f4a2713aSLionel Sambuc if (Flags & DWARF2_FLAG_PROLOGUE_END)
879f4a2713aSLionel Sambuc OS << " prologue_end";
880f4a2713aSLionel Sambuc if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
881f4a2713aSLionel Sambuc OS << " epilogue_begin";
882f4a2713aSLionel Sambuc
883f4a2713aSLionel Sambuc unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
884f4a2713aSLionel Sambuc if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
885f4a2713aSLionel Sambuc OS << " is_stmt ";
886f4a2713aSLionel Sambuc
887f4a2713aSLionel Sambuc if (Flags & DWARF2_FLAG_IS_STMT)
888f4a2713aSLionel Sambuc OS << "1";
889f4a2713aSLionel Sambuc else
890f4a2713aSLionel Sambuc OS << "0";
891f4a2713aSLionel Sambuc }
892f4a2713aSLionel Sambuc
893f4a2713aSLionel Sambuc if (Isa)
894f4a2713aSLionel Sambuc OS << " isa " << Isa;
895f4a2713aSLionel Sambuc if (Discriminator)
896f4a2713aSLionel Sambuc OS << " discriminator " << Discriminator;
897f4a2713aSLionel Sambuc
898f4a2713aSLionel Sambuc if (IsVerboseAsm) {
899f4a2713aSLionel Sambuc OS.PadToColumn(MAI->getCommentColumn());
900f4a2713aSLionel Sambuc OS << MAI->getCommentString() << ' ' << FileName << ':'
901f4a2713aSLionel Sambuc << Line << ':' << Column;
902f4a2713aSLionel Sambuc }
903f4a2713aSLionel Sambuc EmitEOL();
904*0a6a1f1dSLionel Sambuc this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
905*0a6a1f1dSLionel Sambuc Isa, Discriminator, FileName);
906*0a6a1f1dSLionel Sambuc }
907*0a6a1f1dSLionel Sambuc
getDwarfLineTableSymbol(unsigned CUID)908*0a6a1f1dSLionel Sambuc MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
909*0a6a1f1dSLionel Sambuc // Always use the zeroth line table, since asm syntax only supports one line
910*0a6a1f1dSLionel Sambuc // table for now.
911*0a6a1f1dSLionel Sambuc return MCStreamer::getDwarfLineTableSymbol(0);
912f4a2713aSLionel Sambuc }
913f4a2713aSLionel Sambuc
EmitIdent(StringRef IdentString)914f4a2713aSLionel Sambuc void MCAsmStreamer::EmitIdent(StringRef IdentString) {
915f4a2713aSLionel Sambuc assert(MAI->hasIdentDirective() && ".ident directive not supported");
916f4a2713aSLionel Sambuc OS << "\t.ident\t";
917f4a2713aSLionel Sambuc PrintQuotedString(IdentString, OS);
918f4a2713aSLionel Sambuc EmitEOL();
919f4a2713aSLionel Sambuc }
920f4a2713aSLionel Sambuc
EmitCFISections(bool EH,bool Debug)921f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
922f4a2713aSLionel Sambuc MCStreamer::EmitCFISections(EH, Debug);
923f4a2713aSLionel Sambuc OS << "\t.cfi_sections ";
924f4a2713aSLionel Sambuc if (EH) {
925f4a2713aSLionel Sambuc OS << ".eh_frame";
926f4a2713aSLionel Sambuc if (Debug)
927f4a2713aSLionel Sambuc OS << ", .debug_frame";
928f4a2713aSLionel Sambuc } else if (Debug) {
929f4a2713aSLionel Sambuc OS << ".debug_frame";
930f4a2713aSLionel Sambuc }
931f4a2713aSLionel Sambuc
932f4a2713aSLionel Sambuc EmitEOL();
933f4a2713aSLionel Sambuc }
934f4a2713aSLionel Sambuc
EmitCFIStartProcImpl(MCDwarfFrameInfo & Frame)935f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
936f4a2713aSLionel Sambuc OS << "\t.cfi_startproc";
937*0a6a1f1dSLionel Sambuc if (Frame.IsSimple)
938*0a6a1f1dSLionel Sambuc OS << " simple";
939f4a2713aSLionel Sambuc EmitEOL();
940f4a2713aSLionel Sambuc }
941f4a2713aSLionel Sambuc
EmitCFIEndProcImpl(MCDwarfFrameInfo & Frame)942f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
943*0a6a1f1dSLionel Sambuc MCStreamer::EmitCFIEndProcImpl(Frame);
944f4a2713aSLionel Sambuc OS << "\t.cfi_endproc";
945f4a2713aSLionel Sambuc EmitEOL();
946f4a2713aSLionel Sambuc }
947f4a2713aSLionel Sambuc
EmitRegisterName(int64_t Register)948f4a2713aSLionel Sambuc void MCAsmStreamer::EmitRegisterName(int64_t Register) {
949f4a2713aSLionel Sambuc if (InstPrinter && !MAI->useDwarfRegNumForCFI()) {
950f4a2713aSLionel Sambuc const MCRegisterInfo *MRI = getContext().getRegisterInfo();
951f4a2713aSLionel Sambuc unsigned LLVMRegister = MRI->getLLVMRegNum(Register, true);
952f4a2713aSLionel Sambuc InstPrinter->printRegName(OS, LLVMRegister);
953f4a2713aSLionel Sambuc } else {
954f4a2713aSLionel Sambuc OS << Register;
955f4a2713aSLionel Sambuc }
956f4a2713aSLionel Sambuc }
957f4a2713aSLionel Sambuc
EmitCFIDefCfa(int64_t Register,int64_t Offset)958f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
959f4a2713aSLionel Sambuc MCStreamer::EmitCFIDefCfa(Register, Offset);
960f4a2713aSLionel Sambuc OS << "\t.cfi_def_cfa ";
961f4a2713aSLionel Sambuc EmitRegisterName(Register);
962f4a2713aSLionel Sambuc OS << ", " << Offset;
963f4a2713aSLionel Sambuc EmitEOL();
964f4a2713aSLionel Sambuc }
965f4a2713aSLionel Sambuc
EmitCFIDefCfaOffset(int64_t Offset)966f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
967f4a2713aSLionel Sambuc MCStreamer::EmitCFIDefCfaOffset(Offset);
968f4a2713aSLionel Sambuc OS << "\t.cfi_def_cfa_offset " << Offset;
969f4a2713aSLionel Sambuc EmitEOL();
970f4a2713aSLionel Sambuc }
971f4a2713aSLionel Sambuc
EmitCFIDefCfaRegister(int64_t Register)972f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
973f4a2713aSLionel Sambuc MCStreamer::EmitCFIDefCfaRegister(Register);
974f4a2713aSLionel Sambuc OS << "\t.cfi_def_cfa_register ";
975f4a2713aSLionel Sambuc EmitRegisterName(Register);
976f4a2713aSLionel Sambuc EmitEOL();
977f4a2713aSLionel Sambuc }
978f4a2713aSLionel Sambuc
EmitCFIOffset(int64_t Register,int64_t Offset)979f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
980f4a2713aSLionel Sambuc this->MCStreamer::EmitCFIOffset(Register, Offset);
981f4a2713aSLionel Sambuc OS << "\t.cfi_offset ";
982f4a2713aSLionel Sambuc EmitRegisterName(Register);
983f4a2713aSLionel Sambuc OS << ", " << Offset;
984f4a2713aSLionel Sambuc EmitEOL();
985f4a2713aSLionel Sambuc }
986f4a2713aSLionel Sambuc
EmitCFIPersonality(const MCSymbol * Sym,unsigned Encoding)987f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym,
988f4a2713aSLionel Sambuc unsigned Encoding) {
989f4a2713aSLionel Sambuc MCStreamer::EmitCFIPersonality(Sym, Encoding);
990f4a2713aSLionel Sambuc OS << "\t.cfi_personality " << Encoding << ", " << *Sym;
991f4a2713aSLionel Sambuc EmitEOL();
992f4a2713aSLionel Sambuc }
993f4a2713aSLionel Sambuc
EmitCFILsda(const MCSymbol * Sym,unsigned Encoding)994f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
995f4a2713aSLionel Sambuc MCStreamer::EmitCFILsda(Sym, Encoding);
996f4a2713aSLionel Sambuc OS << "\t.cfi_lsda " << Encoding << ", " << *Sym;
997f4a2713aSLionel Sambuc EmitEOL();
998f4a2713aSLionel Sambuc }
999f4a2713aSLionel Sambuc
EmitCFIRememberState()1000f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIRememberState() {
1001f4a2713aSLionel Sambuc MCStreamer::EmitCFIRememberState();
1002f4a2713aSLionel Sambuc OS << "\t.cfi_remember_state";
1003f4a2713aSLionel Sambuc EmitEOL();
1004f4a2713aSLionel Sambuc }
1005f4a2713aSLionel Sambuc
EmitCFIRestoreState()1006f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIRestoreState() {
1007f4a2713aSLionel Sambuc MCStreamer::EmitCFIRestoreState();
1008f4a2713aSLionel Sambuc OS << "\t.cfi_restore_state";
1009f4a2713aSLionel Sambuc EmitEOL();
1010f4a2713aSLionel Sambuc }
1011f4a2713aSLionel Sambuc
EmitCFISameValue(int64_t Register)1012f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
1013f4a2713aSLionel Sambuc MCStreamer::EmitCFISameValue(Register);
1014f4a2713aSLionel Sambuc OS << "\t.cfi_same_value ";
1015f4a2713aSLionel Sambuc EmitRegisterName(Register);
1016f4a2713aSLionel Sambuc EmitEOL();
1017f4a2713aSLionel Sambuc }
1018f4a2713aSLionel Sambuc
EmitCFIRelOffset(int64_t Register,int64_t Offset)1019f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
1020f4a2713aSLionel Sambuc MCStreamer::EmitCFIRelOffset(Register, Offset);
1021f4a2713aSLionel Sambuc OS << "\t.cfi_rel_offset ";
1022f4a2713aSLionel Sambuc EmitRegisterName(Register);
1023f4a2713aSLionel Sambuc OS << ", " << Offset;
1024f4a2713aSLionel Sambuc EmitEOL();
1025f4a2713aSLionel Sambuc }
1026f4a2713aSLionel Sambuc
EmitCFIAdjustCfaOffset(int64_t Adjustment)1027f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
1028f4a2713aSLionel Sambuc MCStreamer::EmitCFIAdjustCfaOffset(Adjustment);
1029f4a2713aSLionel Sambuc OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
1030f4a2713aSLionel Sambuc EmitEOL();
1031f4a2713aSLionel Sambuc }
1032f4a2713aSLionel Sambuc
EmitCFISignalFrame()1033f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFISignalFrame() {
1034f4a2713aSLionel Sambuc MCStreamer::EmitCFISignalFrame();
1035f4a2713aSLionel Sambuc OS << "\t.cfi_signal_frame";
1036f4a2713aSLionel Sambuc EmitEOL();
1037f4a2713aSLionel Sambuc }
1038f4a2713aSLionel Sambuc
EmitCFIUndefined(int64_t Register)1039f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIUndefined(int64_t Register) {
1040f4a2713aSLionel Sambuc MCStreamer::EmitCFIUndefined(Register);
1041f4a2713aSLionel Sambuc OS << "\t.cfi_undefined " << Register;
1042f4a2713aSLionel Sambuc EmitEOL();
1043f4a2713aSLionel Sambuc }
1044f4a2713aSLionel Sambuc
EmitCFIRegister(int64_t Register1,int64_t Register2)1045f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
1046f4a2713aSLionel Sambuc MCStreamer::EmitCFIRegister(Register1, Register2);
1047f4a2713aSLionel Sambuc OS << "\t.cfi_register " << Register1 << ", " << Register2;
1048f4a2713aSLionel Sambuc EmitEOL();
1049f4a2713aSLionel Sambuc }
1050f4a2713aSLionel Sambuc
EmitCFIWindowSave()1051f4a2713aSLionel Sambuc void MCAsmStreamer::EmitCFIWindowSave() {
1052f4a2713aSLionel Sambuc MCStreamer::EmitCFIWindowSave();
1053f4a2713aSLionel Sambuc OS << "\t.cfi_window_save";
1054f4a2713aSLionel Sambuc EmitEOL();
1055f4a2713aSLionel Sambuc }
1056f4a2713aSLionel Sambuc
EmitWinCFIStartProc(const MCSymbol * Symbol)1057*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
1058*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFIStartProc(Symbol);
1059f4a2713aSLionel Sambuc
1060f4a2713aSLionel Sambuc OS << ".seh_proc " << *Symbol;
1061f4a2713aSLionel Sambuc EmitEOL();
1062f4a2713aSLionel Sambuc }
1063f4a2713aSLionel Sambuc
EmitWinCFIEndProc()1064*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFIEndProc() {
1065*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFIEndProc();
1066f4a2713aSLionel Sambuc
1067f4a2713aSLionel Sambuc OS << "\t.seh_endproc";
1068f4a2713aSLionel Sambuc EmitEOL();
1069f4a2713aSLionel Sambuc }
1070f4a2713aSLionel Sambuc
EmitWinCFIStartChained()1071*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFIStartChained() {
1072*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFIStartChained();
1073f4a2713aSLionel Sambuc
1074f4a2713aSLionel Sambuc OS << "\t.seh_startchained";
1075f4a2713aSLionel Sambuc EmitEOL();
1076f4a2713aSLionel Sambuc }
1077f4a2713aSLionel Sambuc
EmitWinCFIEndChained()1078*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFIEndChained() {
1079*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFIEndChained();
1080f4a2713aSLionel Sambuc
1081f4a2713aSLionel Sambuc OS << "\t.seh_endchained";
1082f4a2713aSLionel Sambuc EmitEOL();
1083f4a2713aSLionel Sambuc }
1084f4a2713aSLionel Sambuc
EmitWinEHHandler(const MCSymbol * Sym,bool Unwind,bool Except)1085*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
1086f4a2713aSLionel Sambuc bool Except) {
1087*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinEHHandler(Sym, Unwind, Except);
1088f4a2713aSLionel Sambuc
1089f4a2713aSLionel Sambuc OS << "\t.seh_handler " << *Sym;
1090f4a2713aSLionel Sambuc if (Unwind)
1091f4a2713aSLionel Sambuc OS << ", @unwind";
1092f4a2713aSLionel Sambuc if (Except)
1093f4a2713aSLionel Sambuc OS << ", @except";
1094f4a2713aSLionel Sambuc EmitEOL();
1095f4a2713aSLionel Sambuc }
1096f4a2713aSLionel Sambuc
EmitWinEHHandlerData()1097*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinEHHandlerData() {
1098*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinEHHandlerData();
1099f4a2713aSLionel Sambuc
1100f4a2713aSLionel Sambuc // Switch sections. Don't call SwitchSection directly, because that will
1101f4a2713aSLionel Sambuc // cause the section switch to be visible in the emitted assembly.
1102f4a2713aSLionel Sambuc // We only do this so the section switch that terminates the handler
1103f4a2713aSLionel Sambuc // data block is visible.
1104*0a6a1f1dSLionel Sambuc WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
1105*0a6a1f1dSLionel Sambuc if (const MCSection *XData = WinEH::UnwindEmitter::getXDataSection(
1106*0a6a1f1dSLionel Sambuc CurFrame->Function, getContext()))
1107*0a6a1f1dSLionel Sambuc SwitchSectionNoChange(XData);
1108f4a2713aSLionel Sambuc
1109f4a2713aSLionel Sambuc OS << "\t.seh_handlerdata";
1110f4a2713aSLionel Sambuc EmitEOL();
1111f4a2713aSLionel Sambuc }
1112f4a2713aSLionel Sambuc
EmitWinCFIPushReg(unsigned Register)1113*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register) {
1114*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFIPushReg(Register);
1115f4a2713aSLionel Sambuc
1116f4a2713aSLionel Sambuc OS << "\t.seh_pushreg " << Register;
1117f4a2713aSLionel Sambuc EmitEOL();
1118f4a2713aSLionel Sambuc }
1119f4a2713aSLionel Sambuc
EmitWinCFISetFrame(unsigned Register,unsigned Offset)1120*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
1121*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFISetFrame(Register, Offset);
1122f4a2713aSLionel Sambuc
1123f4a2713aSLionel Sambuc OS << "\t.seh_setframe " << Register << ", " << Offset;
1124f4a2713aSLionel Sambuc EmitEOL();
1125f4a2713aSLionel Sambuc }
1126f4a2713aSLionel Sambuc
EmitWinCFIAllocStack(unsigned Size)1127*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size) {
1128*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFIAllocStack(Size);
1129f4a2713aSLionel Sambuc
1130f4a2713aSLionel Sambuc OS << "\t.seh_stackalloc " << Size;
1131f4a2713aSLionel Sambuc EmitEOL();
1132f4a2713aSLionel Sambuc }
1133f4a2713aSLionel Sambuc
EmitWinCFISaveReg(unsigned Register,unsigned Offset)1134*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
1135*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFISaveReg(Register, Offset);
1136f4a2713aSLionel Sambuc
1137f4a2713aSLionel Sambuc OS << "\t.seh_savereg " << Register << ", " << Offset;
1138f4a2713aSLionel Sambuc EmitEOL();
1139f4a2713aSLionel Sambuc }
1140f4a2713aSLionel Sambuc
EmitWinCFISaveXMM(unsigned Register,unsigned Offset)1141*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
1142*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFISaveXMM(Register, Offset);
1143f4a2713aSLionel Sambuc
1144f4a2713aSLionel Sambuc OS << "\t.seh_savexmm " << Register << ", " << Offset;
1145f4a2713aSLionel Sambuc EmitEOL();
1146f4a2713aSLionel Sambuc }
1147f4a2713aSLionel Sambuc
EmitWinCFIPushFrame(bool Code)1148*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) {
1149*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFIPushFrame(Code);
1150f4a2713aSLionel Sambuc
1151f4a2713aSLionel Sambuc OS << "\t.seh_pushframe";
1152f4a2713aSLionel Sambuc if (Code)
1153f4a2713aSLionel Sambuc OS << " @code";
1154f4a2713aSLionel Sambuc EmitEOL();
1155f4a2713aSLionel Sambuc }
1156f4a2713aSLionel Sambuc
EmitWinCFIEndProlog(void)1157*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitWinCFIEndProlog(void) {
1158*0a6a1f1dSLionel Sambuc MCStreamer::EmitWinCFIEndProlog();
1159f4a2713aSLionel Sambuc
1160f4a2713aSLionel Sambuc OS << "\t.seh_endprologue";
1161f4a2713aSLionel Sambuc EmitEOL();
1162f4a2713aSLionel Sambuc }
1163f4a2713aSLionel Sambuc
AddEncodingComment(const MCInst & Inst,const MCSubtargetInfo & STI)1164*0a6a1f1dSLionel Sambuc void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
1165*0a6a1f1dSLionel Sambuc const MCSubtargetInfo &STI) {
1166f4a2713aSLionel Sambuc raw_ostream &OS = GetCommentOS();
1167f4a2713aSLionel Sambuc SmallString<256> Code;
1168f4a2713aSLionel Sambuc SmallVector<MCFixup, 4> Fixups;
1169f4a2713aSLionel Sambuc raw_svector_ostream VecOS(Code);
1170*0a6a1f1dSLionel Sambuc Emitter->EncodeInstruction(Inst, VecOS, Fixups, STI);
1171f4a2713aSLionel Sambuc VecOS.flush();
1172f4a2713aSLionel Sambuc
1173f4a2713aSLionel Sambuc // If we are showing fixups, create symbolic markers in the encoded
1174f4a2713aSLionel Sambuc // representation. We do this by making a per-bit map to the fixup item index,
1175f4a2713aSLionel Sambuc // then trying to display it as nicely as possible.
1176f4a2713aSLionel Sambuc SmallVector<uint8_t, 64> FixupMap;
1177f4a2713aSLionel Sambuc FixupMap.resize(Code.size() * 8);
1178f4a2713aSLionel Sambuc for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
1179f4a2713aSLionel Sambuc FixupMap[i] = 0;
1180f4a2713aSLionel Sambuc
1181f4a2713aSLionel Sambuc for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1182f4a2713aSLionel Sambuc MCFixup &F = Fixups[i];
1183f4a2713aSLionel Sambuc const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1184f4a2713aSLionel Sambuc for (unsigned j = 0; j != Info.TargetSize; ++j) {
1185f4a2713aSLionel Sambuc unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
1186f4a2713aSLionel Sambuc assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
1187f4a2713aSLionel Sambuc FixupMap[Index] = 1 + i;
1188f4a2713aSLionel Sambuc }
1189f4a2713aSLionel Sambuc }
1190f4a2713aSLionel Sambuc
1191f4a2713aSLionel Sambuc // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
1192f4a2713aSLionel Sambuc // high order halfword of a 32-bit Thumb2 instruction is emitted first.
1193f4a2713aSLionel Sambuc OS << "encoding: [";
1194f4a2713aSLionel Sambuc for (unsigned i = 0, e = Code.size(); i != e; ++i) {
1195f4a2713aSLionel Sambuc if (i)
1196f4a2713aSLionel Sambuc OS << ',';
1197f4a2713aSLionel Sambuc
1198f4a2713aSLionel Sambuc // See if all bits are the same map entry.
1199f4a2713aSLionel Sambuc uint8_t MapEntry = FixupMap[i * 8 + 0];
1200f4a2713aSLionel Sambuc for (unsigned j = 1; j != 8; ++j) {
1201f4a2713aSLionel Sambuc if (FixupMap[i * 8 + j] == MapEntry)
1202f4a2713aSLionel Sambuc continue;
1203f4a2713aSLionel Sambuc
1204f4a2713aSLionel Sambuc MapEntry = uint8_t(~0U);
1205f4a2713aSLionel Sambuc break;
1206f4a2713aSLionel Sambuc }
1207f4a2713aSLionel Sambuc
1208f4a2713aSLionel Sambuc if (MapEntry != uint8_t(~0U)) {
1209f4a2713aSLionel Sambuc if (MapEntry == 0) {
1210f4a2713aSLionel Sambuc OS << format("0x%02x", uint8_t(Code[i]));
1211f4a2713aSLionel Sambuc } else {
1212f4a2713aSLionel Sambuc if (Code[i]) {
1213f4a2713aSLionel Sambuc // FIXME: Some of the 8 bits require fix up.
1214f4a2713aSLionel Sambuc OS << format("0x%02x", uint8_t(Code[i])) << '\''
1215f4a2713aSLionel Sambuc << char('A' + MapEntry - 1) << '\'';
1216f4a2713aSLionel Sambuc } else
1217f4a2713aSLionel Sambuc OS << char('A' + MapEntry - 1);
1218f4a2713aSLionel Sambuc }
1219f4a2713aSLionel Sambuc } else {
1220f4a2713aSLionel Sambuc // Otherwise, write out in binary.
1221f4a2713aSLionel Sambuc OS << "0b";
1222f4a2713aSLionel Sambuc for (unsigned j = 8; j--;) {
1223f4a2713aSLionel Sambuc unsigned Bit = (Code[i] >> j) & 1;
1224f4a2713aSLionel Sambuc
1225f4a2713aSLionel Sambuc unsigned FixupBit;
1226f4a2713aSLionel Sambuc if (MAI->isLittleEndian())
1227f4a2713aSLionel Sambuc FixupBit = i * 8 + j;
1228f4a2713aSLionel Sambuc else
1229f4a2713aSLionel Sambuc FixupBit = i * 8 + (7-j);
1230f4a2713aSLionel Sambuc
1231f4a2713aSLionel Sambuc if (uint8_t MapEntry = FixupMap[FixupBit]) {
1232f4a2713aSLionel Sambuc assert(Bit == 0 && "Encoder wrote into fixed up bit!");
1233f4a2713aSLionel Sambuc OS << char('A' + MapEntry - 1);
1234f4a2713aSLionel Sambuc } else
1235f4a2713aSLionel Sambuc OS << Bit;
1236f4a2713aSLionel Sambuc }
1237f4a2713aSLionel Sambuc }
1238f4a2713aSLionel Sambuc }
1239f4a2713aSLionel Sambuc OS << "]\n";
1240f4a2713aSLionel Sambuc
1241f4a2713aSLionel Sambuc for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
1242f4a2713aSLionel Sambuc MCFixup &F = Fixups[i];
1243f4a2713aSLionel Sambuc const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind());
1244f4a2713aSLionel Sambuc OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset()
1245f4a2713aSLionel Sambuc << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n";
1246f4a2713aSLionel Sambuc }
1247f4a2713aSLionel Sambuc }
1248f4a2713aSLionel Sambuc
EmitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)1249*0a6a1f1dSLionel Sambuc void MCAsmStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) {
1250f4a2713aSLionel Sambuc assert(getCurrentSection().first &&
1251f4a2713aSLionel Sambuc "Cannot emit contents before setting section!");
1252f4a2713aSLionel Sambuc
1253f4a2713aSLionel Sambuc // Show the encoding in a comment if we have a code emitter.
1254f4a2713aSLionel Sambuc if (Emitter)
1255*0a6a1f1dSLionel Sambuc AddEncodingComment(Inst, STI);
1256f4a2713aSLionel Sambuc
1257f4a2713aSLionel Sambuc // Show the MCInst if enabled.
1258f4a2713aSLionel Sambuc if (ShowInst) {
1259f4a2713aSLionel Sambuc Inst.dump_pretty(GetCommentOS(), MAI, InstPrinter.get(), "\n ");
1260f4a2713aSLionel Sambuc GetCommentOS() << "\n";
1261f4a2713aSLionel Sambuc }
1262f4a2713aSLionel Sambuc
1263f4a2713aSLionel Sambuc // If we have an AsmPrinter, use that to print, otherwise print the MCInst.
1264f4a2713aSLionel Sambuc if (InstPrinter)
1265f4a2713aSLionel Sambuc InstPrinter->printInst(&Inst, OS, "");
1266f4a2713aSLionel Sambuc else
1267f4a2713aSLionel Sambuc Inst.print(OS, MAI);
1268f4a2713aSLionel Sambuc EmitEOL();
1269f4a2713aSLionel Sambuc }
1270f4a2713aSLionel Sambuc
EmitBundleAlignMode(unsigned AlignPow2)1271f4a2713aSLionel Sambuc void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
1272f4a2713aSLionel Sambuc OS << "\t.bundle_align_mode " << AlignPow2;
1273f4a2713aSLionel Sambuc EmitEOL();
1274f4a2713aSLionel Sambuc }
1275f4a2713aSLionel Sambuc
EmitBundleLock(bool AlignToEnd)1276f4a2713aSLionel Sambuc void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
1277f4a2713aSLionel Sambuc OS << "\t.bundle_lock";
1278f4a2713aSLionel Sambuc if (AlignToEnd)
1279f4a2713aSLionel Sambuc OS << " align_to_end";
1280f4a2713aSLionel Sambuc EmitEOL();
1281f4a2713aSLionel Sambuc }
1282f4a2713aSLionel Sambuc
EmitBundleUnlock()1283f4a2713aSLionel Sambuc void MCAsmStreamer::EmitBundleUnlock() {
1284f4a2713aSLionel Sambuc OS << "\t.bundle_unlock";
1285f4a2713aSLionel Sambuc EmitEOL();
1286f4a2713aSLionel Sambuc }
1287f4a2713aSLionel Sambuc
1288f4a2713aSLionel Sambuc /// EmitRawText - If this file is backed by an assembly streamer, this dumps
1289f4a2713aSLionel Sambuc /// the specified string in the output .s file. This capability is
1290f4a2713aSLionel Sambuc /// indicated by the hasRawTextSupport() predicate.
EmitRawTextImpl(StringRef String)1291f4a2713aSLionel Sambuc void MCAsmStreamer::EmitRawTextImpl(StringRef String) {
1292f4a2713aSLionel Sambuc if (!String.empty() && String.back() == '\n')
1293f4a2713aSLionel Sambuc String = String.substr(0, String.size()-1);
1294f4a2713aSLionel Sambuc OS << String;
1295f4a2713aSLionel Sambuc EmitEOL();
1296f4a2713aSLionel Sambuc }
1297f4a2713aSLionel Sambuc
FinishImpl()1298f4a2713aSLionel Sambuc void MCAsmStreamer::FinishImpl() {
1299f4a2713aSLionel Sambuc // If we are generating dwarf for assembly source files dump out the sections.
1300f4a2713aSLionel Sambuc if (getContext().getGenDwarfForAssembly())
1301*0a6a1f1dSLionel Sambuc MCGenDwarfInfo::Emit(this);
1302f4a2713aSLionel Sambuc
1303*0a6a1f1dSLionel Sambuc // Emit the label for the line table, if requested - since the rest of the
1304*0a6a1f1dSLionel Sambuc // line table will be defined by .loc/.file directives, and not emitted
1305*0a6a1f1dSLionel Sambuc // directly, the label is the only work required here.
1306*0a6a1f1dSLionel Sambuc auto &Tables = getContext().getMCDwarfLineTables();
1307*0a6a1f1dSLionel Sambuc if (!Tables.empty()) {
1308*0a6a1f1dSLionel Sambuc assert(Tables.size() == 1 && "asm output only supports one line table");
1309*0a6a1f1dSLionel Sambuc if (auto *Label = Tables.begin()->second.getLabel()) {
1310*0a6a1f1dSLionel Sambuc SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
1311*0a6a1f1dSLionel Sambuc EmitLabel(Label);
1312*0a6a1f1dSLionel Sambuc }
1313*0a6a1f1dSLionel Sambuc }
1314f4a2713aSLionel Sambuc }
1315f4a2713aSLionel Sambuc
createAsmStreamer(MCContext & Context,formatted_raw_ostream & OS,bool isVerboseAsm,bool useDwarfDirectory,MCInstPrinter * IP,MCCodeEmitter * CE,MCAsmBackend * MAB,bool ShowInst)1316f4a2713aSLionel Sambuc MCStreamer *llvm::createAsmStreamer(MCContext &Context,
1317f4a2713aSLionel Sambuc formatted_raw_ostream &OS,
1318*0a6a1f1dSLionel Sambuc bool isVerboseAsm, bool useDwarfDirectory,
1319*0a6a1f1dSLionel Sambuc MCInstPrinter *IP, MCCodeEmitter *CE,
1320*0a6a1f1dSLionel Sambuc MCAsmBackend *MAB, bool ShowInst) {
1321*0a6a1f1dSLionel Sambuc return new MCAsmStreamer(Context, OS, isVerboseAsm, useDwarfDirectory, IP, CE,
1322*0a6a1f1dSLionel Sambuc MAB, ShowInst);
1323f4a2713aSLionel Sambuc }
1324