Merge to MachineInstrInfo.h
[oota-llvm.git] / include / llvm / CodeGen / MInstruction.h
1 //===-- llvm/CodeGen/MInstruction.h - Machine Instruction -------*- C++ -*-===//
2 //
3 // This class represents a single machine instruction for the LLVM backend.
4 // This instruction is represented in a completely generic way to allow all
5 // backends to share a common representation.  MInstructions are embedded into
6 // MBasicBlocks, and are maintained as a doubly linked list.
7 //
8 // Because there are a lot of machine instruction that may be in use at a time
9 // (being manipulated), we are sure to keep a very compact representation that
10 // is extremely light-weight.
11 //
12 // This class is used to represent an instruction when it is in SSA form as well
13 // as when it has been register allocated to use physical registers.
14 //
15 // FIXME: This should eventually be merged with the MachineInstr class.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #ifndef CODEGEN_MINSTRUCTION_H
20 #define CODEGEN_MINSTRUCTION_H
21
22 #include <vector>
23 template<typename NodeTy> struct ilist_traits;
24 class MBasicBlock;
25
26 /// MOperand - This class represents a single operand in an instruction.
27 /// Interpretation of this operand is not really possible without information
28 /// from the machine instruction that it is embedded into.
29 ///
30 class MOperand {
31   union {
32     unsigned uVal;
33     int      iVal;
34   };
35 public:
36   MOperand(unsigned Value) : uVal(Value) {}
37   MOperand(int Value) : iVal(Value) {}
38
39   /// Interpretation - This enum is used by the MInstruction class to interpret
40   /// the untyped value field of the operand.
41   enum Interpretation {
42     Register,               // This is some register number
43     SignExtImmediate,       // This is a sign extended immediate
44     ZeroExtImmediate,       // This is a zero extended immediate
45     PCRelativeDisp          // This is a displacement relative to the PC
46     // FIXME: We need a symbolic value here, like global variable address
47   };
48
49   unsigned getUnsignedValue() const { return uVal; }
50   unsigned getSignedValue() const { return iVal; }
51 };
52
53 /// MInstruction - Represent a single machine instruction in the code generator.
54 /// This is meant to be a light weight representation that is completely
55 /// independant of the target machine being code generated for.
56 ///
57 class MInstruction {
58   MInstruction *Prev, *Next;      // Doubly linked list of instructions...
59
60   unsigned Opcode;                // Opcode of the instruction
61   unsigned Dest;                  // Destination register written (or 0 if none)
62
63   std::vector<MOperand> Operands; // Operands of the instruction...
64
65   /// OperandInterpretation - This array specifies how the operands of the
66   /// instruction are to be interpreted (is it a register?, an immediate
67   /// constant?, a PC relative displacement?, etc...).  Only four values are
68   /// allowed, so any instruction with more than four operands (should be
69   /// exceedingly rare, perhaps only PHI nodes) are assumed to have register
70   /// operands beyond the fourth.
71   ///
72   unsigned char OperandInterpretation[4];
73 public:
74   /// MInstruction ctor - Create a new machine instruction, with the specified
75   /// opcode and destination register.  Operands are then added with the
76   /// addOperand method.
77   ///
78   MInstruction(unsigned O = 0, unsigned D = 0) : Opcode(O), Dest(D) {}
79   
80   /// MInstruction ctor - Create a new instruction, and append it to the
81   /// specified basic block.
82   ///
83   MInstruction(MBasicBlock *BB, unsigned Opcode = 0, unsigned Dest = 0);
84
85   /// getOpcode - Return the opcode for this machine instruction.  The value of
86   /// the opcode defines how to interpret the operands of the instruction.
87   ///
88   unsigned getOpcode() const { return Opcode; }
89
90   /// getDestinationReg - This method returns the register written to by this
91   /// instruction.  If this returns zero, the instruction does not produce a
92   /// value, because register #0 is always the garbage marker.
93   ///
94   unsigned getDestinationReg() const { return Dest; }
95
96   /// setDestinationReg - This method changes the register written to by this
97   /// instruction.  Note that if SSA form is currently active then the SSA table
98   /// needs to be updated to match this, thus this method shouldn't be used
99   /// directly.
100   ///
101   void setDestinationReg(unsigned R) { Dest = R; }
102
103   /// getNumOperands - Return the number of operands the instruction currently
104   /// has.
105   ///
106   unsigned getNumOperands() const { return Operands.size(); }
107
108   /// getOperandInterpretation - Return the interpretation of operand #Op
109   ///
110   MOperand::Interpretation getOperandInterpretation(unsigned Op) const {
111     if (Op < 4) return (MOperand::Interpretation)OperandInterpretation[Op];
112     return MOperand::Register;  // Operands >= 4 are all registers
113   }
114
115   unsigned getRegisterOperand(unsigned Op) const {
116     assert(getOperandInterpretation(Op) == MOperand::Register &&
117            "Operand isn't a register!");
118     return Operands[Op].getUnsignedValue();
119   }
120   int getSignExtOperand(unsigned Op) const {
121     assert(getOperandInterpretation(Op) == MOperand::SignExtImmediate &&
122            "Operand isn't a sign extended immediate!");
123     return Operands[Op].getSignedValue();
124   }
125   unsigned getZeroExtOperand(unsigned Op) const {
126     assert(getOperandInterpretation(Op) == MOperand::ZeroExtImmediate &&
127            "Operand isn't a zero extended immediate!");
128     return Operands[Op].getUnsignedValue();
129   }
130   int getPCRelativeOperand(unsigned Op) const {
131     assert(getOperandInterpretation(Op) == MOperand::PCRelativeDisp &&
132            "Operand isn't a PC relative displacement!");
133     return Operands[Op].getSignedValue();
134   }
135
136   /// addOperand - Add a new operand to the instruction with the specified value
137   /// and interpretation.
138   ///
139   void addOperand(unsigned Value, MOperand::Interpretation Ty);
140
141 private:   // Methods used to maintain doubly linked list of instructions...
142   friend class ilist_traits<MInstruction>;
143
144   MInstruction *getPrev() const { return Prev; }
145   MInstruction *getNext() const { return Next; }
146   void setPrev(MInstruction *P) { Prev = P; }
147   void setNext(MInstruction *N) { Next = N; }
148 };
149
150 #endif