MachineInstr.cpp revision 8bcb042f22f06d034f18aee8cb5dd0a04745fd97
1227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//===-- MachineInstr.cpp --------------------------------------------------===//
2227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//
3227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//                     The LLVM Compiler Infrastructure
4227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//
5227a1ecca7f44cb07e74aa8f1bd24b29df629499florian// This file was developed by the LLVM research group and is distributed under
6227a1ecca7f44cb07e74aa8f1bd24b29df629499florian// the University of Illinois Open Source License. See LICENSE.TXT for details.
7227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//
8227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//===----------------------------------------------------------------------===//
9227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//
10227a1ecca7f44cb07e74aa8f1bd24b29df629499florian// Methods common to all machine instructions.
11227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//
12227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//===----------------------------------------------------------------------===//
13227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
14227a1ecca7f44cb07e74aa8f1bd24b29df629499florian#include "llvm/CodeGen/MachineInstr.h"
15227a1ecca7f44cb07e74aa8f1bd24b29df629499florian#include "llvm/CodeGen/MachineFunction.h"
16227a1ecca7f44cb07e74aa8f1bd24b29df629499florian#include "llvm/Target/TargetMachine.h"
17227a1ecca7f44cb07e74aa8f1bd24b29df629499florian#include "llvm/Target/TargetInstrInfo.h"
18227a1ecca7f44cb07e74aa8f1bd24b29df629499florian#include "llvm/Target/MRegisterInfo.h"
19227a1ecca7f44cb07e74aa8f1bd24b29df629499florian#include "llvm/Support/LeakDetector.h"
20227a1ecca7f44cb07e74aa8f1bd24b29df629499florian#include <iostream>
21866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian
22227a1ecca7f44cb07e74aa8f1bd24b29df629499florianusing namespace llvm;
23227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
24227a1ecca7f44cb07e74aa8f1bd24b29df629499florian// Global variable holding an array of descriptors for machine instructions.
25227a1ecca7f44cb07e74aa8f1bd24b29df629499florian// The actual object needs to be created separately for each target machine.
26227a1ecca7f44cb07e74aa8f1bd24b29df629499florian// This variable is initialized and reset by class TargetInstrInfo.
27227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//
28227a1ecca7f44cb07e74aa8f1bd24b29df629499florian// FIXME: This should be a property of the target so that more than one target
29227a1ecca7f44cb07e74aa8f1bd24b29df629499florian// at a time can be active...
30227a1ecca7f44cb07e74aa8f1bd24b29df629499florian//
31227a1ecca7f44cb07e74aa8f1bd24b29df629499floriannamespace llvm {
32227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  extern const TargetInstrDescriptor *TargetInstrDescriptors;
33866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian}
34227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
35227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
36227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// opcode 0 and no operands.
37227a1ecca7f44cb07e74aa8f1bd24b29df629499florianMachineInstr::MachineInstr()
38227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  : Opcode(0), NumImplicitOps(0), parent(0) {
39227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  // Make sure that we get added to a machine basicblock
40227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  LeakDetector::addGarbageObject(this);
41227a1ecca7f44cb07e74aa8f1bd24b29df629499florian}
42227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
43227a1ecca7f44cb07e74aa8f1bd24b29df629499florianvoid MachineInstr::addImplicitDefUseOperands(const TargetInstrDescriptor &TID) {
44227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  if (TID.ImplicitDefs)
45227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs) {
46227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      MachineOperand Op;
47227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.opType = MachineOperand::MO_Register;
48227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.IsDef = true;
49227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.IsImp = true;
50227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.IsKill = false;
51227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.IsDead = false;
52227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.contents.RegNo = *ImpDefs;
53227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.offset = 0;
54227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Operands.push_back(Op);
55227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    }
56227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  if (TID.ImplicitUses)
57227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses) {
58227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      MachineOperand Op;
59227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.opType = MachineOperand::MO_Register;
60227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.IsDef = false;
61227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.IsImp = true;
62227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.IsKill = false;
63227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.IsDead = false;
64227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.contents.RegNo = *ImpUses;
65227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Op.offset = 0;
66227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      Operands.push_back(Op);
67227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    }
68227a1ecca7f44cb07e74aa8f1bd24b29df629499florian}
69227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
70227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// MachineInstr ctor - This constructor create a MachineInstr and add the
71227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// implicit operands. It reserves space for number of operands specified by
72227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// TargetInstrDescriptor or the numOperands if it is not zero. (for
73227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// instructions with variable number of operands).
74227a1ecca7f44cb07e74aa8f1bd24b29df629499florianMachineInstr::MachineInstr(const TargetInstrDescriptor &TID)
75227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  : Opcode(TID.Opcode), NumImplicitOps(0), parent(0) {
76227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  if (TID.ImplicitDefs)
77227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs)
78227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      NumImplicitOps++;
79227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  if (TID.ImplicitUses)
80227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses)
81227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      NumImplicitOps++;
82227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  Operands.reserve(NumImplicitOps + TID.numOperands);
83227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  addImplicitDefUseOperands(TID);
84227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  // Make sure that we get added to a machine basicblock
85227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  LeakDetector::addGarbageObject(this);
86227a1ecca7f44cb07e74aa8f1bd24b29df629499florian}
87227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
88227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// MachineInstr ctor - Work exactly the same as the ctor above, except that the
89227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// MachineInstr is created and added to the end of the specified basic block.
90227a1ecca7f44cb07e74aa8f1bd24b29df629499florian///
91227a1ecca7f44cb07e74aa8f1bd24b29df629499florianMachineInstr::MachineInstr(MachineBasicBlock *MBB,
92227a1ecca7f44cb07e74aa8f1bd24b29df629499florian                           const TargetInstrDescriptor &TID)
93227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  : Opcode(TID.Opcode), NumImplicitOps(0), parent(0) {
94227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  assert(MBB && "Cannot use inserting ctor with null basic block!");
95227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  if (TID.ImplicitDefs)
96227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    for (const unsigned *ImpDefs = TID.ImplicitDefs; *ImpDefs; ++ImpDefs)
97227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      NumImplicitOps++;
98227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  if (TID.ImplicitUses)
99227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    for (const unsigned *ImpUses = TID.ImplicitUses; *ImpUses; ++ImpUses)
100227a1ecca7f44cb07e74aa8f1bd24b29df629499florian      NumImplicitOps++;
101227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  Operands.reserve(NumImplicitOps + TID.numOperands);
102227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  addImplicitDefUseOperands(TID);
103227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  // Make sure that we get added to a machine basicblock
104227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  LeakDetector::addGarbageObject(this);
105227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  MBB->push_back(this);  // Add instruction to end of basic block!
106227a1ecca7f44cb07e74aa8f1bd24b29df629499florian}
107227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
108227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// MachineInstr ctor - Copies MachineInstr arg exactly
109227a1ecca7f44cb07e74aa8f1bd24b29df629499florian///
110227a1ecca7f44cb07e74aa8f1bd24b29df629499florianMachineInstr::MachineInstr(const MachineInstr &MI) {
111227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  Opcode = MI.getOpcode();
112227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  NumImplicitOps = MI.NumImplicitOps;
113227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  Operands.reserve(MI.getNumOperands());
114227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
115227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  // Add operands
116227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  for (unsigned i = 0; i != MI.getNumOperands(); ++i)
117227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    Operands.push_back(MI.getOperand(i));
118227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
119227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  // Set parent, next, and prev to null
120227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  parent = 0;
121227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  prev = 0;
122227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  next = 0;
123227a1ecca7f44cb07e74aa8f1bd24b29df629499florian}
124227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
125227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
126227a1ecca7f44cb07e74aa8f1bd24b29df629499florianMachineInstr::~MachineInstr() {
127227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  LeakDetector::removeGarbageObject(this);
128227a1ecca7f44cb07e74aa8f1bd24b29df629499florian}
129227a1ecca7f44cb07e74aa8f1bd24b29df629499florian
130227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// removeFromParent - This method unlinks 'this' from the containing basic
131227a1ecca7f44cb07e74aa8f1bd24b29df629499florian/// block, and returns it, but does not delete it.
132866862a87a06a70e2e0c0d7e5c773e252db8ecddflorianMachineInstr *MachineInstr::removeFromParent() {
133866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian  assert(getParent() && "Not embedded in a basic block!");
134866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian  getParent()->remove(this);
135866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian  return this;
136866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian}
137866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian
138866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian
139866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian/// OperandComplete - Return true if it's illegal to add a new operand
140866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian///
141866862a87a06a70e2e0c0d7e5c773e252db8ecddflorianbool MachineInstr::OperandsComplete() const {
142866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian  unsigned short NumOperands = TargetInstrDescriptors[Opcode].numOperands;
143866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian  if ((TargetInstrDescriptors[Opcode].Flags & M_VARIABLE_OPS) == 0 &&
144866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian      getNumOperands()-NumImplicitOps >= NumOperands)
145866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian    return true;  // Broken: we have all the operands of this instruction!
146866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian  return false;
147866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian}
148866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian
149866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian/// isIdenticalTo - Return true if this operand is identical to the specified
150866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian/// operand.
151866862a87a06a70e2e0c0d7e5c773e252db8ecddflorianbool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
152e72941d971389b49ba52e1b389eb713bd043ac13florian  if (getType() != Other.getType()) return false;
153e72941d971389b49ba52e1b389eb713bd043ac13florian
154e72941d971389b49ba52e1b389eb713bd043ac13florian  switch (getType()) {
155e72941d971389b49ba52e1b389eb713bd043ac13florian  default: assert(0 && "Unrecognized operand type");
156e72941d971389b49ba52e1b389eb713bd043ac13florian  case MachineOperand::MO_Register:
157e72941d971389b49ba52e1b389eb713bd043ac13florian    return getReg() == Other.getReg() && isDef() == Other.isDef();
158e72941d971389b49ba52e1b389eb713bd043ac13florian  case MachineOperand::MO_Immediate:
159e72941d971389b49ba52e1b389eb713bd043ac13florian    return getImm() == Other.getImm();
160227a1ecca7f44cb07e74aa8f1bd24b29df629499florian  case MachineOperand::MO_MachineBasicBlock:
161227a1ecca7f44cb07e74aa8f1bd24b29df629499florian    return getMBB() == Other.getMBB();
162  case MachineOperand::MO_FrameIndex:
163    return getFrameIndex() == Other.getFrameIndex();
164  case MachineOperand::MO_ConstantPoolIndex:
165    return getConstantPoolIndex() == Other.getConstantPoolIndex() &&
166           getOffset() == Other.getOffset();
167  case MachineOperand::MO_JumpTableIndex:
168    return getJumpTableIndex() == Other.getJumpTableIndex();
169  case MachineOperand::MO_GlobalAddress:
170    return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset();
171  case MachineOperand::MO_ExternalSymbol:
172    return !strcmp(getSymbolName(), Other.getSymbolName()) &&
173           getOffset() == Other.getOffset();
174  }
175}
176
177void MachineInstr::dump() const {
178  std::cerr << "  " << *this;
179}
180
181static inline void OutputReg(std::ostream &os, unsigned RegNo,
182                             const MRegisterInfo *MRI = 0) {
183  if (!RegNo || MRegisterInfo::isPhysicalRegister(RegNo)) {
184    if (MRI)
185      os << "%" << MRI->get(RegNo).Name;
186    else
187      os << "%mreg(" << RegNo << ")";
188  } else
189    os << "%reg" << RegNo;
190}
191
192static void print(const MachineOperand &MO, std::ostream &OS,
193                  const TargetMachine *TM) {
194  const MRegisterInfo *MRI = 0;
195
196  if (TM) MRI = TM->getRegisterInfo();
197
198  switch (MO.getType()) {
199  case MachineOperand::MO_Register:
200    OutputReg(OS, MO.getReg(), MRI);
201    break;
202  case MachineOperand::MO_Immediate:
203    OS << MO.getImmedValue();
204    break;
205  case MachineOperand::MO_MachineBasicBlock:
206    OS << "mbb<"
207       << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
208       << "," << (void*)MO.getMachineBasicBlock() << ">";
209    break;
210  case MachineOperand::MO_FrameIndex:
211    OS << "<fi#" << MO.getFrameIndex() << ">";
212    break;
213  case MachineOperand::MO_ConstantPoolIndex:
214    OS << "<cp#" << MO.getConstantPoolIndex() << ">";
215    break;
216  case MachineOperand::MO_JumpTableIndex:
217    OS << "<jt#" << MO.getJumpTableIndex() << ">";
218    break;
219  case MachineOperand::MO_GlobalAddress:
220    OS << "<ga:" << ((Value*)MO.getGlobal())->getName();
221    if (MO.getOffset()) OS << "+" << MO.getOffset();
222    OS << ">";
223    break;
224  case MachineOperand::MO_ExternalSymbol:
225    OS << "<es:" << MO.getSymbolName();
226    if (MO.getOffset()) OS << "+" << MO.getOffset();
227    OS << ">";
228    break;
229  default:
230    assert(0 && "Unrecognized operand type");
231  }
232}
233
234void MachineInstr::print(std::ostream &OS, const TargetMachine *TM) const {
235  unsigned StartOp = 0;
236
237   // Specialize printing if op#0 is definition
238  if (getNumOperands() && getOperand(0).isReg() && getOperand(0).isDef()) {
239    ::print(getOperand(0), OS, TM);
240    OS << " = ";
241    ++StartOp;   // Don't print this operand again!
242  }
243
244  // Must check if Target machine is not null because machine BB could not
245  // be attached to a Machine function yet
246  if (TM)
247    OS << TM->getInstrInfo()->getName(getOpcode());
248
249  for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
250    const MachineOperand& mop = getOperand(i);
251    if (i != StartOp)
252      OS << ",";
253    OS << " ";
254    ::print(mop, OS, TM);
255
256    if (mop.isReg()) {
257      if (mop.isDef() || mop.isKill() || mop.isDead() || mop.isImplicit()) {
258        OS << "<";
259        bool NeedComma = false;
260        if (mop.isImplicit()) {
261          OS << (mop.isDef() ? "imp-def" : "imp-use");
262          NeedComma = true;
263        } else if (mop.isDef()) {
264          OS << "def";
265          NeedComma = true;
266        }
267        if (mop.isKill() || mop.isDead()) {
268          if (NeedComma)
269            OS << ",";
270          if (mop.isKill())
271            OS << "kill";
272          if (mop.isDead())
273            OS << "dead";
274        }
275        OS << ">";
276      }
277    }
278  }
279
280  OS << "\n";
281}
282
283std::ostream &llvm::operator<<(std::ostream &os, const MachineInstr &MI) {
284  // If the instruction is embedded into a basic block, we can find the target
285  // info for the instruction.
286  if (const MachineBasicBlock *MBB = MI.getParent()) {
287    const MachineFunction *MF = MBB->getParent();
288    if (MF)
289      MI.print(os, &MF->getTarget());
290    else
291      MI.print(os, 0);
292    return os;
293  }
294
295  // Otherwise, print it out in the "raw" format without symbolic register names
296  // and such.
297  os << TargetInstrDescriptors[MI.getOpcode()].Name;
298
299  for (unsigned i = 0, N = MI.getNumOperands(); i < N; i++) {
300    os << "\t" << MI.getOperand(i);
301    if (MI.getOperand(i).isReg() && MI.getOperand(i).isDef())
302      os << "<d>";
303  }
304
305  return os << "\n";
306}
307
308std::ostream &llvm::operator<<(std::ostream &OS, const MachineOperand &MO) {
309  switch (MO.getType()) {
310  case MachineOperand::MO_Register:
311    OutputReg(OS, MO.getReg());
312    break;
313  case MachineOperand::MO_Immediate:
314    OS << (long)MO.getImmedValue();
315    break;
316  case MachineOperand::MO_MachineBasicBlock:
317    OS << "<mbb:"
318       << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
319       << "@" << (void*)MO.getMachineBasicBlock() << ">";
320    break;
321  case MachineOperand::MO_FrameIndex:
322    OS << "<fi#" << MO.getFrameIndex() << ">";
323    break;
324  case MachineOperand::MO_ConstantPoolIndex:
325    OS << "<cp#" << MO.getConstantPoolIndex() << ">";
326    break;
327  case MachineOperand::MO_JumpTableIndex:
328    OS << "<jt#" << MO.getJumpTableIndex() << ">";
329    break;
330  case MachineOperand::MO_GlobalAddress:
331    OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
332    break;
333  case MachineOperand::MO_ExternalSymbol:
334    OS << "<es:" << MO.getSymbolName() << ">";
335    break;
336  default:
337    assert(0 && "Unrecognized operand type");
338    break;
339  }
340
341  return OS;
342}
343