* Make MachineOperand ctors private, so MachineOperand can only be created
[oota-llvm.git] / lib / CodeGen / MachineInstr.cpp
1 //===-- MachineInstr.cpp --------------------------------------------------===//
2 // 
3 //===----------------------------------------------------------------------===//
4
5 #include "llvm/CodeGen/MachineInstr.h"
6 #include "llvm/Value.h"
7 #include "llvm/Target/MachineInstrInfo.h"  // FIXME: shouldn't need this!
8 using std::cerr;
9
10
11 // Constructor for instructions with fixed #operands (nearly all)
12 MachineInstr::MachineInstr(MachineOpCode _opCode,
13                            OpCodeMask    _opCodeMask)
14   : opCode(_opCode), opCodeMask(_opCodeMask),
15     operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()) {
16   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
17 }
18
19 // Constructor for instructions with variable #operands
20 MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned  numOperands,
21                            OpCodeMask    OpCodeMask)
22   : opCode(OpCode), opCodeMask(OpCodeMask),
23     operands(numOperands, MachineOperand()) {
24 }
25
26 // OperandComplete - Return true if it's illegal to add a new operand
27 bool MachineInstr::OperandsComplete() const {
28   int NumOperands = TargetInstrDescriptors[opCode].numOperands;
29   if (NumOperands >= 0 && operands.size() >= (unsigned)NumOperands)
30     return true;  // Broken!
31   return false;
32 }
33
34
35 // 
36 // Support for replacing opcode and operands of a MachineInstr in place.
37 // This only resets the size of the operand vector and initializes it.
38 // The new operands must be set explicitly later.
39 // 
40 void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands,
41                            OpCodeMask Mask) {
42   opCode = Opcode;
43   opCodeMask = Mask;
44   operands.clear();
45   operands.resize(numOperands, MachineOperand());
46 }
47
48 void
49 MachineInstr::SetMachineOperandVal(unsigned i,
50                                    MachineOperand::MachineOperandType opType,
51                                    Value* V,
52                                    bool isdef,
53                                    bool isDefAndUse)
54 {
55   assert(i < operands.size());
56   operands[i].opType = opType;
57   operands[i].value = V;
58   operands[i].regNum = -1;
59   operands[i].flags = 0;
60
61   if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
62     operands[i].markDef();
63   if (isDefAndUse)
64     operands[i].markDefAndUse();
65 }
66
67 void
68 MachineInstr::SetMachineOperandConst(unsigned i,
69                                 MachineOperand::MachineOperandType operandType,
70                                      int64_t intValue)
71 {
72   assert(i < operands.size());
73   assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
74          "immed. constant cannot be defined");
75
76   operands[i].opType = operandType;
77   operands[i].value = NULL;
78   operands[i].immedVal = intValue;
79   operands[i].regNum = -1;
80   operands[i].flags = 0;
81 }
82
83 void
84 MachineInstr::SetMachineOperandReg(unsigned i,
85                                    int regNum,
86                                    bool isdef) {
87   assert(i < operands.size());
88
89   operands[i].opType = MachineOperand::MO_MachineRegister;
90   operands[i].value = NULL;
91   operands[i].regNum = regNum;
92   operands[i].flags = 0;
93
94   if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
95     operands[i].markDef();
96   insertUsedReg(regNum);
97 }
98
99 void
100 MachineInstr::SetRegForOperand(unsigned i, int regNum)
101 {
102   operands[i].setRegForValue(regNum);
103   insertUsedReg(regNum);
104 }
105
106
107 // Subsitute all occurrences of Value* oldVal with newVal in all operands
108 // and all implicit refs.  If defsOnly == true, substitute defs only.
109 unsigned
110 MachineInstr::substituteValue(const Value* oldVal, Value* newVal, bool defsOnly)
111 {
112   unsigned numSubst = 0;
113
114   // Subsitute operands
115   for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O)
116     if (*O == oldVal)
117       if (!defsOnly || O.isDef())
118         {
119           O.getMachineOperand().value = newVal;
120           ++numSubst;
121         }
122
123   // Subsitute implicit refs
124   for (unsigned i=0, N=implicitRefs.size(); i < N; ++i)
125     if (getImplicitRef(i) == oldVal)
126       if (!defsOnly || implicitRefIsDefined(i))
127         {
128           implicitRefs[i].Val = newVal;
129           ++numSubst;
130         }
131
132   return numSubst;
133 }
134
135
136 void
137 MachineInstr::dump() const 
138 {
139   cerr << "  " << *this;
140 }
141
142 static inline std::ostream&
143 OutputValue(std::ostream &os, const Value* val)
144 {
145   os << "(val ";
146   if (val && val->hasName())
147     return os << val->getName() << ")";
148   else
149     return os << (void*) val << ")";              // print address only
150 }
151
152 static inline std::ostream&
153 OutputReg(std::ostream &os, unsigned int regNum)
154 {
155   return os << "%mreg(" << regNum << ")";
156 }
157
158 std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr)
159 {
160   os << TargetInstrDescriptors[minstr.opCode].opCodeString;
161   
162   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
163     os << "\t" << minstr.getOperand(i);
164     if( minstr.operandIsDefined(i) ) 
165       os << "*";
166     if( minstr.operandIsDefinedAndUsed(i) ) 
167       os << "*";
168   }
169   
170   // code for printing implict references
171   unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
172   if(  NumOfImpRefs > 0 ) {
173     os << "\tImplicit: ";
174     for(unsigned z=0; z < NumOfImpRefs; z++) {
175       OutputValue(os, minstr.getImplicitRef(z)); 
176       if( minstr.implicitRefIsDefined(z)) os << "*";
177       if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*";
178       os << "\t";
179     }
180   }
181   
182   return os << "\n";
183 }
184
185 std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
186 {
187   if (mop.opHiBits32())
188     os << "%lm(";
189   else if (mop.opLoBits32())
190     os << "%lo(";
191   else if (mop.opHiBits64())
192     os << "%hh(";
193   else if (mop.opLoBits64())
194     os << "%hm(";
195   
196   switch(mop.opType)
197     {
198     case MachineOperand::MO_VirtualRegister:
199       os << "%reg";
200       OutputValue(os, mop.getVRegValue());
201       if (mop.hasAllocatedReg())
202         os << "==" << OutputReg(os, mop.getAllocatedRegNum());
203       break;
204     case MachineOperand::MO_CCRegister:
205       os << "%ccreg";
206       OutputValue(os, mop.getVRegValue());
207       if (mop.hasAllocatedReg())
208         os << "==" << OutputReg(os, mop.getAllocatedRegNum());
209       break;
210     case MachineOperand::MO_MachineRegister:
211       OutputReg(os, mop.getMachineRegNum());
212       break;
213     case MachineOperand::MO_SignExtendedImmed:
214       os << (long)mop.immedVal;
215       break;
216     case MachineOperand::MO_UnextendedImmed:
217       os << (long)mop.immedVal;
218       break;
219     case MachineOperand::MO_PCRelativeDisp:
220       {
221         const Value* opVal = mop.getVRegValue();
222         bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
223         os << "%disp(" << (isLabel? "label " : "addr-of-val ");
224         if (opVal->hasName())
225           os << opVal->getName();
226         else
227           os << (const void*) opVal;
228         os << ")";
229         break;
230       }
231     default:
232       assert(0 && "Unrecognized operand type");
233       break;
234     }
235   
236   if (mop.flags &
237       (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 
238        MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64))
239     os << ")";
240   
241   return os;
242 }