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