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