mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	because of the lack of a newline, AsmToken::Eof was being found instead of AsmToken::EndOfStatement. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114621 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			210 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			210 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===-EDInst.cpp - LLVM Enhanced Disassembler -----------------------------===//
 | |
| //
 | |
| //                     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 Disassembly library's instruction class.
 | |
| // The instruction is responsible for vending the string representation, 
 | |
| // individual tokens, and operands for a single instruction.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "EDInst.h"
 | |
| #include "EDDisassembler.h"
 | |
| #include "EDOperand.h"
 | |
| #include "EDToken.h"
 | |
| 
 | |
| #include "llvm/MC/EDInstInfo.h"
 | |
| #include "llvm/MC/MCInst.h"
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| EDInst::EDInst(llvm::MCInst *inst,
 | |
|                uint64_t byteSize, 
 | |
|                EDDisassembler &disassembler,
 | |
|                const llvm::EDInstInfo *info) :
 | |
|   Disassembler(disassembler),
 | |
|   Inst(inst),
 | |
|   ThisInstInfo(info),
 | |
|   ByteSize(byteSize),
 | |
|   BranchTarget(-1),
 | |
|   MoveSource(-1),
 | |
|   MoveTarget(-1) {
 | |
|   OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()];
 | |
| }
 | |
| 
 | |
| EDInst::~EDInst() {
 | |
|   unsigned int index;
 | |
|   unsigned int numOperands = Operands.size();
 | |
|   
 | |
|   for (index = 0; index < numOperands; ++index)
 | |
|     delete Operands[index];
 | |
|   
 | |
|   unsigned int numTokens = Tokens.size();
 | |
|   
 | |
|   for (index = 0; index < numTokens; ++index)
 | |
|     delete Tokens[index];
 | |
|   
 | |
|   delete Inst;
 | |
| }
 | |
| 
 | |
| uint64_t EDInst::byteSize() {
 | |
|   return ByteSize;
 | |
| }
 | |
| 
 | |
| int EDInst::stringify() {
 | |
|   if (StringifyResult.valid())
 | |
|     return StringifyResult.result();
 | |
|   
 | |
|   if (Disassembler.printInst(String, *Inst))
 | |
|     return StringifyResult.setResult(-1);
 | |
| 
 | |
|   String.push_back('\n');
 | |
|   
 | |
|   return StringifyResult.setResult(0);
 | |
| }
 | |
| 
 | |
| int EDInst::getString(const char*& str) {
 | |
|   if (stringify())
 | |
|     return -1;
 | |
|   
 | |
|   str = String.c_str();
 | |
|   
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| unsigned EDInst::instID() {
 | |
|   return Inst->getOpcode();
 | |
| }
 | |
| 
 | |
| bool EDInst::isBranch() {
 | |
|   if (ThisInstInfo)
 | |
|     return 
 | |
|       ThisInstInfo->instructionType == kInstructionTypeBranch ||
 | |
|       ThisInstInfo->instructionType == kInstructionTypeCall;
 | |
|   else
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| bool EDInst::isMove() {
 | |
|   if (ThisInstInfo)
 | |
|     return ThisInstInfo->instructionType == kInstructionTypeMove;
 | |
|   else
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| int EDInst::parseOperands() {
 | |
|   if (ParseResult.valid())
 | |
|     return ParseResult.result();
 | |
|   
 | |
|   if (!ThisInstInfo)
 | |
|     return ParseResult.setResult(-1);
 | |
|   
 | |
|   unsigned int opIndex;
 | |
|   unsigned int mcOpIndex = 0;
 | |
|   
 | |
|   for (opIndex = 0; opIndex < ThisInstInfo->numOperands; ++opIndex) {
 | |
|     if (isBranch() &&
 | |
|         (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)) {
 | |
|       BranchTarget = opIndex;
 | |
|     }
 | |
|     else if (isMove()) {
 | |
|       if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagSource)
 | |
|         MoveSource = opIndex;
 | |
|       else if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)
 | |
|         MoveTarget = opIndex;
 | |
|     }
 | |
|     
 | |
|     EDOperand *operand = new EDOperand(Disassembler, *this, opIndex, mcOpIndex);
 | |
|     
 | |
|     Operands.push_back(operand);
 | |
|   }
 | |
|   
 | |
|   return ParseResult.setResult(0);
 | |
| }
 | |
| 
 | |
| int EDInst::branchTargetID() {
 | |
|   if (parseOperands())
 | |
|     return -1;
 | |
|   return BranchTarget;
 | |
| }
 | |
| 
 | |
| int EDInst::moveSourceID() {
 | |
|   if (parseOperands())
 | |
|     return -1;
 | |
|   return MoveSource;
 | |
| }
 | |
| 
 | |
| int EDInst::moveTargetID() {
 | |
|   if (parseOperands())
 | |
|     return -1;
 | |
|   return MoveTarget;
 | |
| }
 | |
| 
 | |
| int EDInst::numOperands() {
 | |
|   if (parseOperands())
 | |
|     return -1;
 | |
|   return Operands.size();
 | |
| }
 | |
| 
 | |
| int EDInst::getOperand(EDOperand *&operand, unsigned int index) {
 | |
|   if (parseOperands())
 | |
|     return -1;
 | |
|   
 | |
|   if (index >= Operands.size())
 | |
|     return -1;
 | |
|   
 | |
|   operand = Operands[index];
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int EDInst::tokenize() {
 | |
|   if (TokenizeResult.valid())
 | |
|     return TokenizeResult.result();
 | |
|   
 | |
|   if (stringify())
 | |
|     return TokenizeResult.setResult(-1);
 | |
|     
 | |
|   return TokenizeResult.setResult(EDToken::tokenize(Tokens,
 | |
|                                                     String,
 | |
|                                                     OperandOrder,
 | |
|                                                     Disassembler));
 | |
|     
 | |
| }
 | |
| 
 | |
| int EDInst::numTokens() {
 | |
|   if (tokenize())
 | |
|     return -1;
 | |
|   return Tokens.size();
 | |
| }
 | |
| 
 | |
| int EDInst::getToken(EDToken *&token, unsigned int index) {
 | |
|   if (tokenize())
 | |
|     return -1;
 | |
|   token = Tokens[index];
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| #ifdef __BLOCKS__
 | |
| int EDInst::visitTokens(EDTokenVisitor_t visitor) {
 | |
|   if (tokenize())
 | |
|     return -1;
 | |
|   
 | |
|   tokvec_t::iterator iter;
 | |
|   
 | |
|   for (iter = Tokens.begin(); iter != Tokens.end(); ++iter) {
 | |
|     int ret = visitor(*iter);
 | |
|     if (ret == 1)
 | |
|       return 0;
 | |
|     if (ret != 0)
 | |
|       return -1;
 | |
|   }
 | |
|   
 | |
|   return 0;
 | |
| }
 | |
| #endif
 |