M68K: Branch targets are a separate addressing mode; PC relative displacements printed as target addresses (#1068)
* Branch targets are a separate addressing mode Branch targets are relative displacements that identify code locations. These are neither .w nor .l nor immediates. This change removes the immediate #s before branch target addresses in disassembly, and represents the actual branch instructions more accurately in the cs_m68k_op datastructure. M68K Python bindings have also been updated. * m68k_inst.pc handles better; print target for PC relative offsets Previous changes to branch operations relied on m68k_inst.pc pointing to (start of instruction + 2). This was not the case - it pointed to the end of the current instruction. This change makes it so that m68k_inst.pc points to (start of instruction), which is simple to work with. It also changes printing of PC relative offsets to print the absolute target address, which is consistent with how most 68000 assemblers & disassemblers behave.
This commit is contained in:
parent
775a1d9825
commit
9944bfde76
|
@ -759,7 +759,23 @@ static void build_imm_special_reg(m68k_info *info, int opcode, int imm, int size
|
|||
op1->reg = reg;
|
||||
}
|
||||
|
||||
static void build_bxx(m68k_info *info, int opcode, int size, int jump_offset)
|
||||
static void build_relative_branch(m68k_info *info, int opcode, int size, int displacement)
|
||||
{
|
||||
cs_m68k_op* op;
|
||||
cs_m68k* ext = build_init_op(info, opcode, 1, size);
|
||||
|
||||
op = &ext->operands[0];
|
||||
|
||||
op->type = M68K_OP_BR_DISP;
|
||||
op->address_mode = M68K_AM_BRANCH_DISPLACEMENT;
|
||||
op->br_disp.disp = displacement;
|
||||
op->br_disp.disp_size = size;
|
||||
|
||||
set_insn_group(info, M68K_GRP_JUMP);
|
||||
set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
|
||||
}
|
||||
|
||||
static void build_absolute_jump_with_immediate(m68k_info *info, int opcode, int size, int immediate)
|
||||
{
|
||||
cs_m68k_op* op;
|
||||
cs_m68k* ext = build_init_op(info, opcode, 1, size);
|
||||
|
@ -768,23 +784,22 @@ static void build_bxx(m68k_info *info, int opcode, int size, int jump_offset)
|
|||
|
||||
op->type = M68K_OP_IMM;
|
||||
op->address_mode = M68K_AM_IMMEDIATE;
|
||||
op->imm = jump_offset;
|
||||
op->imm = immediate;
|
||||
|
||||
set_insn_group(info, M68K_GRP_JUMP);
|
||||
set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
|
||||
}
|
||||
|
||||
static void build_bcc(m68k_info *info, int size, int jump_offset)
|
||||
static void build_bcc(m68k_info *info, int size, int displacement)
|
||||
{
|
||||
build_bxx(info, s_branch_lut[(info->ir >> 8) & 0xf], size, jump_offset);
|
||||
build_relative_branch(info, s_branch_lut[(info->ir >> 8) & 0xf], size, displacement);
|
||||
}
|
||||
|
||||
static void build_trap(m68k_info *info, int size, int jump_offset)
|
||||
static void build_trap(m68k_info *info, int size, int immediate)
|
||||
{
|
||||
build_bxx(info, s_trap_lut[(info->ir >> 8) & 0xf], size, jump_offset);
|
||||
build_absolute_jump_with_immediate(info, s_trap_lut[(info->ir >> 8) & 0xf], size, immediate);
|
||||
}
|
||||
|
||||
static void build_dbxx(m68k_info *info, int opcode, int size, int jump_offset)
|
||||
static void build_dbxx(m68k_info *info, int opcode, int size, int displacement)
|
||||
{
|
||||
cs_m68k_op* op0;
|
||||
cs_m68k_op* op1;
|
||||
|
@ -796,17 +811,18 @@ static void build_dbxx(m68k_info *info, int opcode, int size, int jump_offset)
|
|||
op0->address_mode = M68K_AM_REG_DIRECT_DATA;
|
||||
op0->reg = M68K_REG_D0 + (info->ir & 7);
|
||||
|
||||
op1->type = M68K_OP_IMM;
|
||||
op1->address_mode = M68K_AM_IMMEDIATE;
|
||||
op1->imm = jump_offset;
|
||||
op1->type = M68K_OP_BR_DISP;
|
||||
op1->address_mode = M68K_AM_BRANCH_DISPLACEMENT;
|
||||
op1->br_disp.disp = displacement;
|
||||
op1->br_disp.disp_size = M68K_OP_BR_DISP_SIZE_LONG;
|
||||
|
||||
set_insn_group(info, M68K_GRP_JUMP);
|
||||
set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
|
||||
}
|
||||
|
||||
static void build_dbcc(m68k_info *info, int size, int jump_offset)
|
||||
static void build_dbcc(m68k_info *info, int size, int displacement)
|
||||
{
|
||||
build_dbxx(info, s_dbcc_lut[(info->ir >> 8) & 0xf], size, jump_offset);
|
||||
build_dbxx(info, s_dbcc_lut[(info->ir >> 8) & 0xf], size, displacement);
|
||||
}
|
||||
|
||||
static void build_d_d_ea(m68k_info *info, int opcode, int size)
|
||||
|
@ -1456,21 +1472,18 @@ static void d68000_asl_ea(m68k_info *info)
|
|||
|
||||
static void d68000_bcc_8(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
build_bcc(info, 1, temp_pc + make_int_8(info->ir));
|
||||
build_bcc(info, 1, make_int_8(info->ir));
|
||||
}
|
||||
|
||||
static void d68000_bcc_16(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
build_bcc(info, 2, temp_pc + make_int_16(read_imm_16(info)));
|
||||
build_bcc(info, 2, make_int_16(read_imm_16(info)));
|
||||
}
|
||||
|
||||
static void d68020_bcc_32(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
LIMIT_CPU_TYPES(info, M68020_PLUS);
|
||||
build_bcc(info, 4, temp_pc + read_imm_32(info));
|
||||
build_bcc(info, 4, read_imm_32(info));
|
||||
}
|
||||
|
||||
static void d68000_bchg_r(m68k_info *info)
|
||||
|
@ -1496,7 +1509,7 @@ static void d68000_bclr_s(m68k_info *info)
|
|||
static void d68010_bkpt(m68k_info *info)
|
||||
{
|
||||
LIMIT_CPU_TYPES(info, M68010_PLUS);
|
||||
build_bxx(info, M68K_INS_BKPT, 0, info->ir & 7);
|
||||
build_absolute_jump_with_immediate(info, M68K_INS_BKPT, 0, info->ir & 7);
|
||||
}
|
||||
|
||||
static void d68020_bfchg(m68k_info *info)
|
||||
|
@ -1558,21 +1571,18 @@ static void d68020_bftst(m68k_info *info)
|
|||
|
||||
static void d68000_bra_8(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
build_bxx(info, M68K_INS_BRA, 1, temp_pc + make_int_8(info->ir));
|
||||
build_relative_branch(info, M68K_INS_BRA, 1, make_int_8(info->ir));
|
||||
}
|
||||
|
||||
static void d68000_bra_16(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
build_bxx(info, M68K_INS_BRA, 2, temp_pc + make_int_16(read_imm_16(info)));
|
||||
build_relative_branch(info, M68K_INS_BRA, 2, make_int_16(read_imm_16(info)));
|
||||
}
|
||||
|
||||
static void d68020_bra_32(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
LIMIT_CPU_TYPES(info, M68020_PLUS);
|
||||
build_bxx(info, M68K_INS_BRA, 4, temp_pc + read_imm_32(info));
|
||||
build_relative_branch(info, M68K_INS_BRA, 4, read_imm_32(info));
|
||||
}
|
||||
|
||||
static void d68000_bset_r(m68k_info *info)
|
||||
|
@ -1587,21 +1597,18 @@ static void d68000_bset_s(m68k_info *info)
|
|||
|
||||
static void d68000_bsr_8(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
build_bxx(info, M68K_INS_BSR, 1, temp_pc + make_int_8(info->ir));
|
||||
build_relative_branch(info, M68K_INS_BSR, 1, make_int_8(info->ir));
|
||||
}
|
||||
|
||||
static void d68000_bsr_16(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
build_bxx(info, M68K_INS_BSR, 2, temp_pc + make_int_16(read_imm_16(info)));
|
||||
build_relative_branch(info, M68K_INS_BSR, 2, make_int_16(read_imm_16(info)));
|
||||
}
|
||||
|
||||
static void d68020_bsr_32(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
LIMIT_CPU_TYPES(info, M68020_PLUS);
|
||||
build_bxx(info, M68K_INS_BSR, 4, temp_pc + peek_imm_32(info));
|
||||
build_relative_branch(info, M68K_INS_BSR, 4, peek_imm_32(info));
|
||||
}
|
||||
|
||||
static void d68000_btst_r(m68k_info *info)
|
||||
|
@ -1789,26 +1796,29 @@ static void d68000_cmpm_32(m68k_info *info)
|
|||
build_pi_pi(info, M68K_INS_CMPM, 4);
|
||||
}
|
||||
|
||||
static void make_cpbcc_operand(cs_m68k_op* op, int size, int displacement)
|
||||
{
|
||||
op->address_mode = M68K_AM_BRANCH_DISPLACEMENT;
|
||||
op->type = M68K_OP_BR_DISP;
|
||||
op->br_disp.disp = displacement;
|
||||
op->br_disp.disp_size = size;
|
||||
}
|
||||
|
||||
static void d68020_cpbcc_16(m68k_info *info)
|
||||
{
|
||||
cs_m68k_op* op0;
|
||||
cs_m68k* ext;
|
||||
uint new_pc;
|
||||
LIMIT_CPU_TYPES(info, M68020_PLUS);
|
||||
|
||||
new_pc = info->pc;
|
||||
new_pc += make_int_16(read_imm_16(info));
|
||||
|
||||
// these are all in row with the extension so just doing a add here is fine
|
||||
info->inst->Opcode += (info->ir & 0x2f);
|
||||
|
||||
ext = build_init_op(info, M68K_INS_FBF, 1, 2);
|
||||
op0 = &ext->operands[0];
|
||||
|
||||
op0->address_mode = M68K_AM_IMMEDIATE;
|
||||
op0->type = M68K_OP_IMM;
|
||||
op0->imm = new_pc;
|
||||
|
||||
make_cpbcc_operand(op0, M68K_OP_BR_DISP_SIZE_WORD, make_int_16(read_imm_16(info)));
|
||||
|
||||
set_insn_group(info, M68K_GRP_JUMP);
|
||||
set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
|
||||
}
|
||||
|
||||
|
@ -1816,25 +1826,20 @@ static void d68020_cpbcc_32(m68k_info *info)
|
|||
{
|
||||
cs_m68k* ext;
|
||||
cs_m68k_op* op0;
|
||||
uint new_pc;
|
||||
|
||||
LIMIT_CPU_TYPES(info, M68020_PLUS);
|
||||
|
||||
LIMIT_CPU_TYPES(info, M68020_PLUS);
|
||||
|
||||
new_pc = info->pc;
|
||||
new_pc += read_imm_32(info);
|
||||
|
||||
// these are all in row with the extension so just doing a add here is fine
|
||||
info->inst->Opcode += (info->ir & 0x2f);
|
||||
|
||||
ext = build_init_op(info, M68K_INS_FBF, 1, 4);
|
||||
op0 = &ext->operands[0];
|
||||
|
||||
op0->type = M68K_OP_IMM;
|
||||
op0->address_mode = M68K_AM_IMMEDIATE;
|
||||
op0->imm = new_pc;
|
||||
make_cpbcc_operand(op0, M68K_OP_BR_DISP_SIZE_LONG, read_imm_32(info));
|
||||
|
||||
set_insn_group(info, M68K_GRP_JUMP);
|
||||
set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
|
||||
}
|
||||
|
||||
|
@ -1843,15 +1848,12 @@ static void d68020_cpdbcc(m68k_info *info)
|
|||
cs_m68k* ext;
|
||||
cs_m68k_op* op0;
|
||||
cs_m68k_op* op1;
|
||||
uint new_pc, ext1, ext2;
|
||||
uint ext1, ext2;
|
||||
|
||||
LIMIT_CPU_TYPES(info, M68020_PLUS);
|
||||
|
||||
new_pc = info->pc;
|
||||
ext1 = read_imm_16(info);
|
||||
ext2 = read_imm_16(info);
|
||||
new_pc += make_int_16(ext2) + 2;
|
||||
|
||||
|
||||
// these are all in row with the extension so just doing a add here is fine
|
||||
info->inst->Opcode += (ext1 & 0x2f);
|
||||
|
@ -1862,10 +1864,9 @@ static void d68020_cpdbcc(m68k_info *info)
|
|||
|
||||
op0->reg = M68K_REG_D0 + (info->ir & 7);
|
||||
|
||||
op1->address_mode = M68K_AM_IMMEDIATE;
|
||||
op1->type = M68K_OP_IMM;
|
||||
op1->imm = new_pc;
|
||||
make_cpbcc_operand(op1, M68K_OP_BR_DISP_SIZE_WORD, make_int_16(ext2) + 2);
|
||||
|
||||
set_insn_group(info, M68K_GRP_JUMP);
|
||||
set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
|
||||
}
|
||||
|
||||
|
@ -2212,14 +2213,12 @@ static void d68040_cpush(m68k_info *info)
|
|||
|
||||
static void d68000_dbra(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
build_dbxx(info, M68K_INS_DBRA, 0, temp_pc + make_int_16(read_imm_16(info)));
|
||||
build_dbxx(info, M68K_INS_DBRA, 0, make_int_16(read_imm_16(info)));
|
||||
}
|
||||
|
||||
static void d68000_dbcc(m68k_info *info)
|
||||
{
|
||||
uint temp_pc = info->pc;
|
||||
build_dbcc(info, 0, temp_pc + make_int_16(read_imm_16(info)));
|
||||
build_dbcc(info, 0, make_int_16(read_imm_16(info)));
|
||||
}
|
||||
|
||||
static void d68000_divs(m68k_info *info)
|
||||
|
@ -3091,7 +3090,7 @@ 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));
|
||||
build_absolute_jump_with_immediate(info, M68K_INS_RTD, 0, read_imm_16(info));
|
||||
}
|
||||
|
||||
static void d68000_rte(m68k_info *info)
|
||||
|
@ -3109,7 +3108,7 @@ static void d68020_rtm(m68k_info *info)
|
|||
|
||||
LIMIT_CPU_TYPES(info, M68020_ONLY);
|
||||
|
||||
build_bxx(info, M68K_INS_RTM, 0, 0);
|
||||
build_absolute_jump_with_immediate(info, M68K_INS_RTM, 0, 0);
|
||||
|
||||
ext = &info->extension;
|
||||
op = &ext->operands[0];
|
||||
|
@ -3154,7 +3153,7 @@ static void d68000_scc(m68k_info *info)
|
|||
|
||||
static void d68000_stop(m68k_info *info)
|
||||
{
|
||||
build_bxx(info, M68K_INS_STOP, 0, read_imm_16(info));
|
||||
build_absolute_jump_with_immediate(info, M68K_INS_STOP, 0, read_imm_16(info));
|
||||
}
|
||||
|
||||
static void d68000_sub_er_8(m68k_info *info)
|
||||
|
@ -3269,7 +3268,7 @@ static void d68000_tas(m68k_info *info)
|
|||
|
||||
static void d68000_trap(m68k_info *info)
|
||||
{
|
||||
build_bxx(info, M68K_INS_TRAP, 0, info->ir&0xf);
|
||||
build_absolute_jump_with_immediate(info, M68K_INS_TRAP, 0, info->ir&0xf);
|
||||
}
|
||||
|
||||
static void d68020_trapcc_0(m68k_info *info)
|
||||
|
@ -4019,6 +4018,7 @@ static unsigned int m68k_disassemble(m68k_info *info, uint64_t pc)
|
|||
MCInst *inst = info->inst;
|
||||
cs_m68k* ext = &info->extension;
|
||||
int i;
|
||||
unsigned int size;
|
||||
|
||||
inst->Opcode = M68K_INS_INVALID;
|
||||
|
||||
|
@ -4036,7 +4036,10 @@ static unsigned int m68k_disassemble(m68k_info *info, uint64_t pc)
|
|||
g_instruction_table[info->ir].instruction(info);
|
||||
}
|
||||
|
||||
return info->pc - (unsigned int)pc;
|
||||
size = info->pc - (unsigned int)pc;
|
||||
info->pc = (unsigned int)pc;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* instr, uint16_t* size, uint64_t address, void* inst_info)
|
||||
|
|
|
@ -121,7 +121,7 @@ static void registerPair(SStream* O, const cs_m68k_op* op)
|
|||
s_reg_names[M68K_REG_D0 + op->reg_pair.reg_1]);
|
||||
}
|
||||
|
||||
void printAddressingMode(SStream* O, const cs_m68k* inst, const cs_m68k_op* op)
|
||||
void printAddressingMode(SStream* O, unsigned int pc, const cs_m68k* inst, const cs_m68k_op* op)
|
||||
{
|
||||
switch (op->address_mode) {
|
||||
case M68K_AM_NONE:
|
||||
|
@ -146,7 +146,7 @@ void printAddressingMode(SStream* O, const cs_m68k* inst, const cs_m68k_op* op)
|
|||
case M68K_AM_REGI_ADDR_POST_INC: SStream_concat(O, "(a%d)+", (op->reg - M68K_REG_A0)); break;
|
||||
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, "%s$%x(a%d)", op->mem.disp < 0 ? "-" : "", abs(op->mem.disp), (op->mem.base_reg - M68K_REG_A0)); break;
|
||||
case M68K_AM_PCI_DISP: SStream_concat(O, "%s$%x(pc)", op->mem.disp < 0 ? "-" : "", abs(op->mem.disp)); break;
|
||||
case M68K_AM_PCI_DISP: SStream_concat(O, "$%x(pc)", pc + 2 + 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_IMMEDIATE:
|
||||
|
@ -168,15 +168,21 @@ void printAddressingMode(SStream* O, const cs_m68k* inst, const cs_m68k_op* op)
|
|||
SStream_concat(O, "#$%x", op->imm);
|
||||
break;
|
||||
case M68K_AM_PCI_INDEX_8_BIT_DISP:
|
||||
SStream_concat(O, "%s$%x(pc,%s%s.%c)", op->mem.disp < 0 ? "-" : "", abs(op->mem.disp), s_spacing, getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
|
||||
SStream_concat(O, "$%x(pc,%s%s.%c)", pc + 2 + 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, "%s$%x(%s,%s%s.%c)", op->mem.disp < 0 ? "-" : "", abs(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:
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, "$%x", op->mem.in_disp);
|
||||
|
||||
if (op->address_mode == M68K_AM_PCI_INDEX_BASE_DISP) {
|
||||
SStream_concat(O, "$%x", pc + 2 + op->mem.in_disp);
|
||||
}
|
||||
else {
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, "$%x", op->mem.in_disp);
|
||||
}
|
||||
|
||||
SStream_concat(O, "(");
|
||||
|
||||
|
@ -201,8 +207,13 @@ void printAddressingMode(SStream* O, const cs_m68k* inst, const cs_m68k_op* op)
|
|||
case M68K_AM_MEMI_PRE_INDEX:
|
||||
case M68K_AM_MEMI_POST_INDEX:
|
||||
SStream_concat(O, "([");
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, "$%x", op->mem.in_disp);
|
||||
|
||||
if (op->address_mode == M68K_AM_PC_MEMI_POST_INDEX || op->address_mode == M68K_AM_PC_MEMI_PRE_INDEX) {
|
||||
SStream_concat(O, "$%x", pc + 2 + op->mem.in_disp);
|
||||
} else {
|
||||
if (op->mem.in_disp > 0)
|
||||
SStream_concat(O, "$%x", op->mem.in_disp);
|
||||
}
|
||||
|
||||
if (op->mem.base_reg != M68K_REG_INVALID) {
|
||||
if (op->mem.in_disp > 0)
|
||||
|
@ -228,6 +239,8 @@ void printAddressingMode(SStream* O, const cs_m68k* inst, const cs_m68k_op* op)
|
|||
|
||||
SStream_concat(O, ")");
|
||||
break;
|
||||
case M68K_AM_BRANCH_DISPLACEMENT:
|
||||
SStream_concat(O, "$%x", pc + 2 + op->br_disp.disp);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -305,8 +318,8 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
|||
|
||||
if (MI->Opcode == M68K_INS_CAS2) {
|
||||
int reg_value_0, reg_value_1;
|
||||
printAddressingMode(O, ext, &ext->operands[0]); SStream_concat0(O, ",");
|
||||
printAddressingMode(O, ext, &ext->operands[1]); SStream_concat0(O, ",");
|
||||
printAddressingMode(O, info->pc, ext, &ext->operands[0]); SStream_concat0(O, ",");
|
||||
printAddressingMode(O, info->pc, 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]);
|
||||
|
@ -314,7 +327,7 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)
|
|||
}
|
||||
|
||||
for (i = 0; i < ext->op_count; ++i) {
|
||||
printAddressingMode(O, ext, &ext->operands[i]);
|
||||
printAddressingMode(O, info->pc, ext, &ext->operands[i]);
|
||||
if ((i + 1) != ext->op_count)
|
||||
SStream_concat(O, ",%s", s_spacing);
|
||||
}
|
||||
|
|
|
@ -35,10 +35,17 @@ class M68KOpValue(ctypes.Union):
|
|||
('reg_pair', M68KOpRegPair),
|
||||
)
|
||||
|
||||
class M68KOpBrDisp(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('disp', ctypes.c_int),
|
||||
('disp_size', ctypes.c_ubyte),
|
||||
)
|
||||
|
||||
class M68KOp(ctypes.Structure):
|
||||
_fields_ = (
|
||||
('value', M68KOpValue),
|
||||
('mem', M68KOpMem),
|
||||
('br_disp', M68KOpBrDisp),
|
||||
('register_bits', ctypes.c_uint),
|
||||
('type', ctypes.c_uint),
|
||||
('address_mode', ctypes.c_uint),
|
||||
|
|
|
@ -73,6 +73,7 @@ M68K_AM_PC_MEMI_PRE_INDEX = 15
|
|||
M68K_AM_ABSOLUTE_DATA_SHORT = 16
|
||||
M68K_AM_ABSOLUTE_DATA_LONG = 17
|
||||
M68K_AM_IMMEDIATE = 18
|
||||
M68K_AM_BRANCH_DISPLACEMENT = 19
|
||||
|
||||
# Operand type for instruction's operands
|
||||
|
||||
|
@ -84,6 +85,14 @@ M68K_OP_FP_SINGLE = 4
|
|||
M68K_OP_FP_DOUBLE = 5
|
||||
M68K_OP_REG_BITS = 6
|
||||
M68K_OP_REG_PAIR = 7
|
||||
M68K_OP_BR_DISP = 8
|
||||
|
||||
# Operand type for instruction's operands
|
||||
|
||||
M68K_OP_BR_DISP_SIZE_INVALID = 0
|
||||
M68K_OP_BR_DISP_SIZE_BYTE = 1
|
||||
M68K_OP_BR_DISP_SIZE_WORD = 2
|
||||
M68K_OP_BR_DISP_SIZE_LONG = 4
|
||||
|
||||
M68K_CPU_SIZE_NONE = 0
|
||||
M68K_CPU_SIZE_BYTE = 1
|
||||
|
|
|
@ -40,6 +40,8 @@ s_addressing_modes = {
|
|||
16: "Absolute Data Addressing - Short",
|
||||
17: "Absolute Data Addressing - Long",
|
||||
18: "Immediate value",
|
||||
|
||||
19: "Branch Displacement",
|
||||
}
|
||||
|
||||
def print_read_write_regs(insn):
|
||||
|
@ -82,6 +84,9 @@ def print_insn_detail(insn):
|
|||
elif op.type == M68K_OP_FP_DOUBLE:
|
||||
print("\t\toperands[%u].type: FP_DOUBLE" % i)
|
||||
print("\t\toperands[%u].dimm: %lf", i, op.dimm)
|
||||
elif op.type == M68K_OP_BR_DISP:
|
||||
print("\t\toperands[%u].br_disp.disp: 0x%x" % (i, op.br_disp.disp))
|
||||
print("\t\toperands[%u].br_disp.disp_size: %d" % (i, op.br_disp.disp_size))
|
||||
print()
|
||||
|
||||
# ## Test class Cs
|
||||
|
|
|
@ -104,6 +104,9 @@ typedef enum m68k_address_mode {
|
|||
M68K_AM_ABSOLUTE_DATA_SHORT, // Absolute Data Addressing - Short
|
||||
M68K_AM_ABSOLUTE_DATA_LONG, // Absolute Data Addressing - Long
|
||||
M68K_AM_IMMEDIATE, // Immediate value
|
||||
|
||||
M68K_AM_BRANCH_DISPLACEMENT, // Address as displacement from (PC+2) used by branches
|
||||
|
||||
} m68k_address_mode;
|
||||
|
||||
//> Operand type for instruction's operands
|
||||
|
@ -116,6 +119,7 @@ typedef enum m68k_op_type {
|
|||
M68K_OP_FP_DOUBLE, // double precision Floating-Point operand
|
||||
M68K_OP_REG_BITS, // Register bits move
|
||||
M68K_OP_REG_PAIR, // Register pair in the same op (upper 4 bits for first reg, lower for second)
|
||||
M68K_OP_BR_DISP, // Branch displacement
|
||||
} m68k_op_type;
|
||||
|
||||
// Instruction's operand referring to memory
|
||||
|
@ -134,6 +138,19 @@ typedef struct m68k_op_mem {
|
|||
uint8_t index_size; // 0 = w, 1 = l
|
||||
} m68k_op_mem;
|
||||
|
||||
//> Operand type for instruction's operands
|
||||
typedef enum m68k_op_br_disp_size {
|
||||
M68K_OP_BR_DISP_SIZE_INVALID = 0, // = CS_OP_INVALID (Uninitialized).
|
||||
M68K_OP_BR_DISP_SIZE_BYTE = 1, // signed 8-bit displacement
|
||||
M68K_OP_BR_DISP_SIZE_WORD = 2, // signed 16-bit displacement
|
||||
M68K_OP_BR_DISP_SIZE_LONG = 4, // signed 32-bit displacement
|
||||
} m68k_op_br_disp_size;
|
||||
|
||||
typedef struct m68k_op_br_disp {
|
||||
int32_t disp; // displacement value
|
||||
uint8_t disp_size; // Size from m68k_op_br_disp_size type above
|
||||
} m68k_op_br_disp;
|
||||
|
||||
// Instruction operand
|
||||
typedef struct cs_m68k_op {
|
||||
union {
|
||||
|
@ -148,6 +165,7 @@ typedef struct cs_m68k_op {
|
|||
};
|
||||
|
||||
m68k_op_mem mem; // data when operand is targeting memory
|
||||
m68k_op_br_disp br_disp; // data when operand is a branch displacement
|
||||
uint32_t register_bits; // register bits for movem etc. (always in d0-d7, a0-a7, fp0 - fp7 order)
|
||||
m68k_op_type type;
|
||||
m68k_address_mode address_mode; // M68K addressing mode for this op
|
||||
|
|
Loading…
Reference in New Issue