[M68K] Implemented regs read/write lists

This commit is contained in:
Daniel Collin 2016-06-06 17:55:05 +02:00
parent 1ba113ca08
commit aaf2c49015
5 changed files with 185 additions and 9 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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)))

View File

@ -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,