[M68K] Added basic groups

Added support for basic groups in the M68K backend. Also did some minor cleanups/whitespace fixes while at it.

Relates to this issue https://github.com/aquynh/capstone/issues/494
This commit is contained in:
Daniel Collin 2016-04-10 10:55:21 +02:00
parent 3eae96de19
commit d994c74b02
5 changed files with 111 additions and 67 deletions

View File

@ -28,7 +28,7 @@
*/
/* The code bellow is based on MUSASHI but has been heavily modified for capstore by
* Daniel Collin <daniel@collin.com> 2015 */
* Daniel Collin <daniel@collin.com> 2015-2016 */
/* ======================================================================== */
/* ================================ INCLUDES ============================== */
@ -152,12 +152,11 @@ enum {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static unsigned int m68k_read_disassembler_16(const m68k_info *info, const uint64_t addr)
{
const uint16_t v0 = info->code[addr + 0];
const uint16_t v1 = info->code[addr + 1];
return (v0 << 8) | v1;
return (v0 << 8) | v1;
}
static unsigned int m68k_read_disassembler_32(const m68k_info *info, const uint64_t addr)
@ -380,7 +379,7 @@ static void get_with_index_address_mode(m68k_info *info, cs_m68k_op* op, uint in
if (preindex) {
op->address_mode = is_pc ? M68K_AM_PC_MEMI_PRE_INDEX : M68K_AM_MEMI_PRE_INDEX;
} else if (postindex) {
} else if (postindex) {
op->address_mode = is_pc ? M68K_AM_PC_MEMI_POST_INDEX : M68K_AM_MEMI_POST_INDEX;
}
@ -388,21 +387,21 @@ static void get_with_index_address_mode(m68k_info *info, cs_m68k_op* op, uint in
}
op->mem.index_reg = (EXT_INDEX_AR(extension) ? M68K_REG_A0 : M68K_REG_D0) + EXT_INDEX_REGISTER(extension);
op->mem.index_size = EXT_INDEX_LONG(extension) ? 1 : 0;
op->mem.index_size = EXT_INDEX_LONG(extension) ? 1 : 0;
if (EXT_8BIT_DISPLACEMENT(extension) == 0) {
if (is_pc) {
op->mem.base_reg = M68K_REG_PC;
op->mem.base_reg = M68K_REG_PC;
op->address_mode = M68K_AM_PCI_INDEX_BASE_DISP;
} else {
op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
}
} else {
if (is_pc) {
op->mem.base_reg = M68K_REG_PC;
op->mem.base_reg = M68K_REG_PC;
op->address_mode = M68K_AM_PCI_INDEX_8_BIT_DISP;
} else {
op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
op->address_mode = M68K_AM_AREGI_INDEX_8_BIT_DISP;
}
@ -509,6 +508,11 @@ void get_ea_mode_op(m68k_info *info, cs_m68k_op* op, uint instruction, uint size
}
}
static void set_insn_group(m68k_info *info, m68k_group_type group)
{
info->groups[info->groups_count++] = (uint8_t)group;
}
static cs_m68k* build_init_op(m68k_info *info, int opcode, int count, int size)
{
cs_m68k* ext;
@ -621,7 +625,7 @@ static void build_imm_ea(m68k_info *info, int opcode, uint8_t size, int imm)
op0->type = M68K_OP_IMM;
op0->address_mode = M68K_AM_IMMIDIATE;
op0->imm = imm;
op0->imm = imm;
get_ea_mode_op(info, op1, info->ir, size);
}
@ -745,10 +749,10 @@ static void build_imm_special_reg(m68k_info *info, int opcode, int imm, int size
op0->type = M68K_OP_IMM;
op0->address_mode = M68K_AM_IMMIDIATE;
op0->imm = imm;
op0->imm = imm;
op1->address_mode = M68K_AM_NONE;
op1->reg = reg;
op1->reg = reg;
}
static void build_bxx(m68k_info *info, int opcode, int size, int jump_offset)
@ -761,6 +765,8 @@ static void build_bxx(m68k_info *info, int opcode, int size, int jump_offset)
op->type = M68K_OP_IMM;
op->address_mode = M68K_AM_IMMIDIATE;
op->imm = jump_offset;
set_insn_group(info, M68K_GRP_JUMP);
}
static void build_bcc(m68k_info *info, int size, int jump_offset)
@ -788,6 +794,8 @@ static void build_dbxx(m68k_info *info, int opcode, int size, int jump_offset)
op1->type = M68K_OP_IMM;
op1->address_mode = M68K_AM_IMMIDIATE;
op1->imm = jump_offset;
set_insn_group(info, M68K_GRP_JUMP);
}
static void build_dbcc(m68k_info *info, int size, int jump_offset)
@ -867,7 +875,7 @@ static uint16_t reverse_bits(uint v)
uint r = v; // r will be reversed bits of v; first get LSB of v
uint s = 16 - 1; // extra shift needed at end
for (v >>= 1; v; v >>= 1) {
for (v >>= 1; v; v >>= 1) {
r <<= 1;
r |= v & 1;
s--;
@ -881,7 +889,7 @@ static uint8_t reverse_bits_8(uint v)
uint r = v; // r will be reversed bits of v; first get LSB of v
uint s = 8 - 1; // extra shift needed at end
for (v >>= 1; v; v >>= 1) {
for (v >>= 1; v; v >>= 1) {
r <<= 1;
r |= v & 1;
s--;
@ -1056,7 +1064,7 @@ static void build_cpush_cinv(m68k_info *info, int op_offset)
switch ((info->ir >> 3) & 3) { // scope
// Invalid
case 0:
case 0:
d68000_invalid(info);
return;
// Line
@ -1868,11 +1876,11 @@ static void fmove_fpcr(m68k_info *info, uint extension)
get_ea_mode_op(info, op_ea, info->ir, 4);
if (regsel & 4)
if (regsel & 4)
special->reg = M68K_REG_FPCR;
else if (regsel & 2)
else if (regsel & 2)
special->reg = M68K_REG_FPSR;
else if (regsel & 1)
else if (regsel & 1)
special->reg = M68K_REG_FPIAR;
}
@ -1903,7 +1911,7 @@ static void fmovem(m68k_info *info, uint extension)
op_reglist->reg = M68K_REG_D0 + ((reglist >> 4) & 7);
break;
case 0 :
case 0 :
op_reglist->address_mode = M68K_AM_NONE;
op_reglist->type = M68K_OP_REG_BITS;
op_reglist->register_bits = reglist << 16;
@ -2018,7 +2026,7 @@ static void d68020_cpgen(m68k_info *info)
case 0x28: MCInst_setOpcode(info->inst, M68K_INS_FSUB); supports_single_op = false; break;
case 0x38: MCInst_setOpcode(info->inst, M68K_INS_FCMP); supports_single_op = false; break;
case 0x3a: MCInst_setOpcode(info->inst, M68K_INS_FTST); break;
default:
default:
break;
}
@ -2050,22 +2058,22 @@ static void d68020_cpgen(m68k_info *info)
if (rm == 1) {
switch (src) {
case 0x00 :
case 0x00 :
ext->op_size.cpu_size = M68K_CPU_SIZE_LONG;
get_ea_mode_op(info, op0, info->ir, 4);
break;
case 0x06 :
case 0x06 :
ext->op_size.cpu_size = M68K_CPU_SIZE_BYTE;
get_ea_mode_op(info, op0, info->ir, 1);
break;
case 0x04 :
case 0x04 :
ext->op_size.cpu_size = M68K_CPU_SIZE_WORD;
get_ea_mode_op(info, op0, info->ir, 2);
break;
case 0x01 :
case 0x01 :
ext->op_size.type = M68K_SIZE_TYPE_FPU;
ext->op_size.fpu_size = M68K_FPU_SIZE_SINGLE;
get_ea_mode_op(info, op0, info->ir, 4);
@ -2339,12 +2347,14 @@ static void d68020_extb_32(m68k_info *info)
static void d68000_jmp(m68k_info *info)
{
set_insn_group(info, M68K_GRP_JUMP);
cs_m68k* ext = build_init_op(info, M68K_INS_JMP, 1, 0);
get_ea_mode_op(info, &ext->operands[0], info->ir, 4);
}
static void d68000_jsr(m68k_info *info)
{
set_insn_group(info, M68K_GRP_JUMP);
cs_m68k* ext = build_init_op(info, M68K_INS_JSR, 1, 0);
get_ea_mode_op(info, &ext->operands[0], info->ir, 4);
}
@ -3065,12 +3075,14 @@ static void d68000_roxl_ea(m68k_info *info)
static void d68010_rtd(m68k_info *info)
{
set_insn_group(info, M68K_GRP_RET);
LIMIT_CPU_TYPES(info, M68010_PLUS);
build_bxx(info, M68K_INS_RTD, 0, read_imm_16(info));
}
static void d68000_rte(m68k_info *info)
{
set_insn_group(info, M68K_GRP_IRET);
MCInst_setOpcode(info->inst, M68K_INS_RTE);
}
@ -3079,6 +3091,7 @@ static void d68020_rtm(m68k_info *info)
cs_m68k* ext;
cs_m68k_op* op;
set_insn_group(info, M68K_GRP_RET);
LIMIT_CPU_TYPES(info, M68020_ONLY);
@ -3099,11 +3112,13 @@ static void d68020_rtm(m68k_info *info)
static void d68000_rtr(m68k_info *info)
{
set_insn_group(info, M68K_GRP_RET);
MCInst_setOpcode(info->inst, M68K_INS_RTR);
}
static void d68000_rts(m68k_info *info)
{
set_insn_group(info, M68K_GRP_RET);
MCInst_setOpcode(info->inst, M68K_INS_RTS);
}
@ -3861,14 +3876,14 @@ static unsigned int m68k_disassemble(m68k_info *info, uint64_t pc)
MCInst *inst = info->inst;
cs_m68k* ext = &info->extension;
int i;
inst->Opcode = M68K_INS_INVALID;
build_opcode_table();
memset(ext, 0, sizeof(cs_m68k));
ext->op_size.type = M68K_SIZE_TYPE_CPU;
for (i = 0; i < M68K_OPERAND_COUNT; ++i)
ext->operands[i].type = M68K_OP_REG;
@ -3889,7 +3904,7 @@ bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* i
int s;
int cpu_type = M68K_CPU_TYPE_68000;
cs_struct* handle = instr->csh;
m68k_info *info = (m68k_info *)handle->printer_info;
m68k_info *info = (m68k_info*)handle->printer_info;
info->code = code;
info->code_len = code_len;
@ -3919,7 +3934,7 @@ bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* i
M68K_printInst(instr, &ss, info);
#endif
// Make sure we always stay within range
// Make sure we always stay within range
if (s > (int)code_len)
*size = (uint16_t)code_len;
else

View File

@ -1,5 +1,5 @@
/* Capstone Disassembly Engine */
/* M68K Backend by Daniel Collin <daniel@collin.com> 2015 */
/* M68K Backend by Daniel Collin <daniel@collin.com> 2015-2016 */
#ifndef CS_M68KDISASSEMBLER_H
#define CS_M68KDISASSEMBLER_H
@ -18,6 +18,8 @@ typedef struct m68k_info {
unsigned int type;
unsigned int address_mask; /* Address mask to simulate address lines */
cs_m68k extension;
uint8_t groups[8];
uint8_t groups_count;
} m68k_info;
bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* instr, uint16_t* size, uint64_t address, void* info);

View File

@ -1,5 +1,5 @@
/* Capstone Disassembly Engine */
/* M68K Backend by Daniel Collin <daniel@collin.com> 2015 */
/* M68K Backend by Daniel Collin <daniel@collin.com> 2015-2016 */
#ifdef _MSC_VER
// Disable security warnings for strcat & sprintf
@ -34,7 +34,7 @@ static const char* s_reg_names[] = {
"caar", "msp", "isp", "tc", "itt0", "itt1", "dtt0",
"dtt1", "mmusr", "urp", "srp",
"fpcr", "fpsr", "fpiar",
"fpcr", "fpsr", "fpiar",
};
static const char* s_instruction_names[] = {
@ -49,15 +49,15 @@ static const char* s_instruction_names[] = {
"fcosh", "fdbf", "fdbeq", "fdbogt", "fdboge", "fdbolt", "fdbole", "fdbogl", "fdbor", "fdbun", "fdbueq", "fdbugt", "fdbuge", "fdbult", "fdbule", "fdbne",
"fdbt", "fdbsf", "fdbseq", "fdbgt", "fdbge", "fdblt", "fdble", "fdbgl", "fdbgle", "fdbngle", "fdbngl", "fdbnle", "fdbnlt", "fdbnge", "fdbngt", "fdbsne",
"fdbst", "fdiv", "fsdiv", "fddiv", "fetox", "fetoxm1", "fgetexp", "fgetman", "fint", "fintrz", "flog10", "flog2", "flogn", "flognp1", "fmod", "fmove",
"fsmove", "fdmove", "fmovecr", "fmovem", "fmul", "fsmul", "fdmul", "fneg", "fsneg", "fdneg", "fnop", "frem", "frestore", "fsave", "fscale", "fsgldiv",
"fsmove", "fdmove", "fmovecr", "fmovem", "fmul", "fsmul", "fdmul", "fneg", "fsneg", "fdneg", "fnop", "frem", "frestore", "fsave", "fscale", "fsgldiv",
"fsglmul", "fsin", "fsincos", "fsinh", "fsqrt", "fssqrt", "fdsqrt", "fsf", "fseq", "fsogt", "fsoge", "fsolt", "fsole", "fsogl", "fsor", "fsun", "fsueq",
"fsugt", "fsuge", "fsult", "fsule", "fsne", "fst", "fssf", "fsseq", "fsgt", "fsge", "fslt", "fsle", "fsgl", "fsgle", "fsngle",
"fsngl", "fsnle", "fsnlt", "fsnge", "fsngt", "fssne", "fsst", "fsub", "fssub", "fdsub", "ftan", "ftanh", "ftentox", "ftrapf", "ftrapeq", "ftrapogt",
"ftrapoge", "ftrapolt", "ftrapole", "ftrapogl", "ftrapor", "ftrapun", "ftrapueq", "ftrapugt", "ftrapuge", "ftrapult", "ftrapule", "ftrapne", "ftrapt",
"ftrapsf", "ftrapseq", "ftrapgt", "ftrapge", "ftraplt", "ftraple", "ftrapgl", "ftrapgle", "ftrapngle", "ftrapngl", "ftrapnle", "ftrapnlt", "ftrapnge",
"ftrapngt", "ftrapsne", "ftrapst", "ftst", "ftwotox", "halt", "illegal", "jmp", "jsr", "lea", "link", "lpstop", "lsl", "lsr", "move", "movea", "movec",
"movem", "movep", "moveq", "moves", "move16", "muls", "mulu", "nbcd", "neg", "negx", "nop", "not", "or", "ori", "pack", "pea", "pflush", "pflusha",
"pflushan", "pflushn", "ploadr", "ploadw", "plpar", "plpaw", "pmove", "pmovefd", "ptestr", "ptestw", "pulse", "rems", "remu", "reset", "rol", "ror",
"fsngl", "fsnle", "fsnlt", "fsnge", "fsngt", "fssne", "fsst", "fsub", "fssub", "fdsub", "ftan", "ftanh", "ftentox", "ftrapf", "ftrapeq", "ftrapogt",
"ftrapoge", "ftrapolt", "ftrapole", "ftrapogl", "ftrapor", "ftrapun", "ftrapueq", "ftrapugt", "ftrapuge", "ftrapult", "ftrapule", "ftrapne", "ftrapt",
"ftrapsf", "ftrapseq", "ftrapgt", "ftrapge", "ftraplt", "ftraple", "ftrapgl", "ftrapgle", "ftrapngle", "ftrapngl", "ftrapnle", "ftrapnlt", "ftrapnge",
"ftrapngt", "ftrapsne", "ftrapst", "ftst", "ftwotox", "halt", "illegal", "jmp", "jsr", "lea", "link", "lpstop", "lsl", "lsr", "move", "movea", "movec",
"movem", "movep", "moveq", "moves", "move16", "muls", "mulu", "nbcd", "neg", "negx", "nop", "not", "or", "ori", "pack", "pea", "pflush", "pflusha",
"pflushan", "pflushn", "ploadr", "ploadw", "plpar", "plpaw", "pmove", "pmovefd", "ptestr", "ptestw", "pulse", "rems", "remu", "reset", "rol", "ror",
"roxl", "roxr", "rtd", "rte", "rtm", "rtr", "rts", "sbcd", "st", "sf", "shi", "sls", "scc", "shs", "scs", "slo", "sne", "seq", "svc", "svs", "spl", "smi",
"sge", "slt", "sgt", "sle", "stop", "sub", "suba", "subi", "subq", "subx", "swap", "tas", "trap", "trapv", "trapt", "trapf", "traphi", "trapls",
"trapcc", "traphs", "trapcs", "traplo", "trapne", "trapeq", "trapvc", "trapvs", "trappl", "trapmi", "trapge", "traplt", "trapgt", "traple", "tst", "unlk", "unpk",
@ -100,7 +100,7 @@ static void printRegbitsRange(char* buffer, uint32_t data, const char* prefix)
static void registerBits(SStream* O, const cs_m68k_op* op)
{
char buffer[128];
unsigned int data = op->register_bits;
unsigned int data = op->register_bits;
buffer[0] = 0;
@ -113,7 +113,7 @@ static void registerBits(SStream* O, const cs_m68k_op* op)
static void registerPair(SStream* O, const cs_m68k_op* op)
{
SStream_concat(O, "%s:%s", s_reg_names[M68K_REG_D0 + (op->register_bits >> 4)],
SStream_concat(O, "%s:%s", s_reg_names[M68K_REG_D0 + (op->register_bits >> 4)],
s_reg_names[M68K_REG_D0 + (op->register_bits & 0xf)]);
}
@ -143,8 +143,8 @@ void printAddressingMode(SStream* O, const cs_m68k* inst, const cs_m68k_op* op)
case M68K_AM_REGI_ADDR_PRE_DEC: SStream_concat(O, "-(a%d)", (op->reg - M68K_REG_A0)); break;
case M68K_AM_REGI_ADDR_DISP: SStream_concat(O, "$%x(a%d)", op->mem.disp, (op->reg - M68K_REG_A0)); break;
case M68K_AM_PCI_DISP: SStream_concat(O, "$%x(pc)", op->mem.disp); break;
case M68K_AM_ABSOLUTE_DATA_SHORT: SStream_concat(O, "$%x.w", op->imm); break;
case M68K_AM_ABSOLUTE_DATA_LONG: SStream_concat(O, "$%x.l", op->imm); break;
case M68K_AM_ABSOLUTE_DATA_SHORT: SStream_concat(O, "$%x.w", op->imm); break;
case M68K_AM_ABSOLUTE_DATA_LONG: SStream_concat(O, "$%x.l", op->imm); break;
case M68K_AM_IMMIDIATE:
if (inst->op_size.type == M68K_SIZE_TYPE_FPU) {
if (inst->op_size.fpu_size == M68K_FPU_SIZE_SINGLE)
@ -161,7 +161,7 @@ void printAddressingMode(SStream* O, const cs_m68k* inst, const cs_m68k_op* op)
SStream_concat(O, "$%x(pc,%s%s.%c)", op->mem.disp, s_spacing, getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
break;
case M68K_AM_AREGI_INDEX_8_BIT_DISP:
SStream_concat(O, "$%x(%s,%s%s.%c)", op->mem.disp, getRegName(op->mem.base_reg), s_spacing, getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
SStream_concat(O, "$%x(%s,%s%s.%c)", op->mem.disp, getRegName(op->mem.base_reg), s_spacing, getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
break;
case M68K_AM_PCI_INDEX_BASE_DISP:
case M68K_AM_AREGI_INDEX_BASE_DISP:
@ -196,9 +196,9 @@ void printAddressingMode(SStream* O, const cs_m68k* inst, const cs_m68k_op* op)
if (op->mem.base_reg != M68K_REG_INVALID) {
if (op->mem.in_disp > 0)
SStream_concat(O, ",%s%s", s_spacing, getRegName(op->mem.base_reg));
SStream_concat(O, ",%s%s", s_spacing, getRegName(op->mem.base_reg));
else
SStream_concat(O, "%s", getRegName(op->mem.base_reg));
SStream_concat(O, "%s", getRegName(op->mem.base_reg));
}
if (op->address_mode == M68K_AM_MEMI_POST_INDEX || op->address_mode == M68K_AM_PC_MEMI_POST_INDEX)
@ -238,9 +238,10 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
detail = MI->flat_insn->detail;
if (detail) {
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;
detail->groups_count = 0;
}
if (MI->Opcode == M68K_INS_INVALID) {
@ -262,7 +263,7 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
case M68K_CPU_SIZE_BYTE: SStream_concat0(O, ".b"); break;
case M68K_CPU_SIZE_WORD: SStream_concat0(O, ".w"); break;
case M68K_CPU_SIZE_LONG: SStream_concat0(O, ".l"); break;
case M68K_CPU_SIZE_NONE: break;
case M68K_CPU_SIZE_NONE: break;
}
break;
@ -271,14 +272,14 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
case M68K_FPU_SIZE_SINGLE: SStream_concat0(O, ".s"); break;
case M68K_FPU_SIZE_DOUBLE: SStream_concat0(O, ".d"); break;
case M68K_FPU_SIZE_EXTENDED: SStream_concat0(O, ".x"); break;
case M68K_FPU_SIZE_NONE: break;
case M68K_FPU_SIZE_NONE: break;
}
break;
}
SStream_concat0(O, " ");
// this one is a bit spacial so we do spacial things
// this one is a bit spacial so we do special things
if (MI->Opcode == M68K_INS_CAS2) {
int reg_value_0, reg_value_1;
@ -286,7 +287,7 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
printAddressingMode(O, ext, &ext->operands[1]); SStream_concat0(O, ",");
reg_value_0 = ext->operands[2].register_bits >> 4;
reg_value_1 = ext->operands[2].register_bits & 0xf;
SStream_concat(O, "(%s):(%s)", s_reg_names[M68K_REG_D0 + reg_value_0], s_reg_names[M68K_REG_D0 + reg_value_1]);
SStream_concat(O, "(%s):(%s)", s_reg_names[M68K_REG_D0 + reg_value_0], s_reg_names[M68K_REG_D0 + reg_value_1]);
return;
}
@ -321,9 +322,21 @@ const char* M68K_insn_name(csh handle, unsigned int id)
#endif
}
const char* M68K_group_name(csh handle, unsigned int id)
#ifndef CAPSTONE_DIET
static name_map group_name_maps[] = {
{ M68K_GRP_INVALID , NULL },
{ M68K_GRP_JUMP, "jump" },
{ M68K_GRP_RET , "ret" },
{ M68K_GRP_IRET, "iret" },
};
#endif
const char *M68K_group_name(csh handle, unsigned int id)
{
// TODO: Implement group names in m68k
#ifndef CAPSTONE_DIET
return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
#else
return NULL;
#endif
}

View File

@ -2,7 +2,7 @@
#define CAPSTONE_M68K_H
/* Capstone Disassembly Engine */
/* By Daniel Collin <daniel@collin.com>, 2015 */
/* By Daniel Collin <daniel@collin.com>, 2015-2016 */
#ifdef __cplusplus
extern "C" {
@ -78,7 +78,7 @@ typedef enum m68k_reg {
//> M68K Addressing Modes
typedef enum m68k_adress_mode {
M68K_AM_NONE = 0, // No address mode.
M68K_AM_NONE = 0, // No address mode.
M68K_AM_REG_DIRECT_DATA, // Register Direct - Data
M68K_AM_REG_DIRECT_ADDR, // Register Direct - Address
@ -105,7 +105,7 @@ typedef enum m68k_adress_mode {
M68K_AM_ABSOLUTE_DATA_SHORT, // Absolute Data Addressing - Short
M68K_AM_ABSOLUTE_DATA_LONG, // Absolute Data Addressing - Long
M68K_AM_IMMIDIATE, // Immidate value
} m68k_adress_mode;
} m68k_adress_mode;
//> Operand type for instruction's operands
typedef enum m68k_op_type {
@ -115,7 +115,7 @@ typedef enum m68k_op_type {
M68K_OP_MEM, // = CS_OP_MEM (Memory operand).
M68K_OP_FP, // = CS_OP_FP (Floating-Point operand)
M68K_OP_REG_BITS, // Registes bits movem
M68K_OP_REG_PAIR, // Register pair in the same op (upper 4 bits for first reg, lower for second)
M68K_OP_REG_PAIR, // Register pair in the same op (upper 4 bits for first reg, lower for second)
} m68k_op_type;
// Instruction's operand referring to memory
@ -124,12 +124,12 @@ typedef struct m68k_op_mem {
m68k_reg base_reg; // base register (or M68K_REG_INVALID if irrelevant)
m68k_reg index_reg; // index register (or M68K_REG_INVALID if irrelevant)
m68k_reg in_base_reg; // indirect base register (or M68K_REG_INVALID if irrelevant)
uint32_t in_disp; // indirect displacement
uint32_t out_disp; // outher displacement
uint32_t in_disp; // indirect displacement
uint32_t out_disp; // outher displacement
uint16_t disp; // displacement value
uint8_t scale; // scale for index register
uint8_t bitfield; // set to true if the two values bellow should be used
uint8_t width; // used for bf* instructions
uint8_t bitfield; // set to true if the two values bellow should be used
uint8_t width; // used for bf* instructions
uint8_t offset; // used for bf* instructions
uint8_t index_size; // 0 = w, 1 = l
} m68k_op_mem;
@ -145,10 +145,10 @@ typedef struct cs_m68k_op {
uint32_t register_bits; // register bits for movem/cas2/etc (always in d0-d7, a0-a7, fp0 - fp7 order)
};
m68k_op_type type;
m68k_adress_mode address_mode; // M68K addressing mode for this op
m68k_adress_mode address_mode; // M68K addressing mode for this op
} cs_m68k_op;
// Operation size of the CPU instructions
// Operation size of the CPU instructions
typedef enum m68k_cpu_size {
M68K_CPU_SIZE_NONE = 0, // unsized or unspecified
M68K_CPU_SIZE_BYTE = 1, // 1 byte in size
@ -159,8 +159,8 @@ typedef enum m68k_cpu_size {
// Operation size of the FPU instructions (Notice that FPU instruction can also use CPU sizes if needed)
typedef enum m68k_fpu_size {
M68K_FPU_SIZE_NONE = 0, // unsized like fsave/frestore
M68K_FPU_SIZE_SINGLE = 4, // 4 byte in size (single float)
M68K_FPU_SIZE_DOUBLE = 8, // 8 byte in size (double)
M68K_FPU_SIZE_SINGLE = 4, // 4 byte in size (single float)
M68K_FPU_SIZE_DOUBLE = 8, // 8 byte in size (double)
M68K_FPU_SIZE_EXTENDED = 12, // 12 byte in size (extended real format)
} m68k_fpu_size;
@ -569,6 +569,16 @@ typedef enum m68k_insn {
M68K_INS_UNPK,
} m68k_insn;
//> Group of M68K instructions
typedef enum m68k_group_type {
M68K_GRP_INVALID = 0, // CS_GRUP_INVALID
M68K_GRP_JUMP, // = CS_GRP_JUMP
M68K_GRP_RET = 3, // = CS_GRP_RET
M68K_GRP_IRET, // = CS_GRP_IRET
M68K_GRP_ENDING,
} m68k_group_type;
#ifdef __cplusplus
}
#endif

View File

@ -56,21 +56,25 @@ const char* s_addressing_modes[] = {
"Absolute Data Addressing - Short",
"Absolute Data Addressing - Long",
"Immidate value",
};
};
static void print_insn_detail(cs_insn *ins)
{
cs_m68k* m68k;
cs_detail* detail;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
m68k = &(ins->detail->m68k);
detail = ins->detail;
m68k = &detail->m68k;
if (m68k->op_count)
printf("\top_count: %u\n", m68k->op_count);
printf("\tgroups_count: %u\n", detail->groups_count);
for (i = 0; i < m68k->op_count; i++) {
cs_m68k_op* op = &(m68k->operands[i]);
@ -121,7 +125,7 @@ static void print_insn_detail(cs_insn *ins)
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"
#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"
struct platform platforms[] = {
{