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