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