[Orc] Add explicit move construction/assignment to RCMemoryManager.
[oota-llvm.git] / include / llvm / MC / MCInst.h
1 //===-- llvm/MC/MCInst.h - MCInst class -------------------------*- 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 MCInst and MCOperand classes, which
11 // is the basic representation used to represent low-level machine code
12 // instructions.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_MC_MCINST_H
17 #define LLVM_MC_MCINST_H
18
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/DataTypes.h"
22 #include "llvm/Support/SMLoc.h"
23
24 namespace llvm {
25 class raw_ostream;
26 class MCAsmInfo;
27 class MCInstPrinter;
28 class MCExpr;
29 class MCInst;
30
31 /// \brief Instances of this class represent operands of the MCInst class.
32 /// This is a simple discriminated union.
33 class MCOperand {
34   enum MachineOperandType : unsigned char {
35     kInvalid,     ///< Uninitialized.
36     kRegister,    ///< Register operand.
37     kImmediate,   ///< Immediate operand.
38     kFPImmediate, ///< Floating-point immediate operand.
39     kExpr,        ///< Relocatable immediate operand.
40     kInst         ///< Sub-instruction operand.
41   };
42   MachineOperandType Kind;
43
44   union {
45     unsigned RegVal;
46     int64_t ImmVal;
47     double FPImmVal;
48     const MCExpr *ExprVal;
49     const MCInst *InstVal;
50   };
51
52 public:
53   MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
54
55   bool isValid() const { return Kind != kInvalid; }
56   bool isReg() const { return Kind == kRegister; }
57   bool isImm() const { return Kind == kImmediate; }
58   bool isFPImm() const { return Kind == kFPImmediate; }
59   bool isExpr() const { return Kind == kExpr; }
60   bool isInst() const { return Kind == kInst; }
61
62   /// \brief Returns the register number.
63   unsigned getReg() const {
64     assert(isReg() && "This is not a register operand!");
65     return RegVal;
66   }
67
68   /// \brief Set the register number.
69   void setReg(unsigned Reg) {
70     assert(isReg() && "This is not a register operand!");
71     RegVal = Reg;
72   }
73
74   int64_t getImm() const {
75     assert(isImm() && "This is not an immediate");
76     return ImmVal;
77   }
78   void setImm(int64_t Val) {
79     assert(isImm() && "This is not an immediate");
80     ImmVal = Val;
81   }
82
83   double getFPImm() const {
84     assert(isFPImm() && "This is not an FP immediate");
85     return FPImmVal;
86   }
87
88   void setFPImm(double Val) {
89     assert(isFPImm() && "This is not an FP immediate");
90     FPImmVal = Val;
91   }
92
93   const MCExpr *getExpr() const {
94     assert(isExpr() && "This is not an expression");
95     return ExprVal;
96   }
97   void setExpr(const MCExpr *Val) {
98     assert(isExpr() && "This is not an expression");
99     ExprVal = Val;
100   }
101
102   const MCInst *getInst() const {
103     assert(isInst() && "This is not a sub-instruction");
104     return InstVal;
105   }
106   void setInst(const MCInst *Val) {
107     assert(isInst() && "This is not a sub-instruction");
108     InstVal = Val;
109   }
110
111   static MCOperand createReg(unsigned Reg) {
112     MCOperand Op;
113     Op.Kind = kRegister;
114     Op.RegVal = Reg;
115     return Op;
116   }
117   static MCOperand createImm(int64_t Val) {
118     MCOperand Op;
119     Op.Kind = kImmediate;
120     Op.ImmVal = Val;
121     return Op;
122   }
123   static MCOperand createFPImm(double Val) {
124     MCOperand Op;
125     Op.Kind = kFPImmediate;
126     Op.FPImmVal = Val;
127     return Op;
128   }
129   static MCOperand createExpr(const MCExpr *Val) {
130     MCOperand Op;
131     Op.Kind = kExpr;
132     Op.ExprVal = Val;
133     return Op;
134   }
135   static MCOperand createInst(const MCInst *Val) {
136     MCOperand Op;
137     Op.Kind = kInst;
138     Op.InstVal = Val;
139     return Op;
140   }
141
142   void print(raw_ostream &OS) const;
143   void dump() const;
144 };
145
146 template <> struct isPodLike<MCOperand> { static const bool value = true; };
147
148 /// \brief Instances of this class represent a single low-level machine
149 /// instruction.
150 class MCInst {
151   unsigned Opcode;
152   SMLoc Loc;
153   SmallVector<MCOperand, 8> Operands;
154
155 public:
156   MCInst() : Opcode(0) {}
157
158   void setOpcode(unsigned Op) { Opcode = Op; }
159   unsigned getOpcode() const { return Opcode; }
160
161   void setLoc(SMLoc loc) { Loc = loc; }
162   SMLoc getLoc() const { return Loc; }
163
164   const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
165   MCOperand &getOperand(unsigned i) { return Operands[i]; }
166   unsigned getNumOperands() const { return Operands.size(); }
167
168   void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
169
170   typedef SmallVectorImpl<MCOperand>::iterator iterator;
171   typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator;
172   void clear() { Operands.clear(); }
173   void erase(iterator I) { Operands.erase(I); }
174   size_t size() const { return Operands.size(); }
175   iterator begin() { return Operands.begin(); }
176   const_iterator begin() const { return Operands.begin(); }
177   iterator end() { return Operands.end(); }
178   const_iterator end() const { return Operands.end(); }
179   iterator insert(iterator I, const MCOperand &Op) {
180     return Operands.insert(I, Op);
181   }
182
183   void print(raw_ostream &OS) const;
184   void dump() const;
185
186   /// \brief Dump the MCInst as prettily as possible using the additional MC
187   /// structures, if given. Operators are separated by the \p Separator
188   /// string.
189   void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
190                    StringRef Separator = " ") const;
191 };
192
193 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
194   MO.print(OS);
195   return OS;
196 }
197
198 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
199   MI.print(OS);
200   return OS;
201 }
202
203 } // end namespace llvm
204
205 #endif