blob: b6ca32f2db8694451bd437bd0a97cbb32eec6a66 [file] [log] [blame]
Sean Callananbd51cdd2010-01-29 01:30:01 +00001//===-EDMain.cpp - LLVM Enhanced Disassembly C API ------------------------===//
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 disassembler's public C API.
11//
12//===----------------------------------------------------------------------===//
13
Sean Callananee5dfd42010-02-01 08:49:35 +000014#include "EDDisassembler.h"
15#include "EDInst.h"
16#include "EDOperand.h"
17#include "EDToken.h"
18
19#include "llvm-c/EnhancedDisassembly.h"
Sean Callananbd51cdd2010-01-29 01:30:01 +000020
21int EDGetDisassembler(EDDisassemblerRef *disassembler,
22 const char *triple,
23 EDAssemblySyntax_t syntax) {
Sean Callananee5dfd42010-02-01 08:49:35 +000024 EDDisassembler::initialize();
25
26 EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple,
27 syntax);
28
29 if (ret) {
30 *disassembler = ret;
31 return 0;
Sean Callanan8f993b82010-04-08 00:48:21 +000032 } else {
Sean Callananee5dfd42010-02-01 08:49:35 +000033 return -1;
34 }
Sean Callananbd51cdd2010-01-29 01:30:01 +000035}
Sean Callananee5dfd42010-02-01 08:49:35 +000036
37int EDGetRegisterName(const char** regName,
38 EDDisassemblerRef disassembler,
39 unsigned regID) {
40 const char* name = disassembler->nameWithRegisterID(regID);
Sean Callanan8f993b82010-04-08 00:48:21 +000041 if (!name)
Sean Callananee5dfd42010-02-01 08:49:35 +000042 return -1;
43 *regName = name;
44 return 0;
45}
46
47int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
48 unsigned regID) {
49 return disassembler->registerIsStackPointer(regID) ? 1 : 0;
50}
51
52int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
53 unsigned regID) {
54 return disassembler->registerIsProgramCounter(regID) ? 1 : 0;
55}
56
57unsigned int EDCreateInsts(EDInstRef *insts,
58 unsigned int count,
59 EDDisassemblerRef disassembler,
60 EDByteReaderCallback byteReader,
61 uint64_t address,
62 void *arg) {
63 unsigned int index;
64
Sean Callanan8f993b82010-04-08 00:48:21 +000065 for (index = 0; index < count; ++index) {
Sean Callananee5dfd42010-02-01 08:49:35 +000066 EDInst *inst = disassembler->createInst(byteReader, address, arg);
67
Sean Callanan8f993b82010-04-08 00:48:21 +000068 if (!inst)
Sean Callananee5dfd42010-02-01 08:49:35 +000069 return index;
70
71 insts[index] = inst;
72 address += inst->byteSize();
73 }
74
75 return count;
76}
77
78void EDReleaseInst(EDInstRef inst) {
79 delete inst;
80}
81
82int EDInstByteSize(EDInstRef inst) {
83 return inst->byteSize();
84}
85
86int EDGetInstString(const char **buf,
87 EDInstRef inst) {
88 return inst->getString(*buf);
89}
90
91int EDInstID(unsigned *instID, EDInstRef inst) {
92 *instID = inst->instID();
93 return 0;
94}
95
96int EDInstIsBranch(EDInstRef inst) {
97 return inst->isBranch();
98}
99
100int EDInstIsMove(EDInstRef inst) {
101 return inst->isMove();
102}
103
104int EDBranchTargetID(EDInstRef inst) {
105 return inst->branchTargetID();
106}
107
108int EDMoveSourceID(EDInstRef inst) {
109 return inst->moveSourceID();
110}
111
112int EDMoveTargetID(EDInstRef inst) {
113 return inst->moveTargetID();
114}
115
116int EDNumTokens(EDInstRef inst) {
117 return inst->numTokens();
118}
119
120int EDGetToken(EDTokenRef *token,
121 EDInstRef inst,
122 int index) {
123 return inst->getToken(*token, index);
124}
125
126int EDGetTokenString(const char **buf,
127 EDTokenRef token) {
128 return token->getString(*buf);
129}
130
131int EDOperandIndexForToken(EDTokenRef token) {
132 return token->operandID();
133}
134
135int EDTokenIsWhitespace(EDTokenRef token) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000136 if (token->type() == EDToken::kTokenWhitespace)
Sean Callananee5dfd42010-02-01 08:49:35 +0000137 return 1;
138 else
139 return 0;
140}
141
142int EDTokenIsPunctuation(EDTokenRef token) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000143 if (token->type() == EDToken::kTokenPunctuation)
Sean Callananee5dfd42010-02-01 08:49:35 +0000144 return 1;
145 else
146 return 0;
147}
148
149int EDTokenIsOpcode(EDTokenRef token) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000150 if (token->type() == EDToken::kTokenOpcode)
Sean Callananee5dfd42010-02-01 08:49:35 +0000151 return 1;
152 else
153 return 0;
154}
155
156int EDTokenIsLiteral(EDTokenRef token) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000157 if (token->type() == EDToken::kTokenLiteral)
Sean Callananee5dfd42010-02-01 08:49:35 +0000158 return 1;
159 else
160 return 0;
161}
162
163int EDTokenIsRegister(EDTokenRef token) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000164 if (token->type() == EDToken::kTokenRegister)
Sean Callananee5dfd42010-02-01 08:49:35 +0000165 return 1;
166 else
167 return 0;
168}
169
170int EDTokenIsNegativeLiteral(EDTokenRef token) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000171 if (token->type() != EDToken::kTokenLiteral)
Sean Callananee5dfd42010-02-01 08:49:35 +0000172 return -1;
173
174 return token->literalSign();
175}
176
177int EDLiteralTokenAbsoluteValue(uint64_t *value,
178 EDTokenRef token) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000179 if (token->type() != EDToken::kTokenLiteral)
Sean Callananee5dfd42010-02-01 08:49:35 +0000180 return -1;
181
182 return token->literalAbsoluteValue(*value);
183}
184
185int EDRegisterTokenValue(unsigned *registerID,
186 EDTokenRef token) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000187 if (token->type() != EDToken::kTokenRegister)
Sean Callananee5dfd42010-02-01 08:49:35 +0000188 return -1;
189
190 return token->registerID(*registerID);
191}
192
193int EDNumOperands(EDInstRef inst) {
194 return inst->numOperands();
195}
196
197int EDGetOperand(EDOperandRef *operand,
198 EDInstRef inst,
199 int index) {
200 return inst->getOperand(*operand, index);
201}
202
Sean Callanan76706582010-02-04 01:43:08 +0000203int EDOperandIsRegister(EDOperandRef operand) {
204 return operand->isRegister();
205}
206
207int EDOperandIsImmediate(EDOperandRef operand) {
208 return operand->isImmediate();
209}
210
211int EDOperandIsMemory(EDOperandRef operand) {
212 return operand->isMemory();
213}
214
215int EDRegisterOperandValue(unsigned *value,
216 EDOperandRef operand) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000217 if (!operand->isRegister())
Sean Callanan76706582010-02-04 01:43:08 +0000218 return -1;
219 *value = operand->regVal();
220 return 0;
221}
222
Sean Callanan01cd79f2010-02-08 23:34:25 +0000223int EDImmediateOperandValue(uint64_t *value,
Sean Callanan76706582010-02-04 01:43:08 +0000224 EDOperandRef operand) {
Sean Callanan8f993b82010-04-08 00:48:21 +0000225 if (!operand->isImmediate())
Sean Callanan76706582010-02-04 01:43:08 +0000226 return -1;
227 *value = operand->immediateVal();
228 return 0;
229}
230
Sean Callananee5dfd42010-02-01 08:49:35 +0000231int EDEvaluateOperand(uint64_t *result,
232 EDOperandRef operand,
233 EDRegisterReaderCallback regReader,
234 void *arg) {
235 return operand->evaluate(*result, regReader, arg);
236}
237
238#ifdef __BLOCKS__
239
240struct ByteReaderWrapper {
241 EDByteBlock_t byteBlock;
242};
243
244static int readerWrapperCallback(uint8_t *byte,
245 uint64_t address,
246 void *arg) {
247 struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
248 return wrapper->byteBlock(byte, address);
249}
250
251unsigned int EDBlockCreateInsts(EDInstRef *insts,
252 int count,
253 EDDisassemblerRef disassembler,
254 EDByteBlock_t byteBlock,
255 uint64_t address) {
256 struct ByteReaderWrapper wrapper;
257 wrapper.byteBlock = byteBlock;
258
259 return EDCreateInsts(insts,
260 count,
261 disassembler,
262 readerWrapperCallback,
263 address,
264 (void*)&wrapper);
265}
266
267int EDBlockEvaluateOperand(uint64_t *result,
268 EDOperandRef operand,
269 EDRegisterBlock_t regBlock) {
270 return operand->evaluate(*result, regBlock);
271}
272
273int EDBlockVisitTokens(EDInstRef inst,
274 EDTokenVisitor_t visitor) {
275 return inst->visitTokens(visitor);
276}
277
Sean Callanan37ad4662010-02-02 00:04:46 +0000278#else
279
280extern "C" unsigned int EDBlockCreateInsts() {
281 return 0;
282}
283
284extern "C" int EDBlockEvaluateOperand() {
285 return -1;
286}
287
288extern "C" int EDBlockVisitTokens() {
289 return -1;
290}
291
Sean Callananee5dfd42010-02-01 08:49:35 +0000292#endif