Initial support for the cfi directives. This is just enough to get
[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
12 #include "llvm/Support/ErrorHandling.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/MCSymbol.h"
19 #include "llvm/Target/TargetAsmBackend.h"
20 #include "llvm/Target/TargetAsmInfo.h"
21 using namespace llvm;
22
23 MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
24                                    raw_ostream &_OS, MCCodeEmitter *_Emitter)
25   : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB,
26                                                    *_Emitter,
27                                                    _OS)),
28     CurSectionData(0)
29 {
30 }
31
32 MCObjectStreamer::~MCObjectStreamer() {
33   delete &Assembler->getBackend();
34   delete &Assembler->getEmitter();
35   delete Assembler;
36 }
37
38 MCFragment *MCObjectStreamer::getCurrentFragment() const {
39   assert(getCurrentSectionData() && "No current section!");
40
41   if (!getCurrentSectionData()->empty())
42     return &getCurrentSectionData()->getFragmentList().back();
43
44   return 0;
45 }
46
47 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
48   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
49   if (!F)
50     F = new MCDataFragment(getCurrentSectionData());
51   return F;
52 }
53
54 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
55   switch (Value->getKind()) {
56   case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
57   case MCExpr::Constant:
58     break;
59
60   case MCExpr::Binary: {
61     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
62     AddValueSymbols(BE->getLHS());
63     AddValueSymbols(BE->getRHS());
64     break;
65   }
66
67   case MCExpr::SymbolRef:
68     Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
69     break;
70
71   case MCExpr::Unary:
72     AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
73     break;
74   }
75
76   return Value;
77 }
78
79 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
80                                      bool isPCRel, unsigned AddrSpace) {
81   assert(AddrSpace == 0 && "Address space must be 0!");
82   MCDataFragment *DF = getOrCreateDataFragment();
83
84   // Avoid fixups when possible.
85   int64_t AbsValue;
86   if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
87     EmitIntValue(AbsValue, Size, AddrSpace);
88     return;
89   }
90   DF->addFixup(MCFixup::Create(DF->getContents().size(),
91                                AddValueSymbols(Value),
92                                MCFixup::getKindForSize(Size, isPCRel)));
93   DF->getContents().resize(DF->getContents().size() + Size, 0);
94 }
95
96 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
97   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
98   assert(CurSection && "Cannot emit before setting section!");
99
100   Symbol->setSection(*CurSection);
101
102   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
103
104   // FIXME: This is wasteful, we don't necessarily need to create a data
105   // fragment. Instead, we should mark the symbol as pointing into the data
106   // fragment if it exists, otherwise we should just queue the label and set its
107   // fragment pointer when we emit the next fragment.
108   MCDataFragment *F = getOrCreateDataFragment();
109   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
110   SD.setFragment(F);
111   SD.setOffset(F->getContents().size());
112 }
113
114 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value,
115                                         unsigned AddrSpace) {
116   int64_t IntValue;
117   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
118     EmitULEB128IntValue(IntValue, AddrSpace);
119     return;
120   }
121   new MCLEBFragment(*Value, false, getCurrentSectionData());
122 }
123
124 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value,
125                                         unsigned AddrSpace) {
126   int64_t IntValue;
127   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
128     EmitSLEB128IntValue(IntValue, AddrSpace);
129     return;
130   }
131   new MCLEBFragment(*Value, true, getCurrentSectionData());
132 }
133
134 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
135                                          const MCSymbol *Symbol) {
136   report_fatal_error("This file format doesn't support weak aliases.");
137 }
138
139 void MCObjectStreamer::SwitchSection(const MCSection *Section) {
140   assert(Section && "Cannot switch to a null section!");
141
142   // If already in this section, then this is a noop.
143   if (Section == CurSection) return;
144
145   PrevSection = CurSection;
146   CurSection = Section;
147   CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
148 }
149
150 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
151   // Scan for values.
152   for (unsigned i = Inst.getNumOperands(); i--; )
153     if (Inst.getOperand(i).isExpr())
154       AddValueSymbols(Inst.getOperand(i).getExpr());
155
156   getCurrentSectionData()->setHasInstructions(true);
157
158   // Now that a machine instruction has been assembled into this section, make
159   // a line entry for any .loc directive that has been seen.
160   MCLineEntry::Make(this, getCurrentSection());
161
162   // If this instruction doesn't need relaxation, just emit it as data.
163   if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
164     EmitInstToData(Inst);
165     return;
166   }
167
168   // Otherwise, if we are relaxing everything, relax the instruction as much as
169   // possible and emit it as data.
170   if (getAssembler().getRelaxAll()) {
171     MCInst Relaxed;
172     getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
173     while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
174       getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
175     EmitInstToData(Relaxed);
176     return;
177   }
178
179   // Otherwise emit to a separate fragment.
180   EmitInstToFragment(Inst);
181 }
182
183 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
184   MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
185
186   raw_svector_ostream VecOS(IF->getCode());
187   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
188 }
189
190 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
191                                                 const MCSymbol *LastLabel,
192                                                 const MCSymbol *Label) {
193   if (!LastLabel) {
194     int PointerSize = getContext().getTargetAsmInfo().getPointerSize();
195     EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
196     return;
197   }
198   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
199   const MCExpr *LabelRef =
200     MCSymbolRefExpr::Create(Label, Variant, getContext());
201   const MCExpr *LastLabelRef =
202     MCSymbolRefExpr::Create(LastLabel, Variant, getContext());
203   const MCExpr *AddrDelta =
204     MCBinaryExpr::Create(MCBinaryExpr::Sub, LabelRef, LastLabelRef,
205                          getContext());
206   int64_t Res;
207   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
208     MCDwarfLineAddr::Emit(this, LineDelta, Res);
209     return;
210   }
211   new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
212 }
213
214 void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
215                                         unsigned char Value) {
216   new MCOrgFragment(*Offset, Value, getCurrentSectionData());
217 }
218
219 void MCObjectStreamer::Finish() {
220   // Dump out the dwarf file & directory tables and line tables.
221   if (getContext().hasDwarfFiles())
222     MCDwarfFileTable::Emit(this);
223
224   getAssembler().Finish();
225 }