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
15 using namespace llvm;
16
17 // Pin the vtable to this file.
anchor()18 void MCAtom::anchor() {}
19
remap(uint64_t NewBegin,uint64_t NewEnd)20 void MCAtom::remap(uint64_t NewBegin, uint64_t NewEnd) {
21 Parent->remap(this, NewBegin, NewEnd);
22 }
23
remapForTruncate(uint64_t TruncPt)24 void MCAtom::remapForTruncate(uint64_t TruncPt) {
25 assert((TruncPt >= Begin && TruncPt < End) &&
26 "Truncation point not contained in atom!");
27 remap(Begin, TruncPt);
28 }
29
remapForSplit(uint64_t SplitPt,uint64_t & LBegin,uint64_t & LEnd,uint64_t & RBegin,uint64_t & REnd)30 void 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
addData(const MCData & D)48 void MCDataAtom::addData(const MCData &D) {
49 Data.push_back(D);
50 if (Data.size() > End + 1 - Begin)
51 remap(Begin, End + 1);
52 }
53
truncate(uint64_t TruncPt)54 void MCDataAtom::truncate(uint64_t TruncPt) {
55 remapForTruncate(TruncPt);
56
57 Data.resize(TruncPt - Begin + 1);
58 }
59
split(uint64_t SplitPt)60 MCDataAtom *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
addInst(const MCInst & I,uint64_t Size)77 void 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
truncate(uint64_t TruncPt)84 void 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
split(uint64_t SplitPt)97 MCTextAtom *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