8cbf55e840f3e9fc1814c9e589664ef784916c39
[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 //************************ Class Implementations **************************/
23
24 // Constructor for instructions with fixed #operands (nearly all)
25 MachineInstr::MachineInstr(MachineOpCode _opCode,
26                            OpCodeMask    _opCodeMask)
27   : opCode(_opCode),
28     opCodeMask(_opCodeMask),
29     operands(TargetInstrDescriptors[_opCode].numOperands)
30 {
31   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
32 }
33
34 // Constructor for instructions with variable #operands
35 MachineInstr::MachineInstr(MachineOpCode _opCode,
36                            unsigned      numOperands,
37                            OpCodeMask    _opCodeMask)
38   : opCode(_opCode),
39     opCodeMask(_opCodeMask),
40     operands(numOperands)
41 {
42 }
43
44 void
45 MachineInstr::SetMachineOperand(unsigned int i,
46                                 MachineOperand::MachineOperandType operandType,
47                                 Value* _val, bool isdef=false)
48 {
49   assert(i < operands.size());
50   operands[i].Initialize(operandType, _val);
51   operands[i].isDef = isdef ||
52     TargetInstrDescriptors[opCode].resultPos == (int) i;
53 }
54
55 void
56 MachineInstr::SetMachineOperand(unsigned int i,
57                                 MachineOperand::MachineOperandType operandType,
58                                 int64_t intValue, bool isdef=false)
59 {
60   assert(i < operands.size());
61   operands[i].InitializeConst(operandType, intValue);
62   operands[i].isDef = isdef ||
63     TargetInstrDescriptors[opCode].resultPos == (int) i;
64 }
65
66 void
67 MachineInstr::SetMachineOperand(unsigned int i,
68                                 unsigned int regNum, bool isdef=false)
69 {
70   assert(i < operands.size());
71   operands[i].InitializeReg(regNum);
72   operands[i].isDef = isdef ||
73     TargetInstrDescriptors[opCode].resultPos == (int) i;
74 }
75
76 void
77 MachineInstr::dump(unsigned int indent) const 
78 {
79   for (unsigned i=0; i < indent; i++)
80     cout << "    ";
81   
82   cout << *this;
83 }
84
85 ostream&
86 operator<< (ostream& os, const MachineInstr& minstr)
87 {
88   os << TargetInstrDescriptors[minstr.opCode].opCodeString;
89   
90   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
91     os << "\t" << minstr.getOperand(i);
92   
93 #undef DEBUG_VAL_OP_ITERATOR
94 #ifdef DEBUG_VAL_OP_ITERATOR
95   os << endl << "\tValue operands are: ";
96   for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
97     {
98       const Value* val = *vo;
99       os << val << (vo.isDef()? "(def), " : ", ");
100     }
101   os << endl;
102 #endif
103   
104   return os;
105 }
106
107 static inline ostream&
108 OutputOperand(ostream &os, const MachineOperand &mop)
109 {
110   switch (mop.getOperandType())
111     {
112     case MachineOperand::MO_CCRegister:
113     case MachineOperand::MO_VirtualRegister:
114       return os << "(val " << mop.getVRegValue() << ")";
115     case MachineOperand::MO_MachineRegister:
116       return os << "("     << mop.getMachineRegNum() << ")";
117     default:
118       assert(0 && "Unknown operand type");
119       return os;
120     }
121 }
122
123
124 ostream&
125 operator<<(ostream &os, const MachineOperand &mop)
126 {
127   switch(mop.opType)
128     {
129     case MachineOperand::MO_VirtualRegister:
130     case MachineOperand::MO_MachineRegister:
131       os << "%reg";
132       return OutputOperand(os, mop);
133     case MachineOperand::MO_CCRegister:
134       os << "%ccreg";
135       return OutputOperand(os, mop);
136     case MachineOperand::MO_SignExtendedImmed:
137       return os << mop.immedVal;
138     case MachineOperand::MO_UnextendedImmed:
139       return os << mop.immedVal;
140     case MachineOperand::MO_PCRelativeDisp:
141       {
142         const Value* opVal = mop.getVRegValue();
143         bool isLabel = isa<Method>(opVal) || isa<BasicBlock>(opVal);
144         return os << "%disp("
145                   << (isLabel? "label " : "addr-of-val ")
146                   << opVal << ")";
147       }
148     default:
149       assert(0 && "Unrecognized operand type");
150       break;
151     }
152   
153   return os;
154 }
155
156
157 void
158 PrintMachineInstructions(const Method *const method)
159 {
160   cout << "\n" << method->getReturnType()
161        << " \"" << method->getName() << "\"" << endl;
162   
163   for (Method::const_iterator BI = method->begin(); BI != method->end(); ++BI)
164     {
165       BasicBlock* bb = *BI;
166       cout << "\n"
167            << (bb->hasName()? bb->getName() : "Label")
168            << " (" << bb << ")" << ":"
169            << endl;
170       
171       MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec();
172       for (unsigned i=0; i < mvec.size(); i++)
173         cout << "\t" << *mvec[i] << endl;
174     } 
175   cout << endl << "End method \"" << method->getName() << "\""
176        << endl << endl;
177 }