MachineInstr.cpp revision a2bae305fb5a870c4ef753ed290a7ddea73ec82b
1//===-- MachineInstr.cpp --------------------------------------------------===//
2//
3//===----------------------------------------------------------------------===//
4
5#include "llvm/CodeGen/MachineInstr.h"
6#include "llvm/Value.h"
7#include "llvm/Target/MachineInstrInfo.h"  // FIXME: shouldn't need this!
8using std::cerr;
9
10// Global variable holding an array of descriptors for machine instructions.
11// The actual object needs to be created separately for each target machine.
12// This variable is initialized and reset by class MachineInstrInfo.
13//
14// FIXME: This should be a property of the target so that more than one target
15// at a time can be active...
16//
17extern const MachineInstrDescriptor *TargetInstrDescriptors;
18
19// Constructor for instructions with fixed #operands (nearly all)
20MachineInstr::MachineInstr(MachineOpCode _opCode)
21  : opCode(_opCode),
22    operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()),
23    numImplicitRefs(0)
24{
25  assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
26}
27
28// Constructor for instructions with variable #operands
29MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned  numOperands)
30  : opCode(OpCode),
31    operands(numOperands, MachineOperand()),
32    numImplicitRefs(0)
33{
34}
35
36MachineInstr::MachineInstr(MachineOpCode Opcode, unsigned numOperands,
37                           bool XX, bool YY)
38  : opCode(Opcode),
39    numImplicitRefs(0)
40{
41  operands.reserve(numOperands);
42}
43
44// OperandComplete - Return true if it's illegal to add a new operand
45bool MachineInstr::OperandsComplete() const
46{
47  int NumOperands = TargetInstrDescriptors[opCode].numOperands;
48  if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands)
49    return true;  // Broken!
50  return false;
51}
52
53
54//
55// Support for replacing opcode and operands of a MachineInstr in place.
56// This only resets the size of the operand vector and initializes it.
57// The new operands must be set explicitly later.
58//
59void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands)
60{
61  assert(getNumImplicitRefs() == 0 &&
62         "This is probably broken because implicit refs are going to be lost.");
63  opCode = Opcode;
64  operands.clear();
65  operands.resize(numOperands, MachineOperand());
66}
67
68void
69MachineInstr::SetMachineOperandVal(unsigned i,
70                                   MachineOperand::MachineOperandType opType,
71                                   Value* V,
72                                   bool isdef,
73                                   bool isDefAndUse)
74{
75  assert(i < operands.size());          // may be explicit or implicit op
76  operands[i].opType = opType;
77  operands[i].value = V;
78  operands[i].regNum = -1;
79  operands[i].flags = 0;
80
81  if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
82    operands[i].markDef();
83  if (isDefAndUse)
84    operands[i].markDefAndUse();
85}
86
87void
88MachineInstr::SetMachineOperandConst(unsigned i,
89				MachineOperand::MachineOperandType operandType,
90                                     int64_t intValue)
91{
92  assert(i < getNumOperands());          // must be explicit op
93  assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
94         "immed. constant cannot be defined");
95
96  operands[i].opType = operandType;
97  operands[i].value = NULL;
98  operands[i].immedVal = intValue;
99  operands[i].regNum = -1;
100  operands[i].flags = 0;
101}
102
103void
104MachineInstr::SetMachineOperandReg(unsigned i,
105                                   int regNum,
106                                   bool isdef) {
107  assert(i < getNumOperands());          // must be explicit op
108
109  operands[i].opType = MachineOperand::MO_MachineRegister;
110  operands[i].value = NULL;
111  operands[i].regNum = regNum;
112  operands[i].flags = 0;
113
114  if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
115    operands[i].markDef();
116  insertUsedReg(regNum);
117}
118
119void
120MachineInstr::SetRegForOperand(unsigned i, int regNum)
121{
122  assert(i < getNumOperands());          // must be explicit op
123  operands[i].setRegForValue(regNum);
124  insertUsedReg(regNum);
125}
126
127
128// Subsitute all occurrences of Value* oldVal with newVal in all operands
129// and all implicit refs.  If defsOnly == true, substitute defs only.
130unsigned
131MachineInstr::substituteValue(const Value* oldVal, Value* newVal, bool defsOnly)
132{
133  unsigned numSubst = 0;
134
135  // Subsitute operands
136  for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O)
137    if (*O == oldVal)
138      if (!defsOnly || O.isDef())
139        {
140          O.getMachineOperand().value = newVal;
141          ++numSubst;
142        }
143
144  // Subsitute implicit refs
145  for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i)
146    if (getImplicitRef(i) == oldVal)
147      if (!defsOnly || implicitRefIsDefined(i))
148        {
149          getImplicitOp(i).value = newVal;
150          ++numSubst;
151        }
152
153  return numSubst;
154}
155
156
157void
158MachineInstr::dump() const
159{
160  cerr << "  " << *this;
161}
162
163static inline std::ostream&
164OutputValue(std::ostream &os, const Value* val)
165{
166  os << "(val ";
167  if (val && val->hasName())
168    return os << val->getName() << ")";
169  else
170    return os << (void*) val << ")";              // print address only
171}
172
173static inline std::ostream&
174OutputReg(std::ostream &os, unsigned int regNum)
175{
176  return os << "%mreg(" << regNum << ")";
177}
178
179std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr)
180{
181  os << TargetInstrDescriptors[minstr.opCode].Name;
182
183  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
184    os << "\t" << minstr.getOperand(i);
185    if( minstr.operandIsDefined(i) )
186      os << "*";
187    if( minstr.operandIsDefinedAndUsed(i) )
188      os << "*";
189  }
190
191  // code for printing implict references
192  unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
193  if(  NumOfImpRefs > 0 ) {
194    os << "\tImplicit: ";
195    for(unsigned z=0; z < NumOfImpRefs; z++) {
196      OutputValue(os, minstr.getImplicitRef(z));
197      if( minstr.implicitRefIsDefined(z)) os << "*";
198      if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*";
199      os << "\t";
200    }
201  }
202
203  return os << "\n";
204}
205
206std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
207{
208  if (mop.opHiBits32())
209    os << "%lm(";
210  else if (mop.opLoBits32())
211    os << "%lo(";
212  else if (mop.opHiBits64())
213    os << "%hh(";
214  else if (mop.opLoBits64())
215    os << "%hm(";
216
217  switch(mop.opType)
218    {
219    case MachineOperand::MO_VirtualRegister:
220      os << "%reg";
221      OutputValue(os, mop.getVRegValue());
222      if (mop.hasAllocatedReg())
223        os << "==" << OutputReg(os, mop.getAllocatedRegNum());
224      break;
225    case MachineOperand::MO_CCRegister:
226      os << "%ccreg";
227      OutputValue(os, mop.getVRegValue());
228      if (mop.hasAllocatedReg())
229        os << "==" << OutputReg(os, mop.getAllocatedRegNum());
230      break;
231    case MachineOperand::MO_MachineRegister:
232      OutputReg(os, mop.getMachineRegNum());
233      break;
234    case MachineOperand::MO_SignExtendedImmed:
235      os << (long)mop.immedVal;
236      break;
237    case MachineOperand::MO_UnextendedImmed:
238      os << (long)mop.immedVal;
239      break;
240    case MachineOperand::MO_PCRelativeDisp:
241      {
242        const Value* opVal = mop.getVRegValue();
243        bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
244        os << "%disp(" << (isLabel? "label " : "addr-of-val ");
245        if (opVal->hasName())
246          os << opVal->getName();
247        else
248          os << (const void*) opVal;
249        os << ")";
250        break;
251      }
252    default:
253      assert(0 && "Unrecognized operand type");
254      break;
255    }
256
257  if (mop.flags &
258      (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 |
259       MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64))
260    os << ")";
261
262  return os;
263}
264