MC: Add MCInstFragment, not used yet.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99229 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2010-03-22 23:16:48 +00:00
parent 35b0657dea
commit 3f4dcd92da
3 changed files with 124 additions and 6 deletions

View File

@ -16,6 +16,7 @@
#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/Casting.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/System/DataTypes.h"
#include <vector> // FIXME: Shouldn't be needed.
@ -37,6 +38,8 @@ class TargetAsmBackend;
/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
/// which needs to be rewritten. This region will either be rewritten by the
/// assembler or cause a relocation entry to be generated.
//
// FIXME: This should probably just be merged with MCFixup.
class MCAsmFixup {
public:
/// Offset - The offset inside the fragment which needs to be rewritten.
@ -59,9 +62,10 @@ class MCFragment : public ilist_node<MCFragment> {
public:
enum FragmentType {
FT_Data,
FT_Align,
FT_Data,
FT_Fill,
FT_Inst,
FT_Org,
FT_ZeroFill
};
@ -145,7 +149,6 @@ public:
const SmallString<32> &getContents() const { return Contents; }
/// @}
/// @name Fixup Access
/// @{
@ -177,6 +180,39 @@ public:
virtual void dump();
};
class MCInstFragment : public MCFragment {
/// Inst - The instruction this is a fragment for.
MCInst Inst;
/// InstSize - The size of the currently encoded instruction.
unsigned InstSize;
public:
MCInstFragment(MCInst _Inst, unsigned _InstSize, MCSectionData *SD = 0)
: MCFragment(FT_Inst, SD), Inst(_Inst), InstSize(_InstSize) {}
/// @name Accessors
/// @{
unsigned getInstSize() const { return InstSize; }
const MCInst &getInst() const { return Inst; }
void setInst(MCInst Inst, unsigned InstSize) {
this->Inst = Inst;
this->InstSize = InstSize;
}
/// @}
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Inst;
}
static bool classof(const MCInstFragment *) { return true; }
virtual void dump();
};
class MCAlignFragment : public MCFragment {
/// Alignment - The alignment to ensure, in bytes.
unsigned Alignment;
@ -623,6 +659,9 @@ private:
/// were adjusted.
bool LayoutOnce(MCAsmLayout &Layout);
/// FinishLayout - Finalize a layout, including fragment lowering.
void FinishLayout(MCAsmLayout &Layout);
public:
/// Find the symbol which defines the atom containing given address, inside
/// the given section, or null if there is no such symbol.

View File

@ -327,6 +327,10 @@ void MCAssembler::LayoutSection(MCSectionData &SD,
break;
}
case MCFragment::FT_Inst:
F.setFileSize(cast<MCInstFragment>(F).getInstSize());
break;
case MCFragment::FT_Org: {
MCOrgFragment &OF = cast<MCOrgFragment>(F);
@ -471,7 +475,9 @@ static void WriteFragmentData(const MCFragment &F, MCObjectWriter *OW) {
}
case MCFragment::FT_Data: {
OW->WriteBytes(cast<MCDataFragment>(F).getContents().str());
MCDataFragment &DF = cast<MCDataFragment>(F);
assert(DF.getFileSize() == DF.getContents().size() && "Invalid size!");
OW->WriteBytes(DF.getContents().str());
break;
}
@ -490,6 +496,10 @@ static void WriteFragmentData(const MCFragment &F, MCObjectWriter *OW) {
break;
}
case MCFragment::FT_Inst:
llvm_unreachable("unexpected inst fragment after lowering");
break;
case MCFragment::FT_Org: {
MCOrgFragment &OF = cast<MCOrgFragment>(F);
@ -541,7 +551,14 @@ void MCAssembler::Finish() {
continue;
DEBUG_WITH_TYPE("mc-dump", {
llvm::errs() << "assembler backend - post-layout\n--\n";
llvm::errs() << "assembler backend - post-relaxation\n--\n";
dump(); });
// Finalize the layout, including fragment lowering.
FinishLayout(Layout);
DEBUG_WITH_TYPE("mc-dump", {
llvm::errs() << "assembler backend - final-layout\n--\n";
dump(); });
llvm::OwningPtr<MCObjectWriter> Writer(getBackend().createObjectWriter(OS));
@ -722,8 +739,8 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
// Restart layout.
//
// FIXME: This is O(N^2), but will be eliminated once we have a smart
// MCAsmLayout object.
// FIXME-PERF: This is O(N^2), but will be eliminated once we have a
// smart MCAsmLayout object.
return true;
}
}
@ -732,6 +749,54 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
return false;
}
void MCAssembler::FinishLayout(MCAsmLayout &Layout) {
// Lower out any instruction fragments, to simplify the fixup application and
// output.
//
// FIXME-PERF: We don't have to do this, but the assumption is that it is
// cheap (we will mostly end up eliminating fragments and appending on to data
// fragments), so the extra complexity downstream isn't worth it. Evaluate
// this assumption.
for (iterator it = begin(), ie = end(); it != ie; ++it) {
MCSectionData &SD = *it;
for (MCSectionData::iterator it2 = SD.begin(),
ie2 = SD.end(); it2 != ie2; ++it2) {
MCInstFragment *IF = dyn_cast<MCInstFragment>(it2);
if (!IF)
continue;
// Create a new data fragment for the instruction.
//
// FIXME: Reuse previous data fragment if possible.
MCDataFragment *DF = new MCDataFragment();
SD.getFragmentList().insert(it2, DF);
// Update the data fragments layout data.
DF->setOffset(IF->getOffset());
DF->setFileSize(IF->getInstSize());
// Encode the final instruction.
SmallVector<MCFixup, 4> Fixups;
raw_svector_ostream VecOS(DF->getContents());
getEmitter().EncodeInstruction(IF->getInst(), VecOS, Fixups);
// Copy over the fixups.
//
// FIXME-PERF: Encode fixups directly into the data fragment as well.
for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
MCFixup &F = Fixups[i];
DF->addFixup(MCAsmFixup(DF->getContents().size()+F.getOffset(),
*F.getValue(), F.getKind()));
}
// Delete the instruction fragment and update the iterator.
SD.getFragmentList().erase(IF);
it2 = DF;
}
}
}
// Debugging methods
namespace llvm {
@ -800,6 +865,17 @@ void MCFillFragment::dump() {
<< " Count:" << getCount() << ">";
}
void MCInstFragment::dump() {
raw_ostream &OS = llvm::errs();
OS << "<MCInstFragment ";
this->MCFragment::dump();
OS << "\n ";
OS << " Inst:";
getInst().dump_pretty(OS);
OS << ">";
}
void MCOrgFragment::dump() {
raw_ostream &OS = llvm::errs();

View File

@ -375,6 +375,9 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
CurSectionData->setHasInstructions(true);
// FIXME-PERF: Common case is that we don't need to relax, encode directly
// onto the data fragments buffers.
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);