Implement the first step of pool allocation - Creating, initialization, and
[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 #include "llvm/CodeGen/MachineInstr.h"
16 #include "llvm/Value.h"
17 #include <iostream>
18 using std::cerr;
19
20
21 //************************ Class Implementations **************************/
22
23 // Constructor for instructions with fixed #operands (nearly all)
24 MachineInstr::MachineInstr(MachineOpCode _opCode,
25                            OpCodeMask    _opCodeMask)
26   : opCode(_opCode),
27     opCodeMask(_opCodeMask),
28     operands(TargetInstrDescriptors[_opCode].numOperands)
29 {
30   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
31 }
32
33 // Constructor for instructions with variable #operands
34 MachineInstr::MachineInstr(MachineOpCode _opCode,
35                            unsigned      numOperands,
36                            OpCodeMask    _opCodeMask)
37   : opCode(_opCode),
38     opCodeMask(_opCodeMask),
39     operands(numOperands)
40 {
41 }
42
43 void
44 MachineInstr::SetMachineOperandVal(unsigned int i,
45                                 MachineOperand::MachineOperandType operandType,
46                                 Value* _val, bool isdef=false)
47 {
48   assert(i < operands.size());
49   operands[i].Initialize(operandType, _val);
50   operands[i].isDef = isdef ||
51     TargetInstrDescriptors[opCode].resultPos == (int) i;
52 }
53
54 void
55 MachineInstr::SetMachineOperandConst(unsigned int i,
56                                 MachineOperand::MachineOperandType operandType,
57                                      int64_t intValue)
58 {
59   assert(i < operands.size());
60   assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
61          "immed. constant cannot be defined");
62   operands[i].InitializeConst(operandType, intValue);
63   operands[i].isDef = false;
64 }
65
66 void
67 MachineInstr::SetMachineOperandReg(unsigned int i,
68                                    int regNum,
69                                    bool isdef=false,
70                                    bool isCCReg=false)
71 {
72   assert(i < operands.size());
73   operands[i].InitializeReg(regNum, isCCReg);
74   operands[i].isDef = isdef ||
75     TargetInstrDescriptors[opCode].resultPos == (int) i;
76 }
77
78 void
79 MachineInstr::dump(unsigned int indent) const 
80 {
81   for (unsigned i=0; i < indent; i++)
82     cerr << "    ";
83   
84   cerr << *this;
85 }
86
87 std::ostream &operator<<(std::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     if( minstr.getOperand(i).opIsDef() ) 
94       os << "*";
95   }
96   
97 #undef DEBUG_VAL_OP_ITERATOR
98 #ifdef DEBUG_VAL_OP_ITERATOR
99   os << "\n\tValue operands are: ";
100   for (MachineInstr::val_const_op_iterator vo(&minstr); ! vo.done(); ++vo)
101     {
102       const Value* val = *vo;
103       os << val << (vo.isDef()? "(def), " : ", ");
104     }
105 #endif
106   
107  
108
109 #if 1
110   // code for printing implict references
111
112   unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
113   if(  NumOfImpRefs > 0 ) {
114         
115     os << "\tImplicit:";
116
117     for(unsigned z=0; z < NumOfImpRefs; z++) {
118       os << minstr.getImplicitRef(z);
119       if( minstr.implicitRefIsDefined(z)) os << "*";
120       os << "\t";
121     }
122   }
123
124 #endif
125   return os << "\n";
126 }
127
128 static inline std::ostream &OutputOperand(std::ostream &os,
129                                           const MachineOperand &mop)
130 {
131   Value* val;
132   switch (mop.getOperandType())
133     {
134     case MachineOperand::MO_CCRegister:
135     case MachineOperand::MO_VirtualRegister:
136       val = mop.getVRegValue();
137       os << "(val ";
138       if (val && val->hasName())
139         os << val->getName();
140       else
141         os << val;
142       return os << ")";
143     case MachineOperand::MO_MachineRegister:
144       return os << "("     << mop.getMachineRegNum() << ")";
145     default:
146       assert(0 && "Unknown operand type");
147       return os;
148     }
149 }
150
151
152 std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
153 {
154   switch(mop.opType)
155     {
156     case MachineOperand::MO_VirtualRegister:
157     case MachineOperand::MO_MachineRegister:
158       os << "%reg";
159       return OutputOperand(os, mop);
160     case MachineOperand::MO_CCRegister:
161       os << "%ccreg";
162       return OutputOperand(os, mop);
163     case MachineOperand::MO_SignExtendedImmed:
164       return os << (long)mop.immedVal;
165     case MachineOperand::MO_UnextendedImmed:
166       return os << (long)mop.immedVal;
167     case MachineOperand::MO_PCRelativeDisp:
168       {
169         const Value* opVal = mop.getVRegValue();
170         bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
171         os << "%disp(" << (isLabel? "label " : "addr-of-val ");
172         if (opVal->hasName())
173           os << opVal->getName();
174         else
175           os << opVal;
176         return os << ")";
177       }
178     default:
179       assert(0 && "Unrecognized operand type");
180       break;
181     }
182   
183   return os;
184 }