blob: 16855b3f45d8d314349e1817ce9d3214be49ef98 [file] [log] [blame]
Chris Lattner847da552010-07-20 18:25:19 +00001//===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===//
Sean Callananbd51cdd2010-01-29 01:30:01 +00002//
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
Chris Lattner847da552010-07-20 18:25:19 +000014// FIXME: This code isn't layered right, the headers should be moved to
15// include llvm/MC/MCDisassembler or something.
16#include "../../lib/MC/MCDisassembler/EDDisassembler.h"
17#include "../../lib/MC/MCDisassembler/EDInst.h"
18#include "../../lib/MC/MCDisassembler/EDOperand.h"
19#include "../../lib/MC/MCDisassembler/EDToken.h"
Sean Callananee5dfd42010-02-01 08:49:35 +000020#include "llvm-c/EnhancedDisassembly.h"
Chris Lattner847da552010-07-20 18:25:19 +000021using namespace llvm;
Sean Callananbd51cdd2010-01-29 01:30:01 +000022
23int EDGetDisassembler(EDDisassemblerRef *disassembler,
24 const char *triple,
25 EDAssemblySyntax_t syntax) {
Sean Callananee5dfd42010-02-01 08:49:35 +000026 EDDisassembler::initialize();
27
Chris Lattner847da552010-07-20 18:25:19 +000028 EDDisassembler::AssemblySyntax Syntax;
29 switch (syntax) {
30 default: assert(0 && "Unknown assembly syntax!");
31 case kEDAssemblySyntaxX86Intel:
32 Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel;
33 break;
34 case kEDAssemblySyntaxX86ATT:
35 Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT;
36 break;
37 case kEDAssemblySyntaxARMUAL:
38 Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL;
39 break;
Sean Callananee5dfd42010-02-01 08:49:35 +000040 }
Chris Lattner847da552010-07-20 18:25:19 +000041
42 EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax);
43
44 if (!ret)
45 return -1;
46 *disassembler = ret;
47 return 0;
Sean Callananbd51cdd2010-01-29 01:30:01 +000048}
Sean Callananee5dfd42010-02-01 08:49:35 +000049
50int EDGetRegisterName(const char** regName,
51 EDDisassemblerRef disassembler,
52 unsigned regID) {
Chris Lattner847da552010-07-20 18:25:19 +000053 const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID);
Sean Callanan8f993b82010-04-08 00:48:21 +000054 if (!name)
Sean Callananee5dfd42010-02-01 08:49:35 +000055 return -1;
56 *regName = name;
57 return 0;
58}
59
60int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
61 unsigned regID) {
Chris Lattner847da552010-07-20 18:25:19 +000062 return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0;
Sean Callananee5dfd42010-02-01 08:49:35 +000063}
64
65int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
66 unsigned regID) {
Chris Lattner847da552010-07-20 18:25:19 +000067 return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0;
Sean Callananee5dfd42010-02-01 08:49:35 +000068}
69
70unsigned int EDCreateInsts(EDInstRef *insts,
71 unsigned int count,
72 EDDisassemblerRef disassembler,
Chris Lattner847da552010-07-20 18:25:19 +000073 ::EDByteReaderCallback byteReader,
Sean Callananee5dfd42010-02-01 08:49:35 +000074 uint64_t address,
75 void *arg) {
76 unsigned int index;
77
Sean Callanan8f993b82010-04-08 00:48:21 +000078 for (index = 0; index < count; ++index) {
Chris Lattner847da552010-07-20 18:25:19 +000079 EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader,
80 address, arg);
Sean Callananee5dfd42010-02-01 08:49:35 +000081
Sean Callanan8f993b82010-04-08 00:48:21 +000082 if (!inst)
Sean Callananee5dfd42010-02-01 08:49:35 +000083 return index;
84
85 insts[index] = inst;
86 address += inst->byteSize();
87 }
88
89 return count;
90}
91
92void EDReleaseInst(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +000093 delete ((EDInst*)inst);
Sean Callananee5dfd42010-02-01 08:49:35 +000094}
95
96int EDInstByteSize(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +000097 return ((EDInst*)inst)->byteSize();
Sean Callananee5dfd42010-02-01 08:49:35 +000098}
99
100int EDGetInstString(const char **buf,
101 EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000102 return ((EDInst*)inst)->getString(*buf);
Sean Callananee5dfd42010-02-01 08:49:35 +0000103}
104
105int EDInstID(unsigned *instID, EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000106 *instID = ((EDInst*)inst)->instID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000107 return 0;
108}
109
110int EDInstIsBranch(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000111 return ((EDInst*)inst)->isBranch();
Sean Callananee5dfd42010-02-01 08:49:35 +0000112}
113
114int EDInstIsMove(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000115 return ((EDInst*)inst)->isMove();
Sean Callananee5dfd42010-02-01 08:49:35 +0000116}
117
118int EDBranchTargetID(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000119 return ((EDInst*)inst)->branchTargetID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000120}
121
122int EDMoveSourceID(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000123 return ((EDInst*)inst)->moveSourceID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000124}
125
126int EDMoveTargetID(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000127 return ((EDInst*)inst)->moveTargetID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000128}
129
130int EDNumTokens(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000131 return ((EDInst*)inst)->numTokens();
Sean Callananee5dfd42010-02-01 08:49:35 +0000132}
133
134int EDGetToken(EDTokenRef *token,
135 EDInstRef inst,
136 int index) {
Chris Lattner847da552010-07-20 18:25:19 +0000137 return ((EDInst*)inst)->getToken(*(EDToken**)token, index);
Sean Callananee5dfd42010-02-01 08:49:35 +0000138}
139
140int EDGetTokenString(const char **buf,
141 EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000142 return ((EDToken*)token)->getString(*buf);
Sean Callananee5dfd42010-02-01 08:49:35 +0000143}
144
145int EDOperandIndexForToken(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000146 return ((EDToken*)token)->operandID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000147}
148
149int EDTokenIsWhitespace(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000150 return ((EDToken*)token)->type() == EDToken::kTokenWhitespace;
Sean Callananee5dfd42010-02-01 08:49:35 +0000151}
152
153int EDTokenIsPunctuation(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000154 return ((EDToken*)token)->type() == EDToken::kTokenPunctuation;
Sean Callananee5dfd42010-02-01 08:49:35 +0000155}
156
157int EDTokenIsOpcode(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000158 return ((EDToken*)token)->type() == EDToken::kTokenOpcode;
Sean Callananee5dfd42010-02-01 08:49:35 +0000159}
160
161int EDTokenIsLiteral(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000162 return ((EDToken*)token)->type() == EDToken::kTokenLiteral;
Sean Callananee5dfd42010-02-01 08:49:35 +0000163}
164
165int EDTokenIsRegister(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000166 return ((EDToken*)token)->type() == EDToken::kTokenRegister;
Sean Callananee5dfd42010-02-01 08:49:35 +0000167}
168
169int EDTokenIsNegativeLiteral(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000170 if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
Sean Callananee5dfd42010-02-01 08:49:35 +0000171 return -1;
172
Chris Lattner847da552010-07-20 18:25:19 +0000173 return ((EDToken*)token)->literalSign();
Sean Callananee5dfd42010-02-01 08:49:35 +0000174}
175
Chris Lattner847da552010-07-20 18:25:19 +0000176int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
177 if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
Sean Callananee5dfd42010-02-01 08:49:35 +0000178 return -1;
179
Chris Lattner847da552010-07-20 18:25:19 +0000180 return ((EDToken*)token)->literalAbsoluteValue(*value);
Sean Callananee5dfd42010-02-01 08:49:35 +0000181}
182
183int EDRegisterTokenValue(unsigned *registerID,
184 EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000185 if (((EDToken*)token)->type() != EDToken::kTokenRegister)
Sean Callananee5dfd42010-02-01 08:49:35 +0000186 return -1;
187
Chris Lattner847da552010-07-20 18:25:19 +0000188 return ((EDToken*)token)->registerID(*registerID);
Sean Callananee5dfd42010-02-01 08:49:35 +0000189}
190
191int EDNumOperands(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000192 return ((EDInst*)inst)->numOperands();
Sean Callananee5dfd42010-02-01 08:49:35 +0000193}
194
195int EDGetOperand(EDOperandRef *operand,
196 EDInstRef inst,
197 int index) {
Chris Lattner847da552010-07-20 18:25:19 +0000198 return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index);
Sean Callananee5dfd42010-02-01 08:49:35 +0000199}
200
Sean Callanan76706582010-02-04 01:43:08 +0000201int EDOperandIsRegister(EDOperandRef operand) {
Chris Lattner847da552010-07-20 18:25:19 +0000202 return ((EDOperand*)operand)->isRegister();
Sean Callanan76706582010-02-04 01:43:08 +0000203}
204
205int EDOperandIsImmediate(EDOperandRef operand) {
Chris Lattner847da552010-07-20 18:25:19 +0000206 return ((EDOperand*)operand)->isImmediate();
Sean Callanan76706582010-02-04 01:43:08 +0000207}
208
209int EDOperandIsMemory(EDOperandRef operand) {
Chris Lattner847da552010-07-20 18:25:19 +0000210 return ((EDOperand*)operand)->isMemory();
Sean Callanan76706582010-02-04 01:43:08 +0000211}
212
Chris Lattner847da552010-07-20 18:25:19 +0000213int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) {
214 if (!((EDOperand*)operand)->isRegister())
Sean Callanan76706582010-02-04 01:43:08 +0000215 return -1;
Chris Lattner847da552010-07-20 18:25:19 +0000216 *value = ((EDOperand*)operand)->regVal();
Sean Callanan76706582010-02-04 01:43:08 +0000217 return 0;
218}
219
Chris Lattner847da552010-07-20 18:25:19 +0000220int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) {
221 if (!((EDOperand*)operand)->isImmediate())
Sean Callanan76706582010-02-04 01:43:08 +0000222 return -1;
Chris Lattner847da552010-07-20 18:25:19 +0000223 *value = ((EDOperand*)operand)->immediateVal();
Sean Callanan76706582010-02-04 01:43:08 +0000224 return 0;
225}
226
Chris Lattner847da552010-07-20 18:25:19 +0000227int EDEvaluateOperand(uint64_t *result, EDOperandRef operand,
228 ::EDRegisterReaderCallback regReader, void *arg) {
229 return ((EDOperand*)operand)->evaluate(*result, regReader, arg);
Sean Callananee5dfd42010-02-01 08:49:35 +0000230}
231
232#ifdef __BLOCKS__
233
234struct ByteReaderWrapper {
235 EDByteBlock_t byteBlock;
236};
237
238static int readerWrapperCallback(uint8_t *byte,
239 uint64_t address,
240 void *arg) {
241 struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
242 return wrapper->byteBlock(byte, address);
243}
244
245unsigned int EDBlockCreateInsts(EDInstRef *insts,
246 int count,
247 EDDisassemblerRef disassembler,
248 EDByteBlock_t byteBlock,
249 uint64_t address) {
250 struct ByteReaderWrapper wrapper;
251 wrapper.byteBlock = byteBlock;
252
253 return EDCreateInsts(insts,
254 count,
255 disassembler,
256 readerWrapperCallback,
257 address,
258 (void*)&wrapper);
259}
260
Chris Lattner847da552010-07-20 18:25:19 +0000261int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand,
Sean Callananee5dfd42010-02-01 08:49:35 +0000262 EDRegisterBlock_t regBlock) {
Chris Lattner847da552010-07-20 18:25:19 +0000263 return ((EDOperand*)operand)->evaluate(*result, regBlock);
Sean Callananee5dfd42010-02-01 08:49:35 +0000264}
265
Chris Lattner847da552010-07-20 18:25:19 +0000266int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) {
267 return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor);
Sean Callananee5dfd42010-02-01 08:49:35 +0000268}
269
Sean Callanan37ad4662010-02-02 00:04:46 +0000270#else
271
272extern "C" unsigned int EDBlockCreateInsts() {
273 return 0;
274}
275
276extern "C" int EDBlockEvaluateOperand() {
277 return -1;
278}
279
280extern "C" int EDBlockVisitTokens() {
281 return -1;
282}
283
Sean Callananee5dfd42010-02-01 08:49:35 +0000284#endif