Home | History | Annotate | Download | only in MC
      1 //===- 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 #include <iterator>
     14 
     15 using namespace llvm;
     16 
     17 void MCAtom::remap(uint64_t NewBegin, uint64_t NewEnd) {
     18   Parent->remap(this, NewBegin, NewEnd);
     19 }
     20 
     21 void MCAtom::remapForTruncate(uint64_t TruncPt) {
     22   assert((TruncPt >= Begin && TruncPt < End) &&
     23          "Truncation point not contained in atom!");
     24   remap(Begin, TruncPt);
     25 }
     26 
     27 void MCAtom::remapForSplit(uint64_t SplitPt,
     28                            uint64_t &LBegin, uint64_t &LEnd,
     29                            uint64_t &RBegin, uint64_t &REnd) {
     30   assert((SplitPt > Begin && SplitPt <= End) &&
     31          "Splitting at point not contained in atom!");
     32 
     33   // Compute the new begin/end points.
     34   LBegin = Begin;
     35   LEnd = SplitPt - 1;
     36   RBegin = SplitPt;
     37   REnd = End;
     38 
     39   // Remap this atom to become the lower of the two new ones.
     40   remap(LBegin, LEnd);
     41 }
     42 
     43 // MCDataAtom
     44 
     45 void MCDataAtom::addData(const MCData &D) {
     46   Data.push_back(D);
     47   if (Data.size() > Begin - End)
     48     remap(Begin, End + 1);
     49 }
     50 
     51 void MCDataAtom::truncate(uint64_t TruncPt) {
     52   remapForTruncate(TruncPt);
     53 
     54   Data.resize(TruncPt - Begin + 1);
     55 }
     56 
     57 MCDataAtom *MCDataAtom::split(uint64_t SplitPt) {
     58   uint64_t LBegin, LEnd, RBegin, REnd;
     59   remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd);
     60 
     61   MCDataAtom *RightAtom = Parent->createDataAtom(RBegin, REnd);
     62   RightAtom->setName(getName());
     63 
     64   std::vector<MCData>::iterator I = Data.begin() + (RBegin - LBegin);
     65   assert(I != Data.end() && "Split point not found in range!");
     66 
     67   std::copy(I, Data.end(), std::back_inserter(RightAtom->Data));
     68   Data.erase(I, Data.end());
     69   return RightAtom;
     70 }
     71 
     72 // MCTextAtom
     73 
     74 void 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;
     79 }
     80 
     81 void 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 
     94 MCTextAtom *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 }
    111