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