blob: 2626b39db4c744498c0f5ad51063e22bdf86d3f4 [file] [log] [blame]
Owen Anderson124e1822011-09-22 22:32:22 +00001//===- 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"
Ahmed Bougachaef993562013-05-24 01:07:04 +000013#include <iterator>
Owen Anderson124e1822011-09-22 22:32:22 +000014
15using namespace llvm;
16
Ahmed Bougachaef993562013-05-24 01:07:04 +000017void MCAtom::remap(uint64_t NewBegin, uint64_t NewEnd) {
18 Parent->remap(this, NewBegin, NewEnd);
Owen Anderson042aadd2011-10-10 18:09:38 +000019}
20
Ahmed Bougachaef993562013-05-24 01:07:04 +000021void MCAtom::remapForTruncate(uint64_t TruncPt) {
22 assert((TruncPt >= Begin && TruncPt < End) &&
23 "Truncation point not contained in atom!");
24 remap(Begin, TruncPt);
Owen Anderson042aadd2011-10-10 18:09:38 +000025}
26
Ahmed Bougachaef993562013-05-24 01:07:04 +000027void MCAtom::remapForSplit(uint64_t SplitPt,
28 uint64_t &LBegin, uint64_t &LEnd,
29 uint64_t &RBegin, uint64_t &REnd) {
Owen Anderson124e1822011-09-22 22:32:22 +000030 assert((SplitPt > Begin && SplitPt <= End) &&
31 "Splitting at point not contained in atom!");
32
33 // Compute the new begin/end points.
Ahmed Bougachaef993562013-05-24 01:07:04 +000034 LBegin = Begin;
35 LEnd = SplitPt - 1;
36 RBegin = SplitPt;
37 REnd = End;
Owen Anderson124e1822011-09-22 22:32:22 +000038
39 // Remap this atom to become the lower of the two new ones.
Ahmed Bougachaef993562013-05-24 01:07:04 +000040 remap(LBegin, LEnd);
41}
Owen Anderson124e1822011-09-22 22:32:22 +000042
Ahmed Bougachaef993562013-05-24 01:07:04 +000043// MCDataAtom
Owen Anderson124e1822011-09-22 22:32:22 +000044
Ahmed Bougachaef993562013-05-24 01:07:04 +000045void MCDataAtom::addData(const MCData &D) {
46 Data.push_back(D);
47 if (Data.size() > Begin - End)
48 remap(Begin, End + 1);
49}
Owen Anderson124e1822011-09-22 22:32:22 +000050
Ahmed Bougachaef993562013-05-24 01:07:04 +000051void MCDataAtom::truncate(uint64_t TruncPt) {
52 remapForTruncate(TruncPt);
Owen Anderson124e1822011-09-22 22:32:22 +000053
Ahmed Bougachaef993562013-05-24 01:07:04 +000054 Data.resize(TruncPt - Begin + 1);
55}
Owen Anderson124e1822011-09-22 22:32:22 +000056
Ahmed Bougachaef993562013-05-24 01:07:04 +000057MCDataAtom *MCDataAtom::split(uint64_t SplitPt) {
58 uint64_t LBegin, LEnd, RBegin, REnd;
59 remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd);
Owen Anderson124e1822011-09-22 22:32:22 +000060
Ahmed Bougachaef993562013-05-24 01:07:04 +000061 MCDataAtom *RightAtom = Parent->createDataAtom(RBegin, REnd);
62 RightAtom->setName(getName());
Owen Anderson124e1822011-09-22 22:32:22 +000063
Ahmed Bougachaef993562013-05-24 01:07:04 +000064 std::vector<MCData>::iterator I = Data.begin() + (RBegin - LBegin);
65 assert(I != Data.end() && "Split point not found in range!");
Owen Anderson124e1822011-09-22 22:32:22 +000066
Ahmed Bougachaef993562013-05-24 01:07:04 +000067 std::copy(I, Data.end(), std::back_inserter(RightAtom->Data));
68 Data.erase(I, Data.end());
Owen Anderson124e1822011-09-22 22:32:22 +000069 return RightAtom;
70}
71
Ahmed Bougachaef993562013-05-24 01:07:04 +000072// MCTextAtom
Owen Anderson124e1822011-09-22 22:32:22 +000073
Ahmed Bougachaef993562013-05-24 01:07:04 +000074void 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;
Owen Anderson124e1822011-09-22 22:32:22 +000079}
80
Ahmed Bougachaef993562013-05-24 01:07:04 +000081void 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
94MCTextAtom *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}