diff options
Diffstat (limited to 'lib/MC/MCAtom.cpp')
-rw-r--r-- | lib/MC/MCAtom.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/lib/MC/MCAtom.cpp b/lib/MC/MCAtom.cpp new file mode 100644 index 00000000000..d71444324f3 --- /dev/null +++ b/lib/MC/MCAtom.cpp @@ -0,0 +1,97 @@ +//===- lib/MC/MCAtom.cpp - MCAtom implementation --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCAtom.h" +#include "llvm/MC/MCModule.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +void MCAtom::addInst(const MCInst &I, uint64_t Address, unsigned Size) { + assert(Type == TextAtom && "Trying to add MCInst to a non-text atom!"); + + assert(Address < End+Size && + "Instruction not contiguous with end of atom!"); + if (Address > End) + Parent->remap(this, Begin, End+Size); + + Text.push_back(std::make_pair(Address, I)); +} + +void MCAtom::addData(const MCData &D) { + assert(Type == DataAtom && "Trying to add MCData to a non-data atom!"); + Parent->remap(this, Begin, End+1); + + Data.push_back(D); +} + +MCAtom *MCAtom::split(uint64_t SplitPt) { + assert((SplitPt > Begin && SplitPt <= End) && + "Splitting at point not contained in atom!"); + + // Compute the new begin/end points. + uint64_t LeftBegin = Begin; + uint64_t LeftEnd = SplitPt - 1; + uint64_t RightBegin = SplitPt; + uint64_t RightEnd = End; + + // Remap this atom to become the lower of the two new ones. + Parent->remap(this, LeftBegin, LeftEnd); + + // Create a new atom for the higher atom. + MCAtom *RightAtom = Parent->createAtom(Type, RightBegin, RightEnd); + + // Split the contents of the original atom between it and the new one. The + // precise method depends on whether this is a data or a text atom. + if (isDataAtom()) { + std::vector<MCData>::iterator I = Data.begin() + (RightBegin - LeftBegin); + + assert(I != Data.end() && "Split point not found in range!"); + + std::copy(I, Data.end(), RightAtom->Data.end()); + Data.erase(I, Data.end()); + } else if (isTextAtom()) { + std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin(); + + while (I != Text.end() && I->first < SplitPt) ++I; + + assert(I != Text.end() && "Split point not found in disassembly!"); + assert(I->first == SplitPt && + "Split point does not fall on instruction boundary!"); + + std::copy(I, Text.end(), RightAtom->Text.end()); + Text.erase(I, Text.end()); + } else + llvm_unreachable("Unknown atom type!"); + + return RightAtom; +} + +void MCAtom::truncate(uint64_t TruncPt) { + assert((TruncPt >= Begin && TruncPt < End) && + "Truncation point not contained in atom!"); + + Parent->remap(this, Begin, TruncPt); + + if (isDataAtom()) { + Data.resize(TruncPt - Begin + 1); + } else if (isTextAtom()) { + std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin(); + + while (I != Text.end() && I->first <= TruncPt) ++I; + + assert(I != Text.end() && "Truncation point not found in disassembly!"); + assert(I->first == TruncPt+1 && + "Truncation point does not fall on instruction boundary"); + + Text.erase(I, Text.end()); + } else + llvm_unreachable("Unknown atom type!"); +} + |