Revert r194865 and r194874.
[oota-llvm.git] / include / llvm / MC / MCAtom.h
1 //===-- llvm/MC/MCAtom.h ----------------------------------------*- C++ -*-===//
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 // This file contains the declaration of the MCAtom class, which is used to
11 // represent a contiguous region in a decoded object that is uniformly data or
12 // instructions.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_MC_MCATOM_H
17 #define LLVM_MC_MCATOM_H
18
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/Support/DataTypes.h"
22 #include <vector>
23
24 namespace llvm {
25
26 class MCModule;
27
28 class MCAtom;
29 class MCTextAtom;
30 class MCDataAtom;
31
32 /// \brief Represents a contiguous range of either instructions (a TextAtom)
33 /// or data (a DataAtom).  Address ranges are expressed as _closed_ intervals.
34 class MCAtom {
35 public:
36   virtual ~MCAtom() {}
37
38   enum AtomKind { TextAtom, DataAtom };
39   AtomKind getKind() const { return Kind; }
40
41   /// \brief Get the start address of the atom.
42   uint64_t getBeginAddr() const { return Begin; }
43   /// \brief Get the end address, i.e. the last one inside the atom.
44   uint64_t getEndAddr() const { return End; }
45
46   /// \name Atom modification methods:
47   /// When modifying a TextAtom, keep instruction boundaries in mind.
48   /// For instance, split must me given the start address of an instruction.
49   /// @{
50
51   /// \brief Splits the atom in two at a given address.
52   /// \param SplitPt Address at which to start a new atom, splitting this one.
53   /// \returns The newly created atom starting at \p SplitPt.
54   virtual MCAtom *split(uint64_t SplitPt) = 0;
55
56   /// \brief Truncates an atom, discarding everything after \p TruncPt.
57   /// \param TruncPt Last byte address to be contained in this atom.
58   virtual void truncate(uint64_t TruncPt) = 0;
59   /// @}
60
61   /// \name Naming:
62   ///
63   /// This is mostly for display purposes, and may contain anything that hints
64   /// at what the atom contains: section or symbol name, BB start address, ..
65   /// @{
66   StringRef getName() const { return Name; }
67   void setName(StringRef NewName) { Name = NewName.str(); }
68   /// @}
69
70 protected:
71   const AtomKind Kind;
72   std::string Name;
73   MCModule *Parent;
74   uint64_t Begin, End;
75
76   friend class MCModule;
77   MCAtom(AtomKind K, MCModule *P, uint64_t B, uint64_t E)
78     : Kind(K), Name("(unknown)"), Parent(P), Begin(B), End(E) { }
79
80   /// \name Atom remapping helpers
81   /// @{
82
83   /// \brief Remap the atom, using the given range, updating Begin/End.
84   /// One or both of the bounds can remain the same, but overlapping with other
85   /// atoms in the module is still forbidden.
86   void remap(uint64_t NewBegin, uint64_t NewEnd);
87
88   /// \brief Remap the atom to prepare for a truncation at TruncPt.
89   /// Equivalent to:
90   /// \code
91   ///   // Bound checks
92   ///   remap(Begin, TruncPt);
93   /// \endcode
94   void remapForTruncate(uint64_t TruncPt);
95
96   /// \brief Remap the atom to prepare for a split at SplitPt.
97   /// The bounds for the resulting atoms are returned in {L,R}{Begin,End}.
98   /// The current atom is truncated to \p LEnd.
99   void remapForSplit(uint64_t SplitPt,
100                      uint64_t &LBegin, uint64_t &LEnd,
101                      uint64_t &RBegin, uint64_t &REnd);
102   /// @}
103 };
104
105 /// \name Text atom
106 /// @{
107
108 /// \brief An entry in an MCTextAtom: a disassembled instruction.
109 /// NOTE: Both the Address and Size field are actually redundant when taken in
110 /// the context of the text atom, and may better be exposed in an iterator
111 /// instead of stored in the atom, which would replace this class.
112 class MCDecodedInst {
113 public:
114   MCInst Inst;
115   uint64_t Address;
116   uint64_t Size;
117   MCDecodedInst(const MCInst &Inst, uint64_t Address, uint64_t Size)
118     : Inst(Inst), Address(Address), Size(Size) {}
119 };
120
121 /// \brief An atom consisting of disassembled instructions.
122 class MCTextAtom : public MCAtom {
123 private:
124   typedef std::vector<MCDecodedInst> InstListTy;
125   InstListTy Insts;
126
127   /// \brief The address of the next appended instruction, i.e., the
128   /// address immediately after the last instruction in the atom.
129   uint64_t NextInstAddress;
130 public:
131   /// Append an instruction, expanding the atom if necessary.
132   void addInst(const MCInst &Inst, uint64_t Size);
133
134   /// \name Instruction list access
135   /// @{
136   typedef InstListTy::const_iterator const_iterator;
137   const_iterator begin() const { return Insts.begin(); }
138   const_iterator end()   const { return Insts.end(); }
139
140   const MCDecodedInst &back() const { return Insts.back(); }
141   const MCDecodedInst &at(size_t n) const { return Insts.at(n); }
142   size_t size() const { return Insts.size(); }
143   /// @}
144
145   /// \name Atom type specific split/truncate logic.
146   /// @{
147   MCTextAtom *split(uint64_t SplitPt) LLVM_OVERRIDE;
148   void     truncate(uint64_t TruncPt) LLVM_OVERRIDE;
149   /// @}
150
151   // Class hierarchy.
152   static bool classof(const MCAtom *A) { return A->getKind() == TextAtom; }
153 private:
154   friend class MCModule;
155   // Private constructor - only callable by MCModule
156   MCTextAtom(MCModule *P, uint64_t Begin, uint64_t End)
157     : MCAtom(TextAtom, P, Begin, End), NextInstAddress(Begin) {}
158 };
159 /// @}
160
161 /// \name Data atom
162 /// @{
163
164 /// \brief An entry in an MCDataAtom.
165 // NOTE: This may change to a more complex type in the future.
166 typedef uint8_t MCData;
167
168 /// \brief An atom consising of a sequence of bytes.
169 class MCDataAtom : public MCAtom {
170   std::vector<MCData> Data;
171
172 public:
173   /// Append a data entry, expanding the atom if necessary.
174   void addData(const MCData &D);
175
176   /// Get a reference to the data in this atom.
177   ArrayRef<MCData> getData() const { return Data; }
178
179   /// \name Atom type specific split/truncate logic.
180   /// @{
181   MCDataAtom *split(uint64_t SplitPt) LLVM_OVERRIDE;
182   void     truncate(uint64_t TruncPt) LLVM_OVERRIDE;
183   /// @}
184
185   // Class hierarchy.
186   static bool classof(const MCAtom *A) { return A->getKind() == DataAtom; }
187 private:
188   friend class MCModule;
189   // Private constructor - only callable by MCModule
190   MCDataAtom(MCModule *P, uint64_t Begin, uint64_t End)
191     : MCAtom(DataAtom, P, Begin, End) {
192     Data.reserve(End + 1 - Begin);
193   }
194 };
195
196 }
197
198 #endif