1//===- lib/MC/MCAtom.cpp - MCAtom implementation --------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "llvm/MC/MCAnalysis/MCAtom.h" 11#include "llvm/MC/MCAnalysis/MCModule.h" 12#include "llvm/Support/ErrorHandling.h" 13#include <iterator> 14 15using namespace llvm; 16 17// Pin the vtable to this file. 18void MCAtom::anchor() {} 19 20void MCAtom::remap(uint64_t NewBegin, uint64_t NewEnd) { 21 Parent->remap(this, NewBegin, NewEnd); 22} 23 24void MCAtom::remapForTruncate(uint64_t TruncPt) { 25 assert((TruncPt >= Begin && TruncPt < End) && 26 "Truncation point not contained in atom!"); 27 remap(Begin, TruncPt); 28} 29 30void MCAtom::remapForSplit(uint64_t SplitPt, 31 uint64_t &LBegin, uint64_t &LEnd, 32 uint64_t &RBegin, uint64_t &REnd) { 33 assert((SplitPt > Begin && SplitPt <= End) && 34 "Splitting at point not contained in atom!"); 35 36 // Compute the new begin/end points. 37 LBegin = Begin; 38 LEnd = SplitPt - 1; 39 RBegin = SplitPt; 40 REnd = End; 41 42 // Remap this atom to become the lower of the two new ones. 43 remap(LBegin, LEnd); 44} 45 46// MCDataAtom 47 48void MCDataAtom::addData(const MCData &D) { 49 Data.push_back(D); 50 if (Data.size() > End + 1 - Begin) 51 remap(Begin, End + 1); 52} 53 54void MCDataAtom::truncate(uint64_t TruncPt) { 55 remapForTruncate(TruncPt); 56 57 Data.resize(TruncPt - Begin + 1); 58} 59 60MCDataAtom *MCDataAtom::split(uint64_t SplitPt) { 61 uint64_t LBegin, LEnd, RBegin, REnd; 62 remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd); 63 64 MCDataAtom *RightAtom = Parent->createDataAtom(RBegin, REnd); 65 RightAtom->setName(getName()); 66 67 std::vector<MCData>::iterator I = Data.begin() + (RBegin - LBegin); 68 assert(I != Data.end() && "Split point not found in range!"); 69 70 std::copy(I, Data.end(), std::back_inserter(RightAtom->Data)); 71 Data.erase(I, Data.end()); 72 return RightAtom; 73} 74 75// MCTextAtom 76 77void MCTextAtom::addInst(const MCInst &I, uint64_t Size) { 78 if (NextInstAddress + Size - 1 > End) 79 remap(Begin, NextInstAddress + Size - 1); 80 Insts.push_back(MCDecodedInst(I, NextInstAddress, Size)); 81 NextInstAddress += Size; 82} 83 84void MCTextAtom::truncate(uint64_t TruncPt) { 85 remapForTruncate(TruncPt); 86 87 InstListTy::iterator I = Insts.begin(); 88 while (I != Insts.end() && I->Address <= TruncPt) ++I; 89 90 assert(I != Insts.end() && "Truncation point not found in disassembly!"); 91 assert(I->Address == TruncPt + 1 && 92 "Truncation point does not fall on instruction boundary"); 93 94 Insts.erase(I, Insts.end()); 95} 96 97MCTextAtom *MCTextAtom::split(uint64_t SplitPt) { 98 uint64_t LBegin, LEnd, RBegin, REnd; 99 remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd); 100 101 MCTextAtom *RightAtom = Parent->createTextAtom(RBegin, REnd); 102 RightAtom->setName(getName()); 103 104 InstListTy::iterator I = Insts.begin(); 105 while (I != Insts.end() && I->Address < SplitPt) ++I; 106 assert(I != Insts.end() && "Split point not found in disassembly!"); 107 assert(I->Address == SplitPt && 108 "Split point does not fall on instruction boundary!"); 109 110 std::copy(I, Insts.end(), std::back_inserter(RightAtom->Insts)); 111 Insts.erase(I, Insts.end()); 112 Parent->splitBasicBlocksForAtom(this, RightAtom); 113 return RightAtom; 114} 115