c69d76428cbcf2d3ecbb1f8f02d0b40d8d3e176e
[oota-llvm.git] / lib / MC / MCObjectStreamer.cpp
1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
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/MCObjectStreamer.h"
11 #include "llvm/MC/MCAsmBackend.h"
12 #include "llvm/MC/MCAsmInfo.h"
13 #include "llvm/MC/MCAssembler.h"
14 #include "llvm/MC/MCCodeEmitter.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCDwarf.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCObjectWriter.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/Support/ErrorHandling.h"
21 using namespace llvm;
22
23 MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
24                                    raw_ostream &OS, MCCodeEmitter *Emitter_)
25   : MCStreamer(Context),
26     Assembler(new MCAssembler(Context, TAB,
27                               *Emitter_, *TAB.createObjectWriter(OS),
28                               OS)),
29     CurSectionData(0)
30 {
31 }
32
33 MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
34                                    raw_ostream &OS, MCCodeEmitter *Emitter_,
35                                    MCAssembler *_Assembler)
36   : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0)
37 {
38 }
39
40 MCObjectStreamer::~MCObjectStreamer() {
41   delete &Assembler->getBackend();
42   delete &Assembler->getEmitter();
43   delete &Assembler->getWriter();
44   delete Assembler;
45 }
46
47 void MCObjectStreamer::reset() {
48   if (Assembler)
49     Assembler->reset();
50   MCStreamer::reset();
51 }
52
53 MCFragment *MCObjectStreamer::getCurrentFragment() const {
54   assert(getCurrentSectionData() && "No current section!");
55
56   if (!getCurrentSectionData()->empty())
57     return &getCurrentSectionData()->getFragmentList().back();
58
59   return 0;
60 }
61
62 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
63   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
64   if (!F)
65     F = new MCDataFragment(getCurrentSectionData());
66   return F;
67 }
68
69 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
70   switch (Value->getKind()) {
71   case MCExpr::Target:
72     cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler);
73     break;
74
75   case MCExpr::Constant:
76     break;
77
78   case MCExpr::Binary: {
79     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
80     AddValueSymbols(BE->getLHS());
81     AddValueSymbols(BE->getRHS());
82     break;
83   }
84
85   case MCExpr::SymbolRef:
86     Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
87     break;
88
89   case MCExpr::Unary:
90     AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
91     break;
92   }
93
94   return Value;
95 }
96
97 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
98                                      unsigned AddrSpace) {
99   assert(AddrSpace == 0 && "Address space must be 0!");
100   MCDataFragment *DF = getOrCreateDataFragment();
101
102   // Avoid fixups when possible.
103   int64_t AbsValue;
104   if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
105     EmitIntValue(AbsValue, Size, AddrSpace);
106     return;
107   }
108   DF->getFixups().push_back(
109       MCFixup::Create(DF->getContents().size(), Value,
110                       MCFixup::getKindForSize(Size, false)));
111   DF->getContents().resize(DF->getContents().size() + Size, 0);
112 }
113
114 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
115   RecordProcStart(Frame);
116 }
117
118 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
119   RecordProcEnd(Frame);
120 }
121
122 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
123   MCStreamer::EmitLabel(Symbol);
124
125   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
126
127   // FIXME: This is wasteful, we don't necessarily need to create a data
128   // fragment. Instead, we should mark the symbol as pointing into the data
129   // fragment if it exists, otherwise we should just queue the label and set its
130   // fragment pointer when we emit the next fragment.
131   MCDataFragment *F = getOrCreateDataFragment();
132   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
133   SD.setFragment(F);
134   SD.setOffset(F->getContents().size());
135 }
136
137 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
138   int64_t IntValue;
139   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
140     EmitULEB128IntValue(IntValue);
141     return;
142   }
143   Value = ForceExpAbs(Value);
144   new MCLEBFragment(*Value, false, getCurrentSectionData());
145 }
146
147 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
148   int64_t IntValue;
149   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
150     EmitSLEB128IntValue(IntValue);
151     return;
152   }
153   Value = ForceExpAbs(Value);
154   new MCLEBFragment(*Value, true, getCurrentSectionData());
155 }
156
157 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
158                                          const MCSymbol *Symbol) {
159   report_fatal_error("This file format doesn't support weak aliases.");
160 }
161
162 void MCObjectStreamer::ChangeSection(const MCSection *Section) {
163   assert(Section && "Cannot switch to a null section!");
164
165   CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
166 }
167
168 void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
169   getAssembler().getOrCreateSymbolData(*Symbol);
170   Symbol->setVariableValue(AddValueSymbols(Value));
171 }
172
173 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
174   // Scan for values.
175   for (unsigned i = Inst.getNumOperands(); i--; )
176     if (Inst.getOperand(i).isExpr())
177       AddValueSymbols(Inst.getOperand(i).getExpr());
178
179   getCurrentSectionData()->setHasInstructions(true);
180
181   // Now that a machine instruction has been assembled into this section, make
182   // a line entry for any .loc directive that has been seen.
183   MCLineEntry::Make(this, getCurrentSection());
184
185   // If this instruction doesn't need relaxation, just emit it as data.
186   if (!getAssembler().getBackend().mayNeedRelaxation(Inst)) {
187     EmitInstToData(Inst);
188     return;
189   }
190
191   // Otherwise, if we are relaxing everything, relax the instruction as much as
192   // possible and emit it as data.
193   if (getAssembler().getRelaxAll()) {
194     MCInst Relaxed;
195     getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
196     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
197       getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
198     EmitInstToData(Relaxed);
199     return;
200   }
201
202   // Otherwise emit to a separate fragment.
203   EmitInstToFragment(Inst);
204 }
205
206 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
207   MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
208
209   SmallString<128> Code;
210   raw_svector_ostream VecOS(Code);
211   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
212   VecOS.flush();
213   IF->getContents().append(Code.begin(), Code.end());
214 }
215
216 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
217                                                 const MCSymbol *LastLabel,
218                                                 const MCSymbol *Label,
219                                                 unsigned PointerSize) {
220   if (!LastLabel) {
221     EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
222     return;
223   }
224   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
225   int64_t Res;
226   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
227     MCDwarfLineAddr::Emit(this, LineDelta, Res);
228     return;
229   }
230   AddrDelta = ForceExpAbs(AddrDelta);
231   new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
232 }
233
234 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
235                                                  const MCSymbol *Label) {
236   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
237   int64_t Res;
238   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
239     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
240     return;
241   }
242   AddrDelta = ForceExpAbs(AddrDelta);
243   new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
244 }
245
246 void MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
247   assert(AddrSpace == 0 && "Address space must be 0!");
248   getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
249 }
250
251 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
252                                             int64_t Value,
253                                             unsigned ValueSize,
254                                             unsigned MaxBytesToEmit) {
255   if (MaxBytesToEmit == 0)
256     MaxBytesToEmit = ByteAlignment;
257   new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
258                       getCurrentSectionData());
259
260   // Update the maximum alignment on the current section if necessary.
261   if (ByteAlignment > getCurrentSectionData()->getAlignment())
262     getCurrentSectionData()->setAlignment(ByteAlignment);
263 }
264
265 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
266                                          unsigned MaxBytesToEmit) {
267   EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
268   cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
269 }
270
271 bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
272                                          unsigned char Value) {
273   int64_t Res;
274   if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
275     new MCOrgFragment(*Offset, Value, getCurrentSectionData());
276     return false;
277   }
278
279   MCSymbol *CurrentPos = getContext().CreateTempSymbol();
280   EmitLabel(CurrentPos);
281   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
282   const MCExpr *Ref =
283     MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
284   const MCExpr *Delta =
285     MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
286
287   if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
288     return true;
289   EmitFill(Res, Value, 0);
290   return false;
291 }
292
293 // Associate GPRel32 fixup with data and resize data area
294 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
295   MCDataFragment *DF = getOrCreateDataFragment();
296
297   DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 
298                                             Value, FK_GPRel_4));
299   DF->getContents().resize(DF->getContents().size() + 4, 0);
300 }
301
302 // Associate GPRel32 fixup with data and resize data area
303 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
304   MCDataFragment *DF = getOrCreateDataFragment();
305
306   DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 
307                                             Value, FK_GPRel_4));
308   DF->getContents().resize(DF->getContents().size() + 8, 0);
309 }
310
311 void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
312                                 unsigned AddrSpace) {
313   assert(AddrSpace == 0 && "Address space must be 0!");
314   // FIXME: A MCFillFragment would be more memory efficient but MCExpr has
315   //        problems evaluating expressions across multiple fragments.
316   getOrCreateDataFragment()->getContents().append(NumBytes, FillValue);
317 }
318
319 void MCObjectStreamer::FinishImpl() {
320   // Dump out the dwarf file & directory tables and line tables.
321   const MCSymbol *LineSectionSymbol = NULL;
322   if (getContext().hasDwarfFiles())
323     LineSectionSymbol = MCDwarfFileTable::Emit(this);
324
325   // If we are generating dwarf for assembly source files dump out the sections.
326   if (getContext().getGenDwarfForAssembly())
327     MCGenDwarfInfo::Emit(this, LineSectionSymbol);
328
329   getAssembler().Finish();
330 }