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"
13124e1821033a4b3220f552229652d9460ed90673Owen Anderson
14124e1821033a4b3220f552229652d9460ed90673Owen Andersonusing namespace llvm;
15124e1821033a4b3220f552229652d9460ed90673Owen Anderson
16042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Andersonvoid MCAtom::addInst(const MCInst &I, uint64_t Address, unsigned Size) {
17042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson  assert(Type == TextAtom && "Trying to add MCInst to a non-text atom!");
18042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson
19042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson  assert(Address < End+Size &&
20042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson         "Instruction not contiguous with end of atom!");
21042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson  if (Address > End)
22042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson    Parent->remap(this, Begin, End+Size);
23042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson
24042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson  Text.push_back(std::make_pair(Address, I));
25042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson}
26042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson
27042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Andersonvoid MCAtom::addData(const MCData &D) {
28042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson  assert(Type == DataAtom && "Trying to add MCData to a non-data atom!");
29042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson  Parent->remap(this, Begin, End+1);
30042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson
31042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson  Data.push_back(D);
32042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson}
33042aadd8ee1e532e7ef7b6c3d42bcc94e7a6f156Owen Anderson
34124e1821033a4b3220f552229652d9460ed90673Owen AndersonMCAtom *MCAtom::split(uint64_t SplitPt) {
35124e1821033a4b3220f552229652d9460ed90673Owen Anderson  assert((SplitPt > Begin && SplitPt <= End) &&
36124e1821033a4b3220f552229652d9460ed90673Owen Anderson         "Splitting at point not contained in atom!");
37124e1821033a4b3220f552229652d9460ed90673Owen Anderson
38124e1821033a4b3220f552229652d9460ed90673Owen Anderson  // Compute the new begin/end points.
39124e1821033a4b3220f552229652d9460ed90673Owen Anderson  uint64_t LeftBegin = Begin;
40124e1821033a4b3220f552229652d9460ed90673Owen Anderson  uint64_t LeftEnd = SplitPt - 1;
41124e1821033a4b3220f552229652d9460ed90673Owen Anderson  uint64_t RightBegin = SplitPt;
42124e1821033a4b3220f552229652d9460ed90673Owen Anderson  uint64_t RightEnd = End;
43124e1821033a4b3220f552229652d9460ed90673Owen Anderson
44124e1821033a4b3220f552229652d9460ed90673Owen Anderson  // Remap this atom to become the lower of the two new ones.
45124e1821033a4b3220f552229652d9460ed90673Owen Anderson  Parent->remap(this, LeftBegin, LeftEnd);
46124e1821033a4b3220f552229652d9460ed90673Owen Anderson
47124e1821033a4b3220f552229652d9460ed90673Owen Anderson  // Create a new atom for the higher atom.
48124e1821033a4b3220f552229652d9460ed90673Owen Anderson  MCAtom *RightAtom = Parent->createAtom(Type, RightBegin, RightEnd);
49124e1821033a4b3220f552229652d9460ed90673Owen Anderson
50124e1821033a4b3220f552229652d9460ed90673Owen Anderson  // Split the contents of the original atom between it and the new one.  The
51124e1821033a4b3220f552229652d9460ed90673Owen Anderson  // precise method depends on whether this is a data or a text atom.
52124e1821033a4b3220f552229652d9460ed90673Owen Anderson  if (isDataAtom()) {
53124e1821033a4b3220f552229652d9460ed90673Owen Anderson    std::vector<MCData>::iterator I = Data.begin() + (RightBegin - LeftBegin);
54124e1821033a4b3220f552229652d9460ed90673Owen Anderson
55124e1821033a4b3220f552229652d9460ed90673Owen Anderson    assert(I != Data.end() && "Split point not found in range!");
56124e1821033a4b3220f552229652d9460ed90673Owen Anderson
57124e1821033a4b3220f552229652d9460ed90673Owen Anderson    std::copy(I, Data.end(), RightAtom->Data.end());
58124e1821033a4b3220f552229652d9460ed90673Owen Anderson    Data.erase(I, Data.end());
59124e1821033a4b3220f552229652d9460ed90673Owen Anderson  } else if (isTextAtom()) {
60124e1821033a4b3220f552229652d9460ed90673Owen Anderson    std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin();
61124e1821033a4b3220f552229652d9460ed90673Owen Anderson
62124e1821033a4b3220f552229652d9460ed90673Owen Anderson    while (I != Text.end() && I->first < SplitPt) ++I;
63124e1821033a4b3220f552229652d9460ed90673Owen Anderson
64124e1821033a4b3220f552229652d9460ed90673Owen Anderson    assert(I != Text.end() && "Split point not found in disassembly!");
65124e1821033a4b3220f552229652d9460ed90673Owen Anderson    assert(I->first == SplitPt &&
66124e1821033a4b3220f552229652d9460ed90673Owen Anderson           "Split point does not fall on instruction boundary!");
67124e1821033a4b3220f552229652d9460ed90673Owen Anderson
68124e1821033a4b3220f552229652d9460ed90673Owen Anderson    std::copy(I, Text.end(), RightAtom->Text.end());
69124e1821033a4b3220f552229652d9460ed90673Owen Anderson    Text.erase(I, Text.end());
70124e1821033a4b3220f552229652d9460ed90673Owen Anderson  } else
71124e1821033a4b3220f552229652d9460ed90673Owen Anderson    llvm_unreachable("Unknown atom type!");
72124e1821033a4b3220f552229652d9460ed90673Owen Anderson
73124e1821033a4b3220f552229652d9460ed90673Owen Anderson  return RightAtom;
74124e1821033a4b3220f552229652d9460ed90673Owen Anderson}
75124e1821033a4b3220f552229652d9460ed90673Owen Anderson
76124e1821033a4b3220f552229652d9460ed90673Owen Andersonvoid MCAtom::truncate(uint64_t TruncPt) {
77124e1821033a4b3220f552229652d9460ed90673Owen Anderson  assert((TruncPt >= Begin && TruncPt < End) &&
78124e1821033a4b3220f552229652d9460ed90673Owen Anderson         "Truncation point not contained in atom!");
79124e1821033a4b3220f552229652d9460ed90673Owen Anderson
80124e1821033a4b3220f552229652d9460ed90673Owen Anderson  Parent->remap(this, Begin, TruncPt);
81124e1821033a4b3220f552229652d9460ed90673Owen Anderson
82124e1821033a4b3220f552229652d9460ed90673Owen Anderson  if (isDataAtom()) {
83124e1821033a4b3220f552229652d9460ed90673Owen Anderson    Data.resize(TruncPt - Begin + 1);
84124e1821033a4b3220f552229652d9460ed90673Owen Anderson  } else if (isTextAtom()) {
85124e1821033a4b3220f552229652d9460ed90673Owen Anderson    std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin();
86124e1821033a4b3220f552229652d9460ed90673Owen Anderson
87124e1821033a4b3220f552229652d9460ed90673Owen Anderson    while (I != Text.end() && I->first <= TruncPt) ++I;
88124e1821033a4b3220f552229652d9460ed90673Owen Anderson
89124e1821033a4b3220f552229652d9460ed90673Owen Anderson    assert(I != Text.end() && "Truncation point not found in disassembly!");
90124e1821033a4b3220f552229652d9460ed90673Owen Anderson    assert(I->first == TruncPt+1 &&
91124e1821033a4b3220f552229652d9460ed90673Owen Anderson           "Truncation point does not fall on instruction boundary");
92124e1821033a4b3220f552229652d9460ed90673Owen Anderson
93124e1821033a4b3220f552229652d9460ed90673Owen Anderson    Text.erase(I, Text.end());
94124e1821033a4b3220f552229652d9460ed90673Owen Anderson  } else
95124e1821033a4b3220f552229652d9460ed90673Owen Anderson    llvm_unreachable("Unknown atom type!");
96124e1821033a4b3220f552229652d9460ed90673Owen Anderson}
97124e1821033a4b3220f552229652d9460ed90673Owen Anderson
98