//===-- 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.
//
//===----------------------------------------------------------------------===//

// FIXME: This code isn't layered right, the headers should be moved to
// include llvm/MC/MCDisassembler or something.
#include "../../lib/MC/MCDisassembler/EDDisassembler.h"
#include "../../lib/MC/MCDisassembler/EDInst.h"
#include "../../lib/MC/MCDisassembler/EDOperand.h"
#include "../../lib/MC/MCDisassembler/EDToken.h"
#include "llvm-c/EnhancedDisassembly.h"
using namespace llvm;

int EDGetDisassembler(EDDisassemblerRef *disassembler,
                      const char *triple,
                      EDAssemblySyntax_t syntax) {
  EDDisassembler::initialize();
  
  EDDisassembler::AssemblySyntax Syntax;
  switch (syntax) {
  default: assert(0 && "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
