1124e1821033a4b3220f552229652d9460ed90673Owen Anderson//===- lib/MC/MCAtom.cpp - MCAtom implementation --------------------------===//
2124e1821033a4b3220f552229652d9460ed90673Owen Anderson//
3124e1821033a4b3220f552229652d9460ed90673Owen Anderson//                     The LLVM Compiler Infrastructure
4124e1821033a4b3220f552229652d9460ed90673Owen Anderson//
5124e1821033a4b3220f552229652d9460ed90673Owen Anderson// This file is distributed under the University of Illinois Open Source
6124e1821033a4b3220f552229652d9460ed90673Owen Anderson// License. See LICENSE.TXT for details.
7124e1821033a4b3220f552229652d9460ed90673Owen Anderson//
8124e1821033a4b3220f552229652d9460ed90673Owen Anderson//===----------------------------------------------------------------------===//
9124e1821033a4b3220f552229652d9460ed90673Owen Anderson
10124e1821033a4b3220f552229652d9460ed90673Owen Anderson#include "llvm/MC/MCAtom.h"
11124e1821033a4b3220f552229652d9460ed90673Owen Anderson#include "llvm/MC/MCModule.h"
12124e1821033a4b3220f552229652d9460ed90673Owen Anderson#include "llvm/Support/ErrorHandling.h"
13ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include <iterator>
14124e1821033a4b3220f552229652d9460ed90673Owen Anderson
15124e1821033a4b3220f552229652d9460ed90673Owen Andersonusing namespace llvm;
16124e1821033a4b3220f552229652d9460ed90673Owen Anderson
17ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachavoid MCAtom::remap(uint64_t NewBegin, uint64_t NewEnd) {
18ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  Parent->remap(this, NewBegin, NewEnd);
19042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson}
20042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson
21ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachavoid MCAtom::remapForTruncate(uint64_t TruncPt) {
22ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  assert((TruncPt >= Begin && TruncPt < End) &&
23ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha         "Truncation point not contained in atom!");
24ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  remap(Begin, TruncPt);
25042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson}
26042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson
27ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachavoid MCAtom::remapForSplit(uint64_t SplitPt,
28ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha                           uint64_t &LBegin, uint64_t &LEnd,
29ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha                           uint64_t &RBegin, uint64_t &REnd) {
30124e1821033a4b3220f552229652d9460ed90673Owen Anderson  assert((SplitPt > Begin && SplitPt <= End) &&
31124e1821033a4b3220f552229652d9460ed90673Owen Anderson         "Splitting at point not contained in atom!");
32124e1821033a4b3220f552229652d9460ed90673Owen Anderson
33124e1821033a4b3220f552229652d9460ed90673Owen Anderson  // Compute the new begin/end points.
34ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  LBegin = Begin;
35ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  LEnd = SplitPt - 1;
36ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  RBegin = SplitPt;
37ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  REnd = End;
38124e1821033a4b3220f552229652d9460ed90673Owen Anderson
39124e1821033a4b3220f552229652d9460ed90673Owen Anderson  // Remap this atom to become the lower of the two new ones.
40ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  remap(LBegin, LEnd);
41ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha}
42124e1821033a4b3220f552229652d9460ed90673Owen Anderson
43ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha// MCDataAtom
44124e1821033a4b3220f552229652d9460ed90673Owen Anderson
45ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachavoid MCDataAtom::addData(const MCData &D) {
46ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  Data.push_back(D);
47ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  if (Data.size() > Begin - End)
48ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    remap(Begin, End + 1);
49ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha}
50124e1821033a4b3220f552229652d9460ed90673Owen Anderson
51ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachavoid MCDataAtom::truncate(uint64_t TruncPt) {
52ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  remapForTruncate(TruncPt);
53124e1821033a4b3220f552229652d9460ed90673Owen Anderson
54ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  Data.resize(TruncPt - Begin + 1);
55ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha}
56124e1821033a4b3220f552229652d9460ed90673Owen Anderson
57ef99356dfebb96f6f90efb912c2877214bad060eAhmed BougachaMCDataAtom *MCDataAtom::split(uint64_t SplitPt) {
58ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  uint64_t LBegin, LEnd, RBegin, REnd;
59ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd);
60124e1821033a4b3220f552229652d9460ed90673Owen Anderson
61ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCDataAtom *RightAtom = Parent->createDataAtom(RBegin, REnd);
62ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  RightAtom->setName(getName());
63124e1821033a4b3220f552229652d9460ed90673Owen Anderson
64ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  std::vector<MCData>::iterator I = Data.begin() + (RBegin - LBegin);
65ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  assert(I != Data.end() && "Split point not found in range!");
66124e1821033a4b3220f552229652d9460ed90673Owen Anderson
67ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  std::copy(I, Data.end(), std::back_inserter(RightAtom->Data));
68ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  Data.erase(I, Data.end());
69124e1821033a4b3220f552229652d9460ed90673Owen Anderson  return RightAtom;
70124e1821033a4b3220f552229652d9460ed90673Owen Anderson}
71124e1821033a4b3220f552229652d9460ed90673Owen Anderson
72ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha// MCTextAtom
73124e1821033a4b3220f552229652d9460ed90673Owen Anderson
74ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachavoid MCTextAtom::addInst(const MCInst &I, uint64_t Size) {
75ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  if (NextInstAddress > End)
76ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    remap(Begin, NextInstAddress);
77ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  Insts.push_back(MCDecodedInst(I, NextInstAddress, Size));
78ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  NextInstAddress += Size;
79ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha}
80124e1821033a4b3220f552229652d9460ed90673Owen Anderson
81ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachavoid MCTextAtom::truncate(uint64_t TruncPt) {
82ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  remapForTruncate(TruncPt);
83124e1821033a4b3220f552229652d9460ed90673Owen Anderson
84ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  InstListTy::iterator I = Insts.begin();
85ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  while (I != Insts.end() && I->Address <= TruncPt) ++I;
86124e1821033a4b3220f552229652d9460ed90673Owen Anderson
87ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  assert(I != Insts.end() && "Truncation point not found in disassembly!");
88ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  assert(I->Address == TruncPt + 1 &&
89ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha         "Truncation point does not fall on instruction boundary");
90124e1821033a4b3220f552229652d9460ed90673Owen Anderson
91ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  Insts.erase(I, Insts.end());
92124e1821033a4b3220f552229652d9460ed90673Owen Anderson}
93124e1821033a4b3220f552229652d9460ed90673Owen Anderson
94ef99356dfebb96f6f90efb912c2877214bad060eAhmed BougachaMCTextAtom *MCTextAtom::split(uint64_t SplitPt) {
95ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  uint64_t LBegin, LEnd, RBegin, REnd;
96ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd);
97ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
98ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  MCTextAtom *RightAtom = Parent->createTextAtom(RBegin, REnd);
99ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  RightAtom->setName(getName());
100ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
101ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  InstListTy::iterator I = Insts.begin();
102ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  while (I != Insts.end() && I->Address < SplitPt) ++I;
103ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  assert(I != Insts.end() && "Split point not found in disassembly!");
104ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  assert(I->Address == SplitPt &&
105ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha         "Split point does not fall on instruction boundary!");
106ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
107ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  std::copy(I, Insts.end(), std::back_inserter(RightAtom->Insts));
108ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  Insts.erase(I, Insts.end());
109ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  return RightAtom;
110ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha}
111