| //===- 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 <iterator> |
| |
| 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<MCData>::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; |
| } |