Add a bit to mark operands of asm's that conflict
[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 <cassert>
19 #include <iosfwd>
20
21 namespace llvm {
22   
23 class ConstantFP;
24 class MachineBasicBlock;
25 class GlobalValue;
26 class MachineInstr;
27 class TargetMachine;
28 class MachineRegisterInfo;
29 class raw_ostream;
30   
31 /// MachineOperand class - Representation of each machine instruction operand.
32 ///
33 class MachineOperand {
34 public:
35   enum MachineOperandType {
36     MO_Register,                // Register operand.
37     MO_Immediate,               // Immediate Operand
38     MO_FPImmediate,
39     MO_MachineBasicBlock,       // MachineBasicBlock reference
40     MO_FrameIndex,              // Abstract Stack Frame Index
41     MO_ConstantPoolIndex,       // Address of indexed Constant in Constant Pool
42     MO_JumpTableIndex,          // Address of indexed Jump Table for switch
43     MO_ExternalSymbol,          // Name of external global symbol
44     MO_GlobalAddress            // Address of a global value
45   };
46
47 private:
48   /// OpKind - Specify what kind of operand this is.  This discriminates the
49   /// union.
50   MachineOperandType OpKind : 8;
51   
52   /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register
53   /// operands.
54   
55   /// IsDef - True if this is a def, false if this is a use of the register.
56   ///
57   bool IsDef : 1;
58   
59   /// IsImp - True if this is an implicit def or use, false if it is explicit.
60   ///
61   bool IsImp : 1;
62
63   /// IsKill - True if this instruction is the last use of the register on this
64   /// path through the function.  This is only valid on uses of registers.
65   bool IsKill : 1;
66
67   /// IsDead - True if this register is never used by a subsequent instruction.
68   /// This is only valid on definitions of registers.
69   bool IsDead : 1;
70
71   /// IsEarlyClobber - True if this MO_Register operand is marked earlyclobber
72   /// in an inline asm.  Flag is not valid for any other case.   See gcc doc
73   /// for description of earlyclobber.
74   bool IsEarlyClobber : 1;
75
76   /// OverlapsEarlyClobber - True if this MO_Register operand is used as an
77   /// input to an inline asm that has the earlyclobber bit set on some other
78   /// operand.  Flag is not valid for any other case.   See gcc doc
79   /// for description of earlyclobber.
80   bool OverlapsEarlyClobber : 1;
81
82   /// SubReg - Subregister number, only valid for MO_Register.  A value of 0
83   /// indicates the MO_Register has no subReg.
84   unsigned char SubReg;
85   
86   /// ParentMI - This is the instruction that this operand is embedded into. 
87   /// This is valid for all operand types, when the operand is in an instr.
88   MachineInstr *ParentMI;
89
90   /// Contents union - This contains the payload for the various operand types.
91   union {
92     MachineBasicBlock *MBB;   // For MO_MachineBasicBlock.
93     const ConstantFP *CFP;    // For MO_FPImmediate.
94     int64_t ImmVal;           // For MO_Immediate.
95
96     struct {                  // For MO_Register.
97       unsigned RegNo;
98       MachineOperand **Prev;  // Access list for register.
99       MachineOperand *Next;
100     } Reg;
101     
102     /// OffsetedInfo - This struct contains the offset and an object identifier.
103     /// this represent the object as with an optional offset from it.
104     struct {
105       union {
106         int Index;                // For MO_*Index - The index itself.
107         const char *SymbolName;   // For MO_ExternalSymbol.
108         GlobalValue *GV;          // For MO_GlobalAddress.
109       } Val;
110       int Offset;   // An offset from the object.
111     } OffsetedInfo;
112   } Contents;
113   
114   explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {}
115 public:
116   MachineOperand(const MachineOperand &M) {
117     *this = M;
118   }
119   
120   ~MachineOperand() {}
121   
122   /// getType - Returns the MachineOperandType for this operand.
123   ///
124   MachineOperandType getType() const { return OpKind; }
125
126   /// getParent - Return the instruction that this operand belongs to.
127   ///
128   MachineInstr *getParent() { return ParentMI; }
129   const MachineInstr *getParent() const { return ParentMI; }
130   
131   void print(std::ostream &os, const TargetMachine *TM = 0) const;
132   void print(raw_ostream &os, const TargetMachine *TM = 0) const;
133
134   /// Accessors that tell you what kind of MachineOperand you're looking at.
135   ///
136   bool isRegister() const { return OpKind == MO_Register; }
137   bool isImmediate() const { return OpKind == MO_Immediate; }
138   bool isFPImmediate() const { return OpKind == MO_FPImmediate; }
139   bool isMachineBasicBlock() const { return OpKind == MO_MachineBasicBlock; }
140   bool isFrameIndex() const { return OpKind == MO_FrameIndex; }
141   bool isConstantPoolIndex() const { return OpKind == MO_ConstantPoolIndex; }
142   bool isJumpTableIndex() const { return OpKind == MO_JumpTableIndex; }
143   bool isGlobalAddress() const { return OpKind == MO_GlobalAddress; }
144   bool isExternalSymbol() const { return OpKind == MO_ExternalSymbol; }
145
146   //===--------------------------------------------------------------------===//
147   // Accessors for Register Operands
148   //===--------------------------------------------------------------------===//
149
150   /// getReg - Returns the register number.
151   unsigned getReg() const {
152     assert(isRegister() && "This is not a register operand!");
153     return Contents.Reg.RegNo;
154   }
155   
156   unsigned getSubReg() const {
157     assert(isRegister() && "Wrong MachineOperand accessor");
158     return (unsigned)SubReg;
159   }
160   
161   bool isUse() const { 
162     assert(isRegister() && "Wrong MachineOperand accessor");
163     return !IsDef;
164   }
165   
166   bool isDef() const {
167     assert(isRegister() && "Wrong MachineOperand accessor");
168     return IsDef;
169   }
170   
171   bool isImplicit() const { 
172     assert(isRegister() && "Wrong MachineOperand accessor");
173     return IsImp;
174   }
175   
176   bool isDead() const {
177     assert(isRegister() && "Wrong MachineOperand accessor");
178     return IsDead;
179   }
180   
181   bool isKill() const {
182     assert(isRegister() && "Wrong MachineOperand accessor");
183     return IsKill;
184   }
185   
186   bool isEarlyClobber() const {
187     assert(isRegister() && "Wrong MachineOperand accessor");
188     return IsEarlyClobber;
189   }
190
191   bool overlapsEarlyClobber() const {
192     assert(isRegister() && "Wrong MachineOperand accessor");
193     return OverlapsEarlyClobber;
194   }
195
196   /// getNextOperandForReg - Return the next MachineOperand in the function that
197   /// uses or defines this register.
198   MachineOperand *getNextOperandForReg() const {
199     assert(isRegister() && "This is not a register operand!");
200     return Contents.Reg.Next;
201   }
202
203   //===--------------------------------------------------------------------===//
204   // Mutators for Register Operands
205   //===--------------------------------------------------------------------===//
206   
207   /// Change the register this operand corresponds to.
208   ///
209   void setReg(unsigned Reg);
210   
211   void setSubReg(unsigned subReg) {
212     assert(isRegister() && "Wrong MachineOperand accessor");
213     SubReg = (unsigned char)subReg;
214   }
215   
216   void setIsUse(bool Val = true) {
217     assert(isRegister() && "Wrong MachineOperand accessor");
218     IsDef = !Val;
219   }
220   
221   void setIsDef(bool Val = true) {
222     assert(isRegister() && "Wrong MachineOperand accessor");
223     IsDef = Val;
224   }
225
226   void setImplicit(bool Val = true) { 
227     assert(isRegister() && "Wrong MachineOperand accessor");
228     IsImp = Val;
229   }
230
231   void setIsKill(bool Val = true) {
232     assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
233     IsKill = Val;
234   }
235   
236   void setIsDead(bool Val = true) {
237     assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
238     IsDead = Val;
239   }
240
241   void setIsEarlyClobber(bool Val = true) {
242     assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
243     IsEarlyClobber = Val;
244   }
245
246   void setOverlapsEarlyClobber(bool Val = true) {
247     assert(isRegister() && "Wrong MachineOperand accessor");
248     OverlapsEarlyClobber = Val;
249   }
250
251   //===--------------------------------------------------------------------===//
252   // Accessors for various operand types.
253   //===--------------------------------------------------------------------===//
254   
255   int64_t getImm() const {
256     assert(isImmediate() && "Wrong MachineOperand accessor");
257     return Contents.ImmVal;
258   }
259   
260   const ConstantFP *getFPImm() const {
261     assert(isFPImmediate() && "Wrong MachineOperand accessor");
262     return Contents.CFP;
263   }
264   
265   MachineBasicBlock *getMBB() const {
266     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
267     return Contents.MBB;
268   }
269
270   int getIndex() const {
271     assert((isFrameIndex() || isConstantPoolIndex() || isJumpTableIndex()) &&
272            "Wrong MachineOperand accessor");
273     return Contents.OffsetedInfo.Val.Index;
274   }
275   
276   GlobalValue *getGlobal() const {
277     assert(isGlobalAddress() && "Wrong MachineOperand accessor");
278     return Contents.OffsetedInfo.Val.GV;
279   }
280   
281   int getOffset() const {
282     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
283            "Wrong MachineOperand accessor");
284     return Contents.OffsetedInfo.Offset;
285   }
286   
287   const char *getSymbolName() const {
288     assert(isExternalSymbol() && "Wrong MachineOperand accessor");
289     return Contents.OffsetedInfo.Val.SymbolName;
290   }
291   
292   //===--------------------------------------------------------------------===//
293   // Mutators for various operand types.
294   //===--------------------------------------------------------------------===//
295   
296   void setImm(int64_t immVal) {
297     assert(isImmediate() && "Wrong MachineOperand mutator");
298     Contents.ImmVal = immVal;
299   }
300
301   void setOffset(int Offset) {
302     assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
303         "Wrong MachineOperand accessor");
304     Contents.OffsetedInfo.Offset = Offset;
305   }
306   
307   void setIndex(int Idx) {
308     assert((isFrameIndex() || isConstantPoolIndex() || isJumpTableIndex()) &&
309            "Wrong MachineOperand accessor");
310     Contents.OffsetedInfo.Val.Index = Idx;
311   }
312   
313   void setMBB(MachineBasicBlock *MBB) {
314     assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
315     Contents.MBB = MBB;
316   }
317   
318   //===--------------------------------------------------------------------===//
319   // Other methods.
320   //===--------------------------------------------------------------------===//
321   
322   /// isIdenticalTo - Return true if this operand is identical to the specified
323   /// operand. Note: This method ignores isKill and isDead properties.
324   bool isIdenticalTo(const MachineOperand &Other) const;
325   
326   /// ChangeToImmediate - Replace this operand with a new immediate operand of
327   /// the specified value.  If an operand is known to be an immediate already,
328   /// the setImm method should be used.
329   void ChangeToImmediate(int64_t ImmVal);
330   
331   /// ChangeToRegister - Replace this operand with a new register operand of
332   /// the specified value.  If an operand is known to be an register already,
333   /// the setReg method should be used.
334   void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
335                         bool isKill = false, bool isDead = false);
336   
337   //===--------------------------------------------------------------------===//
338   // Construction methods.
339   //===--------------------------------------------------------------------===//
340   
341   static MachineOperand CreateImm(int64_t Val) {
342     MachineOperand Op(MachineOperand::MO_Immediate);
343     Op.setImm(Val);
344     return Op;
345   }
346   
347   static MachineOperand CreateFPImm(const ConstantFP *CFP) {
348     MachineOperand Op(MachineOperand::MO_FPImmediate);
349     Op.Contents.CFP = CFP;
350     return Op;
351   }
352   
353   static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
354                                   bool isKill = false, bool isDead = false,
355                                   unsigned SubReg = 0,
356                                   bool isEarlyClobber = false,
357                                   bool overlapsEarlyClobber = false) {
358     MachineOperand Op(MachineOperand::MO_Register);
359     Op.IsDef = isDef;
360     Op.IsImp = isImp;
361     Op.IsKill = isKill;
362     Op.IsDead = isDead;
363     Op.IsEarlyClobber = isEarlyClobber;
364     Op.OverlapsEarlyClobber = overlapsEarlyClobber;
365     Op.Contents.Reg.RegNo = Reg;
366     Op.Contents.Reg.Prev = 0;
367     Op.Contents.Reg.Next = 0;
368     Op.SubReg = SubReg;
369     return Op;
370   }
371   static MachineOperand CreateMBB(MachineBasicBlock *MBB) {
372     MachineOperand Op(MachineOperand::MO_MachineBasicBlock);
373     Op.setMBB(MBB);
374     return Op;
375   }
376   static MachineOperand CreateFI(unsigned Idx) {
377     MachineOperand Op(MachineOperand::MO_FrameIndex);
378     Op.setIndex(Idx);
379     return Op;
380   }
381   static MachineOperand CreateCPI(unsigned Idx, int Offset) {
382     MachineOperand Op(MachineOperand::MO_ConstantPoolIndex);
383     Op.setIndex(Idx);
384     Op.setOffset(Offset);
385     return Op;
386   }
387   static MachineOperand CreateJTI(unsigned Idx) {
388     MachineOperand Op(MachineOperand::MO_JumpTableIndex);
389     Op.setIndex(Idx);
390     return Op;
391   }
392   static MachineOperand CreateGA(GlobalValue *GV, int Offset) {
393     MachineOperand Op(MachineOperand::MO_GlobalAddress);
394     Op.Contents.OffsetedInfo.Val.GV = GV;
395     Op.setOffset(Offset);
396     return Op;
397   }
398   static MachineOperand CreateES(const char *SymName, int Offset = 0) {
399     MachineOperand Op(MachineOperand::MO_ExternalSymbol);
400     Op.Contents.OffsetedInfo.Val.SymbolName = SymName;
401     Op.setOffset(Offset);
402     return Op;
403   }
404   const MachineOperand &operator=(const MachineOperand &MO) {
405     OpKind   = MO.OpKind;
406     IsDef    = MO.IsDef;
407     IsImp    = MO.IsImp;
408     IsKill   = MO.IsKill;
409     IsDead   = MO.IsDead;
410     IsEarlyClobber = MO.IsEarlyClobber;
411     OverlapsEarlyClobber = MO.OverlapsEarlyClobber;
412     SubReg   = MO.SubReg;
413     ParentMI = MO.ParentMI;
414     Contents = MO.Contents;
415     return *this;
416   }
417
418   friend class MachineInstr;
419   friend class MachineRegisterInfo;
420 private:
421   //===--------------------------------------------------------------------===//
422   // Methods for handling register use/def lists.
423   //===--------------------------------------------------------------------===//
424
425   /// isOnRegUseList - Return true if this operand is on a register use/def list
426   /// or false if not.  This can only be called for register operands that are
427   /// part of a machine instruction.
428   bool isOnRegUseList() const {
429     assert(isRegister() && "Can only add reg operand to use lists");
430     return Contents.Reg.Prev != 0;
431   }
432   
433   /// AddRegOperandToRegInfo - Add this register operand to the specified
434   /// MachineRegisterInfo.  If it is null, then the next/prev fields should be
435   /// explicitly nulled out.
436   void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo);
437
438   void RemoveRegOperandFromRegInfo() {
439     assert(isOnRegUseList() && "Reg operand is not on a use list");
440     // Unlink this from the doubly linked list of operands.
441     MachineOperand *NextOp = Contents.Reg.Next;
442     *Contents.Reg.Prev = NextOp; 
443     if (NextOp) {
444       assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!");
445       NextOp->Contents.Reg.Prev = Contents.Reg.Prev;
446     }
447     Contents.Reg.Prev = 0;
448     Contents.Reg.Next = 0;
449   }
450 };
451
452 inline std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) {
453   MO.print(OS, 0);
454   return OS;
455 }
456
457 inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) {
458   MO.print(OS, 0);
459   return OS;
460 }
461
462 } // End llvm namespace
463
464 #endif