aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-03-22 23:16:48 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-03-22 23:16:48 +0000
commit3f4dcd92daef80f87919507b6baf2a97d4bfaa2e (patch)
tree3ddd6c5b3c16bbc749cbc16110c982d7db271207 /lib/MC
parent35b0657dea3f5dfee3b753a58c585edd22e3b45c (diff)
downloadexternal_llvm-3f4dcd92daef80f87919507b6baf2a97d4bfaa2e.zip
external_llvm-3f4dcd92daef80f87919507b6baf2a97d4bfaa2e.tar.gz
external_llvm-3f4dcd92daef80f87919507b6baf2a97d4bfaa2e.tar.bz2
MC: Add MCInstFragment, not used yet.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99229 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCAssembler.cpp84
-rw-r--r--lib/MC/MCMachOStreamer.cpp3
2 files changed, 83 insertions, 4 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 8cb7270..ba2e5de 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -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();
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index b57f302..51a2d45 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -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);