mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 00:32:55 +00:00
Refactor MCInstFragment and MCDataFragment to adhere to a common interface,
which removes code duplication and prepares the ground for future additions. Full discussion: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20121203/158233.html git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169626 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e4ccfef809
commit
64d9a32334
@ -102,7 +102,35 @@ public:
|
||||
void dump();
|
||||
};
|
||||
|
||||
class MCDataFragment : public MCFragment {
|
||||
class MCEncodedFragment : public MCFragment {
|
||||
virtual void anchor();
|
||||
public:
|
||||
MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
|
||||
: MCFragment(FType, SD) {
|
||||
}
|
||||
virtual ~MCEncodedFragment();
|
||||
|
||||
typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
|
||||
typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
|
||||
|
||||
virtual SmallString<32> &getContents() = 0;
|
||||
virtual const SmallString<32> &getContents() const = 0;
|
||||
|
||||
virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
|
||||
virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
|
||||
|
||||
virtual fixup_iterator fixup_begin() = 0;
|
||||
virtual const_fixup_iterator fixup_begin() const = 0;
|
||||
virtual fixup_iterator fixup_end() = 0;
|
||||
virtual const_fixup_iterator fixup_end() const = 0;
|
||||
|
||||
static bool classof(const MCFragment *F) {
|
||||
MCFragment::FragmentType Kind = F->getKind();
|
||||
return Kind == MCFragment::FT_Inst || Kind == MCFragment::FT_Data;
|
||||
}
|
||||
};
|
||||
|
||||
class MCDataFragment : public MCEncodedFragment {
|
||||
virtual void anchor();
|
||||
SmallString<32> Contents;
|
||||
|
||||
@ -110,27 +138,19 @@ class MCDataFragment : public MCFragment {
|
||||
SmallVector<MCFixup, 4> Fixups;
|
||||
|
||||
public:
|
||||
typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
|
||||
typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
|
||||
|
||||
public:
|
||||
MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
|
||||
|
||||
/// @name Accessors
|
||||
/// @{
|
||||
MCDataFragment(MCSectionData *SD = 0)
|
||||
: MCEncodedFragment(FT_Data, SD) {
|
||||
}
|
||||
|
||||
SmallString<32> &getContents() { return Contents; }
|
||||
const SmallString<32> &getContents() const { return Contents; }
|
||||
|
||||
/// @}
|
||||
/// @name Fixup Access
|
||||
/// @{
|
||||
SmallVectorImpl<MCFixup> &getFixups() {
|
||||
return Fixups;
|
||||
}
|
||||
|
||||
void addFixup(MCFixup Fixup) {
|
||||
// Enforce invariant that fixups are in offset order.
|
||||
assert((Fixups.empty() || Fixup.getOffset() >= Fixups.back().getOffset()) &&
|
||||
"Fixups must be added in order!");
|
||||
Fixups.push_back(Fixup);
|
||||
const SmallVectorImpl<MCFixup> &getFixups() const {
|
||||
return Fixups;
|
||||
}
|
||||
|
||||
fixup_iterator fixup_begin() { return Fixups.begin(); }
|
||||
@ -139,55 +159,42 @@ public:
|
||||
fixup_iterator fixup_end() {return Fixups.end();}
|
||||
const_fixup_iterator fixup_end() const {return Fixups.end();}
|
||||
|
||||
/// @}
|
||||
|
||||
static bool classof(const MCFragment *F) {
|
||||
return F->getKind() == MCFragment::FT_Data;
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as
|
||||
// it is almost entirely a duplicate of MCDataFragment. If we decide to stick
|
||||
// with this approach (as opposed to making MCInstFragment a very light weight
|
||||
// object with just the MCInst and a code size, then we should just change
|
||||
// MCDataFragment to have an optional MCInst at its end.
|
||||
class MCInstFragment : public MCFragment {
|
||||
class MCInstFragment : public MCEncodedFragment {
|
||||
virtual void anchor();
|
||||
|
||||
/// Inst - The instruction this is a fragment for.
|
||||
MCInst Inst;
|
||||
|
||||
/// Code - Binary data for the currently encoded instruction.
|
||||
SmallString<8> Code;
|
||||
/// Contents - Binary data for the currently encoded instruction.
|
||||
SmallString<32> Contents;
|
||||
|
||||
/// Fixups - The list of fixups in this fragment.
|
||||
SmallVector<MCFixup, 1> Fixups;
|
||||
|
||||
public:
|
||||
typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
|
||||
typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
|
||||
|
||||
public:
|
||||
MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0)
|
||||
: MCFragment(FT_Inst, SD), Inst(_Inst) {
|
||||
: MCEncodedFragment(FT_Inst, SD), Inst(_Inst) {
|
||||
}
|
||||
|
||||
/// @name Accessors
|
||||
/// @{
|
||||
SmallString<32> &getContents() { return Contents; }
|
||||
const SmallString<32> &getContents() const { return Contents; }
|
||||
|
||||
SmallVectorImpl<char> &getCode() { return Code; }
|
||||
const SmallVectorImpl<char> &getCode() const { return Code; }
|
||||
|
||||
unsigned getInstSize() const { return Code.size(); }
|
||||
unsigned getInstSize() const { return Contents.size(); }
|
||||
const MCInst &getInst() const { return Inst; }
|
||||
void setInst(const MCInst& Value) { Inst = Value; }
|
||||
|
||||
/// @}
|
||||
/// @name Fixup Access
|
||||
/// @{
|
||||
SmallVectorImpl<MCFixup> &getFixups() {
|
||||
return Fixups;
|
||||
}
|
||||
|
||||
SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
|
||||
const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
|
||||
const SmallVectorImpl<MCFixup> &getFixups() const {
|
||||
return Fixups;
|
||||
}
|
||||
|
||||
fixup_iterator fixup_begin() { return Fixups.begin(); }
|
||||
const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
|
||||
@ -195,8 +202,6 @@ public:
|
||||
fixup_iterator fixup_end() {return Fixups.end();}
|
||||
const_fixup_iterator fixup_end() const {return Fixups.end();}
|
||||
|
||||
/// @}
|
||||
|
||||
static bool classof(const MCFragment *F) {
|
||||
return F->getKind() == MCFragment::FT_Inst;
|
||||
}
|
||||
|
@ -168,6 +168,11 @@ MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
|
||||
|
||||
/* *** */
|
||||
|
||||
MCEncodedFragment::~MCEncodedFragment() {
|
||||
}
|
||||
|
||||
/* *** */
|
||||
|
||||
MCSectionData::MCSectionData() : Section(0) {}
|
||||
|
||||
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
|
||||
@ -382,9 +387,16 @@ void MCAsmLayout::LayoutFragment(MCFragment *F) {
|
||||
LastValidFragment[F->getParent()] = F;
|
||||
}
|
||||
|
||||
/// WriteFragmentData - Write the \p F data to the output file.
|
||||
static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
const MCFragment &F) {
|
||||
/// \brief Write the contents of a fragment to the given object writer. Expects
|
||||
/// a MCEncodedFragment.
|
||||
static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) {
|
||||
MCEncodedFragment &EF = cast<MCEncodedFragment>(F);
|
||||
OW->WriteBytes(EF.getContents().str());
|
||||
}
|
||||
|
||||
/// \brief Write the fragment \p F to the output file.
|
||||
static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
const MCFragment &F) {
|
||||
MCObjectWriter *OW = &Asm.getWriter();
|
||||
uint64_t Start = OW->getStream().tell();
|
||||
(void) Start;
|
||||
@ -433,13 +445,15 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
break;
|
||||
}
|
||||
|
||||
case MCFragment::FT_Data: {
|
||||
case MCFragment::FT_Data:
|
||||
++stats::EmittedDataFragments;
|
||||
MCDataFragment &DF = cast<MCDataFragment>(F);
|
||||
assert(FragmentSize == DF.getContents().size() && "Invalid size!");
|
||||
OW->WriteBytes(DF.getContents().str());
|
||||
writeFragmentContents(F, OW);
|
||||
break;
|
||||
|
||||
case MCFragment::FT_Inst:
|
||||
++stats::EmittedInstFragments;
|
||||
writeFragmentContents(F, OW);
|
||||
break;
|
||||
}
|
||||
|
||||
case MCFragment::FT_Fill: {
|
||||
MCFillFragment &FF = cast<MCFillFragment>(F);
|
||||
@ -458,13 +472,6 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||
break;
|
||||
}
|
||||
|
||||
case MCFragment::FT_Inst: {
|
||||
++stats::EmittedInstFragments;
|
||||
MCInstFragment &IF = cast<MCInstFragment>(F);
|
||||
OW->WriteBytes(StringRef(IF.getCode().begin(), IF.getCode().size()));
|
||||
break;
|
||||
}
|
||||
|
||||
case MCFragment::FT_LEB: {
|
||||
MCLEBFragment &LF = cast<MCLEBFragment>(F);
|
||||
OW->WriteBytes(LF.getContents().str());
|
||||
@ -538,9 +545,9 @@ void MCAssembler::writeSectionData(const MCSectionData *SD,
|
||||
uint64_t Start = getWriter().getStream().tell();
|
||||
(void)Start;
|
||||
|
||||
for (MCSectionData::const_iterator it = SD->begin(),
|
||||
ie = SD->end(); it != ie; ++it)
|
||||
WriteFragmentData(*this, Layout, *it);
|
||||
for (MCSectionData::const_iterator it = SD->begin(), ie = SD->end();
|
||||
it != ie; ++it)
|
||||
writeFragment(*this, Layout, *it);
|
||||
|
||||
assert(getWriter().getStream().tell() - Start ==
|
||||
Layout.getSectionAddressSize(SD));
|
||||
@ -617,24 +624,14 @@ void MCAssembler::Finish() {
|
||||
for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) {
|
||||
for (MCSectionData::iterator it2 = it->begin(),
|
||||
ie2 = it->end(); it2 != ie2; ++it2) {
|
||||
MCDataFragment *DF = dyn_cast<MCDataFragment>(it2);
|
||||
if (DF) {
|
||||
for (MCDataFragment::fixup_iterator it3 = DF->fixup_begin(),
|
||||
ie3 = DF->fixup_end(); it3 != ie3; ++it3) {
|
||||
MCEncodedFragment *F = dyn_cast<MCEncodedFragment>(it2);
|
||||
if (F) {
|
||||
for (MCEncodedFragment::fixup_iterator it3 = F->fixup_begin(),
|
||||
ie3 = F->fixup_end(); it3 != ie3; ++it3) {
|
||||
MCFixup &Fixup = *it3;
|
||||
uint64_t FixedValue = handleFixup(Layout, *DF, Fixup);
|
||||
getBackend().applyFixup(Fixup, DF->getContents().data(),
|
||||
DF->getContents().size(), FixedValue);
|
||||
}
|
||||
}
|
||||
MCInstFragment *IF = dyn_cast<MCInstFragment>(it2);
|
||||
if (IF) {
|
||||
for (MCInstFragment::fixup_iterator it3 = IF->fixup_begin(),
|
||||
ie3 = IF->fixup_end(); it3 != ie3; ++it3) {
|
||||
MCFixup &Fixup = *it3;
|
||||
uint64_t FixedValue = handleFixup(Layout, *IF, Fixup);
|
||||
getBackend().applyFixup(Fixup, IF->getCode().data(),
|
||||
IF->getCode().size(), FixedValue);
|
||||
uint64_t FixedValue = handleFixup(Layout, *F, Fixup);
|
||||
getBackend().applyFixup(Fixup, F->getContents().data(),
|
||||
F->getContents().size(), FixedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -704,11 +701,8 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
|
||||
|
||||
// Update the instruction fragment.
|
||||
IF.setInst(Relaxed);
|
||||
IF.getCode() = Code;
|
||||
IF.getFixups().clear();
|
||||
// FIXME: Eliminate copy.
|
||||
for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
|
||||
IF.getFixups().push_back(Fixups[i]);
|
||||
IF.getContents() = Code;
|
||||
IF.getFixups() = Fixups;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -977,6 +971,7 @@ void MCAssembler::dump() {
|
||||
#endif
|
||||
|
||||
// anchors for MC*Fragment vtables
|
||||
void MCEncodedFragment::anchor() { }
|
||||
void MCDataFragment::anchor() { }
|
||||
void MCInstFragment::anchor() { }
|
||||
void MCAlignFragment::anchor() { }
|
||||
|
@ -345,7 +345,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
|
||||
// Add the fixups and data.
|
||||
for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
|
||||
Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
|
||||
DF->addFixup(Fixups[i]);
|
||||
DF->getFixups().push_back(Fixups[i]);
|
||||
}
|
||||
DF->getContents().append(Code.begin(), Code.end());
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ void MCMachOStreamer::EmitInstToData(const MCInst &Inst) {
|
||||
// Add the fixups and data.
|
||||
for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
|
||||
Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
|
||||
DF->addFixup(Fixups[i]);
|
||||
DF->getFixups().push_back(Fixups[i]);
|
||||
}
|
||||
DF->getContents().append(Code.begin(), Code.end());
|
||||
}
|
||||
|
@ -99,9 +99,9 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
|
||||
EmitIntValue(AbsValue, Size, AddrSpace);
|
||||
return;
|
||||
}
|
||||
DF->addFixup(MCFixup::Create(DF->getContents().size(),
|
||||
Value,
|
||||
MCFixup::getKindForSize(Size, false)));
|
||||
DF->getFixups().push_back(
|
||||
MCFixup::Create(DF->getContents().size(), Value,
|
||||
MCFixup::getKindForSize(Size, false)));
|
||||
DF->getContents().resize(DF->getContents().size() + Size, 0);
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
|
||||
raw_svector_ostream VecOS(Code);
|
||||
getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
|
||||
VecOS.flush();
|
||||
IF->getCode().append(Code.begin(), Code.end());
|
||||
IF->getContents().append(Code.begin(), Code.end());
|
||||
}
|
||||
|
||||
void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
|
||||
@ -288,7 +288,8 @@ bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
|
||||
void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
|
||||
MCDataFragment *DF = getOrCreateDataFragment();
|
||||
|
||||
DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4));
|
||||
DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
|
||||
Value, FK_GPRel_4));
|
||||
DF->getContents().resize(DF->getContents().size() + 4, 0);
|
||||
}
|
||||
|
||||
@ -296,7 +297,8 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
|
||||
void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
|
||||
MCDataFragment *DF = getOrCreateDataFragment();
|
||||
|
||||
DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4));
|
||||
DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
|
||||
Value, FK_GPRel_4));
|
||||
DF->getContents().resize(DF->getContents().size() + 8, 0);
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ void MCPureStreamer::EmitInstToFragment(const MCInst &Inst) {
|
||||
getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
|
||||
VecOS.flush();
|
||||
|
||||
IF->getCode() = Code;
|
||||
IF->getContents() = Code;
|
||||
IF->getFixups() = Fixups;
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ void MCPureStreamer::EmitInstToData(const MCInst &Inst) {
|
||||
// Add the fixups and data.
|
||||
for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
|
||||
Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
|
||||
DF->addFixup(Fixups[i]);
|
||||
DF->getFixups().push_back(Fixups[i]);
|
||||
}
|
||||
DF->getContents().append(Code.begin(), Code.end());
|
||||
}
|
||||
|
@ -288,9 +288,10 @@ void WinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol)
|
||||
{
|
||||
MCDataFragment *DF = getOrCreateDataFragment();
|
||||
|
||||
DF->addFixup(MCFixup::Create(DF->getContents().size(),
|
||||
MCSymbolRefExpr::Create (Symbol, getContext ()),
|
||||
FK_SecRel_4));
|
||||
DF->getFixups().push_back(
|
||||
MCFixup::Create(DF->getContents().size(),
|
||||
MCSymbolRefExpr::Create (Symbol, getContext ()),
|
||||
FK_SecRel_4));
|
||||
DF->getContents().resize(DF->getContents().size() + 4, 0);
|
||||
}
|
||||
|
||||
@ -339,7 +340,7 @@ void WinCOFFStreamer::EmitInstruction(const MCInst &Instruction) {
|
||||
MCInstFragment *Fragment =
|
||||
new MCInstFragment(Instruction, getCurrentSectionData());
|
||||
|
||||
raw_svector_ostream VecOS(Fragment->getCode());
|
||||
raw_svector_ostream VecOS(Fragment->getContents());
|
||||
|
||||
getAssembler().getEmitter().EncodeInstruction(Instruction, VecOS,
|
||||
Fragment->getFixups());
|
||||
|
Loading…
x
Reference in New Issue
Block a user