[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:
parent
3eae96de19
commit
d994c74b02
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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[] = {
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue