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