MachineInstr.cpp revision ed8f674b9a18312886355288ac49f9a2dd5e4e94
1// $Id$
2//***************************************************************************
3// File:
4//	MachineInstr.cpp
5//
6// Purpose:
7//
8//
9// Strategy:
10//
11// History:
12//	7/2/01	 -  Vikram Adve  -  Created
13//**************************************************************************/
14
15
16#include "llvm/CodeGen/MachineInstr.h"
17#include "llvm/Method.h"
18#include "llvm/ConstPoolVals.h"
19#include "llvm/Instruction.h"
20
21
22//************************ Class Implementations **************************/
23
24// Constructor for instructions with fixed #operands (nearly all)
25MachineInstr::MachineInstr(MachineOpCode _opCode,
26			   OpCodeMask    _opCodeMask)
27  : opCode(_opCode),
28    opCodeMask(_opCodeMask),
29    operands(TargetInstrDescriptors[_opCode].numOperands)
30{
31  assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
32}
33
34// Constructor for instructions with variable #operands
35MachineInstr::MachineInstr(MachineOpCode _opCode,
36			   unsigned	 numOperands,
37			   OpCodeMask    _opCodeMask)
38  : opCode(_opCode),
39    opCodeMask(_opCodeMask),
40    operands(numOperands)
41{
42}
43
44void
45MachineInstr::SetMachineOperand(unsigned int i,
46				MachineOperand::MachineOperandType operandType,
47				Value* _val, bool isdef=false)
48{
49  assert(i < operands.size());
50  operands[i].Initialize(operandType, _val);
51  operands[i].isDef = isdef ||
52		      TargetInstrDescriptors[opCode].resultPos == (int) i;
53}
54
55void
56MachineInstr::SetMachineOperand(unsigned int i,
57				MachineOperand::MachineOperandType operandType,
58				int64_t intValue, bool isdef=false)
59{
60  assert(i < operands.size());
61  operands[i].InitializeConst(operandType, intValue);
62  operands[i].isDef = isdef ||
63		      TargetInstrDescriptors[opCode].resultPos == (int) i;
64}
65
66void
67MachineInstr::SetMachineOperand(unsigned int i,
68				unsigned int regNum, bool isdef=false)
69{
70  assert(i < operands.size());
71  operands[i].InitializeReg(regNum);
72  operands[i].isDef = isdef ||
73		      TargetInstrDescriptors[opCode].resultPos == (int) i;
74}
75
76void
77MachineInstr::dump(unsigned int indent) const
78{
79  for (unsigned i=0; i < indent; i++)
80    cout << "    ";
81
82  cout << *this;
83}
84
85ostream&
86operator<< (ostream& os, const MachineInstr& minstr)
87{
88  os << TargetInstrDescriptors[minstr.opCode].opCodeString;
89
90  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
91    os << "\t" << minstr.getOperand(i);
92
93#undef DEBUG_VAL_OP_ITERATOR
94#ifdef DEBUG_VAL_OP_ITERATOR
95  os << endl << "\tValue operands are: ";
96  for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
97    {
98      const Value* val = *vo;
99      os << val << (vo.isDef()? "(def), " : ", ");
100    }
101  os << endl;
102#endif
103
104  return os;
105}
106
107static inline ostream &OutputOperand(ostream &os, const MachineOperand &mop) {
108  switch (mop.getOperandType()) {
109  case MachineOperand::MO_CCRegister:
110  case MachineOperand::MO_VirtualRegister:
111    return os << "(val " << mop.getVRegValue() << ")";
112  case MachineOperand::MO_MachineRegister:
113    return os << "("     << mop.getMachineRegNum() << ")";
114  default:
115    assert(0 && "Unknown operand type");
116    return os;
117  }
118}
119
120
121ostream &operator<<(ostream &os, const MachineOperand &mop) {
122  switch(mop.opType) {
123  case MachineOperand::MO_VirtualRegister:
124  case MachineOperand::MO_MachineRegister:
125    os << "%reg";
126    return OutputOperand(os, mop);
127  case MachineOperand::MO_CCRegister:
128    os << "%ccreg";
129    return OutputOperand(os, mop);
130  case MachineOperand::MO_SignExtendedImmed:
131    return os << mop.immedVal;
132  case MachineOperand::MO_UnextendedImmed:
133    return os << mop.immedVal;
134  case MachineOperand::MO_PCRelativeDisp:
135    return os << "%disp(label " << mop.getVRegValue() << ")";
136  default:
137    assert(0 && "Unrecognized operand type");
138    break;
139  }
140
141  return os;
142}
143
144
145//---------------------------------------------------------------------------
146// Target-independent utility routines for creating machine instructions
147//---------------------------------------------------------------------------
148
149
150//------------------------------------------------------------------------
151// Function Set2OperandsFromInstr
152// Function Set3OperandsFromInstr
153//
154// For the common case of 2- and 3-operand arithmetic/logical instructions,
155// set the m/c instr. operands directly from the VM instruction's operands.
156// Check whether the first or second operand is 0 and can use a dedicated "0"
157// register.
158// Check whether the second operand should use an immediate field or register.
159// (First and third operands are never immediates for such instructions.)
160//
161// Arguments:
162// canDiscardResult: Specifies that the result operand can be discarded
163//		     by using the dedicated "0"
164//
165// op1position, op2position and resultPosition: Specify in which position
166//		     in the machine instruction the 3 operands (arg1, arg2
167//		     and result) should go.
168//
169// RETURN VALUE: unsigned int flags, where
170//	flags & 0x01	=> operand 1 is constant and needs a register
171//	flags & 0x02	=> operand 2 is constant and needs a register
172//------------------------------------------------------------------------
173
174void
175Set2OperandsFromInstr(MachineInstr* minstr,
176		      InstructionNode* vmInstrNode,
177		      const TargetMachine& target,
178		      bool canDiscardResult,
179		      int op1Position,
180		      int resultPosition)
181{
182  Set3OperandsFromInstr(minstr, vmInstrNode, target,
183			canDiscardResult, op1Position,
184			/*op2Position*/ -1, resultPosition);
185}
186
187#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
188#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
189unsigned
190Set3OperandsFromInstrJUNK(MachineInstr* minstr,
191		      InstructionNode* vmInstrNode,
192		      const TargetMachine& target,
193		      bool canDiscardResult,
194		      int op1Position,
195		      int op2Position,
196		      int resultPosition)
197{
198  assert(op1Position >= 0);
199  assert(resultPosition >= 0);
200
201  unsigned returnFlags = 0x0;
202
203  // Check if operand 1 is 0.  If so, try to use a hardwired 0 register.
204  Value* op1Value = vmInstrNode->leftChild()->getValue();
205  bool isValidConstant;
206  int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
207  if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
208    minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
209  else
210    {
211      if (op1Value->isConstant()) {
212	// value is constant and must be loaded from constant pool
213	returnFlags = returnFlags | (1 << op1Position);
214      }
215      minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
216				op1Value);
217    }
218
219  // Check if operand 2 (if any) fits in the immed. field of the instruction,
220  // or if it is 0 and can use a dedicated machine register
221  if (op2Position >= 0)
222    {
223      Value* op2Value = vmInstrNode->rightChild()->getValue();
224      int64_t immedValue;
225      unsigned int machineRegNum;
226
227      MachineOperand::MachineOperandType
228	op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
229				   /*canUseImmed*/ true,
230				   machineRegNum, immedValue);
231
232      if (op2type == MachineOperand::MO_MachineRegister)
233	minstr->SetMachineOperand(op2Position, machineRegNum);
234      else if (op2type == MachineOperand::MO_VirtualRegister)
235	{
236	  if (op2Value->isConstant()) {
237	    // value is constant and must be loaded from constant pool
238	    returnFlags = returnFlags | (1 << op2Position);
239	  }
240	  minstr->SetMachineOperand(op2Position, op2type, op2Value);
241	}
242      else
243	{
244	  assert(op2type != MO_CCRegister);
245	  minstr->SetMachineOperand(op2Position, op2type, immedValue);
246	}
247    }
248
249  // If operand 3 (result) can be discarded, use a dead register if one exists
250  if (canDiscardResult && target.zeroRegNum >= 0)
251    minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
252  else
253    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
254
255  return returnFlags;
256}
257#endif
258
259
260void
261Set3OperandsFromInstr(MachineInstr* minstr,
262		      InstructionNode* vmInstrNode,
263		      const TargetMachine& target,
264		      bool canDiscardResult,
265		      int op1Position,
266		      int op2Position,
267		      int resultPosition)
268{
269  assert(op1Position >= 0);
270  assert(resultPosition >= 0);
271
272  // operand 1
273  minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
274			    vmInstrNode->leftChild()->getValue());
275
276  // operand 2 (if any)
277  if (op2Position >= 0)
278    minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
279			      vmInstrNode->rightChild()->getValue());
280
281  // result operand: if it can be discarded, use a dead register if one exists
282  if (canDiscardResult && target.zeroRegNum >= 0)
283    minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
284  else
285    minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
286}
287
288
289MachineOperand::MachineOperandType
290ChooseRegOrImmed(Value* val,
291		 MachineOpCode opCode,
292		 const TargetMachine& target,
293		 bool canUseImmed,
294		 unsigned int& getMachineRegNum,
295		 int64_t& getImmedValue)
296{
297  MachineOperand::MachineOperandType opType =
298    MachineOperand::MO_VirtualRegister;
299  getMachineRegNum = 0;
300  getImmedValue = 0;
301
302  // Check for the common case first: argument is not constant
303  //
304  ConstPoolVal *CPV = val->castConstant();
305  if (!CPV) return opType;
306
307  if (CPV->getType() == Type::BoolTy) {
308    ConstPoolBool *CPB = (ConstPoolBool*)CPV;
309    if (!CPB->getValue() && target.zeroRegNum >= 0) {
310      getMachineRegNum = target.zeroRegNum;
311      return MachineOperand::MO_MachineRegister;
312    }
313
314    getImmedValue = 1;
315    return MachineOperand::MO_SignExtendedImmed;
316  }
317
318  if (!CPV->getType()->isIntegral()) return opType;
319
320  // Now get the constant value and check if it fits in the IMMED field.
321  // Take advantage of the fact that the max unsigned value will rarely
322  // fit into any IMMED field and ignore that case (i.e., cast smaller
323  // unsigned constants to signed).
324  //
325  int64_t intValue;
326  if (CPV->getType()->isSigned()) {
327    intValue = ((ConstPoolSInt*)CPV)->getValue();
328  } else {
329    uint64_t V = ((ConstPoolUInt*)CPV)->getValue();
330    if (V >= INT64_MAX) return opType;
331    intValue = (int64_t)V;
332  }
333
334  if (intValue == 0 && target.zeroRegNum >= 0){
335    opType = MachineOperand::MO_MachineRegister;
336    getMachineRegNum = target.zeroRegNum;
337  } else if (canUseImmed &&
338	     target.getInstrInfo().constantFitsInImmedField(opCode, intValue)) {
339    opType = MachineOperand::MO_SignExtendedImmed;
340    getImmedValue = intValue;
341  }
342
343  return opType;
344}
345
346
347void
348PrintMachineInstructions(const Method *const method)
349{
350  cout << "\n" << method->getReturnType()
351       << " \"" << method->getName() << "\"" << endl;
352
353  for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
354    {
355      BasicBlock* bb = *BI;
356      cout << "\n"
357	   << (bb->hasName()? bb->getName() : "Label")
358	   << " (" << bb << ")" << ":"
359	   << endl;
360
361      MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
362      for (unsigned i=0; i < mvec.size(); i++)
363	cout << "\t" << *mvec[i] << endl;
364    }
365  cout << endl << "End method \"" << method->getName() << "\""
366       << endl << endl;
367}
368
369#if 0
370
371void PrintMachineInstructions(Method * method)
372
373{
374  cout << "\n" << method->getReturnType()
375       << " \"" << method->getName() << "\"" << endl;
376
377  for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
378    {
379      const BasicBlock* bb = *BI;
380      cout << "\n"
381	   << (bb->hasName()? bb->getName() : "Label")
382	   << " (" << bb << ")" << ":"
383	   << endl;
384
385      const MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
386      for (unsigned i=0; i < mvec.size(); i++)
387	cout << "\t" << *mvec[i] << endl;
388    }
389  cout << endl << "End method \"" << method->getName() << "\""
390       << endl << endl;
391}
392#endif
393