Add the ability for MCStreamer to emit comments on the same line as directives.
[oota-llvm.git] / lib / MC / MCAsmStreamer.cpp
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/MC/MCAsmInfo.h"
12 #include "llvm/MC/MCCodeEmitter.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCInst.h"
16 #include "llvm/MC/MCInstPrinter.h"
17 #include "llvm/MC/MCSectionMachO.h"
18 #include "llvm/MC/MCSymbol.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/Format.h"
24 #include "llvm/Support/FormattedStream.h"
25 using namespace llvm;
26
27 namespace {
28
29 class MCAsmStreamer : public MCStreamer {
30   formatted_raw_ostream &OS;
31   const MCAsmInfo &MAI;
32   bool IsLittleEndian, IsVerboseAsm;
33   MCInstPrinter *InstPrinter;
34   MCCodeEmitter *Emitter;
35   
36   SmallString<128> CommentToEmit;
37 public:
38   MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
39                 const MCAsmInfo &mai,
40                 bool isLittleEndian, bool isVerboseAsm, MCInstPrinter *printer,
41                 MCCodeEmitter *emitter)
42     : MCStreamer(Context), OS(os), MAI(mai), IsLittleEndian(isLittleEndian),
43       IsVerboseAsm(isVerboseAsm), InstPrinter(printer), Emitter(emitter) {}
44   ~MCAsmStreamer() {}
45
46   bool isLittleEndian() const { return IsLittleEndian; }
47   
48   
49   inline void EmitEOL() {
50     if (CommentToEmit.empty()) {
51       OS << '\n';
52       return;
53     }
54     EmitCommentsAndEOL();
55   }
56   void EmitCommentsAndEOL();
57   
58   /// addComment - Add a comment that can be emitted to the generated .s
59   /// file if applicable as a QoI issue to make the output of the compiler
60   /// more readable.  This only affects the MCAsmStreamer, and only when
61   /// verbose assembly output is enabled.
62   virtual void addComment(const Twine &T);
63   
64   /// @name MCStreamer Interface
65   /// @{
66
67   virtual void SwitchSection(const MCSection *Section);
68
69   virtual void EmitLabel(MCSymbol *Symbol);
70
71   virtual void EmitAssemblerFlag(AssemblerFlag Flag);
72
73   virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
74
75   virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute);
76
77   virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
78
79   virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
80                                 unsigned ByteAlignment);
81
82   virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
83                             unsigned Size = 0, unsigned ByteAlignment = 0);
84
85   virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
86
87   virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
88   virtual void EmitIntValue(uint64_t Value, unsigned Size, unsigned AddrSpace);
89
90   virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
91                         unsigned AddrSpace);
92
93   virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
94                                     unsigned ValueSize = 1,
95                                     unsigned MaxBytesToEmit = 0);
96
97   virtual void EmitValueToOffset(const MCExpr *Offset,
98                                  unsigned char Value = 0);
99   
100   virtual void EmitInstruction(const MCInst &Inst);
101
102   virtual void Finish();
103   
104   /// @}
105 };
106
107 } // end anonymous namespace.
108
109 /// addComment - Add a comment that can be emitted to the generated .s
110 /// file if applicable as a QoI issue to make the output of the compiler
111 /// more readable.  This only affects the MCAsmStreamer, and only when
112 /// verbose assembly output is enabled.
113 void MCAsmStreamer::addComment(const Twine &T) {
114   if (!IsVerboseAsm) return;
115   // Each comment goes on its own line.
116   if (!CommentToEmit.empty())
117     CommentToEmit.push_back('\n');
118   T.toVector(CommentToEmit);
119 }
120
121 void MCAsmStreamer::EmitCommentsAndEOL() {
122   StringRef Comments = CommentToEmit.str();
123   while (!Comments.empty()) {
124     // Emit a line of comments.
125     OS.PadToColumn(MAI.getCommentColumn());
126     size_t Position = Comments.find('\n');
127     OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
128     
129     if (Position == StringRef::npos) break;
130     Comments = Comments.substr(Position+1);
131   }
132   
133   CommentToEmit.clear();
134 }
135
136
137 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
138   assert(Bytes && "Invalid size!");
139   return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
140 }
141
142 static inline const MCExpr *truncateToSize(const MCExpr *Value,
143                                            unsigned Bytes) {
144   // FIXME: Do we really need this routine?
145   return Value;
146 }
147
148 void MCAsmStreamer::SwitchSection(const MCSection *Section) {
149   assert(Section && "Cannot switch to a null section!");
150   if (Section != CurSection) {
151     CurSection = Section;
152     Section->PrintSwitchToSection(MAI, OS);
153   }
154 }
155
156 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
157   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
158   assert(CurSection && "Cannot emit before setting section!");
159
160   OS << *Symbol << ":\n";
161   Symbol->setSection(*CurSection);
162 }
163
164 void MCAsmStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
165   switch (Flag) {
166   default: assert(0 && "Invalid flag!");
167   case SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
168   }
169   OS << '\n';
170 }
171
172 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
173   // Only absolute symbols can be redefined.
174   assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
175          "Cannot define a symbol twice!");
176
177   OS << *Symbol << " = " << *Value << '\n';
178
179   // FIXME: Lift context changes into super class.
180   // FIXME: Set associated section.
181   Symbol->setValue(Value);
182 }
183
184 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
185                                         SymbolAttr Attribute) {
186   switch (Attribute) {
187   case Global:         OS << MAI.getGlobalDirective(); break; // .globl
188   case Hidden:         OS << ".hidden ";          break;
189   case IndirectSymbol: OS << ".indirect_symbol "; break;
190   case Internal:       OS << ".internal ";        break;
191   case LazyReference:  OS << ".lazy_reference ";  break;
192   case NoDeadStrip:    OS << ".no_dead_strip ";   break;
193   case PrivateExtern:  OS << ".private_extern ";  break;
194   case Protected:      OS << ".protected ";       break;
195   case Reference:      OS << ".reference ";       break;
196   case Weak:           OS << ".weak ";            break;
197   case WeakDefinition: OS << ".weak_definition "; break;
198   case WeakReference:  OS << ".weak_reference ";  break;
199   }
200
201   OS << *Symbol << '\n';
202 }
203
204 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
205   OS << ".desc" << ' ' << *Symbol << ',' << DescValue << '\n';
206 }
207
208 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
209                                      unsigned ByteAlignment) {
210   OS << MAI.getCOMMDirective() << *Symbol << ',' << Size;
211   if (ByteAlignment != 0 && MAI.getCOMMDirectiveTakesAlignment()) {
212     if (MAI.getAlignmentIsInBytes())
213       OS << ',' << ByteAlignment;
214     else
215       OS << ',' << Log2_32(ByteAlignment);
216   }
217   OS << '\n';
218 }
219
220 void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
221                                  unsigned Size, unsigned ByteAlignment) {
222   // Note: a .zerofill directive does not switch sections.
223   OS << ".zerofill ";
224   
225   // This is a mach-o specific directive.
226   const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
227   OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
228   
229   if (Symbol != NULL) {
230     OS << ',' << *Symbol << ',' << Size;
231     if (ByteAlignment != 0)
232       OS << ',' << Log2_32(ByteAlignment);
233   }
234   OS << '\n';
235 }
236
237 void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
238   assert(CurSection && "Cannot emit contents before setting section!");
239   const char *Directive = MAI.getData8bitsDirective(AddrSpace);
240   for (unsigned i = 0, e = Data.size(); i != e; ++i)
241     OS << Directive << (unsigned)(unsigned char)Data[i] << '\n';
242 }
243
244 /// EmitIntValue - Special case of EmitValue that avoids the client having
245 /// to pass in a MCExpr for constant integers.
246 void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
247                                  unsigned AddrSpace) {
248   assert(CurSection && "Cannot emit contents before setting section!");
249   const char *Directive = 0;
250   switch (Size) {
251   default: break;
252   case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
253   case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
254   case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
255   case 8:
256     Directive = MAI.getData64bitsDirective(AddrSpace);
257     // If the target doesn't support 64-bit data, emit as two 32-bit halves.
258     if (Directive) break;
259     if (isLittleEndian()) {
260       EmitIntValue((uint32_t)(Value >> 0 ), 4, AddrSpace);
261       EmitIntValue((uint32_t)(Value >> 32), 4, AddrSpace);
262     } else {
263       EmitIntValue((uint32_t)(Value >> 32), 4, AddrSpace);
264       EmitIntValue((uint32_t)(Value >> 0 ), 4, AddrSpace);
265     }
266     return;
267   }
268   
269   assert(Directive && "Invalid size for machine code value!");
270   OS << Directive << truncateToSize(Value, Size);
271   EmitEOL();
272 }
273
274 void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
275                               unsigned AddrSpace) {
276   assert(CurSection && "Cannot emit contents before setting section!");
277   const char *Directive = 0;
278   switch (Size) {
279   default: break;
280   case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
281   case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
282   case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
283   case 8: Directive = MAI.getData64bitsDirective(AddrSpace); break;
284   }
285   
286   assert(Directive && "Invalid size for machine code value!");
287   OS << Directive << *truncateToSize(Value, Size);
288   EmitEOL();
289 }
290
291 /// EmitFill - Emit NumBytes bytes worth of the value specified by
292 /// FillValue.  This implements directives such as '.space'.
293 void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
294                              unsigned AddrSpace) {
295   if (NumBytes == 0) return;
296   
297   if (AddrSpace == 0)
298     if (const char *ZeroDirective = MAI.getZeroDirective()) {
299       OS << ZeroDirective << NumBytes;
300       if (FillValue != 0)
301         OS << ',' << (int)FillValue;
302       EmitEOL();
303       return;
304     }
305
306   // Emit a byte at a time.
307   MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
308 }
309
310 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
311                                          unsigned ValueSize,
312                                          unsigned MaxBytesToEmit) {
313   // Some assemblers don't support non-power of two alignments, so we always
314   // emit alignments as a power of two if possible.
315   if (isPowerOf2_32(ByteAlignment)) {
316     switch (ValueSize) {
317     default: llvm_unreachable("Invalid size for machine code value!");
318     case 1: OS << MAI.getAlignDirective(); break;
319     // FIXME: use MAI for this!
320     case 2: OS << ".p2alignw "; break;
321     case 4: OS << ".p2alignl "; break;
322     case 8: llvm_unreachable("Unsupported alignment size!");
323     }
324     
325     if (MAI.getAlignmentIsInBytes())
326       OS << ByteAlignment;
327     else
328       OS << Log2_32(ByteAlignment);
329
330     if (Value || MaxBytesToEmit) {
331       OS << ", 0x";
332       OS.write_hex(truncateToSize(Value, ValueSize));
333
334       if (MaxBytesToEmit) 
335         OS << ", " << MaxBytesToEmit;
336     }
337     OS << '\n';
338     return;
339   }
340   
341   // Non-power of two alignment.  This is not widely supported by assemblers.
342   // FIXME: Parameterize this based on MAI.
343   switch (ValueSize) {
344   default: llvm_unreachable("Invalid size for machine code value!");
345   case 1: OS << ".balign";  break;
346   case 2: OS << ".balignw"; break;
347   case 4: OS << ".balignl"; break;
348   case 8: llvm_unreachable("Unsupported alignment size!");
349   }
350
351   OS << ' ' << ByteAlignment;
352   OS << ", " << truncateToSize(Value, ValueSize);
353   if (MaxBytesToEmit) 
354     OS << ", " << MaxBytesToEmit;
355   OS << '\n';
356 }
357
358 void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
359                                       unsigned char Value) {
360   // FIXME: Verify that Offset is associated with the current section.
361   OS << ".org " << *Offset << ", " << (unsigned) Value << '\n';
362 }
363
364 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
365   assert(CurSection && "Cannot emit contents before setting section!");
366
367   // If we have an AsmPrinter, use that to print.
368   if (InstPrinter) {
369     InstPrinter->printInst(&Inst);
370     OS << '\n';
371
372     // Show the encoding if we have a code emitter.
373     if (Emitter) {
374       SmallString<256> Code;
375       raw_svector_ostream VecOS(Code);
376       Emitter->EncodeInstruction(Inst, VecOS);
377       VecOS.flush();
378   
379       OS.indent(20);
380       OS << " # encoding: [";
381       for (unsigned i = 0, e = Code.size(); i != e; ++i) {
382         if (i)
383           OS << ',';
384         OS << format("%#04x", uint8_t(Code[i]));
385       }
386       OS << "]\n";
387     }
388
389     return;
390   }
391
392   // Otherwise fall back to a structural printing for now. Eventually we should
393   // always have access to the target specific printer.
394   Inst.print(OS, &MAI);
395   OS << '\n';
396 }
397
398 void MCAsmStreamer::Finish() {
399   OS.flush();
400 }
401     
402 MCStreamer *llvm::createAsmStreamer(MCContext &Context,
403                                     formatted_raw_ostream &OS,
404                                     const MCAsmInfo &MAI, bool isLittleEndian,
405                                     bool isVerboseAsm, MCInstPrinter *IP,
406                                     MCCodeEmitter *CE) {
407   return new MCAsmStreamer(Context, OS, MAI, isLittleEndian, isVerboseAsm,
408                            IP, CE);
409 }