/* Print mips instructions for GDB, the GNU debugger, or for objdump.
Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2005, 2007, 2008
+ 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
page 1. */
{ "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
- ISA_MIPS32 | INSN_MIPS16 | INSN_SMARTMIPS,
+ ISA_MIPS32 | INSN_SMARTMIPS,
mips_cp0_names_mips3264,
mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
mips_hwr_names_numeric },
{ "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
- (ISA_MIPS32R2 | INSN_MIPS16 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
+ (ISA_MIPS32R2 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
| INSN_MIPS3D | INSN_MT),
mips_cp0_names_mips3264r2,
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
/* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
{ "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
- ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX,
+ ISA_MIPS64 | INSN_MIPS3D | INSN_MDMX,
mips_cp0_names_mips3264,
mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
mips_hwr_names_numeric },
{ "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
- (ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
+ (ISA_MIPS64R2 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
| INSN_DSP64 | INSN_MT | INSN_MDMX),
mips_cp0_names_mips3264r2,
mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
ISA_MIPS3 | INSN_LOONGSON_2F, mips_cp0_names_numeric,
NULL, 0, mips_hwr_names_numeric },
+ { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
+ ISA_MIPS64 | INSN_LOONGSON_3A, mips_cp0_names_numeric,
+ NULL, 0, mips_hwr_names_numeric },
+
{ "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
ISA_MIPS64R2 | INSN_OCTEON, mips_cp0_names_numeric, NULL, 0,
mips_hwr_names_numeric },
/* This entry, mips16, is here only for ISA/processor selection; do
not print its name. */
- { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3 | INSN_MIPS16,
+ { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3,
mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
};
(*info->fprintf_func) (info->stream, "%d", op);
break;
+ case 'a': /* 8-bit signed offset in bit 6 */
+ delta = (l >> OP_SH_OFFSET_A) & OP_MASK_OFFSET_A;
+ if (delta & 0x80)
+ delta |= ~OP_MASK_OFFSET_A;
+ (*info->fprintf_func) (info->stream, "%d", delta);
+ break;
+
+ case 'b': /* 8-bit signed offset in bit 3 */
+ delta = (l >> OP_SH_OFFSET_B) & OP_MASK_OFFSET_B;
+ if (delta & 0x80)
+ delta |= ~OP_MASK_OFFSET_B;
+ (*info->fprintf_func) (info->stream, "%d", delta);
+ break;
+
+ case 'c': /* 9-bit signed offset in bit 6 */
+ delta = (l >> OP_SH_OFFSET_C) & OP_MASK_OFFSET_C;
+ if (delta & 0x100)
+ delta |= ~OP_MASK_OFFSET_C;
+ /* Left shift 4 bits to print the real offset. */
+ (*info->fprintf_func) (info->stream, "%d", delta << 4);
+ break;
+
+ case 'z':
+ (*info->fprintf_func) (info->stream, "%s",
+ mips_gpr_names[(l >> OP_SH_RZ) & OP_MASK_RZ]);
+ break;
+
+ case 'Z':
+ (*info->fprintf_func) (info->stream, "%s",
+ mips_fpr_names[(l >> OP_SH_FZ) & OP_MASK_FZ]);
+ break;
+
default:
/* xgettext:c-format */
(*info->fprintf_func) (info->stream,
/* 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)
+ if ((op->pinfo & (INSN_WRITE_GPR_31
+ | INSN_WRITE_GPR_D)) != 0)
info->insn_type = dis_jsr;
else
info->insn_type = dis_branch;
else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
| INSN_COND_BRANCH_LIKELY)) != 0)
{
- if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
+ if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
info->insn_type = dis_condjsr;
else
info->insn_type = dis_condbranch;
signedp = 1;
pcrel = 1;
branch = 1;
- info->insn_type = dis_condbranch;
break;
case 'q':
nbits = 11;
signedp = 1;
pcrel = 1;
branch = 1;
- info->insn_type = dis_branch;
break;
case 'A':
nbits = 8;
}
info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
(*info->print_address_func) (info->target, info);
- info->insn_type = dis_jsr;
- info->branch_delay_insns = 1;
break;
case 'l':
info);
}
+ /* Figure out branch instruction type and delay slot information. */
if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
+ info->branch_delay_insns = 1;
+ if ((op->pinfo & (INSN_UNCOND_BRANCH_DELAY
+ | MIPS16_INSN_UNCOND_BRANCH)) != 0)
{
- info->branch_delay_insns = 1;
- if (info->insn_type != dis_jsr)
+ if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
+ info->insn_type = dis_jsr;
+ else
info->insn_type = dis_branch;
}
+ else if ((op->pinfo & MIPS16_INSN_COND_BRANCH) != 0)
+ info->insn_type = dis_condbranch;
return length;
}