diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-03-22 23:16:48 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-03-22 23:16:48 +0000 |
commit | 3f4dcd92daef80f87919507b6baf2a97d4bfaa2e (patch) | |
tree | 3ddd6c5b3c16bbc749cbc16110c982d7db271207 /lib/MC/MCAssembler.cpp | |
parent | 35b0657dea3f5dfee3b753a58c585edd22e3b45c (diff) |
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/MCAssembler.cpp')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 84 |
1 files changed, 80 insertions, 4 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 8cb72706fe..ba2e5de73e 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(); |