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