diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index ff32eb26fc0..d7f1acea35e 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -180,28 +180,57 @@ public: virtual void dump(); }; +// 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 { /// Inst - The instruction this is a fragment for. MCInst Inst; /// InstSize - The size of the currently encoded instruction. - unsigned InstSize; + SmallString<8> Code; + + /// Fixups - The list of fixups in this fragment. + SmallVector Fixups; public: - MCInstFragment(MCInst _Inst, unsigned _InstSize, MCSectionData *SD = 0) - : MCFragment(FT_Inst, SD), Inst(_Inst), InstSize(_InstSize) {} + typedef SmallVectorImpl::const_iterator const_fixup_iterator; + typedef SmallVectorImpl::iterator fixup_iterator; + +public: + MCInstFragment(MCInst _Inst, MCSectionData *SD = 0) + : MCFragment(FT_Inst, SD), Inst(_Inst) { + } /// @name Accessors /// @{ - unsigned getInstSize() const { return InstSize; } + SmallVectorImpl &getCode() { return Code; } + const SmallVectorImpl &getCode() const { return Code; } + unsigned getInstSize() const { return Code.size(); } + + MCInst &getInst() { return Inst; } const MCInst &getInst() const { return Inst; } - void setInst(MCInst Inst, unsigned InstSize) { - this->Inst = Inst; - this->InstSize = InstSize; - } + void setInst(MCInst Value) { Inst = Value; } + + /// @} + /// @name Fixup Access + /// @{ + + SmallVectorImpl &getFixups() { return Fixups; } + const SmallVectorImpl &getFixups() const { return Fixups; } + + fixup_iterator fixup_begin() { return Fixups.begin(); } + const_fixup_iterator fixup_begin() const { return Fixups.begin(); } + + fixup_iterator fixup_end() {return Fixups.end();} + const_fixup_iterator fixup_end() const {return Fixups.end();} + + size_t fixup_size() const { return Fixups.size(); } /// @} diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index ba2e5de73e5..39bad6dea46 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -773,22 +773,14 @@ void MCAssembler::FinishLayout(MCAsmLayout &Layout) { SD.getFragmentList().insert(it2, DF); // Update the data fragments layout data. + DF->setParent(IF->getParent()); DF->setOffset(IF->getOffset()); DF->setFileSize(IF->getInstSize()); - // Encode the final instruction. - SmallVector 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())); - } + // Copy in the data and the fixups. + DF->getContents().append(IF->getCode().begin(), IF->getCode().end()); + for (unsigned i = 0, e = IF->getFixups().size(); i != e; ++i) + DF->getFixups().push_back(IF->getFixups()[i]); // Delete the instruction fragment and update the iterator. SD.getFragmentList().erase(IF);