xref: /llvm-project/llvm/lib/CodeGen/MachineInstr.cpp (revision c36a504cfe644d53735294f4f45cc3419a1b2b88)
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 }
178