blob: 82056eed1ea9e217472f633a83e4710b873593a0 [file] [log] [blame]
Owen Anderson6cca67f2011-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
Rafael Espindolacbc5ac72014-07-02 19:49:34 +000010#include "llvm/MC/MCAnalysis/MCAtom.h"
11#include "llvm/MC/MCAnalysis/MCModule.h"
Owen Anderson6cca67f2011-09-22 22:32:22 +000012#include "llvm/Support/ErrorHandling.h"
Ahmed Bougachaaa790682013-05-24 01:07:04 +000013#include <iterator>
Owen Anderson6cca67f2011-09-22 22:32:22 +000014
15using namespace llvm;
16
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +000017// Pin the vtable to this file.
18void MCAtom::anchor() {}
19
Ahmed Bougachaaa790682013-05-24 01:07:04 +000020void MCAtom::remap(uint64_t NewBegin, uint64_t NewEnd) {
21 Parent->remap(this, NewBegin, NewEnd);
Owen Andersonbed55042011-10-10 18:09:38 +000022}
23
Ahmed Bougachaaa790682013-05-24 01:07:04 +000024void MCAtom::remapForTruncate(uint64_t TruncPt) {
25 assert((TruncPt >= Begin && TruncPt < End) &&
26 "Truncation point not contained in atom!");
27 remap(Begin, TruncPt);
Owen Andersonbed55042011-10-10 18:09:38 +000028}
29
Ahmed Bougachaaa790682013-05-24 01:07:04 +000030void MCAtom::remapForSplit(uint64_t SplitPt,
31 uint64_t &LBegin, uint64_t &LEnd,
32 uint64_t &RBegin, uint64_t &REnd) {
Owen Anderson6cca67f2011-09-22 22:32:22 +000033 assert((SplitPt > Begin && SplitPt <= End) &&
34 "Splitting at point not contained in atom!");
35
36 // Compute the new begin/end points.
Ahmed Bougachaaa790682013-05-24 01:07:04 +000037 LBegin = Begin;
38 LEnd = SplitPt - 1;
39 RBegin = SplitPt;
40 REnd = End;
Owen Anderson6cca67f2011-09-22 22:32:22 +000041
42 // Remap this atom to become the lower of the two new ones.
Ahmed Bougachaaa790682013-05-24 01:07:04 +000043 remap(LBegin, LEnd);
44}
Owen Anderson6cca67f2011-09-22 22:32:22 +000045
Ahmed Bougachaaa790682013-05-24 01:07:04 +000046// MCDataAtom
Owen Anderson6cca67f2011-09-22 22:32:22 +000047
Ahmed Bougachaaa790682013-05-24 01:07:04 +000048void MCDataAtom::addData(const MCData &D) {
49 Data.push_back(D);
Rafael Espindolabab2afb2013-10-16 18:26:16 +000050 if (Data.size() > End + 1 - Begin)
Ahmed Bougachaaa790682013-05-24 01:07:04 +000051 remap(Begin, End + 1);
52}
Owen Anderson6cca67f2011-09-22 22:32:22 +000053
Ahmed Bougachaaa790682013-05-24 01:07:04 +000054void MCDataAtom::truncate(uint64_t TruncPt) {
55 remapForTruncate(TruncPt);
Owen Anderson6cca67f2011-09-22 22:32:22 +000056
Ahmed Bougachaaa790682013-05-24 01:07:04 +000057 Data.resize(TruncPt - Begin + 1);
58}
Owen Anderson6cca67f2011-09-22 22:32:22 +000059
Ahmed Bougachaaa790682013-05-24 01:07:04 +000060MCDataAtom *MCDataAtom::split(uint64_t SplitPt) {
61 uint64_t LBegin, LEnd, RBegin, REnd;
62 remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd);
Owen Anderson6cca67f2011-09-22 22:32:22 +000063
Ahmed Bougachaaa790682013-05-24 01:07:04 +000064 MCDataAtom *RightAtom = Parent->createDataAtom(RBegin, REnd);
65 RightAtom->setName(getName());
Owen Anderson6cca67f2011-09-22 22:32:22 +000066
Ahmed Bougachaaa790682013-05-24 01:07:04 +000067 std::vector<MCData>::iterator I = Data.begin() + (RBegin - LBegin);
68 assert(I != Data.end() && "Split point not found in range!");
Owen Anderson6cca67f2011-09-22 22:32:22 +000069
Ahmed Bougachaaa790682013-05-24 01:07:04 +000070 std::copy(I, Data.end(), std::back_inserter(RightAtom->Data));
71 Data.erase(I, Data.end());
Owen Anderson6cca67f2011-09-22 22:32:22 +000072 return RightAtom;
73}
74
Ahmed Bougachaaa790682013-05-24 01:07:04 +000075// MCTextAtom
Owen Anderson6cca67f2011-09-22 22:32:22 +000076
Ahmed Bougachaaa790682013-05-24 01:07:04 +000077void MCTextAtom::addInst(const MCInst &I, uint64_t Size) {
Ahmed Bougachac43aa4e2013-08-21 07:27:47 +000078 if (NextInstAddress + Size - 1 > End)
79 remap(Begin, NextInstAddress + Size - 1);
Ahmed Bougachaaa790682013-05-24 01:07:04 +000080 Insts.push_back(MCDecodedInst(I, NextInstAddress, Size));
81 NextInstAddress += Size;
Owen Anderson6cca67f2011-09-22 22:32:22 +000082}
83
Ahmed Bougachaaa790682013-05-24 01:07:04 +000084void 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());
Ahmed Bougachaff12d022013-08-21 07:28:24 +0000112 Parent->splitBasicBlocksForAtom(this, RightAtom);
Ahmed Bougachaaa790682013-05-24 01:07:04 +0000113 return RightAtom;
114}