1 //===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCStreamer.h"
12 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCInst.h"
14 #include "llvm/MC/MCSection.h"
15 #include "llvm/MC/MCSymbol.h"
16 #include "llvm/MC/MCValue.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/Support/raw_ostream.h"
24 class MCAsmStreamer
: public MCStreamer
{
27 MCSection
*CurSection
;
30 MCAsmStreamer(MCContext
&Context
, raw_ostream
&_OS
)
31 : MCStreamer(Context
), OS(_OS
), CurSection(0) {}
34 /// @name MCStreamer Interface
37 virtual void SwitchSection(MCSection
*Section
);
39 virtual void EmitLabel(MCSymbol
*Symbol
);
41 virtual void EmitAssemblerFlag(AssemblerFlag Flag
);
43 virtual void EmitAssignment(MCSymbol
*Symbol
, const MCValue
&Value
,
44 bool MakeAbsolute
= false);
46 virtual void EmitSymbolAttribute(MCSymbol
*Symbol
, SymbolAttr Attribute
);
48 virtual void EmitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
);
50 virtual void EmitLocalSymbol(MCSymbol
*Symbol
, const MCValue
&Value
);
52 virtual void EmitCommonSymbol(MCSymbol
*Symbol
, unsigned Size
,
53 unsigned Pow2Alignment
, bool IsLocal
);
55 virtual void EmitZerofill(MCSection
*Section
, MCSymbol
*Symbol
= NULL
,
56 unsigned Size
= 0, unsigned Pow2Alignment
= 0);
58 virtual void EmitBytes(const StringRef
&Data
);
60 virtual void EmitValue(const MCValue
&Value
, unsigned Size
);
62 virtual void EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
= 0,
63 unsigned ValueSize
= 1,
64 unsigned MaxBytesToEmit
= 0);
66 virtual void EmitValueToOffset(const MCValue
&Offset
,
67 unsigned char Value
= 0);
69 virtual void EmitInstruction(const MCInst
&Inst
);
71 virtual void Finish();
78 /// NeedsQuoting - Return true if the string \arg Str needs quoting, i.e., it
79 /// does not match [a-zA-Z_.][a-zA-Z0-9_.]*.
81 // FIXME: This could be more permissive, do we care?
82 static inline bool NeedsQuoting(const StringRef
&Str
) {
86 // Check that first character is in [a-zA-Z_.].
87 if (!((Str
[0] >= 'a' && Str
[0] <= 'z') ||
88 (Str
[0] >= 'A' && Str
[0] <= 'Z') ||
89 (Str
[0] == '_' || Str
[0] == '.')))
92 // Check subsequent characters are in [a-zA-Z0-9_.].
93 for (unsigned i
= 1, e
= Str
.size(); i
!= e
; ++i
)
94 if (!((Str
[i
] >= 'a' && Str
[i
] <= 'z') ||
95 (Str
[i
] >= 'A' && Str
[i
] <= 'Z') ||
96 (Str
[i
] >= '0' && Str
[i
] <= '9') ||
97 (Str
[i
] == '_' || Str
[i
] == '.')))
103 /// Allow printing sections directly to a raw_ostream with proper quoting.
104 static inline raw_ostream
&operator<<(raw_ostream
&os
, const MCSection
*S
) {
105 if (NeedsQuoting(S
->getName()))
106 return os
<< '"' << S
->getName() << '"';
107 return os
<< S
->getName();
110 /// Allow printing symbols directly to a raw_ostream with proper quoting.
111 static inline raw_ostream
&operator<<(raw_ostream
&os
, const MCSymbol
*S
) {
112 if (NeedsQuoting(S
->getName()))
113 return os
<< '"' << S
->getName() << '"';
114 return os
<< S
->getName();
117 /// Allow printing values directly to a raw_ostream.
118 static inline raw_ostream
&operator<<(raw_ostream
&os
, const MCValue
&Value
) {
119 if (Value
.getSymA()) {
120 os
<< Value
.getSymA();
122 os
<< " - " << Value
.getSymB();
123 if (Value
.getConstant())
124 os
<< " + " << Value
.getConstant();
126 assert(!Value
.getSymB() && "Invalid machine code value!");
127 os
<< Value
.getConstant();
133 static inline int64_t truncateToSize(int64_t Value
, unsigned Bytes
) {
134 assert(Bytes
&& "Invalid size!");
135 return Value
& ((uint64_t) (int64_t) -1 >> (64 - Bytes
* 8));
138 static inline MCValue
truncateToSize(const MCValue
&Value
, unsigned Bytes
) {
139 return MCValue::get(Value
.getSymA(), Value
.getSymB(),
140 truncateToSize(Value
.getConstant(), Bytes
));
143 void MCAsmStreamer::SwitchSection(MCSection
*Section
) {
144 if (Section
!= CurSection
) {
145 CurSection
= Section
;
147 // FIXME: Really we would like the segment, flags, etc. to be separate
148 // values instead of embedded in the name. Not all assemblers understand all
149 // this stuff though.
150 OS
<< ".section " << Section
<< "\n";
154 void MCAsmStreamer::EmitLabel(MCSymbol
*Symbol
) {
155 assert(Symbol
->getSection() == 0 && "Cannot emit a symbol twice!");
156 assert(CurSection
&& "Cannot emit before setting section!");
157 assert(!getContext().GetSymbolValue(Symbol
) &&
158 "Cannot emit symbol which was directly assigned to!");
160 OS
<< Symbol
<< ":\n";
161 Symbol
->setSection(CurSection
);
162 Symbol
->setExternal(false);
165 void MCAsmStreamer::EmitAssemblerFlag(AssemblerFlag Flag
) {
167 case SubsectionsViaSymbols
: OS
<< ".subsections_via_symbols"; break;
172 void MCAsmStreamer::EmitAssignment(MCSymbol
*Symbol
, const MCValue
&Value
,
174 assert(!Symbol
->getSection() && "Cannot assign to a label!");
177 OS
<< ".set " << Symbol
<< ", " << Value
<< '\n';
179 OS
<< Symbol
<< " = " << Value
<< '\n';
182 getContext().SetSymbolValue(Symbol
, Value
);
185 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol
*Symbol
,
186 SymbolAttr Attribute
) {
188 case Global
: OS
<< ".globl"; break;
189 case Hidden
: OS
<< ".hidden"; break;
190 case IndirectSymbol
: OS
<< ".indirect_symbol"; break;
191 case Internal
: OS
<< ".internal"; break;
192 case LazyReference
: OS
<< ".lazy_reference"; break;
193 case NoDeadStrip
: OS
<< ".no_dead_strip"; break;
194 case PrivateExtern
: OS
<< ".private_extern"; break;
195 case Protected
: OS
<< ".protected"; break;
196 case Reference
: OS
<< ".reference"; break;
197 case Weak
: OS
<< ".weak"; break;
198 case WeakDefinition
: OS
<< ".weak_definition"; break;
199 case WeakReference
: OS
<< ".weak_reference"; break;
202 OS
<< ' ' << Symbol
<< '\n';
205 void MCAsmStreamer::EmitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
) {
206 OS
<< ".desc" << ' ' << Symbol
<< ',' << DescValue
<< '\n';
209 void MCAsmStreamer::EmitLocalSymbol(MCSymbol
*Symbol
, const MCValue
&Value
) {
210 OS
<< ".lsym" << ' ' << Symbol
<< ',' << Value
<< '\n';
213 void MCAsmStreamer::EmitCommonSymbol(MCSymbol
*Symbol
, unsigned Size
,
214 unsigned Pow2Alignment
, bool IsLocal
) {
219 OS
<< ' ' << Symbol
<< ',' << Size
;
220 if (Pow2Alignment
!= 0)
221 OS
<< ',' << Pow2Alignment
;
225 void MCAsmStreamer::EmitZerofill(MCSection
*Section
, MCSymbol
*Symbol
,
226 unsigned Size
, unsigned Pow2Alignment
) {
227 // Note: a .zerofill directive does not switch sections
228 // FIXME: Really we would like the segment and section names as well as the
229 // section type to be separate values instead of embedded in the name. Not
230 // all assemblers understand all this stuff though.
231 OS
<< ".zerofill " << Section
;
232 if (Symbol
!= NULL
) {
233 OS
<< ',' << Symbol
<< ',' << Size
;
234 if (Pow2Alignment
!= 0)
235 OS
<< ',' << Pow2Alignment
;
240 void MCAsmStreamer::EmitBytes(const StringRef
&Data
) {
241 assert(CurSection
&& "Cannot emit contents before setting section!");
242 for (unsigned i
= 0, e
= Data
.size(); i
!= e
; ++i
)
243 OS
<< ".byte " << (unsigned) Data
[i
] << '\n';
246 void MCAsmStreamer::EmitValue(const MCValue
&Value
, unsigned Size
) {
247 assert(CurSection
&& "Cannot emit contents before setting section!");
248 // Need target hooks to know how to print this.
251 llvm_unreachable("Invalid size for machine code value!");
252 case 1: OS
<< ".byte"; break;
253 case 2: OS
<< ".short"; break;
254 case 4: OS
<< ".long"; break;
255 case 8: OS
<< ".quad"; break;
258 OS
<< ' ' << truncateToSize(Value
, Size
) << '\n';
261 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
,
263 unsigned MaxBytesToEmit
) {
264 // Some assemblers don't support .balign, so we always emit as .p2align if
265 // this is a power of two. Otherwise we assume the client knows the target
266 // supports .balign and use that.
267 unsigned Pow2
= Log2_32(ByteAlignment
);
268 bool IsPow2
= (1U << Pow2
) == ByteAlignment
;
272 llvm_unreachable("Invalid size for machine code value!");
274 llvm_unreachable("Unsupported alignment size!");
275 case 1: OS
<< (IsPow2
? ".p2align" : ".balign"); break;
276 case 2: OS
<< (IsPow2
? ".p2alignw" : ".balignw"); break;
277 case 4: OS
<< (IsPow2
? ".p2alignl" : ".balignl"); break;
280 OS
<< ' ' << (IsPow2
? Pow2
: ByteAlignment
);
282 OS
<< ", " << truncateToSize(Value
, ValueSize
);
284 OS
<< ", " << MaxBytesToEmit
;
288 void MCAsmStreamer::EmitValueToOffset(const MCValue
&Offset
,
289 unsigned char Value
) {
290 // FIXME: Verify that Offset is associated with the current section.
291 OS
<< ".org " << Offset
<< ", " << (unsigned) Value
<< '\n';
294 static raw_ostream
&operator<<(raw_ostream
&OS
, const MCOperand
&Op
) {
296 return OS
<< "reg:" << Op
.getReg();
298 return OS
<< "imm:" << Op
.getImm();
300 return OS
<< "mbblabel:("
301 << Op
.getMBBLabelFunction() << ", " << Op
.getMBBLabelBlock();
302 assert(Op
.isMCValue() && "Invalid operand!");
303 return OS
<< "val:" << Op
.getMCValue();
306 void MCAsmStreamer::EmitInstruction(const MCInst
&Inst
) {
307 assert(CurSection
&& "Cannot emit contents before setting section!");
308 // FIXME: Implement proper printing.
310 << "opcode=" << Inst
.getOpcode() << ", "
312 for (unsigned i
= 0, e
= Inst
.getNumOperands(); i
!= e
; ++i
) {
315 OS
<< Inst
.getOperand(i
);
320 void MCAsmStreamer::Finish() {
324 MCStreamer
*llvm::createAsmStreamer(MCContext
&Context
, raw_ostream
&OS
) {
325 return new MCAsmStreamer(Context
, OS
);