Split Finish into Finish and FinishImpl to have a common place to do end of
[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/MCAsmInfo.h"
11 #include "llvm/MC/MCObjectStreamer.h"
12
13 #include "llvm/Support/ErrorHandling.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCCodeEmitter.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCDwarf.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/MC/MCAsmBackend.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 MCFragment *MCObjectStreamer::getCurrentFragment() const {
48   assert(getCurrentSectionData() && "No current section!");
49
50   if (!getCurrentSectionData()->empty())
51     return &getCurrentSectionData()->getFragmentList().back();
52
53   return 0;
54 }
55
56 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
57   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
58   if (!F)
59     F = new MCDataFragment(getCurrentSectionData());
60   return F;
61 }
62
63 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
64   switch (Value->getKind()) {
65   case MCExpr::Target:
66     cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler);
67     break;
68
69   case MCExpr::Constant:
70     break;
71
72   case MCExpr::Binary: {
73     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
74     AddValueSymbols(BE->getLHS());
75     AddValueSymbols(BE->getRHS());
76     break;
77   }
78
79   case MCExpr::SymbolRef:
80     Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
81     break;
82
83   case MCExpr::Unary:
84     AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
85     break;
86   }
87
88   return Value;
89 }
90
91 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
92                                      unsigned AddrSpace) {
93   assert(AddrSpace == 0 && "Address space must be 0!");
94   MCDataFragment *DF = getOrCreateDataFragment();
95
96   // Avoid fixups when possible.
97   int64_t AbsValue;
98   if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
99     EmitIntValue(AbsValue, Size, AddrSpace);
100     return;
101   }
102   DF->addFixup(MCFixup::Create(DF->getContents().size(),
103                                Value,
104                                MCFixup::getKindForSize(Size, false)));
105   DF->getContents().resize(DF->getContents().size() + Size, 0);
106 }
107
108 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
109   MCStreamer::EmitLabel(Symbol);
110
111   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
112
113   // FIXME: This is wasteful, we don't necessarily need to create a data
114   // fragment. Instead, we should mark the symbol as pointing into the data
115   // fragment if it exists, otherwise we should just queue the label and set its
116   // fragment pointer when we emit the next fragment.
117   MCDataFragment *F = getOrCreateDataFragment();
118   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
119   SD.setFragment(F);
120   SD.setOffset(F->getContents().size());
121 }
122
123 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
124   int64_t IntValue;
125   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
126     EmitULEB128IntValue(IntValue);
127     return;
128   }
129   Value = ForceExpAbs(Value);
130   new MCLEBFragment(*Value, false, getCurrentSectionData());
131 }
132
133 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
134   int64_t IntValue;
135   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
136     EmitSLEB128IntValue(IntValue);
137     return;
138   }
139   Value = ForceExpAbs(Value);
140   new MCLEBFragment(*Value, true, getCurrentSectionData());
141 }
142
143 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
144                                          const MCSymbol *Symbol) {
145   report_fatal_error("This file format doesn't support weak aliases.");
146 }
147
148 void MCObjectStreamer::ChangeSection(const MCSection *Section) {
149   assert(Section && "Cannot switch to a null section!");
150
151   CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
152 }
153
154 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
155   // Scan for values.
156   for (unsigned i = Inst.getNumOperands(); i--; )
157     if (Inst.getOperand(i).isExpr())
158       AddValueSymbols(Inst.getOperand(i).getExpr());
159
160   getCurrentSectionData()->setHasInstructions(true);
161
162   // Now that a machine instruction has been assembled into this section, make
163   // a line entry for any .loc directive that has been seen.
164   MCLineEntry::Make(this, getCurrentSection());
165
166   // If this instruction doesn't need relaxation, just emit it as data.
167   if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
168     EmitInstToData(Inst);
169     return;
170   }
171
172   // Otherwise, if we are relaxing everything, relax the instruction as much as
173   // possible and emit it as data.
174   if (getAssembler().getRelaxAll()) {
175     MCInst Relaxed;
176     getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
177     while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
178       getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
179     EmitInstToData(Relaxed);
180     return;
181   }
182
183   // Otherwise emit to a separate fragment.
184   EmitInstToFragment(Inst);
185 }
186
187 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
188   MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
189
190   SmallString<128> Code;
191   raw_svector_ostream VecOS(Code);
192   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
193   VecOS.flush();
194   IF->getCode().append(Code.begin(), Code.end());
195 }
196
197 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
198                                                 const MCSymbol *LastLabel,
199                                                 const MCSymbol *Label,
200                                                 unsigned PointerSize) {
201   if (!LastLabel) {
202     EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
203     return;
204   }
205   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
206   int64_t Res;
207   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
208     MCDwarfLineAddr::Emit(this, LineDelta, Res);
209     return;
210   }
211   AddrDelta = ForceExpAbs(AddrDelta);
212   new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
213 }
214
215 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
216                                                  const MCSymbol *Label) {
217   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
218   int64_t Res;
219   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
220     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
221     return;
222   }
223   AddrDelta = ForceExpAbs(AddrDelta);
224   new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
225 }
226
227 void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
228                                         unsigned char Value) {
229   int64_t Res;
230   if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
231     new MCOrgFragment(*Offset, Value, getCurrentSectionData());
232     return;
233   }
234
235   MCSymbol *CurrentPos = getContext().CreateTempSymbol();
236   EmitLabel(CurrentPos);
237   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
238   const MCExpr *Ref =
239     MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
240   const MCExpr *Delta =
241     MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
242
243   if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
244     report_fatal_error("expected assembly-time absolute expression");
245   EmitFill(Res, Value, 0);
246 }
247
248 // Associate GPRel32 fixup with data and resize data area
249 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
250   MCDataFragment *DF = getOrCreateDataFragment();
251
252   DF->addFixup(MCFixup::Create(DF->getContents().size(),
253                                Value,
254                                FK_GPRel_4));
255   DF->getContents().resize(DF->getContents().size() + 4, 0);
256 }
257
258 void MCObjectStreamer::FinishImpl() {
259   // Dump out the dwarf file & directory tables and line tables.
260   if (getContext().hasDwarfFiles())
261     MCDwarfFileTable::Emit(this);
262
263   // If we are generating dwarf for assembly source files dump out the sections.
264   if (getContext().getGenDwarfForAssembly())
265     MCGenDwarfInfo::Emit(this);
266
267   getAssembler().Finish();
268 }