xref: /llvm-project/llvm/lib/CodeGen/MachineInstr.cpp (revision 959a5fbf8eb83a50a811382b9778293584cb0345)
1 //===-- MachineInstr.cpp --------------------------------------------------===//
2 //
3 //===----------------------------------------------------------------------===//
4 
5 #include "llvm/CodeGen/MachineInstr.h"
6 #include "llvm/Value.h"
7 using std::cerr;
8 
9 
10 // Constructor for instructions with fixed #operands (nearly all)
11 MachineInstr::MachineInstr(MachineOpCode _opCode,
12 			   OpCodeMask    _opCodeMask)
13   : opCode(_opCode),
14     opCodeMask(_opCodeMask),
15     operands(TargetInstrDescriptors[_opCode].numOperands)
16 {
17   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
18 }
19 
20 // Constructor for instructions with variable #operands
21 MachineInstr::MachineInstr(MachineOpCode _opCode,
22 			   unsigned	 numOperands,
23 			   OpCodeMask    _opCodeMask)
24   : opCode(_opCode),
25     opCodeMask(_opCodeMask),
26     operands(numOperands)
27 {
28 }
29 
30 void
31 MachineInstr::SetMachineOperandVal(unsigned int i,
32                                    MachineOperand::MachineOperandType opType,
33                                    Value* _val,
34                                    bool isdef,
35                                    bool isDefAndUse)
36 {
37   assert(i < operands.size());
38   operands[i].Initialize(opType, _val);
39   if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
40     operands[i].markDef();
41   if (isDefAndUse)
42     operands[i].markDefAndUse();
43 }
44 
45 void
46 MachineInstr::SetMachineOperandConst(unsigned int i,
47 				MachineOperand::MachineOperandType operandType,
48                                      int64_t intValue)
49 {
50   assert(i < operands.size());
51   assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
52          "immed. constant cannot be defined");
53   operands[i].InitializeConst(operandType, intValue);
54 }
55 
56 void
57 MachineInstr::SetMachineOperandReg(unsigned int i,
58                                    int regNum,
59                                    bool isdef,
60                                    bool isDefAndUse,
61                                    bool isCCReg)
62 {
63   assert(i < operands.size());
64   operands[i].InitializeReg(regNum, isCCReg);
65   if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
66     operands[i].markDef();
67   if (isDefAndUse)
68     operands[i].markDefAndUse();
69   regsUsed.insert(regNum);
70 }
71 
72 void
73 MachineInstr::SetRegForOperand(unsigned i, int regNum)
74 {
75   operands[i].setRegForValue(regNum);
76   regsUsed.insert(regNum);
77 }
78 
79 
80 void
81 MachineInstr::dump() const
82 {
83   cerr << "  " << *this;
84 }
85 
86 static inline std::ostream &OutputValue(std::ostream &os,
87                                         const Value* val)
88 {
89   os << "(val ";
90   if (val && val->hasName())
91     return os << val->getName() << ")";
92   else
93     return os << (void*) val << ")";              // print address only
94 }
95 
96 std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr)
97 {
98   os << TargetInstrDescriptors[minstr.opCode].opCodeString;
99 
100   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
101     os << "\t" << minstr.getOperand(i);
102     if( minstr.operandIsDefined(i) )
103       os << "*";
104     if( minstr.operandIsDefinedAndUsed(i) )
105       os << "*";
106   }
107 
108   // code for printing implict references
109   unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
110   if(  NumOfImpRefs > 0 ) {
111     os << "\tImplicit: ";
112     for(unsigned z=0; z < NumOfImpRefs; z++) {
113       OutputValue(os, minstr.getImplicitRef(z));
114       if( minstr.implicitRefIsDefined(z)) os << "*";
115       if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*";
116       os << "\t";
117     }
118   }
119 
120   return os << "\n";
121 }
122 
123 std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
124 {
125   if (mop.opHiBits32())
126     os << "%lm(";
127   else if (mop.opLoBits32())
128     os << "%lo(";
129   else if (mop.opHiBits64())
130     os << "%hh(";
131   else if (mop.opLoBits64())
132     os << "%hm(";
133 
134   switch(mop.opType)
135     {
136     case MachineOperand::MO_VirtualRegister:
137       os << "%reg";
138       OutputValue(os, mop.getVRegValue());
139       break;
140     case MachineOperand::MO_CCRegister:
141       os << "%ccreg";
142       OutputValue(os, mop.getVRegValue());
143       break;
144     case MachineOperand::MO_MachineRegister:
145       os << "%reg";
146       os << "(" << mop.getMachineRegNum() << ")";
147       break;
148     case MachineOperand::MO_SignExtendedImmed:
149       os << (long)mop.immedVal;
150       break;
151     case MachineOperand::MO_UnextendedImmed:
152       os << (long)mop.immedVal;
153       break;
154     case MachineOperand::MO_PCRelativeDisp:
155       {
156         const Value* opVal = mop.getVRegValue();
157         bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
158         os << "%disp(" << (isLabel? "label " : "addr-of-val ");
159         if (opVal->hasName())
160           os << opVal->getName();
161         else
162           os << (const void*) opVal;
163         os << ")";
164         break;
165       }
166     default:
167       assert(0 && "Unrecognized operand type");
168       break;
169     }
170 
171   if (mop.flags &
172       (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 |
173        MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64))
174     os << ")";
175 
176   return os;
177 }
178