MachineInstr.cpp revision df1c3b8398d1df253ebd389ac1068ec732a2f28f
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/Target/MachineRegInfo.h"
18#include "llvm/Method.h"
19#include "llvm/Instruction.h"
20
21
22
23//************************ Class Implementations **************************/
24
25// Constructor for instructions with fixed #operands (nearly all)
26MachineInstr::MachineInstr(MachineOpCode _opCode,
27			   OpCodeMask    _opCodeMask)
28  : opCode(_opCode),
29    opCodeMask(_opCodeMask),
30    operands(TargetInstrDescriptors[_opCode].numOperands)
31{
32  assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
33}
34
35// Constructor for instructions with variable #operands
36MachineInstr::MachineInstr(MachineOpCode _opCode,
37			   unsigned	 numOperands,
38			   OpCodeMask    _opCodeMask)
39  : opCode(_opCode),
40    opCodeMask(_opCodeMask),
41    operands(numOperands)
42{
43}
44
45void
46MachineInstr::SetMachineOperand(unsigned int i,
47				MachineOperand::MachineOperandType operandType,
48				Value* _val, bool isdef=false)
49{
50  assert(i < operands.size());
51  operands[i].Initialize(operandType, _val);
52  operands[i].isDef = isdef ||
53    TargetInstrDescriptors[opCode].resultPos == (int) i;
54}
55
56void
57MachineInstr::SetMachineOperand(unsigned int i,
58				MachineOperand::MachineOperandType operandType,
59				int64_t intValue, bool isdef=false)
60{
61  assert(i < operands.size());
62  operands[i].InitializeConst(operandType, intValue);
63  operands[i].isDef = isdef ||
64    TargetInstrDescriptors[opCode].resultPos == (int) i;
65}
66
67void
68MachineInstr::SetMachineOperand(unsigned int i,
69				int regNum, bool isdef=false)
70{
71  assert(i < operands.size());
72  operands[i].InitializeReg(regNum);
73  operands[i].isDef = isdef ||
74    TargetInstrDescriptors[opCode].resultPos == (int) i;
75}
76
77void
78MachineInstr::dump(unsigned int indent) const
79{
80  for (unsigned i=0; i < indent; i++)
81    cout << "    ";
82
83  cout << *this;
84}
85
86ostream&
87operator<< (ostream& os, const MachineInstr& minstr)
88{
89  os << TargetInstrDescriptors[minstr.opCode].opCodeString;
90
91  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
92    os << "\t" << minstr.getOperand(i);
93
94#undef DEBUG_VAL_OP_ITERATOR
95#ifdef DEBUG_VAL_OP_ITERATOR
96  os << endl << "\tValue operands are: ";
97  for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
98    {
99      const Value* val = *vo;
100      os << val << (vo.isDef()? "(def), " : ", ");
101    }
102#endif
103
104
105
106#if 1
107  // code for printing implict references
108
109  unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
110  if(  NumOfImpRefs > 0 ) {
111
112    os << "\tImplicit:";
113
114    for(unsigned z=0; z < NumOfImpRefs; z++) {
115      os << minstr.getImplicitRef(z);
116	  cout << "\t";
117    }
118  }
119
120#endif
121
122
123  os << endl;
124
125  return os;
126}
127
128static inline ostream&
129OutputOperand(ostream &os, const MachineOperand &mop)
130{
131  switch (mop.getOperandType())
132    {
133    case MachineOperand::MO_CCRegister:
134    case MachineOperand::MO_VirtualRegister:
135      return os << "(val " << mop.getVRegValue() << ")";
136    case MachineOperand::MO_MachineRegister:
137      return os << "("     << mop.getMachineRegNum() << ")";
138    default:
139      assert(0 && "Unknown operand type");
140      return os;
141    }
142}
143
144
145ostream&
146operator<<(ostream &os, const MachineOperand &mop)
147{
148  switch(mop.opType)
149    {
150    case MachineOperand::MO_VirtualRegister:
151    case MachineOperand::MO_MachineRegister:
152      os << "%reg";
153      return OutputOperand(os, mop);
154    case MachineOperand::MO_CCRegister:
155      os << "%ccreg";
156      return OutputOperand(os, mop);
157    case MachineOperand::MO_SignExtendedImmed:
158      return os << mop.immedVal;
159    case MachineOperand::MO_UnextendedImmed:
160      return os << mop.immedVal;
161    case MachineOperand::MO_PCRelativeDisp:
162      {
163        const Value* opVal = mop.getVRegValue();
164        bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
165        return os << "%disp("
166                  << (isLabel? "label " : "addr-of-val ")
167                  << opVal << ")";
168      }
169    default:
170      assert(0 && "Unrecognized operand type");
171      break;
172    }
173
174  return os;
175}
176
177
178void
179MachineCodeForMethod::putLocalVarAtOffsetFromFP(const Value* local,
180                                                int offset,
181                                                unsigned int size)
182{
183  offsetsFromFP[local] = offset;
184  incrementAutomaticVarsSize(size);
185}
186
187
188void
189MachineCodeForMethod::putLocalVarAtOffsetFromSP(const Value* local,
190                                                int offset,
191                                                unsigned int size)
192{
193  offsetsFromSP[local] = offset;
194  incrementAutomaticVarsSize(size);
195}
196
197
198int
199MachineCodeForMethod::getOffsetFromFP(const Value* local) const
200{
201  hash_map<const Value*, int>::const_iterator pair = offsetsFromFP.find(local);
202  assert(pair != offsetsFromFP.end() && "Offset from FP unknown for Value");
203  return (*pair).second;
204}
205
206
207int
208MachineCodeForMethod::getOffsetFromSP(const Value* local) const
209{
210  hash_map<const Value*, int>::const_iterator pair = offsetsFromSP.find(local);
211  assert(pair != offsetsFromSP.end() && "Offset from SP unknown for Value");
212  return (*pair).second;
213}
214
215
216void
217MachineCodeForMethod::dump() const
218{
219  cout << "\n" << method->getReturnType()
220       << " \"" << method->getName() << "\"" << endl;
221
222  for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
223    {
224      BasicBlock* bb = *BI;
225      cout << "\n"
226	   << (bb->hasName()? bb->getName() : "Label")
227	   << " (" << bb << ")" << ":"
228	   << endl;
229
230      MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
231      for (unsigned i=0; i < mvec.size(); i++)
232	cout << "\t" << *mvec[i];
233    }
234  cout << endl << "End method \"" << method->getName() << "\""
235       << endl << endl;
236}
237