mirror of
https://github.com/capstone-engine/capstone.git
synced 2025-02-12 09:58:42 +00:00
Add operands access support for TriCore
This commit is contained in:
parent
6fc9643161
commit
10a24a9a38
@ -548,6 +548,7 @@ if (CAPSTONE_TRICORE_SUPPORT)
|
|||||||
)
|
)
|
||||||
set(HEADERS_TRICORE
|
set(HEADERS_TRICORE
|
||||||
arch/TriCore/TriCoreDisassembler.h
|
arch/TriCore/TriCoreDisassembler.h
|
||||||
|
arch/TriCore/TriCoreLinkage.h
|
||||||
arch/TriCore/TriCoreGenAsmWriter.inc
|
arch/TriCore/TriCoreGenAsmWriter.inc
|
||||||
arch/TriCore/TriCoreGenDisassemblerTables.inc
|
arch/TriCore/TriCoreGenDisassemblerTables.inc
|
||||||
arch/TriCore/TriCoreGenInstrInfo.inc
|
arch/TriCore/TriCoreGenInstrInfo.inc
|
||||||
|
3
Makefile
3
Makefile
@ -326,11 +326,10 @@ endif
|
|||||||
|
|
||||||
|
|
||||||
LIBOBJ =
|
LIBOBJ =
|
||||||
LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o
|
LIBOBJ += $(OBJDIR)/cs.o $(OBJDIR)/utils.o $(OBJDIR)/SStream.o $(OBJDIR)/MCInstrDesc.o $(OBJDIR)/MCRegisterInfo.o $(OBJDIR)/MCInst.o $(OBJDIR)/Mapping.o
|
||||||
LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_M68K) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_RISCV) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) $(LIBOBJ_SH)
|
LIBOBJ += $(LIBOBJ_ARM) $(LIBOBJ_ARM64) $(LIBOBJ_M68K) $(LIBOBJ_MIPS) $(LIBOBJ_PPC) $(LIBOBJ_RISCV) $(LIBOBJ_SPARC) $(LIBOBJ_SYSZ) $(LIBOBJ_SH)
|
||||||
LIBOBJ += $(LIBOBJ_X86) $(LIBOBJ_XCORE) $(LIBOBJ_TMS320C64X) $(LIBOBJ_M680X) $(LIBOBJ_EVM) $(LIBOBJ_MOS65XX) $(LIBOBJ_WASM) $(LIBOBJ_BPF)
|
LIBOBJ += $(LIBOBJ_X86) $(LIBOBJ_XCORE) $(LIBOBJ_TMS320C64X) $(LIBOBJ_M680X) $(LIBOBJ_EVM) $(LIBOBJ_MOS65XX) $(LIBOBJ_WASM) $(LIBOBJ_BPF)
|
||||||
LIBOBJ += $(LIBOBJ_TRICORE)
|
LIBOBJ += $(LIBOBJ_TRICORE)
|
||||||
LIBOBJ += $(OBJDIR)/MCInst.o
|
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(PKG_EXTRA),)
|
ifeq ($(PKG_EXTRA),)
|
||||||
|
@ -251,3 +251,4 @@ const cs_ac_type mapping_get_op_access(MCInst *MI, unsigned OpNum,
|
|||||||
|
|
||||||
DEFINE_get_detail_op(arm, ARM);
|
DEFINE_get_detail_op(arm, ARM);
|
||||||
DEFINE_get_detail_op(ppc, PPC);
|
DEFINE_get_detail_op(ppc, PPC);
|
||||||
|
DEFINE_get_detail_op(tricore, TriCore);
|
||||||
|
14
Mapping.h
14
Mapping.h
@ -21,9 +21,9 @@ typedef struct insn_map {
|
|||||||
unsigned short mapid; // The Capstone instruction id
|
unsigned short mapid; // The Capstone instruction id
|
||||||
#ifndef CAPSTONE_DIET
|
#ifndef CAPSTONE_DIET
|
||||||
uint16_t regs_use[MAX_IMPL_R_REGS]; ///< list of implicit registers used by
|
uint16_t regs_use[MAX_IMPL_R_REGS]; ///< list of implicit registers used by
|
||||||
///< this instruction
|
///< this instruction
|
||||||
uint16_t regs_mod[MAX_IMPL_W_REGS]; ///< list of implicit registers modified
|
uint16_t regs_mod[MAX_IMPL_W_REGS]; ///< list of implicit registers modified
|
||||||
///< by this instruction
|
///< by this instruction
|
||||||
unsigned char groups
|
unsigned char groups
|
||||||
[MAX_NUM_GROUPS]; ///< list of group this instruction belong to
|
[MAX_NUM_GROUPS]; ///< list of group this instruction belong to
|
||||||
bool branch; // branch instruction?
|
bool branch; // branch instruction?
|
||||||
@ -47,7 +47,7 @@ typedef struct {
|
|||||||
uint8_t /* cs_ac_type */ access; ///< The access type (read, write)
|
uint8_t /* cs_ac_type */ access; ///< The access type (read, write)
|
||||||
uint8_t /* cs_data_type */
|
uint8_t /* cs_data_type */
|
||||||
dtypes[MAX_NO_DATA_TYPES]; ///< List of op types. Terminated by
|
dtypes[MAX_NO_DATA_TYPES]; ///< List of op types. Terminated by
|
||||||
///< CS_DATA_TYPE_LAST
|
///< CS_DATA_TYPE_LAST
|
||||||
} mapping_op;
|
} mapping_op;
|
||||||
|
|
||||||
#define MAX_NO_INSN_MAP_OPS 16
|
#define MAX_NO_INSN_MAP_OPS 16
|
||||||
@ -72,14 +72,14 @@ const cs_ac_type mapping_get_op_access(MCInst *MI, unsigned OpNum,
|
|||||||
/// Assumes the istruction operands map is called "insn_operands"
|
/// Assumes the istruction operands map is called "insn_operands"
|
||||||
/// Only usable by `auto-sync` archs!
|
/// Only usable by `auto-sync` archs!
|
||||||
#define map_get_op_type(MI, OpNum) \
|
#define map_get_op_type(MI, OpNum) \
|
||||||
mapping_get_op_type(MI, OpNum, insn_operands, \
|
mapping_get_op_type(MI, OpNum, (const map_insn_ops *)insn_operands, \
|
||||||
sizeof(insn_operands) / sizeof(insn_operands[0]))
|
sizeof(insn_operands) / sizeof(insn_operands[0]))
|
||||||
|
|
||||||
/// Macro for easier access of operand access flags from the map.
|
/// Macro for easier access of operand access flags from the map.
|
||||||
/// Assumes the istruction operands map is called "insn_operands"
|
/// Assumes the istruction operands map is called "insn_operands"
|
||||||
/// Only usable by `auto-sync` archs!
|
/// Only usable by `auto-sync` archs!
|
||||||
#define map_get_op_access(MI, OpNum) \
|
#define map_get_op_access(MI, OpNum) \
|
||||||
mapping_get_op_access(MI, OpNum, insn_operands, \
|
mapping_get_op_access(MI, OpNum, (const map_insn_ops *)insn_operands, \
|
||||||
sizeof(insn_operands) / \
|
sizeof(insn_operands) / \
|
||||||
sizeof(insn_operands[0]))
|
sizeof(insn_operands[0]))
|
||||||
|
|
||||||
@ -112,6 +112,7 @@ void map_cs_id(MCInst *MI, const insn_map *imap, unsigned int imap_size);
|
|||||||
|
|
||||||
DECL_get_detail_op(arm, ARM);
|
DECL_get_detail_op(arm, ARM);
|
||||||
DECL_get_detail_op(ppc, PPC);
|
DECL_get_detail_op(ppc, PPC);
|
||||||
|
DECL_get_detail_op(tricore, TriCore);
|
||||||
|
|
||||||
/// Increments the detail->arch.op_count by one.
|
/// Increments the detail->arch.op_count by one.
|
||||||
#define DEFINE_inc_detail_op_count(arch, ARCH) \
|
#define DEFINE_inc_detail_op_count(arch, ARCH) \
|
||||||
@ -131,6 +132,8 @@ DEFINE_inc_detail_op_count(arm, ARM);
|
|||||||
DEFINE_dec_detail_op_count(arm, ARM);
|
DEFINE_dec_detail_op_count(arm, ARM);
|
||||||
DEFINE_inc_detail_op_count(ppc, PPC);
|
DEFINE_inc_detail_op_count(ppc, PPC);
|
||||||
DEFINE_dec_detail_op_count(ppc, PPC);
|
DEFINE_dec_detail_op_count(ppc, PPC);
|
||||||
|
DEFINE_inc_detail_op_count(tricore, TriCore);
|
||||||
|
DEFINE_dec_detail_op_count(tricore, TriCore);
|
||||||
|
|
||||||
/// Returns true if a memory operand is currently edited.
|
/// Returns true if a memory operand is currently edited.
|
||||||
static inline bool doing_mem(const MCInst *MI)
|
static inline bool doing_mem(const MCInst *MI)
|
||||||
@ -154,6 +157,7 @@ static inline void set_doing_mem(const MCInst *MI, bool status)
|
|||||||
|
|
||||||
DEFINE_get_arch_detail(arm, ARM);
|
DEFINE_get_arch_detail(arm, ARM);
|
||||||
DEFINE_get_arch_detail(ppc, PPC);
|
DEFINE_get_arch_detail(ppc, PPC);
|
||||||
|
DEFINE_get_arch_detail(tricore, TriCore);
|
||||||
|
|
||||||
static inline bool detail_is_set(const MCInst *MI)
|
static inline bool detail_is_set(const MCInst *MI)
|
||||||
{
|
{
|
||||||
|
@ -27,31 +27,8 @@
|
|||||||
#include "../../MathExtras.h"
|
#include "../../MathExtras.h"
|
||||||
|
|
||||||
#include "TriCoreDisassembler.h"
|
#include "TriCoreDisassembler.h"
|
||||||
|
#include "TriCoreMapping.h"
|
||||||
static bool readInstruction16(const uint8_t *code, size_t code_len,
|
#include "TriCoreLinkage.h"
|
||||||
uint16_t *insn)
|
|
||||||
{
|
|
||||||
if (code_len < 2)
|
|
||||||
// insufficient data
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Encoded as a little-endian 16-bit word in the stream.
|
|
||||||
*insn = (code[0] << 0) | (code[1] << 8);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool readInstruction32(const uint8_t *code, size_t code_len,
|
|
||||||
uint32_t *insn)
|
|
||||||
{
|
|
||||||
if (code_len < 4)
|
|
||||||
// insufficient data
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Encoded as a little-endian 32-bit word in the stream.
|
|
||||||
*insn = (code[0] << 0) | (code[1] << 8) | (code[2] << 16) |
|
|
||||||
(code[3] << 24);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned getReg(MCRegisterInfo *MRI, unsigned RC, unsigned RegNo)
|
static unsigned getReg(MCRegisterInfo *MRI, unsigned RC, unsigned RegNo)
|
||||||
{
|
{
|
||||||
@ -1485,14 +1462,12 @@ static inline bool tryGetInstruction16(const uint8_t *code, size_t code_len,
|
|||||||
uint64_t address, void *info,
|
uint64_t address, void *info,
|
||||||
const uint8_t *decoderTable16)
|
const uint8_t *decoderTable16)
|
||||||
{
|
{
|
||||||
uint16_t insn16;
|
if (code_len < 2) {
|
||||||
DecodeStatus Result;
|
|
||||||
if (!readInstruction16(code, code_len, &insn16)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Calling the auto-generated decoder function.
|
uint16_t insn16 = readBytes16(MI, code);
|
||||||
Result = decodeInstruction_2(decoderTable16, MI, insn16, address, info,
|
DecodeStatus Result = decodeInstruction_2(decoderTable16, MI, insn16,
|
||||||
0);
|
address, info, 0);
|
||||||
if (Result != MCDisassembler_Fail) {
|
if (Result != MCDisassembler_Fail) {
|
||||||
*size = 2;
|
*size = 2;
|
||||||
return true;
|
return true;
|
||||||
@ -1505,14 +1480,12 @@ static inline bool tryGetInstruction32(const uint8_t *code, size_t code_len,
|
|||||||
uint64_t address, void *info,
|
uint64_t address, void *info,
|
||||||
const uint8_t *decoderTable32)
|
const uint8_t *decoderTable32)
|
||||||
{
|
{
|
||||||
uint32_t insn32;
|
if (code_len < 4) {
|
||||||
DecodeStatus Result;
|
|
||||||
if (!readInstruction32(code, code_len, &insn32)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Calling the auto-generated decoder function.
|
uint32_t insn32 = readBytes32(MI, code);
|
||||||
Result = decodeInstruction_4(decoderTable32, MI, insn32, address, info,
|
DecodeStatus Result = decodeInstruction_4(decoderTable32, MI, insn32,
|
||||||
0);
|
address, info, 0);
|
||||||
if (Result != MCDisassembler_Fail) {
|
if (Result != MCDisassembler_Fail) {
|
||||||
*size = 4;
|
*size = 4;
|
||||||
return true;
|
return true;
|
||||||
@ -1520,9 +1493,9 @@ static inline bool tryGetInstruction32(const uint8_t *code, size_t code_len,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TriCore_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
static bool getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||||
MCInst *MI, uint16_t *size, uint64_t address,
|
MCInst *MI, uint16_t *size, uint64_t address,
|
||||||
void *info)
|
void *info)
|
||||||
{
|
{
|
||||||
if (!ud) {
|
if (!ud) {
|
||||||
return false;
|
return false;
|
||||||
@ -1569,7 +1542,19 @@ bool TriCore_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|||||||
DecoderTable32);
|
DecoderTable32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriCore_init(MCRegisterInfo *MRI)
|
bool TriCore_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
||||||
|
size_t ByteLen, MCInst *MI, uint16_t *Size,
|
||||||
|
uint64_t Address, void *Info)
|
||||||
|
{
|
||||||
|
bool Result =
|
||||||
|
getInstruction(handle, Bytes, ByteLen, MI, Size, Address, Info);
|
||||||
|
if (Result) {
|
||||||
|
TriCore_set_instr_map_data(MI);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TriCore_init_mri(MCRegisterInfo *MRI)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
InitMCRegisterInfo(TriCoreRegDesc, 45, RA, PC,
|
InitMCRegisterInfo(TriCoreRegDesc, 45, RA, PC,
|
||||||
|
@ -12,12 +12,7 @@
|
|||||||
#include "../../MCRegisterInfo.h"
|
#include "../../MCRegisterInfo.h"
|
||||||
#include "../../MCInst.h"
|
#include "../../MCInst.h"
|
||||||
|
|
||||||
void TriCore_init(MCRegisterInfo *MRI);
|
void TriCore_init_mri(MCRegisterInfo *MRI);
|
||||||
|
|
||||||
bool TriCore_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|
||||||
MCInst *instr, uint16_t *size, uint64_t address,
|
|
||||||
void *info);
|
|
||||||
|
|
||||||
bool TriCore_getFeatureBits(unsigned int mode, unsigned int feature);
|
bool TriCore_getFeatureBits(unsigned int mode, unsigned int feature);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
#include "../../MathExtras.h"
|
#include "../../MathExtras.h"
|
||||||
#include "../../SStream.h"
|
#include "../../SStream.h"
|
||||||
#include "../../utils.h"
|
#include "../../utils.h"
|
||||||
#include "TriCoreInstPrinter.h"
|
|
||||||
#include "TriCoreMapping.h"
|
#include "TriCoreMapping.h"
|
||||||
|
#include "TriCoreLinkage.h"
|
||||||
|
|
||||||
static const char *getRegisterName(unsigned RegNo);
|
static const char *getRegisterName(unsigned RegNo);
|
||||||
|
|
||||||
@ -35,14 +35,6 @@ static void printInstruction(MCInst *, uint64_t, SStream *);
|
|||||||
|
|
||||||
static void printOperand(MCInst *MI, int OpNum, SStream *O);
|
static void printOperand(MCInst *MI, int OpNum, SStream *O);
|
||||||
|
|
||||||
void TriCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (((cs_struct *)ud)->detail != CS_OPT_ON)
|
|
||||||
return;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GET_INSTRINFO_ENUM
|
#define GET_INSTRINFO_ENUM
|
||||||
|
|
||||||
#include "TriCoreGenInstrInfo.inc"
|
#include "TriCoreGenInstrInfo.inc"
|
||||||
@ -51,39 +43,47 @@ void TriCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
|
|||||||
|
|
||||||
#include "TriCoreGenRegisterInfo.inc"
|
#include "TriCoreGenRegisterInfo.inc"
|
||||||
|
|
||||||
static inline void fill_mem(cs_tricore *tc, uint8_t base, int32_t disp);
|
static bool fill_mem(MCInst *MI, unsigned int reg, int32_t disp);
|
||||||
|
|
||||||
static bool fixup_op_mem(MCInst *pInst, unsigned int reg, int32_t disp);
|
static inline void set_mem(cs_tricore_op *op, uint8_t base, int32_t disp)
|
||||||
|
|
||||||
static inline void fill_tricore_register(MCInst *MI, uint32_t reg)
|
|
||||||
{
|
{
|
||||||
if (!(MI->csh->detail == CS_OPT_ON && MI->flat_insn->detail))
|
op->type |= TRICORE_OP_MEM;
|
||||||
return;
|
op->mem.base = base;
|
||||||
cs_tricore *tricore = &MI->flat_insn->detail->tricore;
|
op->mem.disp = disp;
|
||||||
tricore->operands[tricore->op_count].type = TRICORE_OP_REG;
|
|
||||||
tricore->operands[tricore->op_count].reg = reg;
|
|
||||||
tricore->op_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void fill_tricore_imm(MCInst *MI, int32_t imm)
|
static inline void fill_reg(MCInst *MI, uint32_t reg)
|
||||||
{
|
{
|
||||||
if (!(MI->csh->detail == CS_OPT_ON && MI->flat_insn->detail))
|
if (!detail_is_set(MI))
|
||||||
return;
|
return;
|
||||||
cs_tricore *tricore = &MI->flat_insn->detail->tricore;
|
cs_tricore_op *op = TriCore_get_detail_op(MI, 0);
|
||||||
if (tricore->op_count >= 1 &&
|
op->type = TRICORE_OP_REG;
|
||||||
tricore->operands[tricore->op_count - 1].type == TRICORE_OP_REG &&
|
op->reg = reg;
|
||||||
fixup_op_mem(MI, tricore->operands[tricore->op_count - 1].reg,
|
TriCore_inc_op_count(MI);
|
||||||
imm)) {
|
}
|
||||||
|
|
||||||
|
static inline void fill_imm(MCInst *MI, int32_t imm)
|
||||||
|
{
|
||||||
|
if (!detail_is_set(MI))
|
||||||
return;
|
return;
|
||||||
|
cs_tricore *tricore = TriCore_get_detail(MI);
|
||||||
|
if (tricore->op_count >= 1) {
|
||||||
|
cs_tricore_op *op = TriCore_get_detail_op(MI, -1);
|
||||||
|
if (op->type == TRICORE_OP_REG && fill_mem(MI, op->reg, imm))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
tricore->operands[tricore->op_count].type = TRICORE_OP_IMM;
|
|
||||||
tricore->operands[tricore->op_count].imm = imm;
|
cs_tricore_op *op = TriCore_get_detail_op(MI, 0);
|
||||||
|
op->type = TRICORE_OP_IMM;
|
||||||
|
op->imm = imm;
|
||||||
tricore->op_count++;
|
tricore->op_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool fixup_op_mem(MCInst *pInst, unsigned int reg, int32_t disp)
|
static bool fill_mem(MCInst *MI, unsigned int reg, int32_t disp)
|
||||||
{
|
{
|
||||||
switch (TriCore_map_insn_id(pInst->csh, pInst->Opcode)) {
|
if (!detail_is_set(MI))
|
||||||
|
return false;
|
||||||
|
switch (MI->flat_insn->id) {
|
||||||
case TRICORE_INS_LDMST:
|
case TRICORE_INS_LDMST:
|
||||||
case TRICORE_INS_LDLCX:
|
case TRICORE_INS_LDLCX:
|
||||||
case TRICORE_INS_LD_A:
|
case TRICORE_INS_LD_A:
|
||||||
@ -116,7 +116,7 @@ static bool fixup_op_mem(MCInst *pInst, unsigned int reg, int32_t disp)
|
|||||||
case TRICORE_INS_SWAPMSK_W:
|
case TRICORE_INS_SWAPMSK_W:
|
||||||
case TRICORE_INS_LEA:
|
case TRICORE_INS_LEA:
|
||||||
case TRICORE_INS_LHA: {
|
case TRICORE_INS_LHA: {
|
||||||
switch (MCInst_getOpcode(pInst)) {
|
switch (MCInst_getOpcode(MI)) {
|
||||||
case TRICORE_LDMST_abs:
|
case TRICORE_LDMST_abs:
|
||||||
case TRICORE_LDLCX_abs:
|
case TRICORE_LDLCX_abs:
|
||||||
case TRICORE_LD_A_abs:
|
case TRICORE_LD_A_abs:
|
||||||
@ -144,50 +144,29 @@ static bool fixup_op_mem(MCInst *pInst, unsigned int reg, int32_t disp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cs_tricore *tc = &pInst->flat_insn->detail->tricore;
|
cs_tricore_op *op = TriCore_get_detail_op(MI, -1);
|
||||||
fill_mem(tc, reg, disp);
|
op->type = 0;
|
||||||
|
set_mem(op, reg, disp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void fill_mem(cs_tricore *tc, uint8_t base, int32_t disp)
|
|
||||||
{
|
|
||||||
cs_tricore_op *op = &tc->operands[tc->op_count - 1];
|
|
||||||
op->type = TRICORE_OP_MEM;
|
|
||||||
op->mem.base = base;
|
|
||||||
op->mem.disp = disp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printOperand(MCInst *MI, int OpNum, SStream *O)
|
static void printOperand(MCInst *MI, int OpNum, SStream *O)
|
||||||
{
|
{
|
||||||
MCOperand *Op;
|
|
||||||
if (OpNum >= MI->size)
|
if (OpNum >= MI->size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Op = MCInst_getOperand(MI, OpNum);
|
MCOperand *Op = MCInst_getOperand(MI, OpNum);
|
||||||
|
|
||||||
if (MCOperand_isReg(Op)) {
|
if (MCOperand_isReg(Op)) {
|
||||||
unsigned reg = MCOperand_getReg(Op);
|
unsigned reg = MCOperand_getReg(Op);
|
||||||
SStream_concat(O, "%%%s", getRegisterName(reg));
|
SStream_concat(O, "%%%s", getRegisterName(reg));
|
||||||
fill_tricore_register(MI, reg);
|
fill_reg(MI, reg);
|
||||||
} else if (MCOperand_isImm(Op)) {
|
} else if (MCOperand_isImm(Op)) {
|
||||||
int64_t Imm = MCOperand_getImm(Op);
|
int64_t Imm = MCOperand_getImm(Op);
|
||||||
|
printInt64(O, Imm);
|
||||||
if (Imm >= 0) {
|
fill_imm(MI, (int32_t)Imm);
|
||||||
if (Imm > HEX_THRESHOLD)
|
|
||||||
SStream_concat(O, "0x%" PRIx64, Imm);
|
|
||||||
else
|
|
||||||
SStream_concat(O, "%" PRIu64, Imm);
|
|
||||||
} else {
|
|
||||||
if (Imm < -HEX_THRESHOLD)
|
|
||||||
SStream_concat(O, "-0x%" PRIx64, -Imm);
|
|
||||||
else
|
|
||||||
SStream_concat(O, "-%" PRIu64, -Imm);
|
|
||||||
}
|
|
||||||
|
|
||||||
fill_tricore_imm(MI, (int32_t)Imm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +195,7 @@ static void print_sign_ext(MCInst *MI, int OpNum, SStream *O, unsigned n)
|
|||||||
int32_t imm = (int32_t)MCOperand_getImm(MO);
|
int32_t imm = (int32_t)MCOperand_getImm(MO);
|
||||||
imm = sign_ext_n(imm, n);
|
imm = sign_ext_n(imm, n);
|
||||||
printInt32(O, imm);
|
printInt32(O, imm);
|
||||||
fill_tricore_imm(MI, imm);
|
fill_imm(MI, imm);
|
||||||
} else
|
} else
|
||||||
printOperand(MI, OpNum, O);
|
printOperand(MI, OpNum, O);
|
||||||
}
|
}
|
||||||
@ -257,18 +236,8 @@ static void print_zero_ext(MCInst *MI, int OpNum, SStream *O, unsigned n)
|
|||||||
off4_fixup(MI, &imm);
|
off4_fixup(MI, &imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imm >= 0) {
|
printInt64(O, imm);
|
||||||
if (imm > HEX_THRESHOLD)
|
fill_imm(MI, imm);
|
||||||
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);
|
|
||||||
}
|
|
||||||
fill_tricore_imm(MI, imm);
|
|
||||||
} else
|
} else
|
||||||
printOperand(MI, OpNum, O);
|
printOperand(MI, OpNum, O);
|
||||||
}
|
}
|
||||||
@ -280,7 +249,7 @@ static void printOff18Imm(MCInst *MI, int OpNum, SStream *O)
|
|||||||
uint32_t imm = (uint32_t)MCOperand_getImm(MO);
|
uint32_t imm = (uint32_t)MCOperand_getImm(MO);
|
||||||
imm = ((imm & 0x3C000) << 14) | (imm & 0x3fff);
|
imm = ((imm & 0x3C000) << 14) | (imm & 0x3fff);
|
||||||
SStream_concat(O, "0x%x", imm);
|
SStream_concat(O, "0x%x", imm);
|
||||||
fill_tricore_imm(MI, (int32_t)imm);
|
fill_imm(MI, (int32_t)imm);
|
||||||
} else
|
} else
|
||||||
printOperand(MI, OpNum, O);
|
printOperand(MI, OpNum, O);
|
||||||
}
|
}
|
||||||
@ -311,7 +280,7 @@ static void printDisp24Imm(MCInst *MI, int OpNum, SStream *O)
|
|||||||
}
|
}
|
||||||
|
|
||||||
printUInt32(O, disp);
|
printUInt32(O, disp);
|
||||||
fill_tricore_imm(MI, disp);
|
fill_imm(MI, disp);
|
||||||
} else
|
} else
|
||||||
printOperand(MI, OpNum, O);
|
printOperand(MI, OpNum, O);
|
||||||
}
|
}
|
||||||
@ -356,7 +325,7 @@ static void printDisp15Imm(MCInst *MI, int OpNum, SStream *O)
|
|||||||
}
|
}
|
||||||
|
|
||||||
printUInt32(O, disp);
|
printUInt32(O, disp);
|
||||||
fill_tricore_imm(MI, disp);
|
fill_imm(MI, disp);
|
||||||
} else
|
} else
|
||||||
printOperand(MI, OpNum, O);
|
printOperand(MI, OpNum, O);
|
||||||
}
|
}
|
||||||
@ -381,7 +350,7 @@ static void printDisp8Imm(MCInst *MI, int OpNum, SStream *O)
|
|||||||
}
|
}
|
||||||
|
|
||||||
printUInt32(O, disp);
|
printUInt32(O, disp);
|
||||||
fill_tricore_imm(MI, disp);
|
fill_imm(MI, disp);
|
||||||
} else
|
} else
|
||||||
printOperand(MI, OpNum, O);
|
printOperand(MI, OpNum, O);
|
||||||
}
|
}
|
||||||
@ -426,7 +395,7 @@ static void printDisp4Imm(MCInst *MI, int OpNum, SStream *O)
|
|||||||
}
|
}
|
||||||
|
|
||||||
printUInt32(O, disp);
|
printUInt32(O, disp);
|
||||||
fill_tricore_imm(MI, disp);
|
fill_imm(MI, disp);
|
||||||
} else
|
} else
|
||||||
printOperand(MI, OpNum, O);
|
printOperand(MI, OpNum, O);
|
||||||
}
|
}
|
||||||
@ -467,7 +436,7 @@ static void printOExtImm_4(MCInst *MI, int OpNum, SStream *O)
|
|||||||
imm = 0b11111111111111111111111111100000 | (imm << 1);
|
imm = 0b11111111111111111111111111100000 | (imm << 1);
|
||||||
|
|
||||||
printInt32(O, imm);
|
printInt32(O, imm);
|
||||||
fill_tricore_imm(MI, imm);
|
fill_imm(MI, imm);
|
||||||
} else
|
} else
|
||||||
printOperand(MI, OpNum, O);
|
printOperand(MI, OpNum, O);
|
||||||
}
|
}
|
||||||
@ -485,7 +454,7 @@ static void set_mem_access(MCInst *MI, unsigned int access)
|
|||||||
|
|
||||||
#include "TriCoreGenAsmWriter.inc"
|
#include "TriCoreGenAsmWriter.inc"
|
||||||
|
|
||||||
const char *TriCore_getRegisterName(csh handle, unsigned int id)
|
const char *TriCore_LLVM_getRegisterName(unsigned int id)
|
||||||
{
|
{
|
||||||
#ifndef CAPSTONE_DIET
|
#ifndef CAPSTONE_DIET
|
||||||
return getRegisterName(id);
|
return getRegisterName(id);
|
||||||
@ -494,9 +463,10 @@ const char *TriCore_getRegisterName(csh handle, unsigned int id)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriCore_printInst(MCInst *MI, SStream *O, void *Info)
|
void TriCore_LLVM_printInst(MCInst *MI, uint64_t Address, SStream *O)
|
||||||
{
|
{
|
||||||
printInstruction(MI, MI->address, O);
|
printInstruction(MI, Address, O);
|
||||||
|
TriCore_set_access(MI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // CAPSTONE_HAS_TRICORE
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
/* Capstone Disassembly Engine */
|
|
||||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
|
|
||||||
|
|
||||||
#ifndef CS_TRICOREINSTPRINTER_H
|
|
||||||
#define CS_TRICOREINSTPRINTER_H
|
|
||||||
|
|
||||||
#include "../../MCInst.h"
|
|
||||||
#include "../../MCRegisterInfo.h"
|
|
||||||
#include "../../SStream.h"
|
|
||||||
#include "./TriCoreMapping.h"
|
|
||||||
|
|
||||||
const char *TriCore_getRegisterName(csh handle, unsigned int id);
|
|
||||||
|
|
||||||
void TriCore_printInst(MCInst *MI, SStream *O, void *Info);
|
|
||||||
|
|
||||||
void TriCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci);
|
|
||||||
|
|
||||||
#endif
|
|
21
arch/TriCore/TriCoreLinkage.h
Normal file
21
arch/TriCore/TriCoreLinkage.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* Capstone Disassembly Engine */
|
||||||
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
|
||||||
|
|
||||||
|
#ifndef CS_TRICORE_LINKAGE_H
|
||||||
|
#define CS_TRICORE_LINKAGE_H
|
||||||
|
|
||||||
|
// Function defintions to call static LLVM functions.
|
||||||
|
|
||||||
|
#include "../../MCDisassembler.h"
|
||||||
|
#include "../../MCInst.h"
|
||||||
|
#include "../../MCRegisterInfo.h"
|
||||||
|
#include "../../SStream.h"
|
||||||
|
#include "capstone/capstone.h"
|
||||||
|
|
||||||
|
bool TriCore_LLVM_getInstruction(csh handle, const uint8_t *Bytes,
|
||||||
|
size_t ByteLen, MCInst *MI, uint16_t *Size,
|
||||||
|
uint64_t Address, void *Info);
|
||||||
|
const char *TriCore_LLVM_getRegisterName(unsigned RegNo);
|
||||||
|
void TriCore_LLVM_printInst(MCInst *MI, uint64_t Address, SStream *O);
|
||||||
|
|
||||||
|
#endif // CS_TRICORE_LINKAGE_H
|
@ -5,10 +5,13 @@
|
|||||||
|
|
||||||
#include <stdio.h> // debug
|
#include <stdio.h> // debug
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "../../utils.h"
|
#include "../../utils.h"
|
||||||
|
#include "../../cs_simple_types.h"
|
||||||
|
|
||||||
#include "TriCoreMapping.h"
|
#include "TriCoreMapping.h"
|
||||||
|
#include "TriCoreLinkage.h"
|
||||||
|
|
||||||
#define GET_INSTRINFO_ENUM
|
#define GET_INSTRINFO_ENUM
|
||||||
|
|
||||||
@ -30,52 +33,41 @@ static insn_map insns[] = {
|
|||||||
#include "TriCoreGenCSMappingInsn.inc"
|
#include "TriCoreGenCSMappingInsn.inc"
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int TriCore_map_insn_id(cs_struct *h, unsigned int id)
|
|
||||||
{
|
|
||||||
unsigned short i =
|
|
||||||
insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
|
|
||||||
if (i != 0) {
|
|
||||||
return insns[i].mapid;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// given internal insn id, return public instruction info
|
|
||||||
void TriCore_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
void TriCore_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
|
||||||
{
|
{
|
||||||
unsigned short i;
|
// Not used. Information is set after disassembly.
|
||||||
|
}
|
||||||
|
|
||||||
i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
|
|
||||||
if (i != 0) {
|
|
||||||
insn->id = insns[i].mapid;
|
|
||||||
|
|
||||||
if (h->detail) {
|
|
||||||
#ifndef CAPSTONE_DIET
|
#ifndef CAPSTONE_DIET
|
||||||
memcpy(insn->detail->regs_read, insns[i].regs_use,
|
static tricore_reg flag_regs[] = { TRICORE_REG_PSW };
|
||||||
sizeof(insns[i].regs_use));
|
#endif // CAPSTONE_DIET
|
||||||
insn->detail->regs_read_count =
|
|
||||||
(uint8_t)count_positive(insns[i].regs_use);
|
|
||||||
|
|
||||||
memcpy(insn->detail->regs_write, insns[i].regs_mod,
|
static inline void check_updates_flags(MCInst *MI)
|
||||||
sizeof(insns[i].regs_mod));
|
{
|
||||||
insn->detail->regs_write_count =
|
#ifndef CAPSTONE_DIET
|
||||||
(uint8_t)count_positive(insns[i].regs_mod);
|
if (!MI->flat_insn->detail)
|
||||||
|
return;
|
||||||
memcpy(insn->detail->groups, insns[i].groups,
|
cs_detail *detail = MI->flat_insn->detail;
|
||||||
sizeof(insns[i].groups));
|
for (int i = 0; i < detail->regs_write_count; ++i) {
|
||||||
insn->detail->groups_count =
|
if (detail->regs_write[i] == 0)
|
||||||
(uint8_t)count_positive8(insns[i].groups);
|
return;
|
||||||
|
for (int j = 0; j < ARR_SIZE(flag_regs); ++j) {
|
||||||
if (insns[i].branch || insns[i].indirect_branch) {
|
if (detail->regs_write[i] == flag_regs[j]) {
|
||||||
// this insn also belongs to JUMP group. add JUMP group
|
detail->tricore.update_flags = true;
|
||||||
insn->detail
|
return;
|
||||||
->groups[insn->detail->groups_count] =
|
|
||||||
TRICORE_GRP_JUMP;
|
|
||||||
insn->detail->groups_count++;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // CAPSTONE_DIET
|
||||||
|
}
|
||||||
|
|
||||||
|
void TriCore_set_instr_map_data(MCInst *MI)
|
||||||
|
{
|
||||||
|
map_cs_id(MI, insns, ARR_SIZE(insns));
|
||||||
|
map_implicit_reads(MI, insns);
|
||||||
|
map_implicit_writes(MI, insns);
|
||||||
|
check_updates_flags(MI);
|
||||||
|
map_groups(MI, insns);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CAPSTONE_DIET
|
#ifndef CAPSTONE_DIET
|
||||||
@ -130,4 +122,120 @@ const char *TriCore_group_name(csh handle, unsigned int id)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CAPSTONE_DIET
|
||||||
|
/// A LLVM<->CS Mapping entry of an operand.
|
||||||
|
typedef struct insn_op {
|
||||||
|
uint8_t /* cs_op_type */ type; ///< Operand type (e.g.: reg, imm, mem)
|
||||||
|
uint8_t /* cs_ac_type */ access; ///< The access type (read, write)
|
||||||
|
uint8_t /* cs_data_type */
|
||||||
|
dtypes[10]; ///< List of op types. Terminated by CS_DATA_TYPE_LAST
|
||||||
|
} insn_op;
|
||||||
|
|
||||||
|
///< Operands of an instruction.
|
||||||
|
typedef struct {
|
||||||
|
insn_op ops[16]; ///< NULL terminated array of operands.
|
||||||
|
} insn_ops;
|
||||||
|
|
||||||
|
const insn_ops insn_operands[] = {
|
||||||
|
#include "TriCoreGenCSMappingInsnOp.inc"
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void TriCore_set_access(MCInst *MI)
|
||||||
|
{
|
||||||
|
#ifndef CAPSTONE_DIET
|
||||||
|
if (!(MI->csh->detail == CS_OPT_ON && MI->flat_insn->detail))
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert(MI->Opcode < ARR_SIZE(insn_operands));
|
||||||
|
|
||||||
|
cs_detail *detail = MI->flat_insn->detail;
|
||||||
|
cs_tricore *tc = &(detail->tricore);
|
||||||
|
for (int i = 0; i < tc->op_count; ++i) {
|
||||||
|
cs_ac_type ac = map_get_op_access(MI, i);
|
||||||
|
cs_tricore_op *op = &tc->operands[i];
|
||||||
|
op->access = ac;
|
||||||
|
cs_op_type op_type = map_get_op_type(MI, i);
|
||||||
|
if (op_type != CS_OP_REG) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ac & CS_AC_READ) {
|
||||||
|
detail->regs_read[detail->regs_read_count++] = op->reg;
|
||||||
|
}
|
||||||
|
if (ac & CS_AC_WRITE) {
|
||||||
|
detail->regs_write[detail->regs_write_count++] =
|
||||||
|
op->reg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void TriCore_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||||
|
uint8_t *regs_read_count, cs_regs regs_write,
|
||||||
|
uint8_t *regs_write_count)
|
||||||
|
{
|
||||||
|
#ifndef CAPSTONE_DIET
|
||||||
|
uint8_t read_count, write_count;
|
||||||
|
cs_detail *detail = insn->detail;
|
||||||
|
read_count = detail->regs_read_count;
|
||||||
|
write_count = detail->regs_write_count;
|
||||||
|
|
||||||
|
// implicit registers
|
||||||
|
memcpy(regs_read, detail->regs_read,
|
||||||
|
read_count * sizeof(detail->regs_read[0]));
|
||||||
|
memcpy(regs_write, detail->regs_write,
|
||||||
|
write_count * sizeof(detail->regs_write[0]));
|
||||||
|
|
||||||
|
// explicit registers
|
||||||
|
cs_tricore *tc = &detail->tricore;
|
||||||
|
for (uint8_t i = 0; i < tc->op_count; i++) {
|
||||||
|
cs_tricore_op *op = &(tc->operands[i]);
|
||||||
|
switch ((int)op->type) {
|
||||||
|
case TRICORE_OP_REG:
|
||||||
|
if ((op->access & CS_AC_READ) &&
|
||||||
|
!arr_exist(regs_read, read_count, op->reg)) {
|
||||||
|
regs_read[read_count] = (uint16_t)op->reg;
|
||||||
|
read_count++;
|
||||||
|
}
|
||||||
|
if ((op->access & CS_AC_WRITE) &&
|
||||||
|
!arr_exist(regs_write, write_count, op->reg)) {
|
||||||
|
regs_write[write_count] = (uint16_t)op->reg;
|
||||||
|
write_count++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TRICORE_OP_MEM:
|
||||||
|
// registers appeared in memory references always being read
|
||||||
|
if ((op->mem.base != ARM_REG_INVALID) &&
|
||||||
|
!arr_exist(regs_read, read_count, op->mem.base)) {
|
||||||
|
regs_read[read_count] = (uint16_t)op->mem.base;
|
||||||
|
read_count++;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*regs_read_count = read_count;
|
||||||
|
*regs_write_count = write_count;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TriCore_getInstruction(csh handle, const uint8_t *Bytes, size_t ByteLen,
|
||||||
|
MCInst *MI, uint16_t *Size, uint64_t Address,
|
||||||
|
void *Info)
|
||||||
|
{
|
||||||
|
return TriCore_LLVM_getInstruction(handle, Bytes, ByteLen, MI, Size,
|
||||||
|
Address, Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TriCore_printInst(MCInst *MI, SStream *O, void *Info)
|
||||||
|
{
|
||||||
|
TriCore_LLVM_printInst(MI, MI->address, O);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *TriCore_getRegisterName(csh handle, unsigned int RegNo)
|
||||||
|
{
|
||||||
|
return TriCore_LLVM_getRegisterName(RegNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CAPSTONE_HAS_TRICORE
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
#include <capstone/capstone.h>
|
#include <capstone/capstone.h>
|
||||||
|
|
||||||
unsigned int TriCore_map_insn_id(cs_struct *h, unsigned int id);
|
|
||||||
|
|
||||||
// given internal insn id, return public instruction info
|
// given internal insn id, return public instruction info
|
||||||
void TriCore_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
|
void TriCore_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id);
|
||||||
|
|
||||||
@ -15,7 +13,20 @@ const char *TriCore_insn_name(csh handle, unsigned int id);
|
|||||||
|
|
||||||
const char *TriCore_group_name(csh handle, unsigned int id);
|
const char *TriCore_group_name(csh handle, unsigned int id);
|
||||||
|
|
||||||
cs_err TRICORE_global_init(cs_struct *ud);
|
void TriCore_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||||
cs_err TRICORE_option(cs_struct *handle, cs_opt_type type, size_t value);
|
uint8_t *regs_read_count, cs_regs regs_write,
|
||||||
|
uint8_t *regs_write_count);
|
||||||
|
|
||||||
|
void TriCore_set_access(MCInst *MI);
|
||||||
|
|
||||||
|
void TriCore_set_instr_map_data(MCInst *MI);
|
||||||
|
|
||||||
|
bool TriCore_getInstruction(csh handle, const uint8_t *Bytes, size_t ByteLen,
|
||||||
|
MCInst *MI, uint16_t *Size, uint64_t Address,
|
||||||
|
void *Info);
|
||||||
|
|
||||||
|
void TriCore_printInst(MCInst *MI, SStream *O, void *Info);
|
||||||
|
|
||||||
|
const char *TriCore_getRegisterName(csh handle, unsigned int RegNo);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
#ifdef CAPSTONE_HAS_TRICORE
|
#ifdef CAPSTONE_HAS_TRICORE
|
||||||
|
|
||||||
#include "../../utils.h"
|
#include "../../utils.h"
|
||||||
#include "TriCoreDisassembler.h"
|
|
||||||
#include "TriCoreInstPrinter.h"
|
|
||||||
#include "TriCoreMapping.h"
|
#include "TriCoreMapping.h"
|
||||||
|
#include "TriCoreModule.h"
|
||||||
|
#include "TriCoreDisassembler.h"
|
||||||
|
|
||||||
cs_err TRICORE_global_init(cs_struct *ud)
|
cs_err TRICORE_global_init(cs_struct *ud)
|
||||||
{
|
{
|
||||||
@ -14,18 +14,22 @@ cs_err TRICORE_global_init(cs_struct *ud)
|
|||||||
|
|
||||||
mri = cs_mem_malloc(sizeof(*mri));
|
mri = cs_mem_malloc(sizeof(*mri));
|
||||||
|
|
||||||
TriCore_init(mri);
|
TriCore_init_mri(mri);
|
||||||
ud->printer = TriCore_printInst;
|
ud->printer = TriCore_printInst;
|
||||||
ud->printer_info = mri;
|
ud->printer_info = mri;
|
||||||
ud->getinsn_info = mri;
|
ud->getinsn_info = mri;
|
||||||
ud->disasm = TriCore_getInstruction;
|
ud->disasm = TriCore_getInstruction;
|
||||||
ud->post_printer = TriCore_post_printer;
|
ud->post_printer = NULL;
|
||||||
|
|
||||||
ud->reg_name = TriCore_getRegisterName;
|
ud->reg_name = TriCore_getRegisterName;
|
||||||
ud->insn_id = TriCore_get_insn_id;
|
ud->insn_id = TriCore_get_insn_id;
|
||||||
ud->insn_name = TriCore_insn_name;
|
ud->insn_name = TriCore_insn_name;
|
||||||
ud->group_name = TriCore_group_name;
|
ud->group_name = TriCore_group_name;
|
||||||
|
|
||||||
|
#ifndef CAPSTONE_DIET
|
||||||
|
ud->reg_access = TriCore_reg_access;
|
||||||
|
#endif
|
||||||
|
|
||||||
return CS_ERR_OK;
|
return CS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,11 +265,11 @@ typedef enum {
|
|||||||
CS_DATA_TYPE_Glue =
|
CS_DATA_TYPE_Glue =
|
||||||
189, // This glues nodes together during pre-RA sched
|
189, // This glues nodes together during pre-RA sched
|
||||||
|
|
||||||
CS_DATA_TYPE_isVoid = 190, // This has no value
|
CS_DATA_TYPE_isVoid = 190, // This has no value
|
||||||
|
|
||||||
CS_DATA_TYPE_Untyped = 191, // This value takes a register, but has
|
CS_DATA_TYPE_Untyped = 191, // This value takes a register, but has
|
||||||
// unspecified type. The register class
|
// unspecified type. The register class
|
||||||
// will be determined by the opcode.
|
// will be determined by the opcode.
|
||||||
|
|
||||||
CS_DATA_TYPE_funcref = 192, // WebAssembly's funcref type
|
CS_DATA_TYPE_funcref = 192, // WebAssembly's funcref type
|
||||||
CS_DATA_TYPE_externref = 193, // WebAssembly's externref type
|
CS_DATA_TYPE_externref = 193, // WebAssembly's externref type
|
||||||
|
@ -34,39 +34,51 @@ void print_insn_detail_tricore(csh handle, cs_insn *ins)
|
|||||||
op->imm);
|
op->imm);
|
||||||
break;
|
break;
|
||||||
case TRICORE_OP_MEM:
|
case TRICORE_OP_MEM:
|
||||||
printf("\t\toperands[%u].type: MEM\n", i);
|
printf("\t\toperands[%u].type: MEM\n"
|
||||||
if (op->mem.base != TRICORE_REG_INVALID)
|
"\t\t\t.mem.base: REG = %s\n"
|
||||||
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
|
"\t\t\t.mem.disp: 0x%x\n",
|
||||||
i, cs_reg_name(handle, op->mem.base));
|
i, cs_reg_name(handle, op->mem.base),
|
||||||
if (op->mem.disp != 0)
|
op->mem.disp);
|
||||||
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i,
|
|
||||||
op->mem.disp);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print out all registers accessed by this instruction (either implicit or
|
switch (op->access) {
|
||||||
// explicit)
|
default:
|
||||||
if (!cs_regs_access(handle, ins, regs_read, ®s_read_count,
|
break;
|
||||||
regs_write, ®s_write_count)) {
|
case CS_AC_READ:
|
||||||
if (regs_read_count) {
|
printf("\t\t\t.access: READ\n");
|
||||||
printf("\tRegisters read:");
|
break;
|
||||||
for (i = 0; i < regs_read_count; i++) {
|
case CS_AC_WRITE:
|
||||||
printf(" %s",
|
printf("\t\t\t.access: WRITE\n");
|
||||||
cs_reg_name(handle,
|
break;
|
||||||
regs_read[i]));
|
case CS_AC_READ | CS_AC_WRITE:
|
||||||
}
|
printf("\t\t\t.access: READ | WRITE\n");
|
||||||
printf("\n");
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (regs_write_count) {
|
|
||||||
printf("\tRegisters modified:");
|
|
||||||
for (i = 0; i < regs_write_count; i++) {
|
|
||||||
printf(" %s",
|
|
||||||
cs_reg_name(handle,
|
|
||||||
regs_write[i]));
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Print out all registers accessed by this instruction (either implicit or
|
||||||
|
// explicit)
|
||||||
|
if (!cs_regs_access(handle, ins, regs_read, ®s_read_count,
|
||||||
|
regs_write, ®s_write_count)) {
|
||||||
|
if (regs_read_count) {
|
||||||
|
printf("\tRegisters read:");
|
||||||
|
for (i = 0; i < regs_read_count; i++) {
|
||||||
|
printf(" %s",
|
||||||
|
cs_reg_name(handle, regs_read[i]));
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regs_write_count) {
|
||||||
|
printf("\tRegisters modified:");
|
||||||
|
for (i = 0; i < regs_write_count; i++) {
|
||||||
|
printf(" %s",
|
||||||
|
cs_reg_name(handle, regs_write[i]));
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tricore->update_flags)
|
||||||
|
printf("\tUpdate-flags: True\n");
|
||||||
}
|
}
|
||||||
|
@ -18,40 +18,46 @@ extern "C" {
|
|||||||
#pragma warning(disable : 4201)
|
#pragma warning(disable : 4201)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//> Operand type for instruction's operands
|
/// Operand type for instruction's operands
|
||||||
typedef enum tricore_op_type {
|
typedef enum tricore_op_type {
|
||||||
TRICORE_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized).
|
TRICORE_OP_INVALID = CS_OP_INVALID, ///< CS_OP_INVALID (Uninitialized).
|
||||||
TRICORE_OP_REG, // = CS_OP_REG (Register operand).
|
TRICORE_OP_REG = CS_OP_REG, ///< CS_OP_REG (Register operand).
|
||||||
TRICORE_OP_IMM, // = CS_OP_IMM (Immediate operand).
|
TRICORE_OP_IMM = CS_OP_IMM, ///< CS_OP_IMM (Immediate operand).
|
||||||
TRICORE_OP_MEM, // = CS_OP_MEM (Memory operand).
|
TRICORE_OP_MEM = CS_OPT_MEM, ///< CS_OP_MEM (Memory operand).
|
||||||
} tricore_op_type;
|
} tricore_op_type;
|
||||||
|
|
||||||
// Instruction's operand referring to memory
|
/// Instruction's operand referring to memory
|
||||||
// This is associated with TRICORE_OP_MEM operand type above
|
/// This is associated with TRICORE_OP_MEM operand type above
|
||||||
typedef struct tricore_op_mem {
|
typedef struct tricore_op_mem {
|
||||||
uint8_t base; // base register
|
uint8_t base; ///< base register
|
||||||
int32_t disp; // displacement/offset value
|
int32_t disp; ///< displacement/offset value
|
||||||
} tricore_op_mem;
|
} tricore_op_mem;
|
||||||
|
|
||||||
// Instruction operand
|
/// Instruction operand
|
||||||
typedef struct cs_tricore_op {
|
typedef struct cs_tricore_op {
|
||||||
tricore_op_type type; // operand type
|
tricore_op_type type; ///< operand type
|
||||||
union {
|
union {
|
||||||
unsigned int reg; // register value for REG operand
|
unsigned int reg; ///< register value for REG operand
|
||||||
int32_t imm; // immediate value for IMM operand
|
int32_t imm; ///< immediate value for IMM operand
|
||||||
tricore_op_mem mem; // base/disp value for MEM operand
|
tricore_op_mem mem; ///< base/disp value for MEM operand
|
||||||
};
|
};
|
||||||
|
/// This field is combined of cs_ac_type.
|
||||||
|
/// NOTE: this field is irrelevant if engine is compiled in DIET mode.
|
||||||
|
uint8_t access; ///< How is this operand accessed? (READ, WRITE or READ|WRITE)
|
||||||
} cs_tricore_op;
|
} cs_tricore_op;
|
||||||
|
|
||||||
// Instruction structure
|
#define TRICORE_OP_COUNT 8
|
||||||
|
|
||||||
|
/// Instruction structure
|
||||||
typedef struct cs_tricore {
|
typedef struct cs_tricore {
|
||||||
// Number of operands of this instruction,
|
uint8_t op_count; ///< number of operands of this instruction.
|
||||||
// or 0 when instruction has no operand.
|
cs_tricore_op
|
||||||
uint8_t op_count;
|
operands[TRICORE_OP_COUNT]; ///< operands for this instruction.
|
||||||
cs_tricore_op operands[8]; // operands for this instruction.
|
/// TODO: Mark the modified flags register in td files and regenerate inc files
|
||||||
|
bool update_flags; ///< whether the flags register is updated.
|
||||||
} cs_tricore;
|
} cs_tricore;
|
||||||
|
|
||||||
//> TriCore registers
|
/// TriCore registers
|
||||||
typedef enum tricore_reg {
|
typedef enum tricore_reg {
|
||||||
// generate content <TriCoreGenCSRegEnum.inc> begin
|
// generate content <TriCoreGenCSRegEnum.inc> begin
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@ -123,7 +129,7 @@ typedef enum tricore_reg {
|
|||||||
// generate content <TriCoreGenCSRegEnum.inc> end
|
// generate content <TriCoreGenCSRegEnum.inc> end
|
||||||
} tricore_reg;
|
} tricore_reg;
|
||||||
|
|
||||||
//> TriCore instruction
|
/// TriCore instruction
|
||||||
typedef enum tricore_insn {
|
typedef enum tricore_insn {
|
||||||
TRICORE_INS_INVALID = 0,
|
TRICORE_INS_INVALID = 0,
|
||||||
// generate content <TriCoreGenCSInsnEnum.inc> begin
|
// generate content <TriCoreGenCSInsnEnum.inc> begin
|
||||||
@ -525,13 +531,13 @@ typedef enum tricore_insn {
|
|||||||
TRICORE_INS_ENDING, // <-- mark the end of the list of instructions
|
TRICORE_INS_ENDING, // <-- mark the end of the list of instructions
|
||||||
} tricore_insn;
|
} tricore_insn;
|
||||||
|
|
||||||
//> Group of TriCore instructions
|
/// Group of TriCore instructions
|
||||||
typedef enum tricore_insn_group {
|
typedef enum tricore_insn_group {
|
||||||
TRICORE_GRP_INVALID, ///< = CS_GRP_INVALID
|
TRICORE_GRP_INVALID, ///< = CS_GRP_INVALID
|
||||||
//> Generic groups
|
/// Generic groups
|
||||||
TRICORE_GRP_CALL, ///< = CS_GRP_CALL
|
TRICORE_GRP_CALL, ///< = CS_GRP_CALL
|
||||||
TRICORE_GRP_JUMP, ///< = CS_GRP_JUMP
|
TRICORE_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||||
TRICORE_GRP_ENDING, ///< = mark the end of the list of groups
|
TRICORE_GRP_ENDING, ///< mark the end of the list of groups
|
||||||
} tricore_insn_group;
|
} tricore_insn_group;
|
||||||
|
|
||||||
typedef enum tricore_feature_t {
|
typedef enum tricore_feature_t {
|
||||||
@ -551,7 +557,7 @@ typedef enum tricore_feature_t {
|
|||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
// generate content <TriCoreGenCSFeatureEnum.inc> end
|
// generate content <TriCoreGenCSFeatureEnum.inc> end
|
||||||
TRICORE_FEATURE_ENDING, // <-- mark the end of the list of features
|
TRICORE_FEATURE_ENDING, ///< mark the end of the list of features
|
||||||
} tricore_feature;
|
} tricore_feature;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
x
Reference in New Issue
Block a user