e2cd96433ecce6fc44f9469e279e074270fd27ee
[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::EmitLabel(MCSymbol *Symbol) {
80   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
81   assert(CurSection && "Cannot emit before setting section!");
82
83   Symbol->setSection(*CurSection);
84
85   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
86
87   // FIXME: This is wasteful, we don't necessarily need to create a data
88   // fragment. Instead, we should mark the symbol as pointing into the data
89   // fragment if it exists, otherwise we should just queue the label and set its
90   // fragment pointer when we emit the next fragment.
91   MCDataFragment *F = getOrCreateDataFragment();
92   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
93   SD.setFragment(F);
94   SD.setOffset(F->getContents().size());
95 }
96
97 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value,
98                                         unsigned AddrSpace) {
99   new MCLEBFragment(*Value, false, getCurrentSectionData());
100 }
101
102 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value,
103                                         unsigned AddrSpace) {
104   new MCLEBFragment(*Value, true, getCurrentSectionData());
105 }
106
107 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
108                                          const MCSymbol *Symbol) {
109   report_fatal_error("This file format doesn't support weak aliases.");
110 }
111
112 void MCObjectStreamer::SwitchSection(const MCSection *Section) {
113   assert(Section && "Cannot switch to a null section!");
114
115   // If already in this section, then this is a noop.
116   if (Section == CurSection) return;
117
118   PrevSection = CurSection;
119   CurSection = Section;
120   CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
121 }
122
123 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
124   // Scan for values.
125   for (unsigned i = Inst.getNumOperands(); i--; )
126     if (Inst.getOperand(i).isExpr())
127       AddValueSymbols(Inst.getOperand(i).getExpr());
128
129   getCurrentSectionData()->setHasInstructions(true);
130
131   // Now that a machine instruction has been assembled into this section, make
132   // a line entry for any .loc directive that has been seen.
133   MCLineEntry::Make(this, getCurrentSection());
134
135   // If this instruction doesn't need relaxation, just emit it as data.
136   if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
137     EmitInstToData(Inst);
138     return;
139   }
140
141   // Otherwise, if we are relaxing everything, relax the instruction as much as
142   // possible and emit it as data.
143   if (getAssembler().getRelaxAll()) {
144     MCInst Relaxed;
145     getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
146     while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
147       getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
148     EmitInstToData(Relaxed);
149     return;
150   }
151
152   // Otherwise emit to a separate fragment.
153   EmitInstToFragment(Inst);
154 }
155
156 void MCObjectStreamer::Finish() {
157   getAssembler().Finish();
158 }