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