Move EmitInstruction to MCObjectStreamer so that ELF and MachO can share it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117925 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2010-11-01 16:27:31 +00:00
parent 9729d2e998
commit f89671d994
5 changed files with 50 additions and 69 deletions

View File

@ -33,6 +33,9 @@ class MCObjectStreamer : public MCStreamer {
MCAssembler *Assembler;
MCSectionData *CurSectionData;
virtual void EmitInstToFragment(const MCInst &Inst) = 0;
virtual void EmitInstToData(const MCInst &Inst) = 0;
protected:
MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter,
@ -59,6 +62,7 @@ public:
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
virtual void SwitchSection(const MCSection *Section);
virtual void EmitInstruction(const MCInst &Inst);
virtual void Finish();
/// @}

View File

@ -36,8 +36,6 @@ using namespace llvm;
namespace {
class MCELFStreamer : public MCObjectStreamer {
void EmitInstToFragment(const MCInst &Inst);
void EmitInstToData(const MCInst &Inst);
public:
MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
@ -109,10 +107,12 @@ public:
DEBUG(dbgs() << "FIXME: MCELFStreamer:EmitDwarfFileDirective not implemented\n");
}
virtual void EmitInstruction(const MCInst &Inst);
virtual void Finish();
private:
virtual void EmitInstToFragment(const MCInst &Inst);
virtual void EmitInstToData(const MCInst &Inst);
struct LocalCommon {
MCSymbolData *SD;
uint64_t Size;
@ -510,35 +510,6 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
DF->getContents().append(Code.begin(), Code.end());
}
void MCELFStreamer::EmitInstruction(const MCInst &Inst) {
// Scan for values.
for (unsigned i = 0; i != Inst.getNumOperands(); ++i)
if (Inst.getOperand(i).isExpr())
AddValueSymbols(Inst.getOperand(i).getExpr());
getCurrentSectionData()->setHasInstructions(true);
// If this instruction doesn't need relaxation, just emit it as data.
if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
EmitInstToData(Inst);
return;
}
// Otherwise, if we are relaxing everything, relax the instruction as much as
// possible and emit it as data.
if (getAssembler().getRelaxAll()) {
MCInst Relaxed;
getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
EmitInstToData(Relaxed);
return;
}
// Otherwise emit to a separate fragment.
EmitInstToFragment(Inst);
}
void MCELFStreamer::Finish() {
for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),
e = LocalCommons.end();

View File

@ -31,8 +31,8 @@ namespace {
class MCMachOStreamer : public MCObjectStreamer {
private:
void EmitInstToFragment(const MCInst &Inst);
void EmitInstToData(const MCInst &Inst);
virtual void EmitInstToFragment(const MCInst &Inst);
virtual void EmitInstToData(const MCInst &Inst);
public:
MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB,
@ -98,8 +98,6 @@ public:
//report_fatal_error("unsupported directive: '.file'");
}
virtual void EmitInstruction(const MCInst &Inst);
virtual void Finish();
/// @}
@ -406,39 +404,6 @@ void MCMachOStreamer::EmitInstToData(const MCInst &Inst) {
DF->getContents().append(Code.begin(), Code.end());
}
void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
// Scan for values.
for (unsigned i = Inst.getNumOperands(); i--; )
if (Inst.getOperand(i).isExpr())
AddValueSymbols(Inst.getOperand(i).getExpr());
getCurrentSectionData()->setHasInstructions(true);
// Now that a machine instruction has been assembled into this section, make
// a line entry for any .loc directive that has been seen.
MCLineEntry::Make(this, getCurrentSection());
// If this instruction doesn't need relaxation, just emit it as data.
if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
EmitInstToData(Inst);
return;
}
// Otherwise, if we are relaxing everything, relax the instruction as much as
// possible and emit it as data.
if (getAssembler().getRelaxAll()) {
MCInst Relaxed;
getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
EmitInstToData(Relaxed);
return;
}
// Otherwise emit to a separate fragment.
EmitInstToFragment(Inst);
}
void MCMachOStreamer::Finish() {
// Dump out the dwarf file & directory tables and line tables.
if (getContext().hasDwarfFiles()) {

View File

@ -12,6 +12,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Target/TargetAsmBackend.h"
using namespace llvm;
@ -90,6 +91,39 @@ void MCObjectStreamer::SwitchSection(const MCSection *Section) {
CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
}
void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
// Scan for values.
for (unsigned i = Inst.getNumOperands(); i--; )
if (Inst.getOperand(i).isExpr())
AddValueSymbols(Inst.getOperand(i).getExpr());
getCurrentSectionData()->setHasInstructions(true);
// Now that a machine instruction has been assembled into this section, make
// a line entry for any .loc directive that has been seen.
MCLineEntry::Make(this, getCurrentSection());
// If this instruction doesn't need relaxation, just emit it as data.
if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
EmitInstToData(Inst);
return;
}
// Otherwise, if we are relaxing everything, relax the instruction as much as
// possible and emit it as data.
if (getAssembler().getRelaxAll()) {
MCInst Relaxed;
getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
EmitInstToData(Relaxed);
return;
}
// Otherwise emit to a separate fragment.
EmitInstToFragment(Inst);
}
void MCObjectStreamer::Finish() {
getAssembler().Finish();
}

View File

@ -81,6 +81,13 @@ public:
virtual void Finish();
private:
virtual void EmitInstToFragment(const MCInst &Inst) {
llvm_unreachable("Not used by WinCOFF.");
}
virtual void EmitInstToData(const MCInst &Inst) {
llvm_unreachable("Not used by WinCOFF.");
}
void SetSection(StringRef Section,
unsigned Characteristics,
SectionKind Kind) {