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