a092fb45d8992a99c36d122dbfdfe8db0e3b5841
[oota-llvm.git] / include / llvm / CodeGen / MachineOperand.h
1 //===-- llvm/CodeGen/MachineOperand.h - MachineOperand 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 MachineOperand class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CODEGEN_MACHINEOPERAND_H
15 #define LLVM_CODEGEN_MACHINEOPERAND_H
16
17 #include "llvm/Support/DataTypes.h"
18 #include <vector>
19 #include <cassert>
20 #include <iosfwd>
21
22 namespace llvm {
23   
24 class MachineBasicBlock;
25 class GlobalValue;
26   class MachineInstr;
27   
28 /// MachineOperand class - Representation of each machine instruction operand.
29 ///
30 class MachineOperand {
31 public:
32   enum MachineOperandType {
33     MO_Register,                // Register operand.
34     MO_Immediate,               // Immediate Operand
35     MO_MachineBasicBlock,       // MachineBasicBlock reference
36     MO_FrameIndex,              // Abstract Stack Frame Index
37     MO_ConstantPoolIndex,       // Address of indexed Constant in Constant Pool
38     MO_JumpTableIndex,          // Address of indexed Jump Table for switch
39     MO_ExternalSymbol,          // Name of external global symbol
40     MO_GlobalAddress            // Address of a global value
41   };
42
43 private:
44   union {
45     GlobalValue *GV;          // For MO_GlobalAddress.
46     MachineBasicBlock *MBB;   // For MO_MachineBasicBlock.
47     const char *SymbolName;   // For MO_ExternalSymbol.
48     unsigned RegNo;           // For MO_Register.
49     int64_t immedVal;         // For MO_Immediate and MO_*Index.
50   } contents;
51
52   /// ParentMI - This is the instruction that this operand is embedded into.
53   MachineInstr *ParentMI;
54   
55   MachineOperandType opType:8; // Discriminate the union.
56   bool IsDef : 1;              // True if this is a def, false if this is a use.
57   bool IsImp : 1;              // True if this is an implicit def or use.
58
59   bool IsKill : 1;             // True if this is a reg use and the reg is dead
60                                // immediately after the read.
61   bool IsDead : 1;             // True if this is a reg def and the reg is dead
62                                // immediately after the write. i.e. A register
63                                // that is defined but never used.
64   
65   /// auxInfo - auxiliary information used by the MachineOperand
66   union {
67     /// offset - Offset to address of global or external, only valid for
68     /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
69     int offset;
70
71     /// subReg - SubRegister number, only valid for MO_Register.  A value of 0
72     /// indicates the MO_Register has no subReg.
73     unsigned char subReg;
74   } auxInfo;
75   
76   MachineOperand() : ParentMI(0) {}
77
78   void print(std::ostream &os) const;
79   void print(std::ostream *os) const { if (os) print(*os); }
80
81 public:
82   MachineOperand(const MachineOperand &M) {
83     *this = M;
84   }
85   
86   ~MachineOperand() {}
87   
88   /// getType - Returns the MachineOperandType for this operand.
89   ///
90   MachineOperandType getType() const { return opType; }
91
92   /// Accessors that tell you what kind of MachineOperand you're looking at.
93   ///
94   bool isRegister() const { return opType == MO_Register; }
95   bool isImmediate() const { return opType == MO_Immediate; }
96   bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
97   bool isFrameIndex() const { return opType == MO_FrameIndex; }
98   bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; }
99   bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; }
100   bool isGlobalAddress() const { return opType == MO_GlobalAddress; }
101   bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
102
103   int64_t getImm() const {
104     assert(isImmediate() && "Wrong MachineOperand accessor");
105     return contents.immedVal;
106   }
107   
108   int64_t getImmedValue() const {
109     assert(isImmediate() && "Wrong MachineOperand accessor");
110     return contents.immedVal;
111   }
112   MachineBasicBlock *getMBB() const {
113     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
114     return contents.MBB;
115   }
116   MachineBasicBlock *getMachineBasicBlock() const {
117     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
118     return contents.MBB;
119   }
120   void setMachineBasicBlock(MachineBasicBlock *MBB) {
121     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
122     contents.MBB = MBB;
123   }
124   int getFrameIndex() const {
125     assert(isFrameIndex() && "Wrong MachineOperand accessor");
126     return (int)contents.immedVal;
127   }
128   unsigned getConstantPoolIndex() const {
129     assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
130     return (unsigned)contents.immedVal;
131   }
132   unsigned getJumpTableIndex() const {
133     assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
134     return (unsigned)contents.immedVal;
135   }
136   GlobalValue *getGlobal() const {
137     assert(isGlobalAddress() && "Wrong MachineOperand accessor");
138     return contents.GV;
139   }
140   int getOffset() const {
141     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
142         "Wrong MachineOperand accessor");
143     return auxInfo.offset;
144   }
145   unsigned getSubReg() const {
146     assert(isRegister() && "Wrong MachineOperand accessor");
147     return (unsigned)auxInfo.subReg;
148   }
149   const char *getSymbolName() const {
150     assert(isExternalSymbol() && "Wrong MachineOperand accessor");
151     return contents.SymbolName;
152   }
153
154   bool isUse() const { 
155     assert(isRegister() && "Wrong MachineOperand accessor");
156     return !IsDef;
157   }
158   bool isDef() const {
159     assert(isRegister() && "Wrong MachineOperand accessor");
160     return IsDef;
161   }
162   void setIsUse() {
163     assert(isRegister() && "Wrong MachineOperand accessor");
164     IsDef = false;
165   }
166   void setIsDef() {
167     assert(isRegister() && "Wrong MachineOperand accessor");
168     IsDef = true;
169   }
170
171   bool isImplicit() const { 
172     assert(isRegister() && "Wrong MachineOperand accessor");
173     return IsImp;
174   }
175   void setImplicit() { 
176     assert(isRegister() && "Wrong MachineOperand accessor");
177     IsImp = true;
178   }
179
180   bool isKill() const {
181     assert(isRegister() && "Wrong MachineOperand accessor");
182     return IsKill;
183   }
184   bool isDead() const {
185     assert(isRegister() && "Wrong MachineOperand accessor");
186     return IsDead;
187   }
188   void setIsKill() {
189     assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
190     IsKill = true;
191   }
192   void setIsDead() {
193     assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
194     IsDead = true;
195   }
196   void unsetIsKill() {
197     assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
198     IsKill = false;
199   }
200   void unsetIsDead() {
201     assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
202     IsDead = false;
203   }
204
205   /// getReg - Returns the register number.
206   ///
207   unsigned getReg() const {
208     assert(isRegister() && "This is not a register operand!");
209     return contents.RegNo;
210   }
211
212   /// MachineOperand mutators.
213   ///
214   void setReg(unsigned Reg) {
215     assert(isRegister() && "This is not a register operand!");
216     contents.RegNo = Reg;
217   }
218
219   void setImmedValue(int64_t immVal) {
220     assert(isImmediate() && "Wrong MachineOperand mutator");
221     contents.immedVal = immVal;
222   }
223   void setImm(int64_t immVal) {
224     assert(isImmediate() && "Wrong MachineOperand mutator");
225     contents.immedVal = immVal;
226   }
227
228   void setOffset(int Offset) {
229     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
230             isJumpTableIndex()) &&
231         "Wrong MachineOperand accessor");
232     auxInfo.offset = Offset;
233   }
234   void setSubReg(unsigned subReg) {
235     assert(isRegister() && "Wrong MachineOperand accessor");
236     auxInfo.subReg = (unsigned char)subReg;
237   }
238   void setConstantPoolIndex(unsigned Idx) {
239     assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
240     contents.immedVal = Idx;
241   }
242   void setJumpTableIndex(unsigned Idx) {
243     assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
244     contents.immedVal = Idx;
245   }
246   
247   /// isIdenticalTo - Return true if this operand is identical to the specified
248   /// operand. Note: This method ignores isKill and isDead properties.
249   bool isIdenticalTo(const MachineOperand &Other) const;
250   
251   /// ChangeToImmediate - Replace this operand with a new immediate operand of
252   /// the specified value.  If an operand is known to be an immediate already,
253   /// the setImmedValue method should be used.
254   void ChangeToImmediate(int64_t ImmVal) {
255     opType = MO_Immediate;
256     contents.immedVal = ImmVal;
257   }
258
259   /// ChangeToRegister - Replace this operand with a new register operand of
260   /// the specified value.  If an operand is known to be an register already,
261   /// the setReg method should be used.
262   void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
263                         bool isKill = false, bool isDead = false) {
264     opType = MO_Register;
265     contents.RegNo = Reg;
266     IsDef = isDef;
267     IsImp = isImp;
268     IsKill = isKill;
269     IsDead = isDead;
270   }
271   
272   static MachineOperand CreateImm(int64_t Val) {
273     MachineOperand Op;
274     Op.opType = MachineOperand::MO_Immediate;
275     Op.contents.immedVal = Val;
276     Op.auxInfo.offset = 0;
277     return Op;
278   }
279   static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
280                                   bool isKill = false, bool isDead = false,
281                                   unsigned SubReg = 0) {
282     MachineOperand Op;
283     Op.opType = MachineOperand::MO_Register;
284     Op.IsDef = isDef;
285     Op.IsImp = isImp;
286     Op.IsKill = isKill;
287     Op.IsDead = isDead;
288     Op.contents.RegNo = Reg;
289     Op.auxInfo.subReg = SubReg;
290     return Op;
291   }
292   static MachineOperand CreateMBB(MachineBasicBlock *MBB) {
293     MachineOperand Op;
294     Op.opType = MachineOperand::MO_MachineBasicBlock;
295     Op.contents.MBB = MBB;
296     Op.auxInfo.offset = 0;
297     return Op;
298   }
299   static MachineOperand CreateFI(unsigned Idx) {
300     MachineOperand Op;
301     Op.opType = MachineOperand::MO_FrameIndex;
302     Op.contents.immedVal = Idx;
303     Op.auxInfo.offset = 0;
304     return Op;
305   }
306   static MachineOperand CreateCPI(unsigned Idx, int Offset) {
307     MachineOperand Op;
308     Op.opType = MachineOperand::MO_ConstantPoolIndex;
309     Op.contents.immedVal = Idx;
310     Op.auxInfo.offset = Offset;
311     return Op;
312   }
313   static MachineOperand CreateJTI(unsigned Idx) {
314     MachineOperand Op;
315     Op.opType = MachineOperand::MO_JumpTableIndex;
316     Op.contents.immedVal = Idx;
317     Op.auxInfo.offset = 0;
318     return Op;
319   }
320   static MachineOperand CreateGA(GlobalValue *GV, int Offset) {
321     MachineOperand Op;
322     Op.opType = MachineOperand::MO_GlobalAddress;
323     Op.contents.GV = GV;
324     Op.auxInfo.offset = Offset;
325     return Op;
326   }
327   static MachineOperand CreateES(const char *SymName, int Offset = 0) {
328     MachineOperand Op;
329     Op.opType = MachineOperand::MO_ExternalSymbol;
330     Op.contents.SymbolName = SymName;
331     Op.auxInfo.offset = Offset;
332     return Op;
333   }
334   const MachineOperand &operator=(const MachineOperand &MO) {
335     contents = MO.contents;
336     IsDef    = MO.IsDef;
337     IsImp    = MO.IsImp;
338     IsKill   = MO.IsKill;
339     IsDead   = MO.IsDead;
340     opType   = MO.opType;
341     auxInfo  = MO.auxInfo;
342     ParentMI = MO.ParentMI;
343     return *this;
344   }
345
346   friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop) {
347     mop.print(os);
348     return os;
349   }
350
351   friend class MachineInstr;
352 };
353
354 std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO);
355
356 } // End llvm namespace
357
358 #endif