ADd getImm/setImm methods
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
1 //===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the declaration of the MachineInstr class, which is the
11 // basic representation for all target dependent machine instructions used by
12 // the back end.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
17 #define LLVM_CODEGEN_MACHINEINSTR_H
18
19 #include "llvm/ADT/iterator"
20 #include "llvm/Support/DataTypes.h"
21 #include <vector>
22 #include <cassert>
23
24 namespace llvm {
25
26 class Value;
27 class Function;
28 class MachineBasicBlock;
29 class TargetMachine;
30 class GlobalValue;
31
32 template <typename T> struct ilist_traits;
33 template <typename T> struct ilist;
34
35 //===----------------------------------------------------------------------===//
36 // class MachineOperand
37 //
38 //   Representation of each machine instruction operand.
39 //
40 struct MachineOperand {
41 private:
42   // Bit fields of the flags variable used for different operand properties
43   enum {
44     DEFFLAG     = 0x01,       // this is a def of the operand
45     USEFLAG     = 0x02        // this is a use of the operand
46   };
47
48 public:
49   // UseType - This enum describes how the machine operand is used by
50   // the instruction. Note that the MachineInstr/Operator class
51   // currently uses bool arguments to represent this information
52   // instead of an enum.  Eventually this should change over to use
53   // this _easier to read_ representation instead.
54   //
55   enum UseType {
56     Use = USEFLAG,        /// only read
57     Def = DEFFLAG,        /// only written
58     UseAndDef = Use | Def /// read AND written
59   };
60
61   enum MachineOperandType {
62     MO_Register,                // Register operand.
63     MO_Immediate,               // Immediate Operand
64     MO_MachineBasicBlock,       // MachineBasicBlock reference
65     MO_FrameIndex,              // Abstract Stack Frame Index
66     MO_ConstantPoolIndex,       // Address of indexed Constant in Constant Pool
67     MO_JumpTableIndex,          // Address of indexed Jump Table for switch
68     MO_ExternalSymbol,          // Name of external global symbol
69     MO_GlobalAddress            // Address of a global value
70   };
71
72 private:
73   union {
74     GlobalValue *GV;          // For MO_GlobalAddress.
75     MachineBasicBlock *MBB;   // For MO_MachineBasicBlock.
76     const char *SymbolName;   // For MO_ExternalSymbol.
77     unsigned RegNo;           // For MO_Register.
78     int64_t immedVal;         // For MO_Immediate and MO_*Index.
79   } contents;
80
81   char flags;                   // see bit field definitions above
82   MachineOperandType opType:8;  // Pack into 8 bits efficiently after flags.
83   
84   /// offset - Offset to address of global or external, only valid for
85   /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
86   int offset;
87
88   MachineOperand() {}
89 public:
90   MachineOperand(const MachineOperand &M) {
91     *this = M;
92   }
93
94   ~MachineOperand() {}
95
96   const MachineOperand &operator=(const MachineOperand &MO) {
97     contents = MO.contents;
98     flags    = MO.flags;
99     opType   = MO.opType;
100     offset   = MO.offset;
101     return *this;
102   }
103
104   /// getType - Returns the MachineOperandType for this operand.
105   ///
106   MachineOperandType getType() const { return opType; }
107
108   /// getUseType - Returns the MachineOperandUseType of this operand.
109   ///
110   UseType getUseType() const { return UseType(flags & (USEFLAG|DEFFLAG)); }
111
112   /// Accessors that tell you what kind of MachineOperand you're looking at.
113   ///
114   bool isReg() const { return opType == MO_Register; }
115   bool isImm() const { return opType == MO_Immediate; }
116   bool isMBB() const { return opType == MO_MachineBasicBlock; }
117   
118   bool isRegister() const { return opType == MO_Register; }
119   bool isImmediate() const { return opType == MO_Immediate; }
120   bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
121   bool isFrameIndex() const { return opType == MO_FrameIndex; }
122   bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; }
123   bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; }
124   bool isGlobalAddress() const { return opType == MO_GlobalAddress; }
125   bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
126
127   int64_t getImm() const {
128     assert(isImm() && "Wrong MachineOperand accessor");
129     return contents.immedVal;
130   }
131   
132   int64_t getImmedValue() const {
133     assert(isImm() && "Wrong MachineOperand accessor");
134     return contents.immedVal;
135   }
136   MachineBasicBlock *getMachineBasicBlock() const {
137     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
138     return contents.MBB;
139   }
140   void setMachineBasicBlock(MachineBasicBlock *MBB) {
141     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
142     contents.MBB = MBB;
143   }
144   int getFrameIndex() const {
145     assert(isFrameIndex() && "Wrong MachineOperand accessor");
146     return (int)contents.immedVal;
147   }
148   unsigned getConstantPoolIndex() const {
149     assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
150     return (unsigned)contents.immedVal;
151   }
152   unsigned getJumpTableIndex() const {
153     assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
154     return (unsigned)contents.immedVal;
155   }
156   GlobalValue *getGlobal() const {
157     assert(isGlobalAddress() && "Wrong MachineOperand accessor");
158     return contents.GV;
159   }
160   int getOffset() const {
161     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
162         "Wrong MachineOperand accessor");
163     return offset;
164   }
165   const char *getSymbolName() const {
166     assert(isExternalSymbol() && "Wrong MachineOperand accessor");
167     return contents.SymbolName;
168   }
169
170   /// MachineOperand methods for testing that work on any kind of
171   /// MachineOperand...
172   ///
173   bool isUse() const { return flags & USEFLAG; }
174   bool isDef() const { return flags & DEFFLAG; }
175   MachineOperand &setUse() { flags |= USEFLAG; return *this; }
176   MachineOperand &setDef() { flags |= DEFFLAG; return *this; }
177
178   /// getReg - Returns the register number.
179   ///
180   unsigned getReg() const {
181     assert(isRegister() && "This is not a register operand!");
182     return contents.RegNo;
183   }
184
185   /// MachineOperand mutators.
186   ///
187   void setReg(unsigned Reg) {
188     assert(isRegister() && "This is not a register operand!");
189     contents.RegNo = Reg;
190   }
191
192   void setImmedValue(int64_t immVal) {
193     assert(isImm() && "Wrong MachineOperand mutator");
194     contents.immedVal = immVal;
195   }
196   void setImm(int64_t immVal) {
197     assert(isImm() && "Wrong MachineOperand mutator");
198     contents.immedVal = immVal;
199   }
200
201   void setOffset(int Offset) {
202     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
203             isJumpTableIndex()) &&
204         "Wrong MachineOperand accessor");
205     offset = Offset;
206   }
207   
208   /// ChangeToImmediate - Replace this operand with a new immediate operand of
209   /// the specified value.  If an operand is known to be an immediate already,
210   /// the setImmedValue method should be used.
211   void ChangeToImmediate(int64_t ImmVal) {
212     opType = MO_Immediate;
213     contents.immedVal = ImmVal;
214   }
215
216   /// ChangeToRegister - Replace this operand with a new register operand of
217   /// the specified value.  If an operand is known to be an register already,
218   /// the setReg method should be used.
219   void ChangeToRegister(unsigned Reg) {
220     opType = MO_Register;
221     contents.RegNo = Reg;
222   }
223
224   friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
225
226   friend class MachineInstr;
227 };
228
229
230 //===----------------------------------------------------------------------===//
231 /// MachineInstr - Representation of each machine instruction.
232 ///
233 class MachineInstr {
234   short Opcode;                         // the opcode
235   std::vector<MachineOperand> Operands; // the operands
236   MachineInstr* prev, *next;            // links for our intrusive list
237   MachineBasicBlock* parent;            // pointer to the owning basic block
238
239   // OperandComplete - Return true if it's illegal to add a new operand
240   bool OperandsComplete() const;
241
242   MachineInstr(const MachineInstr&);
243   void operator=(const MachineInstr&); // DO NOT IMPLEMENT
244
245   // Intrusive list support
246   //
247   friend struct ilist_traits<MachineInstr>;
248
249 public:
250   /// MachineInstr ctor - This constructor reserve's space for numOperand
251   /// operands.
252   MachineInstr(short Opcode, unsigned numOperands);
253
254   /// MachineInstr ctor - Work exactly the same as the ctor above, except that
255   /// the MachineInstr is created and added to the end of the specified basic
256   /// block.
257   ///
258   MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps);
259
260   ~MachineInstr();
261
262   const MachineBasicBlock* getParent() const { return parent; }
263   MachineBasicBlock* getParent() { return parent; }
264
265   /// getOpcode - Returns the opcode of this MachineInstr.
266   ///
267   const int getOpcode() const { return Opcode; }
268
269   /// Access to explicit operands of the instruction.
270   ///
271   unsigned getNumOperands() const { return Operands.size(); }
272
273   const MachineOperand& getOperand(unsigned i) const {
274     assert(i < getNumOperands() && "getOperand() out of range!");
275     return Operands[i];
276   }
277   MachineOperand& getOperand(unsigned i) {
278     assert(i < getNumOperands() && "getOperand() out of range!");
279     return Operands[i];
280   }
281
282
283   /// clone - Create a copy of 'this' instruction that is identical in
284   /// all ways except the the instruction has no parent, prev, or next.
285   MachineInstr* clone() const { return new MachineInstr(*this); }
286   
287   /// removeFromParent - This method unlinks 'this' from the containing basic
288   /// block, and returns it, but does not delete it.
289   MachineInstr *removeFromParent();
290   
291   /// eraseFromParent - This method unlinks 'this' from the containing basic
292   /// block and deletes it.
293   void eraseFromParent() {
294     delete removeFromParent();
295   }
296
297   //
298   // Debugging support
299   //
300   void print(std::ostream &OS, const TargetMachine *TM) const;
301   void dump() const;
302   friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
303
304   //===--------------------------------------------------------------------===//
305   // Accessors to add operands when building up machine instructions.
306   //
307
308   /// addRegOperand - Add a register operand.
309   ///
310   void addRegOperand(unsigned Reg,
311                      MachineOperand::UseType UTy = MachineOperand::Use) {
312     MachineOperand &Op = AddNewOperand();
313     Op.opType = MachineOperand::MO_Register;
314     Op.flags = UTy;
315     Op.contents.RegNo = Reg;
316     Op.offset = 0;
317   }
318
319   /// addImmOperand - Add a zero extended constant argument to the
320   /// machine instruction.
321   ///
322   void addImmOperand(int64_t Val) {
323     MachineOperand &Op = AddNewOperand();
324     Op.opType = MachineOperand::MO_Immediate;
325     Op.flags = 0;
326     Op.contents.immedVal = Val;
327     Op.offset = 0;
328   }
329
330   void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
331     MachineOperand &Op = AddNewOperand();
332     Op.opType = MachineOperand::MO_MachineBasicBlock;
333     Op.flags = 0;
334     Op.contents.MBB = MBB;
335     Op.offset = 0;
336   }
337
338   /// addFrameIndexOperand - Add an abstract frame index to the instruction
339   ///
340   void addFrameIndexOperand(unsigned Idx) {
341     MachineOperand &Op = AddNewOperand();
342     Op.opType = MachineOperand::MO_FrameIndex;
343     Op.flags = 0;
344     Op.contents.immedVal = Idx;
345     Op.offset = 0;
346   }
347
348   /// addConstantPoolndexOperand - Add a constant pool object index to the
349   /// instruction.
350   ///
351   void addConstantPoolIndexOperand(unsigned Idx, int Offset) {
352     MachineOperand &Op = AddNewOperand();
353     Op.opType = MachineOperand::MO_ConstantPoolIndex;
354     Op.flags = 0;
355     Op.contents.immedVal = Idx;
356     Op.offset = Offset;
357   }
358
359   /// addJumpTableIndexOperand - Add a jump table object index to the
360   /// instruction.
361   ///
362   void addJumpTableIndexOperand(unsigned Idx) {
363     MachineOperand &Op = AddNewOperand();
364     Op.opType = MachineOperand::MO_JumpTableIndex;
365     Op.flags = 0;
366     Op.contents.immedVal = Idx;
367     Op.offset = 0;
368   }
369   
370   void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
371     MachineOperand &Op = AddNewOperand();
372     Op.opType = MachineOperand::MO_GlobalAddress;
373     Op.flags = 0;
374     Op.contents.GV = GV;
375     Op.offset = Offset;
376   }
377
378   /// addExternalSymbolOperand - Add an external symbol operand to this instr
379   ///
380   void addExternalSymbolOperand(const char *SymName) {
381     MachineOperand &Op = AddNewOperand();
382     Op.opType = MachineOperand::MO_ExternalSymbol;
383     Op.flags = 0;
384     Op.contents.SymbolName = SymName;
385     Op.offset = 0;
386   }
387
388   //===--------------------------------------------------------------------===//
389   // Accessors used to modify instructions in place.
390   //
391
392   /// setOpcode - Replace the opcode of the current instruction with a new one.
393   ///
394   void setOpcode(unsigned Op) { Opcode = Op; }
395
396   /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
397   /// fewer operand than it started with.
398   ///
399   void RemoveOperand(unsigned i) {
400     Operands.erase(Operands.begin()+i);
401   }
402 private:
403   MachineOperand &AddNewOperand() {
404     assert(!OperandsComplete() &&
405            "Trying to add an operand to a machine instr that is already done!");
406     Operands.push_back(MachineOperand());
407     return Operands.back();
408   }
409 };
410
411 //===----------------------------------------------------------------------===//
412 // Debugging Support
413
414 std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI);
415 std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO);
416
417 } // End llvm namespace
418
419 #endif