Moved function PrintMachineInstructions here.
[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 //************************** System Include Files ***************************/
17
18 #include <strstream>
19
20
21 //*************************** User Include Files ***************************/
22
23 #include "llvm/Method.h"
24 #include "llvm/ConstPoolVals.h"
25 #include "llvm/Instruction.h"
26 #include "llvm/CodeGen/MachineInstr.h"
27
28
29 //************************ Class Implementations **************************/
30
31 // Constructor for instructions with fixed #operands (nearly all)
32 MachineInstr::MachineInstr(MachineOpCode _opCode,
33                            OpCodeMask    _opCodeMask)
34   : opCode(_opCode),
35     opCodeMask(_opCodeMask),
36     operands(TargetInstrDescriptors[_opCode].numOperands)
37 {
38   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
39 }
40
41 // Constructor for instructions with variable #operands
42 MachineInstr::MachineInstr(MachineOpCode _opCode,
43                            unsigned      numOperands,
44                            OpCodeMask    _opCodeMask)
45   : opCode(_opCode),
46     opCodeMask(_opCodeMask),
47     operands(numOperands)
48 {
49 }
50
51 void
52 MachineInstr::SetMachineOperand(unsigned int i,
53                                 MachineOperand::MachineOperandType operandType,
54                                 Value* _val, bool isdef=false)
55 {
56   assert(i < operands.size());
57   operands[i].Initialize(operandType, _val);
58   operands[i].isDef = isdef ||
59                       TargetInstrDescriptors[opCode].resultPos == (int) i;
60 }
61
62 void
63 MachineInstr::SetMachineOperand(unsigned int i,
64                                 MachineOperand::MachineOperandType operandType,
65                                 int64_t intValue, bool isdef=false)
66 {
67   assert(i < operands.size());
68   operands[i].InitializeConst(operandType, intValue);
69   operands[i].isDef = isdef ||
70                       TargetInstrDescriptors[opCode].resultPos == (int) i;
71 }
72
73 void
74 MachineInstr::SetMachineOperand(unsigned int i,
75                                 unsigned int regNum, bool isdef=false)
76 {
77   assert(i < operands.size());
78   operands[i].InitializeReg(regNum);
79   operands[i].isDef = isdef ||
80                       TargetInstrDescriptors[opCode].resultPos == (int) i;
81 }
82
83 void
84 MachineInstr::dump(unsigned int indent) const 
85 {
86   for (unsigned i=0; i < indent; i++)
87     cout << "    ";
88   
89   cout << *this;
90 }
91
92 ostream&
93 operator<< (ostream& os, const MachineInstr& minstr)
94 {
95   os << TargetInstrDescriptors[minstr.opCode].opCodeString;
96   
97   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
98     os << "\t" << minstr.getOperand(i);
99   
100 #undef DEBUG_VAL_OP_ITERATOR
101 #ifdef DEBUG_VAL_OP_ITERATOR
102   os << endl << "\tValue operands are: ";
103   for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
104     {
105       const Value* val = *vo;
106       os << val << (vo.isDef()? "(def), " : ", ");
107     }
108   os << endl;
109 #endif
110   
111   return os;
112 }
113
114 ostream&
115 operator<< (ostream& os, const MachineOperand& mop)
116 {
117   strstream regInfo;
118   if (mop.opType == MachineOperand::MO_VirtualRegister)
119     regInfo << "(val " << mop.value << ")" << ends;
120   else if (mop.opType == MachineOperand::MO_MachineRegister)
121     regInfo << "("       << mop.regNum << ")" << ends;
122   else if (mop.opType == MachineOperand::MO_CCRegister)
123     regInfo << "(val " << mop.value << ")" << ends;
124   
125   switch(mop.opType)
126     {
127     case MachineOperand::MO_VirtualRegister:
128     case MachineOperand::MO_MachineRegister:
129       os << "%reg" << regInfo.str();
130       free(regInfo.str());
131       break;
132       
133     case MachineOperand::MO_CCRegister:
134       os << "%ccreg" << regInfo.str();
135       free(regInfo.str());
136       break;
137
138     case MachineOperand::MO_SignExtendedImmed:
139       os << mop.immedVal;
140       break;
141
142     case MachineOperand::MO_UnextendedImmed:
143       os << mop.immedVal;
144       break;
145
146     case MachineOperand::MO_PCRelativeDisp:
147       os << "%disp(label " << mop.value << ")";
148       break;
149
150     default:
151       assert(0 && "Unrecognized operand type");
152       break;
153     }
154
155   return os;
156 }
157
158
159 //---------------------------------------------------------------------------
160 // Target-independent utility routines for creating machine instructions
161 //---------------------------------------------------------------------------
162
163
164 //------------------------------------------------------------------------ 
165 // Function Set2OperandsFromInstr
166 // Function Set3OperandsFromInstr
167 // 
168 // For the common case of 2- and 3-operand arithmetic/logical instructions,
169 // set the m/c instr. operands directly from the VM instruction's operands.
170 // Check whether the first or second operand is 0 and can use a dedicated "0" register.
171 // Check whether the second operand should use an immediate field or register.
172 // (First and third operands are never immediates for such instructions.)
173 // 
174 // Arguments:
175 // canDiscardResult: Specifies that the result operand can be discarded
176 //                   by using the dedicated "0"
177 // 
178 // op1position, op2position and resultPosition: Specify in which position
179 //                   in the machine instruction the 3 operands (arg1, arg2
180 //                   and result) should go.
181 // 
182 // RETURN VALUE: unsigned int flags, where
183 //      flags & 0x01    => operand 1 is constant and needs a register
184 //      flags & 0x02    => operand 2 is constant and needs a register
185 //------------------------------------------------------------------------ 
186
187 void
188 Set2OperandsFromInstr(MachineInstr* minstr,
189                       InstructionNode* vmInstrNode,
190                       const TargetMachine& target,
191                       bool canDiscardResult,
192                       int op1Position,
193                       int resultPosition)
194 {
195   Set3OperandsFromInstr(minstr, vmInstrNode, target,
196                         canDiscardResult, op1Position,
197                         /*op2Position*/ -1, resultPosition);
198 }
199
200 #undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
201 #ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
202 unsigned
203 Set3OperandsFromInstrJUNK(MachineInstr* minstr,
204                       InstructionNode* vmInstrNode,
205                       const TargetMachine& target,
206                       bool canDiscardResult,
207                       int op1Position,
208                       int op2Position,
209                       int resultPosition)
210 {
211   assert(op1Position >= 0);
212   assert(resultPosition >= 0);
213   
214   unsigned returnFlags = 0x0;
215   
216   // Check if operand 1 is 0.  If so, try to use a hardwired 0 register.
217   Value* op1Value = vmInstrNode->leftChild()->getValue();
218   bool isValidConstant;
219   int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
220   if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
221     minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
222   else
223     {
224       if (op1Value->getValueType() == Value::ConstantVal)
225         {// value is constant and must be loaded from constant pool
226           returnFlags = returnFlags | (1 << op1Position);
227         }
228       minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
229                                             op1Value);
230     }
231   
232   // Check if operand 2 (if any) fits in the immed. field of the instruction,
233   // or if it is 0 and can use a dedicated machine register
234   if (op2Position >= 0)
235     {
236       Value* op2Value = vmInstrNode->rightChild()->getValue();
237       int64_t immedValue;
238       unsigned int machineRegNum;
239       
240       MachineOperand::MachineOperandType
241         op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
242                                    /*canUseImmed*/ true,
243                                    machineRegNum, immedValue);
244       
245       if (op2type == MachineOperand::MO_MachineRegister)
246         minstr->SetMachineOperand(op2Position, machineRegNum);
247       else if (op2type == MachineOperand::MO_VirtualRegister)
248         {
249           if (op2Value->getValueType() == Value::ConstantVal)
250             {// value is constant and must be loaded from constant pool
251               returnFlags = returnFlags | (1 << op2Position);
252             }
253           minstr->SetMachineOperand(op2Position, op2type, op2Value);
254         }
255       else
256         {
257           assert(op2type != MO_CCRegister);
258           minstr->SetMachineOperand(op2Position, op2type, immedValue);
259         }
260     }
261   
262   // If operand 3 (result) can be discarded, use a dead register if one exists
263   if (canDiscardResult && target.zeroRegNum >= 0)
264     minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
265   else
266     minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
267
268   return returnFlags;
269 }
270 #endif
271
272
273 void
274 Set3OperandsFromInstr(MachineInstr* minstr,
275                       InstructionNode* vmInstrNode,
276                       const TargetMachine& target,
277                       bool canDiscardResult,
278                       int op1Position,
279                       int op2Position,
280                       int resultPosition)
281 {
282   assert(op1Position >= 0);
283   assert(resultPosition >= 0);
284   
285   // operand 1
286   minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
287                             vmInstrNode->leftChild()->getValue());   
288   
289   // operand 2 (if any)
290   if (op2Position >= 0)
291     minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
292                               vmInstrNode->rightChild()->getValue());   
293   
294   // result operand: if it can be discarded, use a dead register if one exists
295   if (canDiscardResult && target.zeroRegNum >= 0)
296     minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
297   else
298     minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
299 }
300
301
302 MachineOperand::MachineOperandType
303 ChooseRegOrImmed(Value* val,
304                  MachineOpCode opCode,
305                  const TargetMachine& target,
306                  bool canUseImmed,
307                  unsigned int& getMachineRegNum,
308                  int64_t& getImmedValue)
309 {
310   MachineOperand::MachineOperandType opType =
311     MachineOperand::MO_VirtualRegister;
312   getMachineRegNum = 0;
313   getImmedValue = 0;
314   
315   // Check for the common case first: argument is not constant
316   // 
317   if (val->getValueType() != Value::ConstantVal)
318     return opType;
319   
320   // Now get the constant value and check if it fits in the IMMED field.
321   // Take advantage of the fact that the max unsigned value will rarely
322   // fit into any IMMED field and ignore that case (i.e., cast smaller
323   // unsigned constants to signed).
324   // 
325   bool isValidConstant;
326   int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant);
327   
328   if (isValidConstant)
329     {
330       if (intValue == 0 && target.zeroRegNum >= 0)
331         {
332           opType = MachineOperand::MO_MachineRegister;
333           getMachineRegNum = target.zeroRegNum;
334         }
335       else if (canUseImmed &&
336                target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
337         {
338           opType = MachineOperand::MO_SignExtendedImmed;
339           getImmedValue = intValue;
340         }
341     }
342   
343   return opType;
344 }
345
346
347 void
348 PrintMachineInstructions(Method* method)
349 {
350   cout << "\n" << method->getReturnType()
351        << " \"" << method->getName() << "\"" << endl;
352   
353   for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
354     {
355       BasicBlock* bb = *BI;
356       cout << "\n"
357            << (bb->hasName()? bb->getName() : "Label")
358            << " (" << bb << ")" << ":"
359            << endl;
360       
361       MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
362       for (unsigned i=0; i < mvec.size(); i++)
363         cout << "\t" << *mvec[i] << endl;
364     } 
365   cout << endl << "End method \"" << method->getName() << "\""
366        << endl << endl;
367 }