1 //===-- llvm/CodeGen/MInstruction.h - Machine Instruction -------*- C++ -*-===//
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.
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.
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.
15 // FIXME: This should eventually be merged with the MachineInstr class.
17 //===----------------------------------------------------------------------===//
19 #ifndef CODEGEN_MINSTRUCTION_H
20 #define CODEGEN_MINSTRUCTION_H
23 template<typename NodeTy> struct ilist_traits;
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.
36 MOperand(unsigned Value) : uVal(Value) {}
37 MOperand(int Value) : iVal(Value) {}
39 /// Interpretation - This enum is used by the MInstruction class to interpret
40 /// the untyped value field of the operand.
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
49 unsigned getUnsignedValue() const { return uVal; }
50 unsigned getSignedValue() const { return iVal; }
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.
58 MInstruction *Prev, *Next; // Doubly linked list of instructions...
60 unsigned Opcode; // Opcode of the instruction
61 unsigned Dest; // Destination register written (or 0 if none)
63 std::vector<MOperand> Operands; // Operands of the instruction...
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.
72 unsigned char OperandInterpretation[4];
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.
78 MInstruction(unsigned O = 0, unsigned D = 0) : Opcode(O), Dest(D) {}
80 /// MInstruction ctor - Create a new instruction, and append it to the
81 /// specified basic block.
83 MInstruction(MBasicBlock *BB, unsigned Opcode = 0, unsigned Dest = 0);
85 /// getOpcode - Return the opcode for this machine instruction. The value of
86 /// the opcode defines how to interpret the operands of the instruction.
88 unsigned getOpcode() const { return Opcode; }
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.
94 unsigned getDestinationReg() const { return Dest; }
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
101 void setDestinationReg(unsigned R) { Dest = R; }
103 /// getNumOperands - Return the number of operands the instruction currently
106 unsigned getNumOperands() const { return Operands.size(); }
108 /// getOperandInterpretation - Return the interpretation of operand #Op
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
115 unsigned getRegisterOperand(unsigned Op) const {
116 assert(getOperandInterpretation(Op) == MOperand::Register &&
117 "Operand isn't a register!");
118 return Operands[Op].getUnsignedValue();
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();
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();
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();
136 /// addOperand - Add a new operand to the instruction with the specified value
137 /// and interpretation.
139 void addOperand(unsigned Value, MOperand::Interpretation Ty);
141 private: // Methods used to maintain doubly linked list of instructions...
142 friend class ilist_traits<MInstruction>;
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; }