mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160445 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			277 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===-- 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"
 | |
| using namespace llvm;
 | |
| 
 | |
| int EDGetDisassembler(EDDisassemblerRef *disassembler,
 | |
|                       const char *triple,
 | |
|                       EDAssemblySyntax_t syntax) {
 | |
|   EDDisassembler::AssemblySyntax Syntax;
 | |
|   switch (syntax) {
 | |
|   default: llvm_unreachable("Unknown assembly syntax!");
 | |
|   case kEDAssemblySyntaxX86Intel:
 | |
|     Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel;
 | |
|     break;
 | |
|   case kEDAssemblySyntaxX86ATT:
 | |
|     Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT;
 | |
|     break;
 | |
|   case kEDAssemblySyntaxARMUAL:
 | |
|     Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL;
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax);
 | |
| 
 | |
|   if (!ret)
 | |
|     return -1;
 | |
|   *disassembler = ret;
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int EDGetRegisterName(const char** regName,
 | |
|                       EDDisassemblerRef disassembler,
 | |
|                       unsigned regID) {
 | |
|   const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID);
 | |
|   if (!name)
 | |
|     return -1;
 | |
|   *regName = name;
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
 | |
|                              unsigned regID) {
 | |
|   return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0;
 | |
| }
 | |
| 
 | |
| int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
 | |
|                                unsigned regID) {
 | |
|   return ((EDDisassembler*)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 = ((EDDisassembler*)disassembler)->createInst(byteReader,
 | |
|                                                                address, arg);
 | |
| 
 | |
|     if (!inst)
 | |
|       return index;
 | |
| 
 | |
|     insts[index] = inst;
 | |
|     address += inst->byteSize();
 | |
|   }
 | |
| 
 | |
|   return count;
 | |
| }
 | |
| 
 | |
| void EDReleaseInst(EDInstRef inst) {
 | |
|   delete ((EDInst*)inst);
 | |
| }
 | |
| 
 | |
| int EDInstByteSize(EDInstRef inst) {
 | |
|   return ((EDInst*)inst)->byteSize();
 | |
| }
 | |
| 
 | |
| int EDGetInstString(const char **buf,
 | |
|                     EDInstRef inst) {
 | |
|   return ((EDInst*)inst)->getString(*buf);
 | |
| }
 | |
| 
 | |
| int EDInstID(unsigned *instID, EDInstRef inst) {
 | |
|   *instID = ((EDInst*)inst)->instID();
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int EDInstIsBranch(EDInstRef inst) {
 | |
|   return ((EDInst*)inst)->isBranch();
 | |
| }
 | |
| 
 | |
| int EDInstIsMove(EDInstRef inst) {
 | |
|   return ((EDInst*)inst)->isMove();
 | |
| }
 | |
| 
 | |
| int EDBranchTargetID(EDInstRef inst) {
 | |
|   return ((EDInst*)inst)->branchTargetID();
 | |
| }
 | |
| 
 | |
| int EDMoveSourceID(EDInstRef inst) {
 | |
|   return ((EDInst*)inst)->moveSourceID();
 | |
| }
 | |
| 
 | |
| int EDMoveTargetID(EDInstRef inst) {
 | |
|   return ((EDInst*)inst)->moveTargetID();
 | |
| }
 | |
| 
 | |
| int EDNumTokens(EDInstRef inst) {
 | |
|   return ((EDInst*)inst)->numTokens();
 | |
| }
 | |
| 
 | |
| int EDGetToken(EDTokenRef *token,
 | |
|                EDInstRef inst,
 | |
|                int index) {
 | |
|   return ((EDInst*)inst)->getToken(*(EDToken**)token, index);
 | |
| }
 | |
| 
 | |
| int EDGetTokenString(const char **buf,
 | |
|                      EDTokenRef token) {
 | |
|   return ((EDToken*)token)->getString(*buf);
 | |
| }
 | |
| 
 | |
| int EDOperandIndexForToken(EDTokenRef token) {
 | |
|   return ((EDToken*)token)->operandID();
 | |
| }
 | |
| 
 | |
| int EDTokenIsWhitespace(EDTokenRef token) {
 | |
|   return ((EDToken*)token)->type() == EDToken::kTokenWhitespace;
 | |
| }
 | |
| 
 | |
| int EDTokenIsPunctuation(EDTokenRef token) {
 | |
|   return ((EDToken*)token)->type() == EDToken::kTokenPunctuation;
 | |
| }
 | |
| 
 | |
| int EDTokenIsOpcode(EDTokenRef token) {
 | |
|   return ((EDToken*)token)->type() == EDToken::kTokenOpcode;
 | |
| }
 | |
| 
 | |
| int EDTokenIsLiteral(EDTokenRef token) {
 | |
|   return ((EDToken*)token)->type() == EDToken::kTokenLiteral;
 | |
| }
 | |
| 
 | |
| int EDTokenIsRegister(EDTokenRef token) {
 | |
|   return ((EDToken*)token)->type() == EDToken::kTokenRegister;
 | |
| }
 | |
| 
 | |
| int EDTokenIsNegativeLiteral(EDTokenRef token) {
 | |
|   if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
 | |
|     return -1;
 | |
| 
 | |
|   return ((EDToken*)token)->literalSign();
 | |
| }
 | |
| 
 | |
| int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
 | |
|   if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
 | |
|     return -1;
 | |
| 
 | |
|   return ((EDToken*)token)->literalAbsoluteValue(*value);
 | |
| }
 | |
