aboutsummaryrefslogtreecommitdiff
path: root/opcodes/mips-dis.c
diff options
context:
space:
mode:
Diffstat (limited to 'opcodes/mips-dis.c')
-rw-r--r--opcodes/mips-dis.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index a11e1c0..feb9d94 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -155,10 +155,9 @@ print_insn_arg (d, l, pc, info)
break;
case 'a':
- (*info->print_address_func)
- ((((pc + 4) & ~(bfd_vma) 0x0fffffff)
- | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
- info);
+ info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
+ | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
+ (*info->print_address_func) (info->target, info);
break;
case 'p':
@@ -166,9 +165,8 @@ print_insn_arg (d, l, pc, info)
delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
if (delta & 0x8000)
delta |= ~0xffff;
- (*info->print_address_func)
- ((delta << 2) + pc + INSNLEN,
- info);
+ info->target = (delta << 2) + pc + INSNLEN;
+ (*info->print_address_func) (info->target, info);
break;
case 'd':
@@ -457,6 +455,12 @@ print_insn_mips (memaddr, word, info)
info->bytes_per_chunk = INSNLEN;
info->display_endian = info->endian;
+ info->insn_info_valid = 1;
+ info->branch_delay_insns = 0;
+ info->data_size = 0;
+ info->insn_type = dis_nonbranch;
+ info->target = 0;
+ info->target2 = 0;
op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
if (op != NULL)
@@ -470,6 +474,28 @@ print_insn_mips (memaddr, word, info)
if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor))
continue;
+ /* Figure out instruction type and branch delay information. */
+ if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
+ {
+ if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
+ info->insn_type = dis_jsr;
+ else
+ info->insn_type = dis_branch;
+ info->branch_delay_insns = 1;
+ }
+ else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
+ | INSN_COND_BRANCH_LIKELY)) != 0)
+ {
+ if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
+ info->insn_type = dis_condjsr;
+ else
+ info->insn_type = dis_condbranch;
+ info->branch_delay_insns = 1;
+ }
+ else if ((op->pinfo & (INSN_STORE_MEMORY
+ | INSN_LOAD_MEMORY_DELAY)) != 0)
+ info->insn_type = dis_dref;
+
(*info->fprintf_func) (info->stream, "%s", op->name);
d = op->args;
@@ -486,6 +512,7 @@ print_insn_mips (memaddr, word, info)
}
/* Handle undefined instructions. */
+ info->insn_type = dis_noninsn;
(*info->fprintf_func) (info->stream, "0x%x", word);
return INSNLEN;
}
@@ -1006,7 +1033,6 @@ print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
else
{
bfd_vma baseaddr;
- bfd_vma val;
if (branch)
{
@@ -1049,9 +1075,8 @@ print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
baseaddr = memaddr - 2;
}
}
- val = (baseaddr & ~((1 << shift) - 1)) + immed;
- (*info->print_address_func) (val, info);
- info->target = val;
+ info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
+ (*info->print_address_func) (info->target, info);
}
}
break;
@@ -1060,9 +1085,9 @@ print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
if (! use_extend)
extend = 0;
l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
- (*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info);
+ info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
+ (*info->print_address_func) (info->target, info);
info->insn_type = dis_jsr;
- info->target = ((memaddr + 4) & 0xf0000000) | l;
info->branch_delay_insns = 1;
break;