Move EmitValueToOffset to the ObjectStreamer.
[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/MCDwarf.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCSymbol.h"
18 #include "llvm/Target/TargetAsmBackend.h"
19 using namespace llvm;
20
21 MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
22                                    raw_ostream &_OS, MCCodeEmitter *_Emitter,
23                                    bool _PadSectionToAlignment)
24   : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB,
25                                                    *_Emitter,
26                                                    _PadSectionToAlignment,
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::EmitValue(const MCExpr *Value, unsigned Size,
80                                  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)) {
87     // FIXME: Endianness assumption.
88     for (unsigned i = 0; i != Size; ++i)
89       DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
90   } else {
91     DF->addFixup(MCFixup::Create(DF->getContents().size(),
92                                  AddValueSymbols(Value),
93                                  MCFixup::getKindForSize(Size, false)));
94     DF->getContents().resize(DF->getContents().size() + Size, 0);
95   }
96 }
97
98 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
99   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
100   assert(CurSection && "Cannot emit before setting section!");
101
102   Symbol->setSection(*CurSection);
103
104   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
105
106   // FIXME: This is wasteful, we don't necessarily need to create a data
107   // fragment. Instead, we should mark the symbol as pointing into the data
108   // fragment if it exists, otherwise we should just queue the label and set its
109   // fragment pointer when we emit the next fragment.
110   MCDataFragment *F = getOrCreateDataFragment();
111   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
112   SD.setFragment(F);
113   SD.setOffset(F->getContents().size());
114 }
115
116 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value,
117                                         unsigned AddrSpace) {
118   new MCLEBFragment(*Value, false, getCurrentSectionData());
119 }
120
121 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value,
122                                         unsigned AddrSpace) {
123   new MCLEBFragment(*Value, true, getCurrentSectionData());
124 }
125
126 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
127                                          const MCSymbol *Symbol) {
128   report_fatal_error("This file format doesn't support weak aliases.");
129 }
130
131 void MCObjectStreamer::SwitchSection(const MCSection *Section) {
132   assert(Section && "Cannot switch to a null section!");
133
134   // If already in this section, then this is a noop.
135   if (Section == CurSection) return;
136
137   PrevSection = CurSection;
138   CurSection = Section;
139   CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
140 }
141
142 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
143   // Scan for values.
144   for (unsigned i = Inst.getNumOperands(); i--; )
145     if (Inst.getOperand(i).isExpr())
146       AddValueSymbols(Inst.getOperand(i).getExpr());
147
148   getCurrentSectionData()->setHasInstructions(true);
149
150   // Now that a machine instruction has been assembled into this section, make
151   // a line entry for any .loc directive that has been seen.
152   MCLineEntry::Make(this, getCurrentSection());
153
154   // If this instruction doesn't need relaxation, just emit it as data.
155   if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
156     EmitInstToData(Inst);
157     return;
158   }
159
160   // Otherwise, if we are relaxing everything, relax the instruction as much as
161   // possible and emit it as data.
162   if (getAssembler().getRelaxAll()) {
163     MCInst Relaxed;
164     getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
165     while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
166       getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
167     EmitInstToData(Relaxed);
168     return;
169   }
170
171   // Otherwise emit to a separate fragment.
172   EmitInstToFragment(Inst);
173 }
174
175 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
176   MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
177
178   raw_svector_ostream VecOS(IF->getCode());
179   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
180 }
181
182 void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
183                                         unsigned char Value) {
184   new MCOrgFragment(*Offset, Value, getCurrentSectionData());
185 }
186
187 void MCObjectStreamer::Finish() {
188   getAssembler().Finish();
189 }