blob: c658717b02490090081a0e8d964e7c0125534d47 [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
Daniel Dunbar5a939952011-11-29 00:25:57 +000014#include "EDDisassembler.h"
15#include "EDInst.h"
16#include "EDOperand.h"
17#include "EDToken.h"
Sean Callananee5dfd42010-02-01 08:49:35 +000018#include "llvm-c/EnhancedDisassembly.h"
Chris Lattner847da552010-07-20 18:25:19 +000019using namespace llvm;
Sean Callananbd51cdd2010-01-29 01:30:01 +000020
21int EDGetDisassembler(EDDisassemblerRef *disassembler,
22 const char *triple,
23 EDAssemblySyntax_t syntax) {
Chris Lattner847da552010-07-20 18:25:19 +000024 EDDisassembler::AssemblySyntax Syntax;
25 switch (syntax) {
Craig Topper85814382012-02-07 05:05:23 +000026 default: llvm_unreachable("Unknown assembly syntax!");
Chris Lattner847da552010-07-20 18:25:19 +000027 case kEDAssemblySyntaxX86Intel:
28 Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel;
29 break;
30 case kEDAssemblySyntaxX86ATT:
31 Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT;
32 break;
33 case kEDAssemblySyntaxARMUAL:
34 Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL;
35 break;
Sean Callananee5dfd42010-02-01 08:49:35 +000036 }
Chris Lattner847da552010-07-20 18:25:19 +000037
38 EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax);
39
40 if (!ret)
41 return -1;
42 *disassembler = ret;
43 return 0;
Sean Callananbd51cdd2010-01-29 01:30:01 +000044}
Sean Callananee5dfd42010-02-01 08:49:35 +000045
46int EDGetRegisterName(const char** regName,
47 EDDisassemblerRef disassembler,
48 unsigned regID) {
Chris Lattner847da552010-07-20 18:25:19 +000049 const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID);
Sean Callanan8f993b82010-04-08 00:48:21 +000050 if (!name)
Sean Callananee5dfd42010-02-01 08:49:35 +000051 return -1;
52 *regName = name;
53 return 0;
54}
55
56int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
57 unsigned regID) {
Chris Lattner847da552010-07-20 18:25:19 +000058 return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0;
Sean Callananee5dfd42010-02-01 08:49:35 +000059}
60
61int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
62 unsigned regID) {
Chris Lattner847da552010-07-20 18:25:19 +000063 return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0;
Sean Callananee5dfd42010-02-01 08:49:35 +000064}
65
66unsigned int EDCreateInsts(EDInstRef *insts,
67 unsigned int count,
68 EDDisassemblerRef disassembler,
Chris Lattner847da552010-07-20 18:25:19 +000069 ::EDByteReaderCallback byteReader,
Sean Callananee5dfd42010-02-01 08:49:35 +000070 uint64_t address,
71 void *arg) {
72 unsigned int index;
73
Sean Callanan8f993b82010-04-08 00:48:21 +000074 for (index = 0; index < count; ++index) {
Chris Lattner847da552010-07-20 18:25:19 +000075 EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader,
76 address, arg);
Sean Callananee5dfd42010-02-01 08:49:35 +000077
Sean Callanan8f993b82010-04-08 00:48:21 +000078 if (!inst)
Sean Callananee5dfd42010-02-01 08:49:35 +000079 return index;
80
81 insts[index] = inst;
82 address += inst->byteSize();
83 }
84
85 return count;
86}
87
88void EDReleaseInst(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +000089 delete ((EDInst*)inst);
Sean Callananee5dfd42010-02-01 08:49:35 +000090}
91
92int EDInstByteSize(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +000093 return ((EDInst*)inst)->byteSize();
Sean Callananee5dfd42010-02-01 08:49:35 +000094}
95
96int EDGetInstString(const char **buf,
97 EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +000098 return ((EDInst*)inst)->getString(*buf);
Sean Callananee5dfd42010-02-01 08:49:35 +000099}
100
101int EDInstID(unsigned *instID, EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000102 *instID = ((EDInst*)inst)->instID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000103 return 0;
104}
105
106int EDInstIsBranch(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000107 return ((EDInst*)inst)->isBranch();
Sean Callananee5dfd42010-02-01 08:49:35 +0000108}
109
110int EDInstIsMove(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000111 return ((EDInst*)inst)->isMove();
Sean Callananee5dfd42010-02-01 08:49:35 +0000112}
113
114int EDBranchTargetID(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000115 return ((EDInst*)inst)->branchTargetID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000116}
117
118int EDMoveSourceID(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000119 return ((EDInst*)inst)->moveSourceID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000120}
121
122int EDMoveTargetID(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000123 return ((EDInst*)inst)->moveTargetID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000124}
125
126int EDNumTokens(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000127 return ((EDInst*)inst)->numTokens();
Sean Callananee5dfd42010-02-01 08:49:35 +0000128}
129
130int EDGetToken(EDTokenRef *token,
131 EDInstRef inst,
132 int index) {
Chris Lattner847da552010-07-20 18:25:19 +0000133 return ((EDInst*)inst)->getToken(*(EDToken**)token, index);
Sean Callananee5dfd42010-02-01 08:49:35 +0000134}
135
136int EDGetTokenString(const char **buf,
137 EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000138 return ((EDToken*)token)->getString(*buf);
Sean Callananee5dfd42010-02-01 08:49:35 +0000139}
140
141int EDOperandIndexForToken(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000142 return ((EDToken*)token)->operandID();
Sean Callananee5dfd42010-02-01 08:49:35 +0000143}
144
145int EDTokenIsWhitespace(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000146 return ((EDToken*)token)->type() == EDToken::kTokenWhitespace;
Sean Callananee5dfd42010-02-01 08:49:35 +0000147}
148
149int EDTokenIsPunctuation(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000150 return ((EDToken*)token)->type() == EDToken::kTokenPunctuation;
Sean Callananee5dfd42010-02-01 08:49:35 +0000151}
152
153int EDTokenIsOpcode(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000154 return ((EDToken*)token)->type() == EDToken::kTokenOpcode;
Sean Callananee5dfd42010-02-01 08:49:35 +0000155}
156
157int EDTokenIsLiteral(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000158 return ((EDToken*)token)->type() == EDToken::kTokenLiteral;
Sean Callananee5dfd42010-02-01 08:49:35 +0000159}
160
161int EDTokenIsRegister(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000162 return ((EDToken*)token)->type() == EDToken::kTokenRegister;
Sean Callananee5dfd42010-02-01 08:49:35 +0000163}
164
165int EDTokenIsNegativeLiteral(EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000166 if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
Sean Callananee5dfd42010-02-01 08:49:35 +0000167 return -1;
168
Chris Lattner847da552010-07-20 18:25:19 +0000169 return ((EDToken*)token)->literalSign();
Sean Callananee5dfd42010-02-01 08:49:35 +0000170}
171
Chris Lattner847da552010-07-20 18:25:19 +0000172int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
173 if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
Sean Callananee5dfd42010-02-01 08:49:35 +0000174 return -1;
175
Chris Lattner847da552010-07-20 18:25:19 +0000176 return ((EDToken*)token)->literalAbsoluteValue(*value);
Sean Callananee5dfd42010-02-01 08:49:35 +0000177}
178
179int EDRegisterTokenValue(unsigned *registerID,
180 EDTokenRef token) {
Chris Lattner847da552010-07-20 18:25:19 +0000181 if (((EDToken*)token)->type() != EDToken::kTokenRegister)
Sean Callananee5dfd42010-02-01 08:49:35 +0000182 return -1;
183
Chris Lattner847da552010-07-20 18:25:19 +0000184 return ((EDToken*)token)->registerID(*registerID);
Sean Callananee5dfd42010-02-01 08:49:35 +0000185}
186
187int EDNumOperands(EDInstRef inst) {
Chris Lattner847da552010-07-20 18:25:19 +0000188 return ((EDInst*)inst)->numOperands();
Sean Callananee5dfd42010-02-01 08:49:35 +0000189}
190
191int EDGetOperand(EDOperandRef *operand,
192 EDInstRef inst,
193 int index) {
Chris Lattner847da552010-07-20 18:25:19 +0000194 return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index);
Sean Callananee5dfd42010-02-01 08:49:35 +0000195}
196
Sean Callanan76706582010-02-04 01:43:08 +0000197int EDOperandIsRegister(EDOperandRef operand) {
Chris Lattner847da552010-07-20 18:25:19 +0000198 return ((EDOperand*)operand)->isRegister();
Sean Callanan76706582010-02-04 01:43:08 +0000199}
200
201int EDOperandIsImmediate(EDOperandRef operand) {
Chris Lattner847da552010-07-20 18:25:19 +0000202 return ((EDOperand*)operand)->isImmediate();
Sean Callanan76706582010-02-04 01:43:08 +0000203}
204
205int EDOperandIsMemory(EDOperandRef operand) {
Chris Lattner847da552010-07-20 18:25:19 +0000206 return ((EDOperand*)operand)->isMemory();
Sean Callanan76706582010-02-04 01:43:08 +0000207}
208
Chris Lattner847da552010-07-20 18:25:19 +0000209int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) {
210 if (!((EDOperand*)operand)->isRegister())
Sean Callanan76706582010-02-04 01:43:08 +0000211 return -1;
Chris Lattner847da552010-07-20 18:25:19 +0000212 *value = ((EDOperand*)operand)->regVal();
Sean Callanan76706582010-02-04 01:43:08 +0000213 return 0;
214}
215
Chris Lattner847da552010-07-20 18:25:19 +0000216int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) {
217 if (!((EDOperand*)operand)->isImmediate())
Sean Callanan76706582010-02-04 01:43:08 +0000218 return -1;
Chris Lattner847da552010-07-20 18:25:19 +0000219 *value = ((EDOperand*)operand)->immediateVal();
Sean Callanan76706582010-02-04 01:43:08 +0000220 return 0;
221}
222
Chris Lattner847da552010-07-20 18:25:19 +0000223int EDEvaluateOperand(uint64_t *result, EDOperandRef operand,
224 ::EDRegisterReaderCallback regReader, void *arg) {
225 return ((EDOperand*)operand)->evaluate(*result, regReader, arg);
Sean Callananee5dfd42010-02-01 08:49:35 +0000226}
227
228#ifdef __BLOCKS__
229
230struct ByteReaderWrapper {
231 EDByteBlock_t byteBlock;
232};
233
234static int readerWrapperCallback(uint8_t *byte,
235 uint64_t address,
236 void *arg) {
237 struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
238 return wrapper->byteBlock(byte, address);
239}
240
241unsigned int EDBlockCreateInsts(EDInstRef *insts,
242 int count,
243 EDDisassemblerRef disassembler,
244 EDByteBlock_t byteBlock,
245 uint64_t address) {
246 struct ByteReaderWrapper wrapper;
247 wrapper.byteBlock = byteBlock;
248
249 return EDCreateInsts(insts,
250 count,
251 disassembler,
252 readerWrapperCallback,
253 address,
254 (void*)&wrapper);
255}
256
Chris Lattner847da552010-07-20 18:25:19 +0000257int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand,
Sean Callananee5dfd42010-02-01 08:49:35 +0000258 EDRegisterBlock_t regBlock) {
Chris Lattner847da552010-07-20 18:25:19 +0000259 return ((EDOperand*)operand)->evaluate(*result, regBlock);
Sean Callananee5dfd42010-02-01 08:49:35 +0000260}
261
Chris Lattner847da552010-07-20 18:25:19 +0000262int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) {
263 return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor);
Sean Callananee5dfd42010-02-01 08:49:35 +0000264}
265
Sean Callanan37ad4662010-02-02 00:04:46 +0000266#else
267
268extern "C" unsigned int EDBlockCreateInsts() {
269 return 0;
270}
271
272extern "C" int EDBlockEvaluateOperand() {
273 return -1;
274}
275
276extern "C" int EDBlockVisitTokens() {
277 return -1;
278}
279
Sean Callananee5dfd42010-02-01 08:49:35 +0000280#endif