summaryrefslogtreecommitdiffstats
path: root/tools/edis/EDMain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/edis/EDMain.cpp')
-rw-r--r--tools/edis/EDMain.cpp293
1 files changed, 293 insertions, 0 deletions
diff --git a/tools/edis/EDMain.cpp b/tools/edis/EDMain.cpp
new file mode 100644
index 0000000..3585657
--- /dev/null
+++ b/tools/edis/EDMain.cpp
@@ -0,0 +1,293 @@
+//===-EDMain.cpp - LLVM Enhanced Disassembly C API ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the enhanced disassembler's public C API.
+//
+//===----------------------------------------------------------------------===//
+
+#include "EDDisassembler.h"
+#include "EDInst.h"
+#include "EDOperand.h"
+#include "EDToken.h"
+
+#include "llvm-c/EnhancedDisassembly.h"
+
+int EDGetDisassembler(EDDisassemblerRef *disassembler,
+ const char *triple,
+ EDAssemblySyntax_t syntax) {
+ EDDisassembler::initialize();
+
+ EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple,
+ syntax);
+
+ if (ret) {
+ *disassembler = ret;
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+int EDGetRegisterName(const char** regName,
+ EDDisassemblerRef disassembler,
+ unsigned regID) {
+ const char* name = disassembler->nameWithRegisterID(regID);
+ if(!name)
+ return -1;
+ *regName = name;
+ return 0;
+}
+
+int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
+ unsigned regID) {
+ return disassembler->registerIsStackPointer(regID) ? 1 : 0;
+}
+
+int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
+ unsigned regID) {
+ return disassembler->registerIsProgramCounter(regID) ? 1 : 0;
+}
+
+unsigned int EDCreateInsts(EDInstRef *insts,
+ unsigned int count,
+ EDDisassemblerRef disassembler,
+ EDByteReaderCallback byteReader,
+ uint64_t address,
+ void *arg) {
+ unsigned int index;
+
+ for (index = 0; index < count; index++) {
+ EDInst *inst = disassembler->createInst(byteReader, address, arg);
+
+ if(!inst)
+ return index;
+
+ insts[index] = inst;
+ address += inst->byteSize();
+ }
+
+ return count;
+}
+
+void EDReleaseInst(EDInstRef inst) {
+ delete inst;
+}
+
+int EDInstByteSize(EDInstRef inst) {
+ return inst->byteSize();
+}
+
+int EDGetInstString(const char **buf,
+ EDInstRef inst) {
+ return inst->getString(*buf);
+}
+
+int EDInstID(unsigned *instID, EDInstRef inst) {
+ *instID = inst->instID();
+ return 0;
+}
+
+int EDInstIsBranch(EDInstRef inst) {
+ return inst->isBranch();
+}
+
+int EDInstIsMove(EDInstRef inst) {
+ return inst->isMove();
+}
+
+int EDBranchTargetID(EDInstRef inst) {
+ return inst->branchTargetID();
+}
+
+int EDMoveSourceID(EDInstRef inst) {
+ return inst->moveSourceID();
+}
+
+int EDMoveTargetID(EDInstRef inst) {
+ return inst->moveTargetID();
+}
+
+int EDNumTokens(EDInstRef inst) {
+ return inst->numTokens();
+}
+
+int EDGetToken(EDTokenRef *token,
+ EDInstRef inst,
+ int index) {
+ return inst->getToken(*token, index);
+}
+
+int EDGetTokenString(const char **buf,
+ EDTokenRef token) {
+ return token->getString(*buf);
+}
+
+int EDOperandIndexForToken(EDTokenRef token) {
+ return token->operandID();
+}
+
+int EDTokenIsWhitespace(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenWhitespace)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsPunctuation(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenPunctuation)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsOpcode(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenOpcode)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsLiteral(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenLiteral)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsRegister(EDTokenRef token) {
+ if(token->type() == EDToken::kTokenRegister)
+ return 1;
+ else
+ return 0;
+}
+
+int EDTokenIsNegativeLiteral(EDTokenRef token) {
+ if(token->type() != EDToken::kTokenLiteral)
+ return -1;
+
+ return token->literalSign();
+}
+
+int EDLiteralTokenAbsoluteValue(uint64_t *value,
+ EDTokenRef token) {
+ if(token->type() != EDToken::kTokenLiteral)
+ return -1;
+
+ return token->literalAbsoluteValue(*value);
+}
+
+int EDRegisterTokenValue(unsigned *registerID,
+ EDTokenRef token) {
+ if(token->type() != EDToken::kTokenRegister)
+ return -1;
+
+ return token->registerID(*registerID);
+}
+
+int EDNumOperands(EDInstRef inst) {
+ return inst->numOperands();
+}
+
+int EDGetOperand(EDOperandRef *operand,
+ EDInstRef inst,
+ int index) {
+ return inst->getOperand(*operand, index);
+}
+
+int EDOperandIsRegister(EDOperandRef operand) {
+ return operand->isRegister();
+}
+
+int EDOperandIsImmediate(EDOperandRef operand) {
+ return operand->isImmediate();
+}
+
+int EDOperandIsMemory(EDOperandRef operand) {
+ return operand->isMemory();
+}
+
+int EDRegisterOperandValue(unsigned *value,
+ EDOperandRef operand) {
+ if(!operand->isRegister())
+ return -1;
+ *value = operand->regVal();
+ return 0;
+}
+
+int EDImmediateOperandValue(uint64_t *value,
+ EDOperandRef operand) {
+ if(!operand->isImmediate())
+ return -1;
+ *value = operand->immediateVal();
+ return 0;
+}
+
+int EDEvaluateOperand(uint64_t *result,
+ EDOperandRef operand,
+ EDRegisterReaderCallback regReader,
+ void *arg) {
+ return operand->evaluate(*result, regReader, arg);
+}
+
+#ifdef __BLOCKS__
+
+struct ByteReaderWrapper {
+ EDByteBlock_t byteBlock;
+};
+
+static int readerWrapperCallback(uint8_t *byte,
+ uint64_t address,
+ void *arg) {
+ struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
+ return wrapper->byteBlock(byte, address);
+}
+
+unsigned int EDBlockCreateInsts(EDInstRef *insts,
+ int count,
+ EDDisassemblerRef disassembler,
+ EDByteBlock_t byteBlock,
+ uint64_t address) {
+ struct ByteReaderWrapper wrapper;
+ wrapper.byteBlock = byteBlock;
+
+ return EDCreateInsts(insts,
+ count,
+ disassembler,
+ readerWrapperCallback,
+ address,
+ (void*)&wrapper);
+}
+
+int EDBlockEvaluateOperand(uint64_t *result,
+ EDOperandRef operand,
+ EDRegisterBlock_t regBlock) {
+ return operand->evaluate(*result, regBlock);
+}
+
+int EDBlockVisitTokens(EDInstRef inst,
+ EDTokenVisitor_t visitor) {
+ return inst->visitTokens(visitor);
+}
+
+#else
+
+extern "C" unsigned int EDBlockCreateInsts() {
+ return 0;
+}
+
+extern "C" int EDBlockEvaluateOperand() {
+ return -1;
+}
+
+extern "C" int EDBlockVisitTokens() {
+ return -1;
+}
+
+#endif
OpenPOWER on IntegriCloud