904a412add72cdf1400f31264f90bc6db911e6eb
[oota-llvm.git] / lib / CodeGen / MachineInstr.cpp
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 //
19 extern const TargetInstrDescriptor *TargetInstrDescriptors;
20
21 // Constructor for instructions with variable #operands
22 MachineInstr::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 ///
35 MachineInstr::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 ///
47 MachineInstr::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
60 bool 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 // 
74 void 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
83 void 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
92 void
93 MachineInstr::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
108 void 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   insertUsedReg(regNum);
115 }
116
117 void
118 MachineInstr::SetRegForOperand(unsigned i, int regNum)
119 {
120   assert(i < getNumOperands());          // must be explicit op
121   operands[i].setRegForValue(regNum);
122   insertUsedReg(regNum);
123 }
124
125 void
126 MachineInstr::SetRegForImplicitRef(unsigned i, int regNum)
127 {
128   getImplicitOp(i).setRegForValue(regNum);
129   insertUsedReg(regNum);
130 }
131
132
133 // Subsitute all occurrences of Value* oldVal with newVal in all operands
134 // and all implicit refs.
135 // If defsOnly == true, substitute defs only.
136 unsigned
137 MachineInstr::substituteValue(const Value* oldVal, Value* newVal,
138                               bool defsOnly, bool notDefsAndUses,
139                               bool& someArgsWereIgnored)
140 {
141   assert((defsOnly || !notDefsAndUses) &&
142          "notDefsAndUses is irrelevant if defsOnly == false.");
143   
144   unsigned numSubst = 0;
145
146   // Subsitute operands
147   for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O)
148     if (*O == oldVal)
149       if (!defsOnly ||
150           notDefsAndUses && O.isDefOnly() ||
151           !notDefsAndUses && !O.isUseOnly())
152         {
153           O.getMachineOperand().value = newVal;
154           ++numSubst;
155         }
156       else
157         someArgsWereIgnored = true;
158
159   // Subsitute implicit refs
160   for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i)
161     if (getImplicitRef(i) == oldVal)
162       if (!defsOnly ||
163           notDefsAndUses && getImplicitOp(i).opIsDefOnly() ||
164           !notDefsAndUses && !getImplicitOp(i).opIsUse())
165         {
166           getImplicitOp(i).value = newVal;
167           ++numSubst;
168         }
169       else
170         someArgsWereIgnored = true;
171
172   return numSubst;
173 }
174
175
176 void
177 MachineInstr::dump() const 
178 {
179   std::cerr << "  " << *this;
180 }
181
182 static inline std::ostream&
183 OutputValue(std::ostream &os, const Value* val)
184 {
185   os << "(val ";
186   os << (void*) val;                    // print address always
187   if (val && val->hasName())
188     os << " " << val->getName() << ")"; // print name also, if available
189   return os;
190 }
191
192 static inline void OutputReg(std::ostream &os, unsigned RegNo,
193                              const MRegisterInfo *MRI = 0) {
194   if (MRI) {
195     if (RegNo < MRegisterInfo::FirstVirtualRegister)
196       os << "%" << MRI->get(RegNo).Name;
197     else
198       os << "%reg" << RegNo;
199   } else
200     os << "%mreg(" << RegNo << ")";
201 }
202
203 static void print(const MachineOperand &MO, std::ostream &OS,
204                   const TargetMachine &TM) {
205   const MRegisterInfo *MRI = TM.getRegisterInfo();
206   bool CloseParen = true;
207   if (MO.opHiBits32())
208     OS << "%lm(";
209   else if (MO.opLoBits32())
210     OS << "%lo(";
211   else if (MO.opHiBits64())
212     OS << "%hh(";
213   else if (MO.opLoBits64())
214     OS << "%hm(";
215   else
216     CloseParen = false;
217   
218   switch (MO.getType()) {
219   case MachineOperand::MO_VirtualRegister:
220     if (MO.getVRegValue()) {
221       OS << "%reg";
222       OutputValue(OS, MO.getVRegValue());
223       if (MO.hasAllocatedReg())
224         OS << "==";
225     }
226     if (MO.hasAllocatedReg())
227       OutputReg(OS, MO.getAllocatedRegNum(), MRI);
228     break;
229   case MachineOperand::MO_CCRegister:
230     OS << "%ccreg";
231     OutputValue(OS, MO.getVRegValue());
232     if (MO.hasAllocatedReg()) {
233       OS << "==";
234       OutputReg(OS, MO.getAllocatedRegNum(), MRI);
235     }
236     break;
237   case MachineOperand::MO_MachineRegister:
238     OutputReg(OS, MO.getMachineRegNum(), MRI);
239     break;
240   case MachineOperand::MO_SignExtendedImmed:
241     OS << (long)MO.getImmedValue();
242     break;
243   case MachineOperand::MO_UnextendedImmed:
244     OS << (long)MO.getImmedValue();
245     break;
246   case MachineOperand::MO_PCRelativeDisp: {
247     const Value* opVal = MO.getVRegValue();
248     bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
249     OS << "%disp(" << (isLabel? "label " : "addr-of-val ");
250     if (opVal->hasName())
251       OS << opVal->getName();
252     else
253       OS << (const void*) opVal;
254     OS << ")";
255     break;
256   }
257   case MachineOperand::MO_MachineBasicBlock:
258     OS << "bb<"
259        << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
260        << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
261     break;
262   case MachineOperand::MO_FrameIndex:
263     OS << "<fi#" << MO.getFrameIndex() << ">";
264     break;
265   case MachineOperand::MO_ConstantPoolIndex:
266     OS << "<cp#" << MO.getConstantPoolIndex() << ">";
267     break;
268   case MachineOperand::MO_GlobalAddress:
269     OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
270     break;
271   case MachineOperand::MO_ExternalSymbol:
272     OS << "<es:" << MO.getSymbolName() << ">";
273     break;
274   default:
275     assert(0 && "Unrecognized operand type");
276   }
277
278   if (CloseParen)
279     OS << ")";
280 }
281
282 void MachineInstr::print(std::ostream &OS, const TargetMachine &TM) const {
283   unsigned StartOp = 0;
284
285    // Specialize printing if op#0 is definition
286   if (getNumOperands() &&
287       (getOperand(0).opIsDefOnly() || getOperand(0).opIsDefAndUse())) {
288     ::print(getOperand(0), OS, TM);
289     OS << " = ";
290     ++StartOp;   // Don't print this operand again!
291   }
292   OS << TM.getInstrInfo().getName(getOpcode());
293   
294   for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
295     const MachineOperand& mop = getOperand(i);
296     if (i != StartOp)
297       OS << ",";
298     OS << " ";
299     ::print(mop, OS, TM);
300     
301     if (mop.opIsDefAndUse())
302       OS << "<def&use>";
303     else if (mop.opIsDefOnly())
304       OS << "<def>";
305   }
306     
307   // code for printing implict references
308   if (getNumImplicitRefs()) {
309     OS << "\tImplicitRefs: ";
310     for(unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) {
311       OS << "\t";
312       OutputValue(OS, getImplicitRef(i));
313       if (getImplicitOp(i).opIsDefAndUse())
314         OS << "<def&use>";
315       else if (getImplicitOp(i).opIsDefOnly())
316         OS << "<def>";
317     }
318   }
319   
320   OS << "\n";
321 }
322
323
324 std::ostream &operator<<(std::ostream& os, const MachineInstr& MI)
325 {
326   os << TargetInstrDescriptors[MI.opCode].Name;
327   
328   for (unsigned i=0, N=MI.getNumOperands(); i < N; i++) {
329     os << "\t" << MI.getOperand(i);
330     if (MI.getOperand(i).opIsDefOnly())
331       os << "<d>";
332     if (MI.getOperand(i).opIsDefAndUse())
333       os << "<d&u>";
334   }
335   
336   // code for printing implict references
337   unsigned NumOfImpRefs = MI.getNumImplicitRefs();
338   if (NumOfImpRefs > 0) {
339     os << "\tImplicit: ";
340     for (unsigned z=0; z < NumOfImpRefs; z++) {
341       OutputValue(os, MI.getImplicitRef(z)); 
342       if (MI.getImplicitOp(z).opIsDefOnly()) os << "<d>";
343       if (MI.getImplicitOp(z).opIsDefAndUse()) os << "<d&u>";
344       os << "\t";
345     }
346   }
347   
348   return os << "\n";
349 }
350
351 std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO)
352 {
353   if (MO.opHiBits32())
354     OS << "%lm(";
355   else if (MO.opLoBits32())
356     OS << "%lo(";
357   else if (MO.opHiBits64())
358     OS << "%hh(";
359   else if (MO.opLoBits64())
360     OS << "%hm(";
361   
362   switch (MO.getType())
363     {
364     case MachineOperand::MO_VirtualRegister:
365       if (MO.hasAllocatedReg())
366         OutputReg(OS, MO.getAllocatedRegNum());
367
368       if (MO.getVRegValue()) {
369         if (MO.hasAllocatedReg()) OS << "==";
370         OS << "%vreg";
371         OutputValue(OS, MO.getVRegValue());
372       }
373       break;
374     case MachineOperand::MO_CCRegister:
375       OS << "%ccreg";
376       OutputValue(OS, MO.getVRegValue());
377       if (MO.hasAllocatedReg()) {
378         OS << "==";
379         OutputReg(OS, MO.getAllocatedRegNum());
380       }
381       break;
382     case MachineOperand::MO_MachineRegister:
383       OutputReg(OS, MO.getMachineRegNum());
384       break;
385     case MachineOperand::MO_SignExtendedImmed:
386       OS << (long)MO.getImmedValue();
387       break;
388     case MachineOperand::MO_UnextendedImmed:
389       OS << (long)MO.getImmedValue();
390       break;
391     case MachineOperand::MO_PCRelativeDisp:
392       {
393         const Value* opVal = MO.getVRegValue();
394         bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
395         OS << "%disp(" << (isLabel? "label " : "addr-of-val ");
396         if (opVal->hasName())
397           OS << opVal->getName();
398         else
399           OS << (const void*) opVal;
400         OS << ")";
401         break;
402       }
403     case MachineOperand::MO_MachineBasicBlock:
404       OS << "bb<"
405          << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
406          << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
407       break;
408     case MachineOperand::MO_FrameIndex:
409       OS << "<fi#" << MO.getFrameIndex() << ">";
410       break;
411     case MachineOperand::MO_ConstantPoolIndex:
412       OS << "<cp#" << MO.getConstantPoolIndex() << ">";
413       break;
414     case MachineOperand::MO_GlobalAddress:
415       OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
416       break;
417     case MachineOperand::MO_ExternalSymbol:
418       OS << "<es:" << MO.getSymbolName() << ">";
419       break;
420     default:
421       assert(0 && "Unrecognized operand type");
422       break;
423     }
424   
425   if (MO.flags &
426       (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 
427        MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64))
428     OS << ")";
429   
430   return OS;
431 }