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