mirror of
https://github.com/xenia-project/capstone.git
synced 2024-10-07 08:53:32 +00:00
[M68K] Implemented regs read/write lists
This commit is contained in:
parent
1ba113ca08
commit
aaf2c49015
@ -3833,6 +3833,135 @@ static int instruction_is_valid(m68k_info *info, const unsigned int word_check)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int exists_reg_list(uint16_t *regs, uint8_t count, m68k_reg reg)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (regs[i] == (uint16_t)reg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_reg_to_rw_list(m68k_info *info, m68k_reg reg, int write)
|
||||
{
|
||||
if (reg == M68K_REG_INVALID)
|
||||
return;
|
||||
|
||||
if (write)
|
||||
{
|
||||
if (exists_reg_list(info->regs_write, info->regs_write_count, reg))
|
||||
return;
|
||||
|
||||
info->regs_write[info->regs_write_count++] = (uint16_t)reg;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (exists_reg_list(info->regs_read, info->regs_read_count, reg))
|
||||
return;
|
||||
|
||||
info->regs_read[info->regs_read_count++] = (uint16_t)reg;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_am_reg_list(m68k_info *info, cs_m68k_op *op, int write)
|
||||
{
|
||||
switch (op->address_mode) {
|
||||
case M68K_AM_REG_DIRECT_ADDR:
|
||||
case M68K_AM_REG_DIRECT_DATA:
|
||||
add_reg_to_rw_list(info, op->reg, write);
|
||||
break;
|
||||
|
||||
case M68K_AM_REGI_ADDR_POST_INC:
|
||||
case M68K_AM_REGI_ADDR_PRE_DEC:
|
||||
add_reg_to_rw_list(info, op->reg, 1);
|
||||
break;
|
||||
|
||||
case M68K_AM_REGI_ADDR:
|
||||
case M68K_AM_REGI_ADDR_DISP:
|
||||
add_reg_to_rw_list(info, op->reg, 0);
|
||||
break;
|
||||
|
||||
case M68K_AM_AREGI_INDEX_8_BIT_DISP:
|
||||
case M68K_AM_AREGI_INDEX_BASE_DISP:
|
||||
case M68K_AM_MEMI_POST_INDEX:
|
||||
case M68K_AM_MEMI_PRE_INDEX:
|
||||
case M68K_AM_PCI_INDEX_8_BIT_DISP:
|
||||
case M68K_AM_PCI_INDEX_BASE_DISP:
|
||||
case M68K_AM_PC_MEMI_PRE_INDEX:
|
||||
case M68K_AM_PC_MEMI_POST_INDEX:
|
||||
add_reg_to_rw_list(info, op->mem.index_reg, 0);
|
||||
add_reg_to_rw_list(info, op->mem.base_reg, 0);
|
||||
break;
|
||||
|
||||
// no register(s) in the other addressing modes
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_bits_range(m68k_info *info, m68k_reg reg_start, uint8_t bits, int write)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
if (bits & (1 << i)) {
|
||||
add_reg_to_rw_list(info, reg_start + i, write);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void update_reg_list_regbits(m68k_info *info, cs_m68k_op *op, int write)
|
||||
{
|
||||
uint32_t bits = op->register_bits;
|
||||
update_bits_range(info, M68K_REG_D0, bits & 0xff, write);
|
||||
update_bits_range(info, M68K_REG_A0, (bits >> 8) & 0xff, write);
|
||||
update_bits_range(info, M68K_REG_FP0, (bits >> 16) & 0xff, write);
|
||||
}
|
||||
|
||||
static void update_op_reg_list(m68k_info *info, cs_m68k_op *op, int write)
|
||||
{
|
||||
switch ((int)op->type) {
|
||||
case M68K_OP_REG:
|
||||
add_reg_to_rw_list(info, op->reg, write);
|
||||
break;
|
||||
|
||||
case M68K_OP_MEM:
|
||||
update_am_reg_list(info, op, write);
|
||||
break;
|
||||
|
||||
case M68K_OP_REG_BITS:
|
||||
update_reg_list_regbits(info, op, write);
|
||||
break;
|
||||
|
||||
case M68K_OP_REG_PAIR:
|
||||
add_reg_to_rw_list(info, M68K_REG_D0 + op->reg_pair.reg_0, write);
|
||||
add_reg_to_rw_list(info, M68K_REG_D0 + op->reg_pair.reg_1, write);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void build_regs_read_write_counts(m68k_info *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!info->extension.op_count)
|
||||
return;
|
||||
|
||||
if (info->extension.op_count == 1) {
|
||||
update_op_reg_list(info, &info->extension.operands[0], 1);
|
||||
} else {
|
||||
// first operand is always read
|
||||
update_op_reg_list(info, &info->extension.operands[0], 0);
|
||||
|
||||
// remaning write
|
||||
for (i = 1; i < info->extension.op_count; ++i)
|
||||
update_op_reg_list(info, &info->extension.operands[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void m68k_setup_internals(m68k_info* info, MCInst* inst, unsigned int pc, unsigned int cpu_type)
|
||||
{
|
||||
info->inst = inst;
|
||||
@ -3913,6 +4042,8 @@ bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* i
|
||||
m68k_info *info = (m68k_info*)handle->printer_info;
|
||||
|
||||
info->groups_count = 0;
|
||||
info->regs_read_count = 0;
|
||||
info->regs_write_count = 0;
|
||||
info->code = code;
|
||||
info->code_len = code_len;
|
||||
info->baseAddress = address;
|
||||
@ -3936,6 +4067,8 @@ bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* i
|
||||
return false;
|
||||
}
|
||||
|
||||
build_regs_read_write_counts(info);
|
||||
|
||||
#ifdef M68K_DEBUG
|
||||
SStream_Init(&ss);
|
||||
M68K_printInst(instr, &ss, info);
|
||||
|
@ -17,6 +17,10 @@ typedef struct m68k_info {
|
||||
unsigned int type;
|
||||
unsigned int address_mask; /* Address mask to simulate address lines */
|
||||
cs_m68k extension;
|
||||
uint16_t regs_read[12]; // list of implicit registers read by this insn
|
||||
uint8_t regs_read_count; // number of implicit registers read by this insn
|
||||
uint16_t regs_write[20]; // list of implicit registers modified by this insn
|
||||
uint8_t regs_write_count; // number of implicit registers modified by this insn
|
||||
uint8_t groups[8];
|
||||
uint8_t groups_count;
|
||||
} m68k_info;
|
||||
|
@ -233,6 +233,9 @@ void printAddressingMode(SStream* O, const cs_m68k* inst, const cs_m68k_op* op)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define m68k_sizeof_array(array) (int)(sizeof(array)/sizeof(array[0]))
|
||||
#define m68k_min(a, b) (a < b) ? a : b
|
||||
|
||||
void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
@ -243,11 +246,20 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
||||
|
||||
detail = MI->flat_insn->detail;
|
||||
if (detail) {
|
||||
int regs_read_count = m68k_min(m68k_sizeof_array(detail->regs_read), info->regs_read_count);
|
||||
int regs_write_count = m68k_min(m68k_sizeof_array(detail->regs_write), info->regs_write_count);
|
||||
int groups_count = m68k_min(m68k_sizeof_array(detail->groups), info->groups_count);
|
||||
|
||||
memcpy(&detail->m68k, ext, sizeof(cs_m68k));
|
||||
memcpy(&detail->groups, &info->groups, info->groups_count);
|
||||
detail->groups_count = info->groups_count;
|
||||
detail->regs_read_count = 0;
|
||||
detail->regs_write_count = 0;
|
||||
|
||||
memcpy(&detail->regs_read, &info->regs_read, regs_read_count * sizeof(uint16_t));
|
||||
detail->regs_read_count = regs_read_count;
|
||||
|
||||
memcpy(&detail->regs_write, &info->regs_write, regs_write_count * sizeof(uint16_t));
|
||||
detail->regs_write_count = regs_write_count;
|
||||
|
||||
memcpy(&detail->groups, &info->groups, groups_count);
|
||||
detail->groups_count = groups_count;
|
||||
}
|
||||
|
||||
if (MI->Opcode == M68K_INS_INVALID) {
|
||||
|
@ -6,7 +6,7 @@ from capstone import *
|
||||
from capstone.m68k import *
|
||||
from xprint import to_hex, to_x
|
||||
|
||||
M68K_CODE = b"\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75"
|
||||
M68K_CODE = b"\x4c\x00\x54\x04\x48\xe7\xe0\x30\x4c\xdf\x0c\x07\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4e\xb9\x00\x00\x00\x12\x4e\x75"
|
||||
|
||||
all_tests = (
|
||||
(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K"),
|
||||
@ -42,11 +42,20 @@ s_addressing_modes = {
|
||||
18: "Immidate value",
|
||||
}
|
||||
|
||||
def print_read_write_regs(insn):
|
||||
for m in insn.regs_read:
|
||||
print("\treading from reg: %s" % insn.reg_name(m))
|
||||
|
||||
for m in insn.regs_write:
|
||||
print("\twriting to reg: %s" % insn.reg_name(m))
|
||||
|
||||
def print_insn_detail(insn):
|
||||
if len(insn.operands) > 0:
|
||||
print("\top_count: %u" % (len(insn.operands)))
|
||||
print("\tgroups_count: %u" % len(insn.groups))
|
||||
|
||||
print_read_write_regs(insn)
|
||||
|
||||
for i, op in enumerate(insn.operands):
|
||||
if op.type == M68K_OP_REG:
|
||||
print("\t\toperands[%u].type: REG = %s" % (i, insn.reg_name(op.reg)))
|
||||
|
@ -58,6 +58,25 @@ const char* s_addressing_modes[] = {
|
||||
"Immidate value",
|
||||
};
|
||||
|
||||
static void print_read_write_regs(cs_detail* detail)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < detail->regs_read_count; ++i)
|
||||
{
|
||||
uint16_t reg_id = detail->regs_read[i];
|
||||
const char* reg_name = cs_reg_name(handle, reg_id);
|
||||
printf("\treading from reg: %s\n", reg_name);
|
||||
}
|
||||
|
||||
for (i = 0; i < detail->regs_write_count; ++i)
|
||||
{
|
||||
uint16_t reg_id = detail->regs_write[i];
|
||||
const char* reg_name = cs_reg_name(handle, reg_id);
|
||||
printf("\twriting to reg: %s\n", reg_name);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_insn_detail(cs_insn *ins)
|
||||
{
|
||||
cs_m68k* m68k;
|
||||
@ -73,6 +92,8 @@ static void print_insn_detail(cs_insn *ins)
|
||||
if (m68k->op_count)
|
||||
printf("\top_count: %u\n", m68k->op_count);
|
||||
|
||||
print_read_write_regs(detail);
|
||||
|
||||
printf("\tgroups_count: %u\n", detail->groups_count);
|
||||
|
||||
for (i = 0; i < m68k->op_count; i++) {
|
||||
@ -119,12 +140,9 @@ static void print_insn_detail(cs_insn *ins)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void test()
|
||||
{
|
||||
#define M68K_CODE "\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75"
|
||||
|
||||
#define M68K_CODE "\x4C\x00\x54\x04\x48\xe7\xe0\x30\x4C\xDF\x0C\x07\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75"
|
||||
struct platform platforms[] = {
|
||||
{
|
||||
CS_ARCH_M68K,
|
||||
|
Loading…
Reference in New Issue
Block a user