MachineInstr.cpp revision 27a08935ca4ccf2121c2cf4bfbf148e2382c7762
1//===-- MachineInstr.cpp --------------------------------------------------===//
2//
3//===----------------------------------------------------------------------===//
4
5#include "llvm/CodeGen/MachineInstr.h"
6#include "llvm/Value.h"
7using std::cerr;
8
9
10// Constructor for instructions with fixed #operands (nearly all)
11MachineInstr::MachineInstr(MachineOpCode _opCode,
12			   OpCodeMask    _opCodeMask)
13  : opCode(_opCode),
14    opCodeMask(_opCodeMask),
15    operands(TargetInstrDescriptors[_opCode].numOperands)
16{
17  assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
18}
19
20// Constructor for instructions with variable #operands
21MachineInstr::MachineInstr(MachineOpCode _opCode,
22			   unsigned	 numOperands,
23			   OpCodeMask    _opCodeMask)
24  : opCode(_opCode),
25    opCodeMask(_opCodeMask),
26    operands(numOperands)
27{
28}
29
30//
31// Support for replacing opcode and operands of a MachineInstr in place.
32// This only resets the size of the operand vector and initializes it.
33// The new operands must be set explicitly later.
34//
35void
36MachineInstr::replace(MachineOpCode _opCode,
37                      unsigned	    numOperands,
38                      OpCodeMask    _opCodeMask)
39{
40  opCode = _opCode;
41  opCodeMask = _opCodeMask;
42  operands.clear();
43  operands.resize(numOperands);
44}
45
46void
47MachineInstr::SetMachineOperandVal(unsigned int i,
48                                   MachineOperand::MachineOperandType opType,
49                                   Value* _val,
50                                   bool isdef,
51                                   bool isDefAndUse)
52{
53  assert(i < operands.size());
54  operands[i].Initialize(opType, _val);
55  if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
56    operands[i].markDef();
57  if (isDefAndUse)
58    operands[i].markDefAndUse();
59}
60
61void
62MachineInstr::SetMachineOperandConst(unsigned int i,
63				MachineOperand::MachineOperandType operandType,
64                                     int64_t intValue)
65{
66  assert(i < operands.size());
67  assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
68         "immed. constant cannot be defined");
69  operands[i].InitializeConst(operandType, intValue);
70}
71
72void
73MachineInstr::SetMachineOperandReg(unsigned int i,
74                                   int regNum,
75                                   bool isdef,
76                                   bool isDefAndUse,
77                                   bool isCCReg)
78{
79  assert(i < operands.size());
80  operands[i].InitializeReg(regNum, isCCReg);
81  if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
82    operands[i].markDef();
83  if (isDefAndUse)
84    operands[i].markDefAndUse();
85  insertUsedReg(regNum);
86}
87
88void
89MachineInstr::SetRegForOperand(unsigned i, int regNum)
90{
91  operands[i].setRegForValue(regNum);
92  insertUsedReg(regNum);
93}
94
95
96// Subsitute all occurrences of Value* oldVal with newVal in all operands
97// and all implicit refs.  If defsOnly == true, substitute defs only.
98unsigned
99MachineInstr::substituteValue(const Value* oldVal, Value* newVal, bool defsOnly)
100{
101  unsigned numSubst = 0;
102
103  // Subsitute operands
104  for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O)
105    if (*O == oldVal)
106      if (!defsOnly || O.isDef())
107        {
108          O.getMachineOperand().value = newVal;
109          ++numSubst;
110        }
111
112  // Subsitute implicit refs
113  for (unsigned i=0, N=implicitRefs.size(); i < N; ++i)
114    if (getImplicitRef(i) == oldVal)
115      if (!defsOnly || implicitRefIsDefined(i))
116        {
117          implicitRefs[i].Val = newVal;
118          ++numSubst;
119        }
120
121  return numSubst;
122}
123
124
125void
126MachineInstr::dump() const
127{
128  cerr << "  " << *this;
129}
130
131static inline std::ostream&
132OutputValue(std::ostream &os, const Value* val)
133{
134  os << "(val ";
135  if (val && val->hasName())
136    return os << val->getName() << ")";
137  else
138    return os << (void*) val << ")";              // print address only
139}
140
141static inline std::ostream&
142OutputReg(std::ostream &os, unsigned int regNum)
143{
144  return os << "%mreg(" << regNum << ")";
145}
146
147std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr)
148{
149  os << TargetInstrDescriptors[minstr.opCode].opCodeString;
150
151  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
152    os << "\t" << minstr.getOperand(i);
153    if( minstr.operandIsDefined(i) )
154      os << "*";
155    if( minstr.operandIsDefinedAndUsed(i) )
156      os << "*";
157  }
158
159  // code for printing implict references
160  unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
161  if(  NumOfImpRefs > 0 ) {
162    os << "\tImplicit: ";
163    for(unsigned z=0; z < NumOfImpRefs; z++) {
164      OutputValue(os, minstr.getImplicitRef(z));
165      if( minstr.implicitRefIsDefined(z)) os << "*";
166      if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*";
167      os << "\t";
168    }
169  }
170
171  return os << "\n";
172}
173
174std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
175{
176  if (mop.opHiBits32())
177    os << "%lm(";
178  else if (mop.opLoBits32())
179    os << "%lo(";
180  else if (mop.opHiBits64())
181    os << "%hh(";
182  else if (mop.opLoBits64())
183    os << "%hm(";
184
185  switch(mop.opType)
186    {
187    case MachineOperand::MO_VirtualRegister:
188      os << "%reg";
189      OutputValue(os, mop.getVRegValue());
190      if (mop.hasAllocatedReg())
191        os << "==" << OutputReg(os, mop.getAllocatedRegNum());
192      break;
193    case MachineOperand::MO_CCRegister:
194      os << "%ccreg";
195      OutputValue(os, mop.getVRegValue());
196      if (mop.hasAllocatedReg())
197        os << "==" << OutputReg(os, mop.getAllocatedRegNum());
198      break;
199    case MachineOperand::MO_MachineRegister:
200      OutputReg(os, mop.getMachineRegNum());
201      break;
202    case MachineOperand::MO_SignExtendedImmed:
203      os << (long)mop.immedVal;
204      break;
205    case MachineOperand::MO_UnextendedImmed:
206      os << (long)mop.immedVal;
207      break;
208    case MachineOperand::MO_PCRelativeDisp:
209      {
210        const Value* opVal = mop.getVRegValue();
211        bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
212        os << "%disp(" << (isLabel? "label " : "addr-of-val ");
213        if (opVal->hasName())
214          os << opVal->getName();
215        else
216          os << (const void*) opVal;
217        os << ")";
218        break;
219      }
220    default:
221      assert(0 && "Unrecognized operand type");
222      break;
223    }
224
225  if (mop.flags &
226      (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 |
227       MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64))
228    os << ")";
229
230  return os;
231}
232