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