146 lines
4.3 KiB
C
146 lines
4.3 KiB
C
//===-- XCoreInstPrinter.cpp - Convert XCore MCInst to assembly syntax --------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This class prints an XCore MCInst to a .s file.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/* Capstone Disassembly Engine */
|
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
|
|
|
|
#ifdef CAPSTONE_HAS_XCORE
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "XCoreInstPrinter.h"
|
|
#include "../../MCInst.h"
|
|
#include "../../utils.h"
|
|
#include "../../SStream.h"
|
|
#include "../../MCRegisterInfo.h"
|
|
#include "../../MathExtras.h"
|
|
#include "XCoreMapping.h"
|
|
|
|
static const char *getRegisterName(unsigned RegNo);
|
|
|
|
void XCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
|
|
{
|
|
/*
|
|
if (((cs_struct *)ud)->detail != CS_OPT_ON)
|
|
return;
|
|
*/
|
|
}
|
|
|
|
static void set_mem_access(MCInst *MI, bool status, int reg)
|
|
{
|
|
if (MI->csh->detail != CS_OPT_ON)
|
|
return;
|
|
|
|
MI->csh->doing_mem = status;
|
|
if (status) {
|
|
if (reg != 0xffff && reg != -0xffff) {
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_MEM;
|
|
if (reg) {
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base = reg;
|
|
} else {
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base = XCORE_REG_INVALID;
|
|
}
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = XCORE_REG_INVALID;
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = 0;
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.sign = 1;
|
|
} else {
|
|
// the last op should be the memory base
|
|
MI->flat_insn.xcore.op_count--;
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_MEM;
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base = MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].reg;
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = XCORE_REG_INVALID;
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = 0;
|
|
if (reg > 0)
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.sign = 1;
|
|
else
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.sign = -1;
|
|
}
|
|
} else {
|
|
// done, create the next operand slot
|
|
MI->flat_insn.xcore.op_count++;
|
|
}
|
|
}
|
|
|
|
static void _printOperand(MCInst *MI, MCOperand *MO, SStream *O)
|
|
{
|
|
if (MCOperand_isReg(MO)) {
|
|
unsigned reg;
|
|
|
|
reg = MCOperand_getReg(MO);
|
|
SStream_concat(O, "%s", getRegisterName(reg));
|
|
|
|
if (MI->csh->detail) {
|
|
if (MI->csh->doing_mem) {
|
|
if (MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base == ARM_REG_INVALID)
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.base = reg;
|
|
else
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.index = reg;
|
|
} else {
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_REG;
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].reg = reg;
|
|
MI->flat_insn.xcore.op_count++;
|
|
}
|
|
}
|
|
} else if (MCOperand_isImm(MO)) {
|
|
int32_t Imm = (int32_t)MCOperand_getImm(MO);
|
|
|
|
if (Imm >= 0) {
|
|
if (Imm > HEX_THRESHOLD)
|
|
SStream_concat(O, "0x%x", Imm);
|
|
else
|
|
SStream_concat(O, "%u", Imm);
|
|
} else {
|
|
if (Imm < -HEX_THRESHOLD)
|
|
SStream_concat(O, "-0x%x", -Imm);
|
|
else
|
|
SStream_concat(O, "-%u", -Imm);
|
|
}
|
|
|
|
if (MI->csh->detail) {
|
|
if (MI->csh->doing_mem) {
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].mem.disp = Imm;
|
|
} else {
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].type = XCORE_OP_IMM;
|
|
MI->flat_insn.xcore.operands[MI->flat_insn.xcore.op_count].imm = Imm;
|
|
MI->flat_insn.xcore.op_count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void printOperand(MCInst *MI, int OpNum, SStream *O)
|
|
{
|
|
_printOperand(MI, MCInst_getOperand(MI, OpNum), O);
|
|
}
|
|
|
|
static void printInlineJT(MCInst *MI, int OpNum, SStream *O)
|
|
{
|
|
}
|
|
|
|
static void printInlineJT32(MCInst *MI, int OpNum, SStream *O)
|
|
{
|
|
}
|
|
|
|
#define PRINT_ALIAS_INSTR
|
|
#include "XCoreGenAsmWriter.inc"
|
|
|
|
void XCore_printInst(MCInst *MI, SStream *O, void *Info)
|
|
{
|
|
printInstruction(MI, O, Info);
|
|
}
|
|
|
|
#endif
|