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 
     14 using namespace llvm;
     15 
     16 void 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 
     27 void 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 
     34 MCAtom *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 
     76 void 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 
     98