blob: de40770e900915adb7d30f5ae0a06fb550e551ac [file] [log] [blame]
Sean Callananee5dfd42010-02-01 08:49:35 +00001//===-EDInst.cpp - LLVM Enhanced Disassembler -----------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Enhanced Disassembly library's instruction class.
11// The instruction is responsible for vending the string representation,
12// individual tokens, and operands for a single instruction.
13//
14//===----------------------------------------------------------------------===//
15
16#include "EDDisassembler.h"
17#include "EDInst.h"
18#include "EDOperand.h"
19#include "EDToken.h"
20
21#include "llvm/MC/MCInst.h"
22
23using namespace llvm;
24
25EDInst::EDInst(llvm::MCInst *inst,
26 uint64_t byteSize,
27 EDDisassembler &disassembler,
28 const InstInfo *info) :
29 Disassembler(disassembler),
30 Inst(inst),
31 ThisInstInfo(info),
32 ByteSize(byteSize),
33 BranchTarget(-1),
34 MoveSource(-1),
35 MoveTarget(-1) {
Sean Callanan4285b292010-04-09 00:11:15 +000036 OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()];
Sean Callananee5dfd42010-02-01 08:49:35 +000037}
38
39EDInst::~EDInst() {
40 unsigned int index;
41 unsigned int numOperands = Operands.size();
42
43 for (index = 0; index < numOperands; ++index)
44 delete Operands[index];
45
46 unsigned int numTokens = Tokens.size();
47
48 for (index = 0; index < numTokens; ++index)
49 delete Tokens[index];
50
51 delete Inst;
52}
53
54uint64_t EDInst::byteSize() {
55 return ByteSize;
56}
57
58int EDInst::stringify() {
59 if (StringifyResult.valid())
60 return StringifyResult.result();
61
62 if (Disassembler.printInst(String, *Inst))
63 return StringifyResult.setResult(-1);
Sean Callananee5dfd42010-02-01 08:49:35 +000064
65 return StringifyResult.setResult(0);
66}
67
68int EDInst::getString(const char*& str) {
69 if (stringify())
70 return -1;
71
72 str = String.c_str();
73
74 return 0;
75}
76
77unsigned EDInst::instID() {
78 return Inst->getOpcode();
79}
80
81bool EDInst::isBranch() {
82 if (ThisInstInfo)
Sean Callanan8f993b82010-04-08 00:48:21 +000083 return ThisInstInfo->instructionType == kInstructionTypeBranch;
Sean Callananee5dfd42010-02-01 08:49:35 +000084 else
85 return false;
86}
87
88bool EDInst::isMove() {
89 if (ThisInstInfo)
Sean Callanan8f993b82010-04-08 00:48:21 +000090 return ThisInstInfo->instructionType == kInstructionTypeMove;
Sean Callananee5dfd42010-02-01 08:49:35 +000091 else
92 return false;
93}
94
95int EDInst::parseOperands() {
96 if (ParseResult.valid())
Sean Callanan8f993b82010-04-08 00:48:21 +000097 return ParseResult.result();
Sean Callananee5dfd42010-02-01 08:49:35 +000098
99 if (!ThisInstInfo)
100 return ParseResult.setResult(-1);
101
102 unsigned int opIndex;
103 unsigned int mcOpIndex = 0;
104
105 for (opIndex = 0; opIndex < ThisInstInfo->numOperands; ++opIndex) {
106 if (isBranch() &&
107 (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)) {
108 BranchTarget = opIndex;
109 }
110 else if (isMove()) {
111 if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagSource)
112 MoveSource = opIndex;
113 else if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)
114 MoveTarget = opIndex;
115 }
116
117 EDOperand *operand = new EDOperand(Disassembler, *this, opIndex, mcOpIndex);
118
119 Operands.push_back(operand);
120 }
121
122 return ParseResult.setResult(0);
123}
124
125int EDInst::branchTargetID() {
126 if (parseOperands())
127 return -1;
128 return BranchTarget;
129}
130
131int EDInst::moveSourceID() {
132 if (parseOperands())
133 return -1;
134 return MoveSource;
135}
136
137int EDInst::moveTargetID() {
138 if (parseOperands())
139 return -1;
140 return MoveTarget;
141}
142
143int EDInst::numOperands() {
144 if (parseOperands())
145 return -1;
146 return Operands.size();
147}
148
149int EDInst::getOperand(EDOperand *&operand, unsigned int index) {
150 if (parseOperands())
151 return -1;
152
153 if (index >= Operands.size())
154 return -1;
155
156 operand = Operands[index];
157 return 0;
158}
159
160int EDInst::tokenize() {
161 if (TokenizeResult.valid())
162 return TokenizeResult.result();
163
164 if (stringify())
165 return TokenizeResult.setResult(-1);
166
167 return TokenizeResult.setResult(EDToken::tokenize(Tokens,
168 String,
169 OperandOrder,
170 Disassembler));
171
172}
173
174int EDInst::numTokens() {
175 if (tokenize())
176 return -1;
177 return Tokens.size();
178}
179
180int EDInst::getToken(EDToken *&token, unsigned int index) {
181 if (tokenize())
182 return -1;
183 token = Tokens[index];
184 return 0;
185}
186
187#ifdef __BLOCKS__
188int EDInst::visitTokens(EDTokenVisitor_t visitor) {
189 if (tokenize())
190 return -1;
191
192 tokvec_t::iterator iter;
193
194 for (iter = Tokens.begin(); iter != Tokens.end(); ++iter) {
195 int ret = visitor(*iter);
196 if (ret == 1)
197 return 0;
198 if (ret != 0)
199 return -1;
200 }
201
202 return 0;
203}
204#endif