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