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