Add some short-hand accessors
[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 getImmedValue() const {
128     assert(isImmediate() && "Wrong MachineOperand accessor");
129     return contents.immedVal;
130   }
131   MachineBasicBlock *getMachineBasicBlock() const {
132     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
133     return contents.MBB;
134   }
135   void setMachineBasicBlock(MachineBasicBlock *MBB) {
136     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
137     contents.MBB = MBB;
138   }
139   int getFrameIndex() const {
140     assert(isFrameIndex() && "Wrong MachineOperand accessor");
141     return (int)contents.immedVal;
142   }
143   unsigned getConstantPoolIndex() const {
144     assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
145     return (unsigned)contents.immedVal;
146   }
147   unsigned getJumpTableIndex() const {
148     assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
149     return (unsigned)contents.immedVal;
150   }
151   GlobalValue *getGlobal() const {
152     assert(isGlobalAddress() && "Wrong MachineOperand accessor");
153     return contents.GV;
154   }
155   int getOffset() const {
156     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
157         "Wrong MachineOperand accessor");
158     return offset;
159   }
160   const char *getSymbolName() const {
161     assert(isExternalSymbol() && "Wrong MachineOperand accessor");
162     return contents.SymbolName;
163   }
164
165   /// MachineOperand methods for testing that work on any kind of
166   /// MachineOperand...
167   ///
168   bool            isUse           () const { return flags & USEFLAG; }
169   MachineOperand& setUse          ()       { flags |= USEFLAG; return *this; }
170   bool            isDef           () const { return flags & DEFFLAG; }
171   MachineOperand& setDef          ()       { flags |= DEFFLAG; return *this; }
172
173   /// getReg - Returns the register number.
174   ///
175   unsigned getReg() const {
176     assert(isRegister() && "This is not a register operand!");
177     return contents.RegNo;
178   }
179
180   /// MachineOperand mutators.
181   ///
182   void setReg(unsigned Reg) {
183     assert(isRegister() && "This is not a register operand!");
184     contents.RegNo = Reg;
185   }
186
187   void setImmedValue(int64_t immVal) {
188     assert(isImmediate() && "Wrong MachineOperand mutator");
189     contents.immedVal = immVal;
190   }
191
192   void setOffset(int Offset) {
193     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
194             isJumpTableIndex()) &&
195         "Wrong MachineOperand accessor");
196     offset = Offset;
197   }
198   
199   /// ChangeToImmediate - Replace this operand with a new immediate operand of
200   /// the specified value.  If an operand is known to be an immediate already,
201   /// the setImmedValue method should be used.
202   void ChangeToImmediate(int64_t ImmVal) {
203     opType = MO_Immediate;
204     contents.immedVal = ImmVal;
205   }
206
207   /// ChangeToRegister - Replace this operand with a new register operand of
208   /// the specified value.  If an operand is known to be an register already,
209   /// the setReg method should be used.
210   void ChangeToRegister(unsigned Reg) {
211     opType = MO_Register;
212     contents.RegNo = Reg;
213   }
214
215   friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
216
217   friend class MachineInstr;
218 };
219
220
221 //===----------------------------------------------------------------------===//
222 /// MachineInstr - Representation of each machine instruction.
223 ///
224 class MachineInstr {
225   short Opcode;                         // the opcode
226   std::vector<MachineOperand> Operands; // the operands
227   MachineInstr* prev, *next;            // links for our intrusive list
228   MachineBasicBlock* parent;            // pointer to the owning basic block
229
230   // OperandComplete - Return true if it's illegal to add a new operand
231   bool OperandsComplete() const;
232
233   MachineInstr(const MachineInstr&);
234   void operator=(const MachineInstr&); // DO NOT IMPLEMENT
235
236   // Intrusive list support
237   //
238   friend struct ilist_traits<MachineInstr>;
239
240 public:
241   /// MachineInstr ctor - This constructor reserve's space for numOperand
242   /// operands.
243   MachineInstr(short Opcode, unsigned numOperands);
244
245   /// MachineInstr ctor - Work exactly the same as the ctor above, except that
246   /// the MachineInstr is created and added to the end of the specified basic
247   /// block.
248   ///
249   MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps);
250
251   ~MachineInstr();
252
253   const MachineBasicBlock* getParent() const { return parent; }
254   MachineBasicBlock* getParent() { return parent; }
255
256   /// getOpcode - Returns the opcode of this MachineInstr.
257   ///
258   const int getOpcode() const { return Opcode; }
259
260   /// Access to explicit operands of the instruction.
261   ///
262   unsigned getNumOperands() const { return Operands.size(); }
263
264   const MachineOperand& getOperand(unsigned i) const {
265     assert(i < getNumOperands() && "getOperand() out of range!");
266     return Operands[i];
267   }
268   MachineOperand& getOperand(unsigned i) {
269     assert(i < getNumOperands() && "getOperand() out of range!");
270     return Operands[i];
271   }
272
273
274   /// clone - Create a copy of 'this' instruction that is identical in
275   /// all ways except the the instruction has no parent, prev, or next.
276   MachineInstr* clone() const { return new MachineInstr(*this); }
277   
278   /// removeFromParent - This method unlinks 'this' from the containing basic
279   /// block, and returns it, but does not delete it.
280   MachineInstr *removeFromParent();
281   
282   /// eraseFromParent - This method unlinks 'this' from the containing basic
283   /// block and deletes it.
284   void eraseFromParent() {
285     delete removeFromParent();
286   }
287
288   //
289   // Debugging support
290   //
291   void print(std::ostream &OS, const TargetMachine *TM) const;
292   void dump() const;
293   friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
294
295   //===--------------------------------------------------------------------===//
296   // Accessors to add operands when building up machine instructions.
297   //
298
299   /// addRegOperand - Add a register operand.
300   ///
301   void addRegOperand(unsigned Reg,
302                      MachineOperand::UseType UTy = MachineOperand::Use) {
303     MachineOperand &Op = AddNewOperand();
304     Op.opType = MachineOperand::MO_Register;
305     Op.flags = UTy;
306     Op.contents.RegNo = Reg;
307     Op.offset = 0;
308   }
309
310   /// addImmOperand - Add a zero extended constant argument to the
311   /// machine instruction.
312   ///
313   void addImmOperand(int64_t Val) {
314     MachineOperand &Op = AddNewOperand();
315     Op.opType = MachineOperand::MO_Immediate;
316     Op.flags = 0;
317     Op.contents.immedVal = Val;
318     Op.offset = 0;
319   }
320
321   void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
322     MachineOperand &Op = AddNewOperand();
323     Op.opType = MachineOperand::MO_MachineBasicBlock;
324     Op.flags = 0;
325     Op.contents.MBB = MBB;
326     Op.offset = 0;
327   }
328
329   /// addFrameIndexOperand - Add an abstract frame index to the instruction
330   ///
331   void addFrameIndexOperand(unsigned Idx) {
332     MachineOperand &Op = AddNewOperand();
333     Op.opType = MachineOperand::MO_FrameIndex;
334     Op.flags = 0;
335     Op.contents.immedVal = Idx;
336     Op.offset = 0;
337   }
338
339   /// addConstantPoolndexOperand - Add a constant pool object index to the
340   /// instruction.
341   ///
342   void addConstantPoolIndexOperand(unsigned Idx, int Offset) {
343     MachineOperand &Op = AddNewOperand();
344     Op.opType = MachineOperand::MO_ConstantPoolIndex;
345     Op.flags = 0;
346     Op.contents.immedVal = Idx;
347     Op.offset = Offset;
348   }
349
350   /// addJumpTableIndexOperand - Add a jump table object index to the
351   /// instruction.
352   ///
353   void addJumpTableIndexOperand(unsigned Idx) {
354     MachineOperand &Op = AddNewOperand();
355     Op.opType = MachineOperand::MO_JumpTableIndex;
356     Op.flags = 0;
357     Op.contents.immedVal = Idx;
358     Op.offset = 0;
359   }
360   
361   void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
362     MachineOperand &Op = AddNewOperand();
363     Op.opType = MachineOperand::MO_GlobalAddress;
364     Op.flags = 0;
365     Op.contents.GV = GV;
366     Op.offset = Offset;
367   }
368
369   /// addExternalSymbolOperand - Add an external symbol operand to this instr
370   ///
371   void addExternalSymbolOperand(const char *SymName) {
372     MachineOperand &Op = AddNewOperand();
373     Op.opType = MachineOperand::MO_ExternalSymbol;
374     Op.flags = 0;
375     Op.contents.SymbolName = SymName;
376     Op.offset = 0;
377   }
378
379   //===--------------------------------------------------------------------===//
380   // Accessors used to modify instructions in place.
381   //
382
383   /// setOpcode - Replace the opcode of the current instruction with a new one.
384   ///
385   void setOpcode(unsigned Op) { Opcode = Op; }
386
387   /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
388   /// fewer operand than it started with.
389   ///
390   void RemoveOperand(unsigned i) {
391     Operands.erase(Operands.begin()+i);
392   }
393 private:
394   MachineOperand &AddNewOperand() {
395     assert(!OperandsComplete() &&
396            "Trying to add an operand to a machine instr that is already done!");
397     Operands.push_back(MachineOperand());
398     return Operands.back();
399   }
400 };
401
402 //===----------------------------------------------------------------------===//
403 // Debugging Support
404
405 std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI);
406 std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO);
407
408 } // End llvm namespace
409
410 #endif