1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCObjectStreamer.h"
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/Target/TargetAsmBackend.h"
20 MCObjectStreamer::MCObjectStreamer(MCContext
&Context
, TargetAsmBackend
&TAB
,
21 raw_ostream
&_OS
, MCCodeEmitter
*_Emitter
,
22 bool _PadSectionToAlignment
)
23 : MCStreamer(Context
), Assembler(new MCAssembler(Context
, TAB
,
25 _PadSectionToAlignment
,
31 MCObjectStreamer::~MCObjectStreamer() {
32 delete &Assembler
->getBackend();
33 delete &Assembler
->getEmitter();
37 MCFragment
*MCObjectStreamer::getCurrentFragment() const {
38 assert(getCurrentSectionData() && "No current section!");
40 if (!getCurrentSectionData()->empty())
41 return &getCurrentSectionData()->getFragmentList().back();
46 MCDataFragment
*MCObjectStreamer::getOrCreateDataFragment() const {
47 MCDataFragment
*F
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
49 F
= new MCDataFragment(getCurrentSectionData());
53 const MCExpr
*MCObjectStreamer::AddValueSymbols(const MCExpr
*Value
) {
54 switch (Value
->getKind()) {
55 case MCExpr::Target
: llvm_unreachable("Can't handle target exprs yet!");
56 case MCExpr::Constant
:
59 case MCExpr::Binary
: {
60 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(Value
);
61 AddValueSymbols(BE
->getLHS());
62 AddValueSymbols(BE
->getRHS());
66 case MCExpr::SymbolRef
:
67 Assembler
->getOrCreateSymbolData(cast
<MCSymbolRefExpr
>(Value
)->getSymbol());
71 AddValueSymbols(cast
<MCUnaryExpr
>(Value
)->getSubExpr());
78 void MCObjectStreamer::EmitULEB128Value(const MCExpr
*Value
,
80 new MCLEBFragment(*Value
, false, getCurrentSectionData());
83 void MCObjectStreamer::EmitSLEB128Value(const MCExpr
*Value
,
85 new MCLEBFragment(*Value
, true, getCurrentSectionData());
88 void MCObjectStreamer::EmitWeakReference(MCSymbol
*Alias
,
89 const MCSymbol
*Symbol
) {
90 report_fatal_error("This file format doesn't support weak aliases.");
93 void MCObjectStreamer::SwitchSection(const MCSection
*Section
) {
94 assert(Section
&& "Cannot switch to a null section!");
96 // If already in this section, then this is a noop.
97 if (Section
== CurSection
) return;
99 PrevSection
= CurSection
;
100 CurSection
= Section
;
101 CurSectionData
= &getAssembler().getOrCreateSectionData(*Section
);
104 void MCObjectStreamer::EmitInstruction(const MCInst
&Inst
) {
106 for (unsigned i
= Inst
.getNumOperands(); i
--; )
107 if (Inst
.getOperand(i
).isExpr())
108 AddValueSymbols(Inst
.getOperand(i
).getExpr());
110 getCurrentSectionData()->setHasInstructions(true);
112 // Now that a machine instruction has been assembled into this section, make
113 // a line entry for any .loc directive that has been seen.
114 MCLineEntry::Make(this, getCurrentSection());
116 // If this instruction doesn't need relaxation, just emit it as data.
117 if (!getAssembler().getBackend().MayNeedRelaxation(Inst
)) {
118 EmitInstToData(Inst
);
122 // Otherwise, if we are relaxing everything, relax the instruction as much as
123 // possible and emit it as data.
124 if (getAssembler().getRelaxAll()) {
126 getAssembler().getBackend().RelaxInstruction(Inst
, Relaxed
);
127 while (getAssembler().getBackend().MayNeedRelaxation(Relaxed
))
128 getAssembler().getBackend().RelaxInstruction(Relaxed
, Relaxed
);
129 EmitInstToData(Relaxed
);
133 // Otherwise emit to a separate fragment.
134 EmitInstToFragment(Inst
);
137 void MCObjectStreamer::Finish() {
138 getAssembler().Finish();