mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 04:09:45 +00:00
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:
parent
35b0657dea
commit
3f4dcd92da
@ -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.
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user