MachineInstr.h revision 68498cefe602bf5364168b4acd0bd5806cdd72ec
1// $Id$ -*-c++-*-
2//***************************************************************************
3// File:
4//	MachineInstr.h
5//
6// Purpose:
7//
8//
9// Strategy:
10//
11// History:
12//	7/2/01	 -  Vikram Adve  -  Created
13//**************************************************************************/
14
15#ifndef LLVM_CODEGEN_MACHINEINSTR_H
16#define LLVM_CODEGEN_MACHINEINSTR_H
17
18#include "llvm/CodeGen/InstrForest.h"
19#include "llvm/Tools/DataTypes.h"
20#include "llvm/Support/Unique.h"
21#include "llvm/CodeGen/TargetMachine.h"
22
23//---------------------------------------------------------------------------
24// class MachineOperand
25//
26// Purpose:
27//   Representation of each machine instruction operand.
28//   This class is designed so that you can allocate a vector of operands
29//   first and initialize each one later.
30//
31//   E.g, for this VM instruction:
32//		ptr = alloca type, numElements
33//   we generate 2 machine instructions on the SPARC:
34//
35//		mul Constant, Numelements -> Reg
36//		add %sp, Reg -> Ptr
37//
38//   Each instruction has 3 operands, listed above.  Of those:
39//   -	Reg, NumElements, and Ptr are of operand type MO_Register.
40//   -	Constant is of operand type MO_SignExtendedImmed on the SPARC.
41//
42//   For the register operands, the virtual register type is as follows:
43//
44//   -  Reg will be of virtual register type MO_MInstrVirtualReg.  The field
45//	MachineInstr* minstr will point to the instruction that computes reg.
46//
47//   -	%sp will be of virtual register type MO_MachineReg.
48//	The field regNum identifies the machine register.
49//
50//   -	NumElements will be of virtual register type MO_VirtualReg.
51//	The field Value* value identifies the value.
52//
53//   -	Ptr will also be of virtual register type MO_VirtualReg.
54//	Again, the field Value* value identifies the value.
55//
56//---------------------------------------------------------------------------
57
58class MachineOperand {
59public:
60  friend ostream& operator<<(ostream& os, const MachineOperand& mop);
61
62public:
63  enum MachineOperandType {
64    MO_Register,
65    MO_CCRegister,
66    MO_SignExtendedImmed,
67    MO_UnextendedImmed,
68    MO_PCRelativeDisp,
69  };
70
71  enum VirtualRegisterType {
72    MO_VirtualReg,		// virtual register for *value
73    MO_MachineReg		// pre-assigned machine register `regNum'
74  };
75
76  MachineOperandType machineOperandType;
77
78  VirtualRegisterType vregType;
79
80  Value*	value;		// BasicBlockVal for a label operand.
81				// ConstantVal for a non-address immediate.
82				// Virtual register for a register operand.
83
84  unsigned int regNum;		// register number for an explicit register
85
86  int64_t immedVal;		// constant value for an explicit constant
87
88  /*ctor*/		MachineOperand	();
89  /*ctor*/		MachineOperand	(MachineOperandType operandType,
90					 Value* _val);
91  /*copy ctor*/		MachineOperand	(const MachineOperand&);
92  /*dtor*/		~MachineOperand	() {}
93
94  // These functions are provided so that a vector of operands can be
95  // statically allocated and individual ones can be initialized later.
96  //
97  void			Initialize	(MachineOperandType operandType,
98					 Value* _val);
99  void			InitializeConst	(MachineOperandType operandType,
100					 int64_t intValue);
101  void			InitializeReg	(unsigned int regNum);
102};
103
104
105inline
106MachineOperand::MachineOperand()
107  : machineOperandType(MO_Register),
108    vregType(MO_VirtualReg),
109    value(NULL),
110    regNum(0),
111    immedVal(0)
112{}
113
114inline
115MachineOperand::MachineOperand(MachineOperandType operandType,
116			       Value* _val)
117  : machineOperandType(operandType),
118    vregType(MO_VirtualReg),
119    value(_val),
120    regNum(0),
121    immedVal(0)
122{}
123
124inline
125MachineOperand::MachineOperand(const MachineOperand& mo)
126  : machineOperandType(mo.machineOperandType),
127    vregType(mo.vregType),
128    value(mo.value),
129    regNum(mo.regNum),
130    immedVal(mo.immedVal)
131{
132}
133
134inline void
135MachineOperand::Initialize(MachineOperandType operandType,
136			   Value* _val)
137{
138  machineOperandType = operandType;
139  value = _val;
140}
141
142inline void
143MachineOperand::InitializeConst(MachineOperandType operandType,
144				int64_t intValue)
145{
146  machineOperandType = operandType;
147  value = NULL;
148  immedVal = intValue;
149}
150
151inline void
152MachineOperand::InitializeReg(unsigned int _regNum)
153{
154  machineOperandType = MO_Register;
155  vregType = MO_MachineReg;
156  value = NULL;
157  regNum = _regNum;
158}
159
160
161//---------------------------------------------------------------------------
162// class MachineInstr
163//
164// Purpose:
165//   Representation of each machine instruction.
166//
167//   MachineOpCode must be an enum, defined separately for each target.
168//   E.g., It is defined in SparcInstructionSelection.h for the SPARC.
169//   The array MachineInstrInfo TargetMachineInstrInfo[] objects
170//   (indexed by opCode) provides information about each target instruction.
171//
172//   opCodeMask is used to record variants of an instruction.
173//   E.g., each branch instruction on SPARC has 2 flags (i.e., 4 variants):
174//	ANNUL:		   if 1: Annul delay slot instruction.
175//	PREDICT-NOT-TAKEN: if 1: predict branch not taken.
176//   Instead of creating 4 different opcodes for BNZ, we create a single
177//   opcode and set bits in opCodeMask for each of these flags.
178//---------------------------------------------------------------------------
179
180class MachineInstr : public Unique {
181private:
182  MachineOpCode	opCode;
183  OpCodeMask	opCodeMask;		// extra bits for variants of an opcode
184  vector<MachineOperand> operands;	// operand 0 is the result
185
186public:
187  /*ctor*/		MachineInstr	(MachineOpCode _opCode,
188					 OpCodeMask    _opCodeMask = 0x0);
189
190  /*dtor*/ virtual	~MachineInstr	();
191
192  const MachineOpCode	getOpCode	() const;
193
194  unsigned int		getNumOperands	() const;
195
196  const MachineOperand& getOperand	(unsigned int i) const;
197
198  void			dump		(unsigned int indent = 0);
199
200public:
201  friend ostream& operator<<(ostream& os, const MachineInstr& minstr);
202
203public:
204  // Access to set the operands when building the machine instruction
205  void			SetMachineOperand(unsigned int i,
206			      MachineOperand::MachineOperandType operandType,
207			      Value* _val);
208  void			SetMachineOperand(unsigned int i,
209			      MachineOperand::MachineOperandType operandType,
210			      int64_t intValue);
211  void			SetMachineOperand(unsigned int i,
212					  unsigned int regNum);
213};
214
215inline const MachineOpCode
216MachineInstr::getOpCode() const
217{
218  return opCode;
219}
220
221inline unsigned int
222MachineInstr::getNumOperands() const
223{
224  assert(operands.size() == TargetMachineInstrInfo[opCode].numOperands);
225  return operands.size();
226}
227
228inline const MachineOperand&
229MachineInstr::getOperand(unsigned int i) const
230{
231  return operands[i];
232}
233
234
235//---------------------------------------------------------------------------
236// class MachineInstructionsForVMInstr
237//
238// Purpose:
239//   Representation of the sequence of machine instructions created
240//   for a single VM instruction.  Additionally records any temporary
241//   "values" used as intermediate values in this sequence.
242//   Note that such values should be treated as pure SSA values with
243//   no interpretation of their operands (i.e., as a TmpInstruction object
244//   which actually represents such a value).
245//
246//---------------------------------------------------------------------------
247
248class MachineCodeForVMInstr: public vector<MachineInstr*>
249{
250private:
251  vector<Value*> tempVec;
252
253public:
254  /*ctor*/	MachineCodeForVMInstr	()	{}
255  /*ctor*/	~MachineCodeForVMInstr	();
256
257  const vector<Value*>&
258		getTempValues		() const { return tempVec; }
259
260  void		addTempValue		(Value* val)
261						 { tempVec.push_back(val); }
262
263  // dropAllReferences() - This function drops all references within
264  // temporary (hidden) instructions created in implementing the original
265  // VM intruction.  This ensures there are no remaining "uses" within
266  // these hidden instructions, before the values of a method are freed.
267  //
268  // Make this inline because it has to be called from class Instruction
269  // and inlining it avoids a serious circurality in link order.
270  inline void dropAllReferences() {
271    for (unsigned i=0, N=tempVec.size(); i < N; i++)
272    if (tempVec[i]->getValueType() == Value::InstructionVal)
273      ((Instruction*) tempVec[i])->dropAllReferences();
274  }
275};
276
277inline
278MachineCodeForVMInstr::~MachineCodeForVMInstr()
279{
280  // Free the Value objects created to hold intermediate values
281  for (unsigned i=0, N=tempVec.size(); i < N; i++)
282    delete tempVec[i];
283
284  // Free the MachineInstr objects allocated, if any.
285  for (unsigned i=0, N=this->size(); i < N; i++)
286    delete (*this)[i];
287}
288
289//---------------------------------------------------------------------------
290// Target-independent utility routines for creating machine instructions
291//---------------------------------------------------------------------------
292
293
294//------------------------------------------------------------------------
295// Function Set2OperandsFromInstr
296// Function Set3OperandsFromInstr
297//
298// For the common case of 2- and 3-operand arithmetic/logical instructions,
299// set the m/c instr. operands directly from the VM instruction's operands.
300// Check whether the first or second operand is 0 and can use a dedicated
301// "0" register.
302// Check whether the second operand should use an immediate field or register.
303// (First and third operands are never immediates for such instructions.)
304//
305// Arguments:
306// canDiscardResult: Specifies that the result operand can be discarded
307//		     by using the dedicated "0"
308//
309// op1position, op2position and resultPosition: Specify in which position
310//		     in the machine instruction the 3 operands (arg1, arg2
311//		     and result) should go.
312//
313// RETURN VALUE: unsigned int flags, where
314//	flags & 0x01	=> operand 1 is constant and needs a register
315//	flags & 0x02	=> operand 2 is constant and needs a register
316//------------------------------------------------------------------------
317
318void		Set2OperandsFromInstr	(MachineInstr* minstr,
319					 InstructionNode* vmInstrNode,
320					 const TargetMachine& targetMachine,
321					 bool canDiscardResult = false,
322					 int op1Position = 0,
323					 int resultPosition = 1);
324
325void		Set3OperandsFromInstr	(MachineInstr* minstr,
326					 InstructionNode* vmInstrNode,
327					 const TargetMachine& targetMachine,
328					 bool canDiscardResult = false,
329					 int op1Position = 0,
330					 int op2Position = 1,
331					 int resultPosition = 2);
332
333MachineOperand::MachineOperandType
334		ChooseRegOrImmed(Value* val,
335			     MachineOpCode opCode,
336			     const TargetMachine& targetMachine,
337			     bool canUseImmed,
338			     MachineOperand::VirtualRegisterType& getVRegType,
339			     unsigned int& getMachineRegNum,
340			     int64_t& getImmedValue);
341
342ostream& operator<<(ostream& os, const MachineInstr& minstr);
343
344
345ostream& operator<<(ostream& os, const MachineOperand& mop);
346
347
348//**************************************************************************/
349
350#endif
351