| 
 | |
| int EDRegisterTokenValue(unsigned *registerID,
 | |
|                          EDTokenRef token) {
 | |
|   if (((EDToken*)token)->type() != EDToken::kTokenRegister)
 | |
|     return -1;
 | |
| 
 | |
|   return ((EDToken*)token)->registerID(*registerID);
 | |
| }
 | |
| 
 | |
| int EDNumOperands(EDInstRef inst) {
 | |
|   return ((EDInst*)inst)->numOperands();
 | |
| }
 | |
| 
 | |
| int EDGetOperand(EDOperandRef *operand,
 | |
|                  EDInstRef inst,
 | |
|                  int index) {
 | |
|   return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index);
 | |
| }
 | |
| 
 | |
| int EDOperandIsRegister(EDOperandRef operand) {
 | |
|   return ((EDOperand*)operand)->isRegister();
 | |
| }
 | |
| 
 | |
| int EDOperandIsImmediate(EDOperandRef operand) {
 | |
|   return ((EDOperand*)operand)->isImmediate();
 | |
| }
 | |
| 
 | |
| int EDOperandIsMemory(EDOperandRef operand) {
 | |
|   return ((EDOperand*)operand)->isMemory();
 | |
| }
 | |
| 
 | |
| int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) {
 | |
|   if (!((EDOperand*)operand)->isRegister())
 | |
|     return -1;
 | |
|   *value = ((EDOperand*)operand)->regVal();
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) {
 | |
|   if (!((EDOperand*)operand)->isImmediate())
 | |
|     return -1;
 | |
|   *value = ((EDOperand*)operand)->immediateVal();
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int EDEvaluateOperand(uint64_t *result, EDOperandRef operand,
 | |
|                       ::EDRegisterReaderCallback regReader, void *arg) {
 | |
|   return ((EDOperand*)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 ((EDOperand*)operand)->evaluate(*result, regBlock);
 | |
| }
 | |
| 
 | |
| int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) {
 | |
|   return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor);
 | |
| }
 | |
| 
 | |
| #else
 | |
| 
 | |
| extern "C" unsigned int EDBlockCreateInsts() {
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| extern "C" int EDBlockEvaluateOperand() {
 | |
|   return -1;
 | |
| }
 | |
| 
 | |
| extern "C" int EDBlockVisitTokens() {
 | |
|   return -1;
 | |
| }
 | |
| 
 | |
| #endif
 |