MachineInstr.cpp revision 610234d5c9582e2645738ad9c347b855962122b7
1//===-- MachineInstr.cpp --------------------------------------------------===//
2//
3//===----------------------------------------------------------------------===//
4
5#include "llvm/CodeGen/MachineInstr.h"
6#include "llvm/CodeGen/MachineBasicBlock.h"
7#include "llvm/Value.h"
8#include "llvm/Target/TargetMachine.h"
9#include "llvm/Target/TargetInstrInfo.h"
10#include "llvm/Target/MRegisterInfo.h"
11
12// Global variable holding an array of descriptors for machine instructions.
13// The actual object needs to be created separately for each target machine.
14// This variable is initialized and reset by class TargetInstrInfo.
15//
16// FIXME: This should be a property of the target so that more than one target
17// at a time can be active...
18//
19extern const TargetInstrDescriptor *TargetInstrDescriptors;
20
21// Constructor for instructions with variable #operands
22MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned  numOperands)
23  : opCode(OpCode),
24    opCodeFlags(0),
25    operands(numOperands, MachineOperand()),
26    numImplicitRefs(0)
27{
28}
29
30/// MachineInstr ctor - This constructor only does a _reserve_ of the operands,
31/// not a resize for them.  It is expected that if you use this that you call
32/// add* methods below to fill up the operands, instead of the Set methods.
33/// Eventually, the "resizing" ctors will be phased out.
34///
35MachineInstr::MachineInstr(MachineOpCode Opcode, unsigned numOperands,
36                           bool XX, bool YY)
37  : opCode(Opcode),
38    opCodeFlags(0),
39    numImplicitRefs(0)
40{
41  operands.reserve(numOperands);
42}
43
44/// MachineInstr ctor - Work exactly the same as the ctor above, except that the
45/// MachineInstr is created and added to the end of the specified basic block.
46///
47MachineInstr::MachineInstr(MachineBasicBlock *MBB, MachineOpCode Opcode,
48                           unsigned numOperands)
49  : opCode(Opcode),
50    opCodeFlags(0),
51    numImplicitRefs(0)
52{
53  assert(MBB && "Cannot use inserting ctor with null basic block!");
54  operands.reserve(numOperands);
55  MBB->push_back(this);  // Add instruction to end of basic block!
56}
57
58
59// OperandComplete - Return true if it's illegal to add a new operand
60bool MachineInstr::OperandsComplete() const
61{
62  int NumOperands = TargetInstrDescriptors[opCode].numOperands;
63  if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands)
64    return true;  // Broken: we have all the operands of this instruction!
65  return false;
66}
67
68
69//
70// Support for replacing opcode and operands of a MachineInstr in place.
71// This only resets the size of the operand vector and initializes it.
72// The new operands must be set explicitly later.
73//
74void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands)
75{
76  assert(getNumImplicitRefs() == 0 &&
77         "This is probably broken because implicit refs are going to be lost.");
78  opCode = Opcode;
79  operands.clear();
80  operands.resize(numOperands, MachineOperand());
81}
82
83void MachineInstr::SetMachineOperandVal(unsigned i,
84                                        MachineOperand::MachineOperandType opTy,
85                                        Value* V) {
86  assert(i < operands.size());          // may be explicit or implicit op
87  operands[i].opType = opTy;
88  operands[i].value = V;
89  operands[i].regNum = -1;
90}
91
92void
93MachineInstr::SetMachineOperandConst(unsigned i,
94				MachineOperand::MachineOperandType operandType,
95                                     int64_t intValue)
96{
97  assert(i < getNumOperands());          // must be explicit op
98  assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
99         "immed. constant cannot be defined");
100
101  operands[i].opType = operandType;
102  operands[i].value = NULL;
103  operands[i].immedVal = intValue;
104  operands[i].regNum = -1;
105  operands[i].flags = 0;
106}
107
108void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) {
109  assert(i < getNumOperands());          // must be explicit op
110
111  operands[i].opType = MachineOperand::MO_MachineRegister;
112  operands[i].value = NULL;
113  operands[i].regNum = regNum;
114}
115
116void
117MachineInstr::SetRegForOperand(unsigned i, int regNum)
118{
119  assert(i < getNumOperands());          // must be explicit op
120  operands[i].setRegForValue(regNum);
121}
122
123void
124MachineInstr::SetRegForImplicitRef(unsigned i, int regNum)
125{
126  getImplicitOp(i).setRegForValue(regNum);
127}
128
129
130// Subsitute all occurrences of Value* oldVal with newVal in all operands
131// and all implicit refs.
132// If defsOnly == true, substitute defs only.
133unsigned
134MachineInstr::substituteValue(const Value* oldVal, Value* newVal,
135                              bool defsOnly, bool notDefsAndUses,
136                              bool& someArgsWereIgnored)
137{
138  assert((defsOnly || !notDefsAndUses) &&
139         "notDefsAndUses is irrelevant if defsOnly == false.");
140
141  unsigned numSubst = 0;
142
143  // Subsitute operands
144  for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O)
145    if (*O == oldVal)
146      if (!defsOnly ||
147          notDefsAndUses && O.isDefOnly() ||
148          !notDefsAndUses && !O.isUseOnly())
149        {
150          O.getMachineOperand().value = newVal;
151          ++numSubst;
152        }
153      else
154        someArgsWereIgnored = true;
155
156  // Subsitute implicit refs
157  for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i)
158    if (getImplicitRef(i) == oldVal)
159      if (!defsOnly ||
160          notDefsAndUses && getImplicitOp(i).opIsDefOnly() ||
161          !notDefsAndUses && !getImplicitOp(i).opIsUse())
162        {
163          getImplicitOp(i).value = newVal;
164          ++numSubst;
165        }
166      else
167        someArgsWereIgnored = true;
168
169  return numSubst;
170}
171
172
173void
174MachineInstr::dump() const
175{
176  std::cerr << "  " << *this;
177}
178
179static inline std::ostream&
180OutputValue(std::ostream &os, const Value* val)
181{
182  os << "(val ";
183  os << (void*) val;                    // print address always
184  if (val && val->hasName())
185    os << " " << val->getName() << ")"; // print name also, if available
186  return os;
187}
188
189static inline void OutputReg(std::ostream &os, unsigned RegNo,
190                             const MRegisterInfo *MRI = 0) {
191  if (MRI) {
192    if (RegNo < MRegisterInfo::FirstVirtualRegister)
193      os << "%" << MRI->get(RegNo).Name;
194    else
195      os << "%reg" << RegNo;
196  } else
197    os << "%mreg(" << RegNo << ")";
198}
199
200static void print(const MachineOperand &MO, std::ostream &OS,
201                  const TargetMachine &TM) {
202  const MRegisterInfo *MRI = TM.getRegisterInfo();
203  bool CloseParen = true;
204  if (MO.opHiBits32())
205    OS << "%lm(";
206  else if (MO.opLoBits32())
207    OS << "%lo(";
208  else if (MO.opHiBits64())
209    OS << "%hh(";
210  else if (MO.opLoBits64())
211    OS << "%hm(";
212  else
213    CloseParen = false;
214
215  switch (MO.getType()) {
216  case MachineOperand::MO_VirtualRegister:
217    if (MO.getVRegValue()) {
218      OS << "%reg";
219      OutputValue(OS, MO.getVRegValue());
220      if (MO.hasAllocatedReg())
221        OS << "==";
222    }
223    if (MO.hasAllocatedReg())
224      OutputReg(OS, MO.getAllocatedRegNum(), MRI);
225    break;
226  case MachineOperand::MO_CCRegister:
227    OS << "%ccreg";
228    OutputValue(OS, MO.getVRegValue());
229    if (MO.hasAllocatedReg()) {
230      OS << "==";
231      OutputReg(OS, MO.getAllocatedRegNum(), MRI);
232    }
233    break;
234  case MachineOperand::MO_MachineRegister:
235    OutputReg(OS, MO.getMachineRegNum(), MRI);
236    break;
237  case MachineOperand::MO_SignExtendedImmed:
238    OS << (long)MO.getImmedValue();
239    break;
240  case MachineOperand::MO_UnextendedImmed:
241    OS << (long)MO.getImmedValue();
242    break;
243  case MachineOperand::MO_PCRelativeDisp: {
244    const Value* opVal = MO.getVRegValue();
245    bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
246    OS << "%disp(" << (isLabel? "label " : "addr-of-val ");
247    if (opVal->hasName())
248      OS << opVal->getName();
249    else
250      OS << (const void*) opVal;
251    OS << ")";
252    break;
253  }
254  case MachineOperand::MO_MachineBasicBlock:
255    OS << "bb<"
256       << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
257       << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
258    break;
259  case MachineOperand::MO_FrameIndex:
260    OS << "<fi#" << MO.getFrameIndex() << ">";
261    break;
262  case MachineOperand::MO_ConstantPoolIndex:
263    OS << "<cp#" << MO.getConstantPoolIndex() << ">";
264    break;
265  case MachineOperand::MO_GlobalAddress:
266    OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
267    break;
268  case MachineOperand::MO_ExternalSymbol:
269    OS << "<es:" << MO.getSymbolName() << ">";
270    break;
271  default:
272    assert(0 && "Unrecognized operand type");
273  }
274
275  if (CloseParen)
276    OS << ")";
277}
278
279void MachineInstr::print(std::ostream &OS, const TargetMachine &TM) const {
280  unsigned StartOp = 0;
281
282   // Specialize printing if op#0 is definition
283  if (getNumOperands() &&
284      (getOperand(0).opIsDefOnly() || getOperand(0).opIsDefAndUse())) {
285    ::print(getOperand(0), OS, TM);
286    OS << " = ";
287    ++StartOp;   // Don't print this operand again!
288  }
289  OS << TM.getInstrInfo().getName(getOpcode());
290
291  for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
292    const MachineOperand& mop = getOperand(i);
293    if (i != StartOp)
294      OS << ",";
295    OS << " ";
296    ::print(mop, OS, TM);
297
298    if (mop.opIsDefAndUse())
299      OS << "<def&use>";
300    else if (mop.opIsDefOnly())
301      OS << "<def>";
302  }
303
304  // code for printing implict references
305  if (getNumImplicitRefs()) {
306    OS << "\tImplicitRefs: ";
307    for(unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) {
308      OS << "\t";
309      OutputValue(OS, getImplicitRef(i));
310      if (getImplicitOp(i).opIsDefAndUse())
311        OS << "<def&use>";
312      else if (getImplicitOp(i).opIsDefOnly())
313        OS << "<def>";
314    }
315  }
316
317  OS << "\n";
318}
319
320
321std::ostream &operator<<(std::ostream& os, const MachineInstr& MI)
322{
323  os << TargetInstrDescriptors[MI.opCode].Name;
324
325  for (unsigned i=0, N=MI.getNumOperands(); i < N; i++) {
326    os << "\t" << MI.getOperand(i);
327    if (MI.getOperand(i).opIsDefOnly())
328      os << "<d>";
329    if (MI.getOperand(i).opIsDefAndUse())
330      os << "<d&u>";
331  }
332
333  // code for printing implict references
334  unsigned NumOfImpRefs = MI.getNumImplicitRefs();
335  if (NumOfImpRefs > 0) {
336    os << "\tImplicit: ";
337    for (unsigned z=0; z < NumOfImpRefs; z++) {
338      OutputValue(os, MI.getImplicitRef(z));
339      if (MI.getImplicitOp(z).opIsDefOnly()) os << "<d>";
340      if (MI.getImplicitOp(z).opIsDefAndUse()) os << "<d&u>";
341      os << "\t";
342    }
343  }
344
345  return os << "\n";
346}
347
348std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO)
349{
350  if (MO.opHiBits32())
351    OS << "%lm(";
352  else if (MO.opLoBits32())
353    OS << "%lo(";
354  else if (MO.opHiBits64())
355    OS << "%hh(";
356  else if (MO.opLoBits64())
357    OS << "%hm(";
358
359  switch (MO.getType())
360    {
361    case MachineOperand::MO_VirtualRegister:
362      if (MO.hasAllocatedReg())
363        OutputReg(OS, MO.getAllocatedRegNum());
364
365      if (MO.getVRegValue()) {
366	if (MO.hasAllocatedReg()) OS << "==";
367	OS << "%vreg";
368	OutputValue(OS, MO.getVRegValue());
369      }
370      break;
371    case MachineOperand::MO_CCRegister:
372      OS << "%ccreg";
373      OutputValue(OS, MO.getVRegValue());
374      if (MO.hasAllocatedReg()) {
375        OS << "==";
376        OutputReg(OS, MO.getAllocatedRegNum());
377      }
378      break;
379    case MachineOperand::MO_MachineRegister:
380      OutputReg(OS, MO.getMachineRegNum());
381      break;
382    case MachineOperand::MO_SignExtendedImmed:
383      OS << (long)MO.getImmedValue();
384      break;
385    case MachineOperand::MO_UnextendedImmed:
386      OS << (long)MO.getImmedValue();
387      break;
388    case MachineOperand::MO_PCRelativeDisp:
389      {
390        const Value* opVal = MO.getVRegValue();
391        bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
392        OS << "%disp(" << (isLabel? "label " : "addr-of-val ");
393        if (opVal->hasName())
394          OS << opVal->getName();
395        else
396          OS << (const void*) opVal;
397        OS << ")";
398        break;
399      }
400    case MachineOperand::MO_MachineBasicBlock:
401      OS << "bb<"
402         << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
403         << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
404      break;
405    case MachineOperand::MO_FrameIndex:
406      OS << "<fi#" << MO.getFrameIndex() << ">";
407      break;
408    case MachineOperand::MO_ConstantPoolIndex:
409      OS << "<cp#" << MO.getConstantPoolIndex() << ">";
410      break;
411    case MachineOperand::MO_GlobalAddress:
412      OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
413      break;
414    case MachineOperand::MO_ExternalSymbol:
415      OS << "<es:" << MO.getSymbolName() << ">";
416      break;
417    default:
418      assert(0 && "Unrecognized operand type");
419      break;
420    }
421
422  if (MO.flags &
423      (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 |
424       MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64))
425    OS << ")";
426
427  return OS;
428}
429