119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- lib/MC/MCAtom.cpp - MCAtom implementation --------------------------===// 219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// The LLVM Compiler Infrastructure 419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source 619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details. 719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCAtom.h" 1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCModule.h" 1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ErrorHandling.h" 1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm; 1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCAtom::addInst(const MCInst &I, uint64_t Address, unsigned Size) { 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Type == TextAtom && "Trying to add MCInst to a non-text atom!"); 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Address < End+Size && 2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Instruction not contiguous with end of atom!"); 2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Address > End) 2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Parent->remap(this, Begin, End+Size); 2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Text.push_back(std::make_pair(Address, I)); 2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCAtom::addData(const MCData &D) { 2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Type == DataAtom && "Trying to add MCData to a non-data atom!"); 2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Parent->remap(this, Begin, End+1); 3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Data.push_back(D); 3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMCAtom *MCAtom::split(uint64_t SplitPt) { 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert((SplitPt > Begin && SplitPt <= End) && 3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Splitting at point not contained in atom!"); 3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Compute the new begin/end points. 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uint64_t LeftBegin = Begin; 4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uint64_t LeftEnd = SplitPt - 1; 4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uint64_t RightBegin = SplitPt; 4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman uint64_t RightEnd = End; 4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Remap this atom to become the lower of the two new ones. 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Parent->remap(this, LeftBegin, LeftEnd); 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Create a new atom for the higher atom. 4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCAtom *RightAtom = Parent->createAtom(Type, RightBegin, RightEnd); 4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Split the contents of the original atom between it and the new one. The 5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // precise method depends on whether this is a data or a text atom. 5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isDataAtom()) { 5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<MCData>::iterator I = Data.begin() + (RightBegin - LeftBegin); 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(I != Data.end() && "Split point not found in range!"); 5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::copy(I, Data.end(), RightAtom->Data.end()); 5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Data.erase(I, Data.end()); 5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (isTextAtom()) { 6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin(); 6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman while (I != Text.end() && I->first < SplitPt) ++I; 6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(I != Text.end() && "Split point not found in disassembly!"); 6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(I->first == SplitPt && 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Split point does not fall on instruction boundary!"); 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::copy(I, Text.end(), RightAtom->Text.end()); 6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Text.erase(I, Text.end()); 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else 7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm_unreachable("Unknown atom type!"); 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return RightAtom; 7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCAtom::truncate(uint64_t TruncPt) { 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert((TruncPt >= Begin && TruncPt < End) && 7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Truncation point not contained in atom!"); 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Parent->remap(this, Begin, TruncPt); 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isDataAtom()) { 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Data.resize(TruncPt - Begin + 1); 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (isTextAtom()) { 8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin(); 8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman while (I != Text.end() && I->first <= TruncPt) ++I; 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(I != Text.end() && "Truncation point not found in disassembly!"); 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(I->first == TruncPt+1 && 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Truncation point does not fall on instruction boundary"); 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Text.erase(I, Text.end()); 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm_unreachable("Unknown atom type!"); 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 98