b4f275db38c6d4ebdce3aa59097ea5167852c46c
[oota-llvm.git] / lib / CodeGen / MachineInstr.cpp
1 // $Id$
2 //***************************************************************************
3 // File:
4 //      MachineInstr.cpp
5 // 
6 // Purpose:
7 //      
8 // 
9 // Strategy:
10 // 
11 // History:
12 //      7/2/01   -  Vikram Adve  -  Created
13 //**************************************************************************/
14
15
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/Target/MachineRegInfo.h"
18 #include "llvm/Method.h"
19 #include "llvm/Instruction.h"
20
21
22
23 //************************ Class Implementations **************************/
24
25 // Constructor for instructions with fixed #operands (nearly all)
26 MachineInstr::MachineInstr(MachineOpCode _opCode,
27                            OpCodeMask    _opCodeMask)
28   : opCode(_opCode),
29     opCodeMask(_opCodeMask),
30     operands(TargetInstrDescriptors[_opCode].numOperands)
31 {
32   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
33 }
34
35 // Constructor for instructions with variable #operands
36 MachineInstr::MachineInstr(MachineOpCode _opCode,
37                            unsigned      numOperands,
38                            OpCodeMask    _opCodeMask)
39   : opCode(_opCode),
40     opCodeMask(_opCodeMask),
41     operands(numOperands)
42 {
43 }
44
45 void
46 MachineInstr::SetMachineOperand(unsigned int i,
47                                 MachineOperand::MachineOperandType operandType,
48                                 Value* _val, bool isdef=false)
49 {
50   assert(i < operands.size());
51   operands[i].Initialize(operandType, _val);
52   operands[i].isDef = isdef ||
53     TargetInstrDescriptors[opCode].resultPos == (int) i;
54 }
55
56 void
57 MachineInstr::SetMachineOperand(unsigned int i,
58                                 MachineOperand::MachineOperandType operandType,
59                                 int64_t intValue, bool isdef=false)
60 {
61   assert(i < operands.size());
62   operands[i].InitializeConst(operandType, intValue);
63   operands[i].isDef = isdef ||
64     TargetInstrDescriptors[opCode].resultPos == (int) i;
65 }
66
67 void
68 MachineInstr::SetMachineOperand(unsigned int i,
69                                 unsigned int regNum, bool isdef=false)
70 {
71   assert(i < operands.size());
72   operands[i].InitializeReg(regNum);
73   operands[i].isDef = isdef ||
74     TargetInstrDescriptors[opCode].resultPos == (int) i;
75 }
76
77 void
78 MachineInstr::dump(unsigned int indent) const 
79 {
80   for (unsigned i=0; i < indent; i++)
81     cout << "    ";
82   
83   cout << *this;
84 }
85
86 ostream&
87 operator<< (ostream& os, const MachineInstr& minstr)
88 {
89   os << TargetInstrDescriptors[minstr.opCode].opCodeString;
90   
91   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
92     os << "\t" << minstr.getOperand(i);
93   
94 #undef DEBUG_VAL_OP_ITERATOR
95 #ifdef DEBUG_VAL_OP_ITERATOR
96   os << endl << "\tValue operands are: ";
97   for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
98     {
99       const Value* val = *vo;
100       os << val << (vo.isDef()? "(def), " : ", ");
101     }
102 #endif
103   
104  
105
106 #if 1
107   // code for printing implict references
108
109   unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
110   if(  NumOfImpRefs > 0 ) {
111         
112     os << "\tImplicit:";
113
114     for(unsigned z=0; z < NumOfImpRefs; z++) {
115       os << minstr.getImplicitRef(z);
116           cout << "\t";
117     }
118   }
119
120 #endif
121
122
123   os << endl;
124   
125   return os;
126 }
127
128 static inline ostream&
129 OutputOperand(ostream &os, const MachineOperand &mop)
130 {
131   switch (mop.getOperandType())
132     {
133     case MachineOperand::MO_CCRegister:
134     case MachineOperand::MO_VirtualRegister:
135       return os << "(val " << mop.getVRegValue() << ")";
136     case MachineOperand::MO_MachineRegister:
137       return os << "("     << mop.getMachineRegNum() << ")";
138     default:
139       assert(0 && "Unknown operand type");
140       return os;
141     }
142 }
143
144
145 ostream&
146 operator<<(ostream &os, const MachineOperand &mop)
147 {
148   switch(mop.opType)
149     {
150     case MachineOperand::MO_VirtualRegister:
151     case MachineOperand::MO_MachineRegister:
152       os << "%reg";
153       return OutputOperand(os, mop);
154     case MachineOperand::MO_CCRegister:
155       os << "%ccreg";
156       return OutputOperand(os, mop);
157     case MachineOperand::MO_SignExtendedImmed:
158       return os << mop.immedVal;
159     case MachineOperand::MO_UnextendedImmed:
160       return os << mop.immedVal;
161     case MachineOperand::MO_PCRelativeDisp:
162       {
163         const Value* opVal = mop.getVRegValue();
164         bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
165         return os << "%disp("
166                   << (isLabel? "label " : "addr-of-val ")
167                   << opVal << ")";
168       }
169     default:
170       assert(0 && "Unrecognized operand type");
171       break;
172     }
173   
174   return os;
175 }
176
177
178 void
179 MachineCodeForMethod::putLocalVarAtOffsetFromFP(const Value* local,
180                                                 int offset,
181                                                 unsigned int size)
182 {
183   offsetsFromFP[local] = offset;
184   incrementAutomaticVarsSize(size);
185 }
186
187
188 void
189 MachineCodeForMethod::putLocalVarAtOffsetFromSP(const Value* local,
190                                                 int offset,
191                                                 unsigned int size)
192 {
193   offsetsFromSP[local] = offset;
194   incrementAutomaticVarsSize(size);
195 }
196
197
198 int
199 MachineCodeForMethod::getOffsetFromFP(const Value* local) const
200 {
201   hash_map<const Value*, int>::const_iterator pair = offsetsFromFP.find(local);
202   assert(pair != offsetsFromFP.end() && "Offset from FP unknown for Value");
203   return (*pair).second;
204 }
205
206
207 int
208 MachineCodeForMethod::getOffsetFromSP(const Value* local) const
209 {
210   hash_map<const Value*, int>::const_iterator pair = offsetsFromSP.find(local);
211   assert(pair != offsetsFromSP.end() && "Offset from SP unknown for Value");
212   return (*pair).second;
213 }
214
215
216 void
217 MachineCodeForMethod::dump() const
218 {
219   cout << "\n" << method->getReturnType()
220        << " \"" << method->getName() << "\"" << endl;
221   
222   for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
223     {
224       BasicBlock* bb = *BI;
225       cout << "\n"
226            << (bb->hasName()? bb->getName() : "Label")
227            << " (" << bb << ")" << ":"
228            << endl;
229       
230       MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
231       for (unsigned i=0; i < mvec.size(); i++)
232         cout << "\t" << *mvec[i];
233     } 
234   cout << endl << "End method \"" << method->getName() << "\""
235        << endl << endl;
236 }