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 14 using namespace llvm; 15 16 void MCAtom::addInst(const MCInst &I, uint64_t Address, unsigned Size) { 17 assert(Type == TextAtom && "Trying to add MCInst to a non-text atom!"); 18 19 assert(Address < End+Size && 20 "Instruction not contiguous with end of atom!"); 21 if (Address > End) 22 Parent->remap(this, Begin, End+Size); 23 24 Text.push_back(std::make_pair(Address, I)); 25 } 26 27 void MCAtom::addData(const MCData &D) { 28 assert(Type == DataAtom && "Trying to add MCData to a non-data atom!"); 29 Parent->remap(this, Begin, End+1); 30 31 Data.push_back(D); 32 } 33 34 MCAtom *MCAtom::split(uint64_t SplitPt) { 35 assert((SplitPt > Begin && SplitPt <= End) && 36 "Splitting at point not contained in atom!"); 37 38 // Compute the new begin/end points. 39 uint64_t LeftBegin = Begin; 40 uint64_t LeftEnd = SplitPt - 1; 41 uint64_t RightBegin = SplitPt; 42 uint64_t RightEnd = End; 43 44 // Remap this atom to become the lower of the two new ones. 45 Parent->remap(this, LeftBegin, LeftEnd); 46 47 // Create a new atom for the higher atom. 48 MCAtom *RightAtom = Parent->createAtom(Type, RightBegin, RightEnd); 49 50 // Split the contents of the original atom between it and the new one. The 51 // precise method depends on whether this is a data or a text atom. 52 if (isDataAtom()) { 53 std::vector<MCData>::iterator I = Data.begin() + (RightBegin - LeftBegin); 54 55 assert(I != Data.end() && "Split point not found in range!"); 56 57 std::copy(I, Data.end(), RightAtom->Data.end()); 58 Data.erase(I, Data.end()); 59 } else if (isTextAtom()) { 60 std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin(); 61 62 while (I != Text.end() && I->first < SplitPt) ++I; 63 64 assert(I != Text.end() && "Split point not found in disassembly!"); 65 assert(I->first == SplitPt && 66 "Split point does not fall on instruction boundary!"); 67 68 std::copy(I, Text.end(), RightAtom->Text.end()); 69 Text.erase(I, Text.end()); 70 } else 71 llvm_unreachable("Unknown atom type!"); 72 73 return RightAtom; 74 } 75 76 void MCAtom::truncate(uint64_t TruncPt) { 77 assert((TruncPt >= Begin && TruncPt < End) && 78 "Truncation point not contained in atom!"); 79 80 Parent->remap(this, Begin, TruncPt); 81 82 if (isDataAtom()) { 83 Data.resize(TruncPt - Begin + 1); 84 } else if (isTextAtom()) { 85 std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin(); 86 87 while (I != Text.end() && I->first <= TruncPt) ++I; 88 89 assert(I != Text.end() && "Truncation point not found in disassembly!"); 90 assert(I->first == TruncPt+1 && 91 "Truncation point does not fall on instruction boundary"); 92 93 Text.erase(I, Text.end()); 94 } else 95 llvm_unreachable("Unknown atom type!"); 96 } 97 98