X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=opcodes%2Fmips-dis.c;h=01e446c56aa507f0bb3cf0f73f4d8fbb4f2a1155;hb=9a2c7088871654be1a94ea4d721fb9c76b4a3162;hp=59e1824f220a58730c1322063879a1660988624b;hpb=022fac6d2a2b74313c0262e97b280b1c7fc720f4;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c index 59e1824f22..01e446c56a 100644 --- a/opcodes/mips-dis.c +++ b/opcodes/mips-dis.c @@ -1,20 +1,20 @@ /* 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 + 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp). - This file is part of GDB, GAS, and the GNU binutils. + This file is part of the GNU opcodes library. - This program is free software; you can redistribute it and/or modify + This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; either version 3, or (at your option) + any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + It is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software @@ -124,6 +124,30 @@ static const char * const mips_cp0_names_numeric[32] = "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" }; +static const char * const mips_cp0_names_r3000[32] = +{ + "c0_index", "c0_random", "c0_entrylo", "$3", + "c0_context", "$5", "$6", "$7", + "c0_badvaddr", "$9", "c0_entryhi", "$11", + "c0_sr", "c0_cause", "c0_epc", "c0_prid", + "$16", "$17", "$18", "$19", + "$20", "$21", "$22", "$23", + "$24", "$25", "$26", "$27", + "$28", "$29", "$30", "$31", +}; + +static const char * const mips_cp0_names_r4000[32] = +{ + "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", + "c0_context", "c0_pagemask", "c0_wired", "$7", + "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", + "c0_sr", "c0_cause", "c0_epc", "c0_prid", + "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", + "c0_xcontext", "$21", "$22", "$23", + "$24", "$25", "c0_ecc", "c0_cacheerr", + "c0_taglo", "c0_taghi", "c0_errorepc", "$31", +}; + static const char * const mips_cp0_names_mips3264[32] = { "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", @@ -295,6 +319,56 @@ static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] = { 29, 3, "c0_datahi_d" }, }; +/* Xlr cop0 register names. */ +static const char * const mips_cp0_names_xlr[32] = { + "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", + "c0_context", "c0_pagemask", "c0_wired", "$7", + "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", + "c0_status", "c0_cause", "c0_epc", "c0_prid", + "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", + "c0_xcontext", "$21", "$22", "c0_debug", + "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i", + "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave", +}; + +/* XLR's CP0 Select Registers. */ + +static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = { + { 9, 6, "c0_extintreq" }, + { 9, 7, "c0_extintmask" }, + { 15, 1, "c0_ebase" }, + { 16, 1, "c0_config1" }, + { 16, 2, "c0_config2" }, + { 16, 3, "c0_config3" }, + { 16, 7, "c0_procid2" }, + { 18, 1, "c0_watchlo,1" }, + { 18, 2, "c0_watchlo,2" }, + { 18, 3, "c0_watchlo,3" }, + { 18, 4, "c0_watchlo,4" }, + { 18, 5, "c0_watchlo,5" }, + { 18, 6, "c0_watchlo,6" }, + { 18, 7, "c0_watchlo,7" }, + { 19, 1, "c0_watchhi,1" }, + { 19, 2, "c0_watchhi,2" }, + { 19, 3, "c0_watchhi,3" }, + { 19, 4, "c0_watchhi,4" }, + { 19, 5, "c0_watchhi,5" }, + { 19, 6, "c0_watchhi,6" }, + { 19, 7, "c0_watchhi,7" }, + { 25, 1, "c0_perfcnt,1" }, + { 25, 2, "c0_perfcnt,2" }, + { 25, 3, "c0_perfcnt,3" }, + { 25, 4, "c0_perfcnt,4" }, + { 25, 5, "c0_perfcnt,5" }, + { 25, 6, "c0_perfcnt,6" }, + { 25, 7, "c0_perfcnt,7" }, + { 27, 1, "c0_cacheerr,1" }, + { 27, 2, "c0_cacheerr,2" }, + { 27, 3, "c0_cacheerr,3" }, + { 28, 1, "c0_datalo" }, + { 29, 1, "c0_datahi" } +}; + static const char * const mips_hwr_names_numeric[32] = { "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", @@ -346,11 +420,11 @@ const struct mips_arch_choice mips_arch_choices[] = mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, + mips_cp0_names_r3000, NULL, 0, mips_hwr_names_numeric }, { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, + mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric }, { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, @@ -362,7 +436,7 @@ const struct mips_arch_choice mips_arch_choices[] = { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, + mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric }, { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, @@ -385,6 +459,10 @@ const struct mips_arch_choice mips_arch_choices[] = mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, + { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, + mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, + { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, + mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, @@ -394,26 +472,28 @@ const struct mips_arch_choice mips_arch_choices[] = MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95), page 1. */ { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32, - ISA_MIPS32 | INSN_MIPS16 | INSN_DSP, + 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_DSP | INSN_MT, + (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), mips_hwr_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 | INSN_DSP, + 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_MDMX | INSN_DSP, + (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), mips_hwr_names_mips3264r2 }, @@ -424,9 +504,27 @@ const struct mips_arch_choice mips_arch_choices[] = mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1), mips_hwr_names_numeric }, + { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E, + ISA_MIPS3 | INSN_LOONGSON_2E, mips_cp0_names_numeric, + NULL, 0, mips_hwr_names_numeric }, + + { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F, + ISA_MIPS3 | INSN_LOONGSON_2F, 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 }, + + { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR, + ISA_MIPS64 | INSN_XLR, + mips_cp0_names_xlr, + mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr), + 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 }, }; @@ -573,7 +671,7 @@ parse_mips_dis_option (const char *option, unsigned int len) const struct mips_arch_choice *chosen_arch; /* Try to match options that are simple flags */ - if (strncmp (option, "no-aliases", 10) == 0) + if (CONST_STRNEQ (option, "no-aliases")) { no_aliases = 1; return; @@ -844,6 +942,33 @@ print_insn_args (const char *d, break; } + case 'x': /* bbit bit index */ + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_BBITIND) & OP_MASK_BBITIND); + break; + + case 'p': /* cins, cins32, exts and exts32 position */ + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_CINSPOS) & OP_MASK_CINSPOS); + break; + + case 's': /* cins and exts length-minus-one */ + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1); + break; + + case 'S': /* cins32 and exts32 length-minus-one field */ + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1); + break; + + case 'Q': /* seqi/snei immediate field */ + op = (l >> OP_SH_SEQI) & OP_MASK_SEQI; + /* Sign-extend it. */ + op = (op ^ 512) - 512; + (*info->fprintf_func) (info->stream, "%d", op); + break; + default: /* xgettext:c-format */ (*info->fprintf_func) (info->stream, @@ -853,6 +978,11 @@ print_insn_args (const char *d, } break; + case '2': + (*info->fprintf_func) (info->stream, "0x%lx", + (l >> OP_SH_BP) & OP_MASK_BP); + break; + case '3': (*info->fprintf_func) (info->stream, "0x%lx", (l >> OP_SH_SA3) & OP_MASK_SA3); @@ -1034,6 +1164,7 @@ print_insn_args (const char *d, break; case '<': + case '1': (*info->fprintf_func) (info->stream, "0x%lx", (l >> OP_SH_SHAMT) & OP_MASK_SHAMT); break; @@ -1201,7 +1332,7 @@ print_insn_args (const char *d, default: /* xgettext:c-format */ (*info->fprintf_func) (info->stream, - _("# internal error, undefined modifier(%c)"), + _("# internal error, undefined modifier (%c)"), *d); return; } @@ -1529,7 +1660,6 @@ print_mips16_insn_arg (char type, signedp = 1; pcrel = 1; branch = 1; - info->insn_type = dis_condbranch; break; case 'q': nbits = 11; @@ -1537,7 +1667,6 @@ print_mips16_insn_arg (char type, signedp = 1; pcrel = 1; branch = 1; - info->insn_type = dis_branch; break; case 'A': nbits = 8; @@ -1658,8 +1787,6 @@ print_mips16_insn_arg (char type, } 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': @@ -1951,12 +2078,19 @@ print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info) 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; } @@ -1996,10 +2130,10 @@ _print_insn_mips (bfd_vma memaddr, #if SYMTAB_AVAILABLE if (info->mach == bfd_mach_mips16 - || (info->flavour == bfd_target_elf_flavour - && info->symbols != NULL - && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other - == STO_MIPS16))) + || (info->symbols != NULL + && bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour + && ELF_ST_IS_MIPS16 ((*(elf_symbol_type **) info->symbols) + ->internal_elf_sym.st_other))) return print_insn_mips16 (memaddr, info); #endif