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