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