//===- 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" #include using namespace llvm; // Pin the vtable to this file. void MCAtom::anchor() {} void MCAtom::remap(uint64_t NewBegin, uint64_t NewEnd) { Parent->remap(this, NewBegin, NewEnd); } void MCAtom::remapForTruncate(uint64_t TruncPt) { assert((TruncPt >= Begin && TruncPt < End) && "Truncation point not contained in atom!"); remap(Begin, TruncPt); } void MCAtom::remapForSplit(uint64_t SplitPt, uint64_t &LBegin, uint64_t &LEnd, uint64_t &RBegin, uint64_t &REnd) { assert((SplitPt > Begin && SplitPt <= End) && "Splitting at point not contained in atom!"); // Compute the new begin/end points. LBegin = Begin; LEnd = SplitPt - 1; RBegin = SplitPt; REnd = End; // Remap this atom to become the lower of the two new ones. remap(LBegin, LEnd); } // MCDataAtom void MCDataAtom::addData(const MCData &D) { Data.push_back(D); if (Data.size() > End + 1 - Begin) remap(Begin, End + 1); } void MCDataAtom::truncate(uint64_t TruncPt) { remapForTruncate(TruncPt); Data.resize(TruncPt - Begin + 1); } MCDataAtom *MCDataAtom::split(uint64_t SplitPt) { uint64_t LBegin, LEnd, RBegin, REnd; remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd); MCDataAtom *RightAtom = Parent->createDataAtom(RBegin, REnd); RightAtom->setName(getName()); std::vector::iterator I = Data.begin() + (RBegin - LBegin); assert(I != Data.end() && "Split point not found in range!"); std::copy(I, Data.end(), std::back_inserter(RightAtom->Data)); Data.erase(I, Data.end()); return RightAtom; } // MCTextAtom void MCTextAtom::addInst(const MCInst &I, uint64_t Size) { if (NextInstAddress + Size - 1 > End) remap(Begin, NextInstAddress + Size - 1); Insts.push_back(MCDecodedInst(I, NextInstAddress, Size)); NextInstAddress += Size; } void MCTextAtom::truncate(uint64_t TruncPt) { remapForTruncate(TruncPt); InstListTy::iterator I = Insts.begin(); while (I != Insts.end() && I->Address <= TruncPt) ++I; assert(I != Insts.end() && "Truncation point not found in disassembly!"); assert(I->Address == TruncPt + 1 && "Truncation point does not fall on instruction boundary"); Insts.erase(I, Insts.end()); } MCTextAtom *MCTextAtom::split(uint64_t SplitPt) { uint64_t LBegin, LEnd, RBegin, REnd; remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd); MCTextAtom *RightAtom = Parent->createTextAtom(RBegin, REnd); RightAtom->setName(getName()); InstListTy::iterator I = Insts.begin(); while (I != Insts.end() && I->Address < SplitPt) ++I; assert(I != Insts.end() && "Split point not found in disassembly!"); assert(I->Address == SplitPt && "Split point does not fall on instruction boundary!"); std::copy(I, Insts.end(), std::back_inserter(RightAtom->Insts)); Insts.erase(I, Insts.end()); Parent->splitBasicBlocksForAtom(this, RightAtom); return RightAtom; }