blob: d71444324f3d8bff6181bba72a06e8c3e10e2209 [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"
13
14using namespace llvm;
15
Owen Anderson042aadd2011-10-10 18:09:38 +000016void 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
27void 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
Owen Anderson124e1822011-09-22 22:32:22 +000034MCAtom *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
76void 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