Home | History | Annotate | Line # | Download | only in opcodes
mips-dis.c revision 1.3
      1  1.1     skrll /* Print mips instructions for GDB, the GNU debugger, or for objdump.
      2  1.1     skrll    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
      3  1.3  christos    2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009
      4  1.1     skrll    Free Software Foundation, Inc.
      5  1.1     skrll    Contributed by Nobuyuki Hikichi(hikichi (at) sra.co.jp).
      6  1.1     skrll 
      7  1.1     skrll    This file is part of the GNU opcodes library.
      8  1.1     skrll 
      9  1.1     skrll    This library is free software; you can redistribute it and/or modify
     10  1.1     skrll    it under the terms of the GNU General Public License as published by
     11  1.1     skrll    the Free Software Foundation; either version 3, or (at your option)
     12  1.1     skrll    any later version.
     13  1.1     skrll 
     14  1.1     skrll    It is distributed in the hope that it will be useful, but WITHOUT
     15  1.1     skrll    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     16  1.1     skrll    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     17  1.1     skrll    License for more details.
     18  1.1     skrll 
     19  1.1     skrll    You should have received a copy of the GNU General Public License
     20  1.1     skrll    along with this program; if not, write to the Free Software
     21  1.1     skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     22  1.1     skrll    MA 02110-1301, USA.  */
     23  1.1     skrll 
     24  1.1     skrll #include "sysdep.h"
     25  1.1     skrll #include "dis-asm.h"
     26  1.1     skrll #include "libiberty.h"
     27  1.1     skrll #include "opcode/mips.h"
     28  1.1     skrll #include "opintl.h"
     29  1.1     skrll 
     30  1.1     skrll /* FIXME: These are needed to figure out if the code is mips16 or
     31  1.1     skrll    not. The low bit of the address is often a good indicator.  No
     32  1.1     skrll    symbol table is available when this code runs out in an embedded
     33  1.1     skrll    system as when it is used for disassembler support in a monitor.  */
     34  1.1     skrll 
     35  1.1     skrll #if !defined(EMBEDDED_ENV)
     36  1.1     skrll #define SYMTAB_AVAILABLE 1
     37  1.1     skrll #include "elf-bfd.h"
     38  1.1     skrll #include "elf/mips.h"
     39  1.1     skrll #endif
     40  1.1     skrll 
     41  1.1     skrll /* Mips instructions are at maximum this many bytes long.  */
     42  1.1     skrll #define INSNLEN 4
     43  1.1     skrll 
     44  1.1     skrll 
     45  1.1     skrll /* FIXME: These should be shared with gdb somehow.  */
     47  1.1     skrll 
     48  1.1     skrll struct mips_cp0sel_name
     49  1.1     skrll {
     50  1.1     skrll   unsigned int cp0reg;
     51  1.1     skrll   unsigned int sel;
     52  1.1     skrll   const char * const name;
     53  1.1     skrll };
     54  1.1     skrll 
     55  1.1     skrll /* The mips16 registers.  */
     56  1.1     skrll static const unsigned int mips16_to_32_reg_map[] =
     57  1.1     skrll {
     58  1.1     skrll   16, 17, 2, 3, 4, 5, 6, 7
     59  1.1     skrll };
     60  1.1     skrll 
     61  1.1     skrll #define mips16_reg_names(rn)	mips_gpr_names[mips16_to_32_reg_map[rn]]
     62  1.1     skrll 
     63  1.1     skrll 
     64  1.1     skrll static const char * const mips_gpr_names_numeric[32] =
     65  1.1     skrll {
     66  1.1     skrll   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
     67  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
     68  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
     69  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
     70  1.1     skrll };
     71  1.1     skrll 
     72  1.1     skrll static const char * const mips_gpr_names_oldabi[32] =
     73  1.1     skrll {
     74  1.1     skrll   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
     75  1.1     skrll   "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
     76  1.1     skrll   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
     77  1.1     skrll   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
     78  1.1     skrll };
     79  1.1     skrll 
     80  1.1     skrll static const char * const mips_gpr_names_newabi[32] =
     81  1.1     skrll {
     82  1.1     skrll   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
     83  1.1     skrll   "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3",
     84  1.1     skrll   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
     85  1.1     skrll   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
     86  1.1     skrll };
     87  1.1     skrll 
     88  1.1     skrll static const char * const mips_fpr_names_numeric[32] =
     89  1.1     skrll {
     90  1.1     skrll   "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
     91  1.1     skrll   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
     92  1.1     skrll   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
     93  1.1     skrll   "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
     94  1.1     skrll };
     95  1.1     skrll 
     96  1.1     skrll static const char * const mips_fpr_names_32[32] =
     97  1.1     skrll {
     98  1.1     skrll   "fv0",  "fv0f", "fv1",  "fv1f", "ft0",  "ft0f", "ft1",  "ft1f",
     99  1.1     skrll   "ft2",  "ft2f", "ft3",  "ft3f", "fa0",  "fa0f", "fa1",  "fa1f",
    100  1.1     skrll   "ft4",  "ft4f", "ft5",  "ft5f", "fs0",  "fs0f", "fs1",  "fs1f",
    101  1.1     skrll   "fs2",  "fs2f", "fs3",  "fs3f", "fs4",  "fs4f", "fs5",  "fs5f"
    102  1.1     skrll };
    103  1.1     skrll 
    104  1.1     skrll static const char * const mips_fpr_names_n32[32] =
    105  1.1     skrll {
    106  1.1     skrll   "fv0",  "ft14", "fv1",  "ft15", "ft0",  "ft1",  "ft2",  "ft3",
    107  1.1     skrll   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
    108  1.1     skrll   "fa4",  "fa5",  "fa6",  "fa7",  "fs0",  "ft8",  "fs1",  "ft9",
    109  1.1     skrll   "fs2",  "ft10", "fs3",  "ft11", "fs4",  "ft12", "fs5",  "ft13"
    110  1.1     skrll };
    111  1.1     skrll 
    112  1.1     skrll static const char * const mips_fpr_names_64[32] =
    113  1.1     skrll {
    114  1.1     skrll   "fv0",  "ft12", "fv1",  "ft13", "ft0",  "ft1",  "ft2",  "ft3",
    115  1.1     skrll   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
    116  1.1     skrll   "fa4",  "fa5",  "fa6",  "fa7",  "ft8",  "ft9",  "ft10", "ft11",
    117  1.1     skrll   "fs0",  "fs1",  "fs2",  "fs3",  "fs4",  "fs5",  "fs6",  "fs7"
    118  1.1     skrll };
    119  1.1     skrll 
    120  1.1     skrll static const char * const mips_cp0_names_numeric[32] =
    121  1.1     skrll {
    122  1.1     skrll   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    123  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    124  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    125  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    126  1.1     skrll };
    127  1.1     skrll 
    128  1.1     skrll static const char * const mips_cp0_names_r3000[32] =
    129  1.1     skrll {
    130  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo",   "$3",
    131  1.1     skrll   "c0_context",   "$5",           "$6",           "$7",
    132  1.1     skrll   "c0_badvaddr",  "$9",           "c0_entryhi",   "$11",
    133  1.1     skrll   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    134  1.1     skrll   "$16",          "$17",          "$18",          "$19",
    135  1.1     skrll   "$20",          "$21",          "$22",          "$23",
    136  1.1     skrll   "$24",          "$25",          "$26",          "$27",
    137  1.1     skrll   "$28",          "$29",          "$30",          "$31",
    138  1.1     skrll };
    139  1.1     skrll 
    140  1.1     skrll static const char * const mips_cp0_names_r4000[32] =
    141  1.1     skrll {
    142  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    143  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    144  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    145  1.1     skrll   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    146  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    147  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "$23",
    148  1.1     skrll   "$24",          "$25",          "c0_ecc",       "c0_cacheerr",
    149  1.1     skrll   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "$31",
    150  1.1     skrll };
    151  1.1     skrll 
    152  1.1     skrll static const char * const mips_cp0_names_mips3264[32] =
    153  1.1     skrll {
    154  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    155  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    156  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    157  1.1     skrll   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    158  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    159  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    160  1.1     skrll   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
    161  1.1     skrll   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
    162  1.1     skrll };
    163  1.1     skrll 
    164  1.1     skrll static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
    165  1.1     skrll {
    166  1.1     skrll   { 16, 1, "c0_config1"		},
    167  1.1     skrll   { 16, 2, "c0_config2"		},
    168  1.1     skrll   { 16, 3, "c0_config3"		},
    169  1.1     skrll   { 18, 1, "c0_watchlo,1"	},
    170  1.1     skrll   { 18, 2, "c0_watchlo,2"	},
    171  1.1     skrll   { 18, 3, "c0_watchlo,3"	},
    172  1.1     skrll   { 18, 4, "c0_watchlo,4"	},
    173  1.1     skrll   { 18, 5, "c0_watchlo,5"	},
    174  1.1     skrll   { 18, 6, "c0_watchlo,6"	},
    175  1.1     skrll   { 18, 7, "c0_watchlo,7"	},
    176  1.1     skrll   { 19, 1, "c0_watchhi,1"	},
    177  1.1     skrll   { 19, 2, "c0_watchhi,2"	},
    178  1.1     skrll   { 19, 3, "c0_watchhi,3"	},
    179  1.1     skrll   { 19, 4, "c0_watchhi,4"	},
    180  1.1     skrll   { 19, 5, "c0_watchhi,5"	},
    181  1.1     skrll   { 19, 6, "c0_watchhi,6"	},
    182  1.1     skrll   { 19, 7, "c0_watchhi,7"	},
    183  1.1     skrll   { 25, 1, "c0_perfcnt,1"	},
    184  1.1     skrll   { 25, 2, "c0_perfcnt,2"	},
    185  1.1     skrll   { 25, 3, "c0_perfcnt,3"	},
    186  1.1     skrll   { 25, 4, "c0_perfcnt,4"	},
    187  1.1     skrll   { 25, 5, "c0_perfcnt,5"	},
    188  1.1     skrll   { 25, 6, "c0_perfcnt,6"	},
    189  1.1     skrll   { 25, 7, "c0_perfcnt,7"	},
    190  1.1     skrll   { 27, 1, "c0_cacheerr,1"	},
    191  1.1     skrll   { 27, 2, "c0_cacheerr,2"	},
    192  1.1     skrll   { 27, 3, "c0_cacheerr,3"	},
    193  1.1     skrll   { 28, 1, "c0_datalo"		},
    194  1.1     skrll   { 29, 1, "c0_datahi"		}
    195  1.1     skrll };
    196  1.1     skrll 
    197  1.1     skrll static const char * const mips_cp0_names_mips3264r2[32] =
    198  1.1     skrll {
    199  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    200  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "c0_hwrena",
    201  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    202  1.1     skrll   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    203  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    204  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    205  1.1     skrll   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
    206  1.1     skrll   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
    207  1.1     skrll };
    208  1.1     skrll 
    209  1.1     skrll static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
    210  1.1     skrll {
    211  1.1     skrll   {  4, 1, "c0_contextconfig"	},
    212  1.1     skrll   {  0, 1, "c0_mvpcontrol"	},
    213  1.1     skrll   {  0, 2, "c0_mvpconf0"	},
    214  1.1     skrll   {  0, 3, "c0_mvpconf1"	},
    215  1.1     skrll   {  1, 1, "c0_vpecontrol"	},
    216  1.1     skrll   {  1, 2, "c0_vpeconf0"	},
    217  1.1     skrll   {  1, 3, "c0_vpeconf1"	},
    218  1.1     skrll   {  1, 4, "c0_yqmask"		},
    219  1.1     skrll   {  1, 5, "c0_vpeschedule"	},
    220  1.1     skrll   {  1, 6, "c0_vpeschefback"	},
    221  1.1     skrll   {  2, 1, "c0_tcstatus"	},
    222  1.1     skrll   {  2, 2, "c0_tcbind"		},
    223  1.1     skrll   {  2, 3, "c0_tcrestart"	},
    224  1.1     skrll   {  2, 4, "c0_tchalt"		},
    225  1.1     skrll   {  2, 5, "c0_tccontext"	},
    226  1.1     skrll   {  2, 6, "c0_tcschedule"	},
    227  1.1     skrll   {  2, 7, "c0_tcschefback"	},
    228  1.1     skrll   {  5, 1, "c0_pagegrain"	},
    229  1.1     skrll   {  6, 1, "c0_srsconf0"	},
    230  1.1     skrll   {  6, 2, "c0_srsconf1"	},
    231  1.1     skrll   {  6, 3, "c0_srsconf2"	},
    232  1.1     skrll   {  6, 4, "c0_srsconf3"	},
    233  1.1     skrll   {  6, 5, "c0_srsconf4"	},
    234  1.1     skrll   { 12, 1, "c0_intctl"		},
    235  1.1     skrll   { 12, 2, "c0_srsctl"		},
    236  1.1     skrll   { 12, 3, "c0_srsmap"		},
    237  1.1     skrll   { 15, 1, "c0_ebase"		},
    238  1.1     skrll   { 16, 1, "c0_config1"		},
    239  1.1     skrll   { 16, 2, "c0_config2"		},
    240  1.1     skrll   { 16, 3, "c0_config3"		},
    241  1.1     skrll   { 18, 1, "c0_watchlo,1"	},
    242  1.1     skrll   { 18, 2, "c0_watchlo,2"	},
    243  1.1     skrll   { 18, 3, "c0_watchlo,3"	},
    244  1.1     skrll   { 18, 4, "c0_watchlo,4"	},
    245  1.1     skrll   { 18, 5, "c0_watchlo,5"	},
    246  1.1     skrll   { 18, 6, "c0_watchlo,6"	},
    247  1.1     skrll   { 18, 7, "c0_watchlo,7"	},
    248  1.1     skrll   { 19, 1, "c0_watchhi,1"	},
    249  1.1     skrll   { 19, 2, "c0_watchhi,2"	},
    250  1.1     skrll   { 19, 3, "c0_watchhi,3"	},
    251  1.1     skrll   { 19, 4, "c0_watchhi,4"	},
    252  1.1     skrll   { 19, 5, "c0_watchhi,5"	},
    253  1.1     skrll   { 19, 6, "c0_watchhi,6"	},
    254  1.1     skrll   { 19, 7, "c0_watchhi,7"	},
    255  1.1     skrll   { 23, 1, "c0_tracecontrol"	},
    256  1.1     skrll   { 23, 2, "c0_tracecontrol2"	},
    257  1.1     skrll   { 23, 3, "c0_usertracedata"	},
    258  1.1     skrll   { 23, 4, "c0_tracebpc"	},
    259  1.1     skrll   { 25, 1, "c0_perfcnt,1"	},
    260  1.1     skrll   { 25, 2, "c0_perfcnt,2"	},
    261  1.1     skrll   { 25, 3, "c0_perfcnt,3"	},
    262  1.1     skrll   { 25, 4, "c0_perfcnt,4"	},
    263  1.1     skrll   { 25, 5, "c0_perfcnt,5"	},
    264  1.1     skrll   { 25, 6, "c0_perfcnt,6"	},
    265  1.1     skrll   { 25, 7, "c0_perfcnt,7"	},
    266  1.1     skrll   { 27, 1, "c0_cacheerr,1"	},
    267  1.1     skrll   { 27, 2, "c0_cacheerr,2"	},
    268  1.1     skrll   { 27, 3, "c0_cacheerr,3"	},
    269  1.1     skrll   { 28, 1, "c0_datalo"		},
    270  1.1     skrll   { 28, 2, "c0_taglo1"		},
    271  1.1     skrll   { 28, 3, "c0_datalo1"		},
    272  1.1     skrll   { 28, 4, "c0_taglo2"		},
    273  1.1     skrll   { 28, 5, "c0_datalo2"		},
    274  1.1     skrll   { 28, 6, "c0_taglo3"		},
    275  1.1     skrll   { 28, 7, "c0_datalo3"		},
    276  1.1     skrll   { 29, 1, "c0_datahi"		},
    277  1.1     skrll   { 29, 2, "c0_taghi1"		},
    278  1.1     skrll   { 29, 3, "c0_datahi1"		},
    279  1.1     skrll   { 29, 4, "c0_taghi2"		},
    280  1.1     skrll   { 29, 5, "c0_datahi2"		},
    281  1.1     skrll   { 29, 6, "c0_taghi3"		},
    282  1.1     skrll   { 29, 7, "c0_datahi3"		},
    283  1.1     skrll };
    284  1.1     skrll 
    285  1.1     skrll /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods.  */
    286  1.1     skrll static const char * const mips_cp0_names_sb1[32] =
    287  1.1     skrll {
    288  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    289  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    290  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    291  1.1     skrll   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    292  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    293  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    294  1.1     skrll   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
    295  1.1     skrll   "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
    296  1.1     skrll };
    297  1.1     skrll 
    298  1.1     skrll static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
    299  1.1     skrll {
    300  1.1     skrll   { 16, 1, "c0_config1"		},
    301  1.1     skrll   { 18, 1, "c0_watchlo,1"	},
    302  1.1     skrll   { 19, 1, "c0_watchhi,1"	},
    303  1.1     skrll   { 22, 0, "c0_perftrace"	},
    304  1.1     skrll   { 23, 3, "c0_edebug"		},
    305  1.1     skrll   { 25, 1, "c0_perfcnt,1"	},
    306  1.1     skrll   { 25, 2, "c0_perfcnt,2"	},
    307  1.1     skrll   { 25, 3, "c0_perfcnt,3"	},
    308  1.1     skrll   { 25, 4, "c0_perfcnt,4"	},
    309  1.1     skrll   { 25, 5, "c0_perfcnt,5"	},
    310  1.1     skrll   { 25, 6, "c0_perfcnt,6"	},
    311  1.1     skrll   { 25, 7, "c0_perfcnt,7"	},
    312  1.1     skrll   { 26, 1, "c0_buserr_pa"	},
    313  1.1     skrll   { 27, 1, "c0_cacheerr_d"	},
    314  1.1     skrll   { 27, 3, "c0_cacheerr_d_pa"	},
    315  1.1     skrll   { 28, 1, "c0_datalo_i"	},
    316  1.1     skrll   { 28, 2, "c0_taglo_d"		},
    317  1.1     skrll   { 28, 3, "c0_datalo_d"	},
    318  1.1     skrll   { 29, 1, "c0_datahi_i"	},
    319  1.1     skrll   { 29, 2, "c0_taghi_d"		},
    320  1.1     skrll   { 29, 3, "c0_datahi_d"	},
    321  1.1     skrll };
    322  1.2      matt 
    323  1.2      matt /* Xlr cop0 register names.  */
    324  1.2      matt static const char * const mips_cp0_names_xlr[32] = {
    325  1.3  christos   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    326  1.2      matt   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    327  1.2      matt   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    328  1.2      matt   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    329  1.3  christos   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    330  1.2      matt   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    331  1.2      matt   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
    332  1.2      matt   "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
    333  1.2      matt };
    334  1.2      matt 
    335  1.2      matt /* XLR's CP0 Select Registers.  */
    336  1.2      matt 
    337  1.2      matt static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
    338  1.2      matt   {  9, 6, "c0_extintreq"       },
    339  1.2      matt   {  9, 7, "c0_extintmask"      },
    340  1.2      matt   { 15, 1, "c0_ebase"           },
    341  1.2      matt   { 16, 1, "c0_config1"         },
    342  1.2      matt   { 16, 2, "c0_config2"         },
    343  1.2      matt   { 16, 3, "c0_config3"         },
    344  1.2      matt   { 16, 7, "c0_procid2"         },
    345  1.2      matt   { 18, 1, "c0_watchlo,1"       },
    346  1.2      matt   { 18, 2, "c0_watchlo,2"       },
    347  1.2      matt   { 18, 3, "c0_watchlo,3"       },
    348  1.2      matt   { 18, 4, "c0_watchlo,4"       },
    349  1.2      matt   { 18, 5, "c0_watchlo,5"       },
    350  1.2      matt   { 18, 6, "c0_watchlo,6"       },
    351  1.2      matt   { 18, 7, "c0_watchlo,7"       },
    352  1.2      matt   { 19, 1, "c0_watchhi,1"       },
    353  1.2      matt   { 19, 2, "c0_watchhi,2"       },
    354  1.2      matt   { 19, 3, "c0_watchhi,3"       },
    355  1.2      matt   { 19, 4, "c0_watchhi,4"       },
    356  1.2      matt   { 19, 5, "c0_watchhi,5"       },
    357  1.2      matt   { 19, 6, "c0_watchhi,6"       },
    358  1.2      matt   { 19, 7, "c0_watchhi,7"       },
    359  1.2      matt   { 25, 1, "c0_perfcnt,1"       },
    360  1.2      matt   { 25, 2, "c0_perfcnt,2"       },
    361  1.2      matt   { 25, 3, "c0_perfcnt,3"       },
    362  1.2      matt   { 25, 4, "c0_perfcnt,4"       },
    363  1.2      matt   { 25, 5, "c0_perfcnt,5"       },
    364  1.2      matt   { 25, 6, "c0_perfcnt,6"       },
    365  1.2      matt   { 25, 7, "c0_perfcnt,7"       },
    366  1.2      matt   { 27, 1, "c0_cacheerr,1"      },
    367  1.2      matt   { 27, 2, "c0_cacheerr,2"      },
    368  1.2      matt   { 27, 3, "c0_cacheerr,3"      },
    369  1.2      matt   { 28, 1, "c0_datalo"          },
    370  1.2      matt   { 29, 1, "c0_datahi"          }
    371  1.2      matt };
    372  1.1     skrll 
    373  1.1     skrll static const char * const mips_hwr_names_numeric[32] =
    374  1.1     skrll {
    375  1.1     skrll   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    376  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    377  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    378  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    379  1.1     skrll };
    380  1.1     skrll 
    381  1.1     skrll static const char * const mips_hwr_names_mips3264r2[32] =
    382  1.1     skrll {
    383  1.1     skrll   "hwr_cpunum",   "hwr_synci_step", "hwr_cc",     "hwr_ccres",
    384  1.1     skrll   "$4",          "$5",            "$6",           "$7",
    385  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    386  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    387  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    388  1.1     skrll };
    389  1.1     skrll 
    390  1.1     skrll struct mips_abi_choice
    391  1.1     skrll {
    392  1.1     skrll   const char * name;
    393  1.1     skrll   const char * const *gpr_names;
    394  1.1     skrll   const char * const *fpr_names;
    395  1.1     skrll };
    396  1.1     skrll 
    397  1.1     skrll struct mips_abi_choice mips_abi_choices[] =
    398  1.1     skrll {
    399  1.1     skrll   { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
    400  1.1     skrll   { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
    401  1.1     skrll   { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
    402  1.1     skrll   { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
    403  1.1     skrll };
    404  1.1     skrll 
    405  1.1     skrll struct mips_arch_choice
    406  1.1     skrll {
    407  1.1     skrll   const char *name;
    408  1.1     skrll   int bfd_mach_valid;
    409  1.1     skrll   unsigned long bfd_mach;
    410  1.1     skrll   int processor;
    411  1.1     skrll   int isa;
    412  1.1     skrll   const char * const *cp0_names;
    413  1.1     skrll   const struct mips_cp0sel_name *cp0sel_names;
    414  1.1     skrll   unsigned int cp0sel_names_len;
    415  1.1     skrll   const char * const *hwr_names;
    416  1.1     skrll };
    417  1.1     skrll 
    418  1.1     skrll const struct mips_arch_choice mips_arch_choices[] =
    419  1.1     skrll {
    420  1.1     skrll   { "numeric",	0, 0, 0, 0,
    421  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    422  1.1     skrll 
    423  1.1     skrll   { "r3000",	1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1,
    424  1.1     skrll     mips_cp0_names_r3000, NULL, 0, mips_hwr_names_numeric },
    425  1.1     skrll   { "r3900",	1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1,
    426  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    427  1.1     skrll   { "r4000",	1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3,
    428  1.1     skrll     mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
    429  1.1     skrll   { "r4010",	1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2,
    430  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    431  1.1     skrll   { "vr4100",	1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3,
    432  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    433  1.1     skrll   { "vr4111",	1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3,
    434  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    435  1.1     skrll   { "vr4120",	1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3,
    436  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    437  1.1     skrll   { "r4300",	1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3,
    438  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    439  1.1     skrll   { "r4400",	1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3,
    440  1.1     skrll     mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
    441  1.1     skrll   { "r4600",	1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3,
    442  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    443  1.1     skrll   { "r4650",	1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3,
    444  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    445  1.1     skrll   { "r5000",	1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4,
    446  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    447  1.1     skrll   { "vr5400",	1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4,
    448  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    449  1.1     skrll   { "vr5500",	1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4,
    450  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    451  1.1     skrll   { "r6000",	1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2,
    452  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    453  1.1     skrll   { "rm7000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
    454  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    455  1.1     skrll   { "rm9000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
    456  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    457  1.1     skrll   { "r8000",	1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4,
    458  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    459  1.1     skrll   { "r10000",	1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4,
    460  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    461  1.1     skrll   { "r12000",	1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4,
    462  1.3  christos     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    463  1.3  christos   { "r14000",	1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4,
    464  1.3  christos     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    465  1.3  christos   { "r16000",	1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4,
    466  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    467  1.1     skrll   { "mips5",	1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5,
    468  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    469  1.1     skrll 
    470  1.1     skrll   /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
    471  1.1     skrll      Note that MIPS-3D and MDMX are not applicable to MIPS32.  (See
    472  1.1     skrll      _MIPS32 Architecture For Programmers Volume I: Introduction to the
    473  1.1     skrll      MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
    474  1.1     skrll      page 1.  */
    475  1.3  christos   { "mips32",	1, bfd_mach_mipsisa32, CPU_MIPS32,
    476  1.1     skrll     ISA_MIPS32 | INSN_SMARTMIPS,
    477  1.1     skrll     mips_cp0_names_mips3264,
    478  1.1     skrll     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
    479  1.1     skrll     mips_hwr_names_numeric },
    480  1.1     skrll 
    481  1.3  christos   { "mips32r2",	1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
    482  1.1     skrll     (ISA_MIPS32R2 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
    483  1.1     skrll      | INSN_MIPS3D | INSN_MT),
    484  1.1     skrll     mips_cp0_names_mips3264r2,
    485  1.1     skrll     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    486  1.1     skrll     mips_hwr_names_mips3264r2 },
    487  1.1     skrll 
    488  1.1     skrll   /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs.  */
    489  1.3  christos   { "mips64",	1, bfd_mach_mipsisa64, CPU_MIPS64,
    490  1.1     skrll     ISA_MIPS64 | INSN_MIPS3D | INSN_MDMX,
    491  1.1     skrll     mips_cp0_names_mips3264,
    492  1.1     skrll     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
    493  1.1     skrll     mips_hwr_names_numeric },
    494  1.1     skrll 
    495  1.3  christos   { "mips64r2",	1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
    496  1.1     skrll     (ISA_MIPS64R2 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
    497  1.1     skrll      | INSN_DSP64 | INSN_MT | INSN_MDMX),
    498  1.1     skrll     mips_cp0_names_mips3264r2,
    499  1.1     skrll     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    500  1.1     skrll     mips_hwr_names_mips3264r2 },
    501  1.1     skrll 
    502  1.1     skrll   { "sb1",	1, bfd_mach_mips_sb1, CPU_SB1,
    503  1.1     skrll     ISA_MIPS64 | INSN_MIPS3D | INSN_SB1,
    504  1.1     skrll     mips_cp0_names_sb1,
    505  1.1     skrll     mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
    506  1.1     skrll     mips_hwr_names_numeric },
    507  1.1     skrll 
    508  1.1     skrll   { "loongson2e",   1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
    509  1.1     skrll     ISA_MIPS3 | INSN_LOONGSON_2E, mips_cp0_names_numeric,
    510  1.1     skrll     NULL, 0, mips_hwr_names_numeric },
    511  1.1     skrll 
    512  1.1     skrll   { "loongson2f",   1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
    513  1.1     skrll     ISA_MIPS3 | INSN_LOONGSON_2F, mips_cp0_names_numeric,
    514  1.1     skrll     NULL, 0, mips_hwr_names_numeric },
    515  1.1     skrll 
    516  1.1     skrll   { "octeon",   1, bfd_mach_mips_octeon, CPU_OCTEON,
    517  1.1     skrll     ISA_MIPS64R2 | INSN_OCTEON, mips_cp0_names_numeric, NULL, 0,
    518  1.1     skrll     mips_hwr_names_numeric },
    519  1.2      matt 
    520  1.2      matt   { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
    521  1.2      matt     ISA_MIPS64 | INSN_XLR,
    522  1.2      matt     mips_cp0_names_xlr,
    523  1.2      matt     mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
    524  1.2      matt     mips_hwr_names_numeric },
    525  1.1     skrll 
    526  1.1     skrll   /* This entry, mips16, is here only for ISA/processor selection; do
    527  1.3  christos      not print its name.  */
    528  1.1     skrll   { "",		1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3,
    529  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    530  1.1     skrll };
    531  1.1     skrll 
    532  1.1     skrll /* ISA and processor type to disassemble for, and register names to use.
    533  1.1     skrll    set_default_mips_dis_options and parse_mips_dis_options fill in these
    534  1.1     skrll    values.  */
    535  1.1     skrll static int mips_processor;
    536  1.1     skrll static int mips_isa;
    537  1.1     skrll static const char * const *mips_gpr_names;
    538  1.1     skrll static const char * const *mips_fpr_names;
    539  1.1     skrll static const char * const *mips_cp0_names;
    540  1.1     skrll static const struct mips_cp0sel_name *mips_cp0sel_names;
    541  1.1     skrll static int mips_cp0sel_names_len;
    542  1.1     skrll static const char * const *mips_hwr_names;
    543  1.1     skrll 
    544  1.1     skrll /* Other options */
    545  1.1     skrll static int no_aliases;	/* If set disassemble as most general inst.  */
    546  1.1     skrll 
    547  1.1     skrll static const struct mips_abi_choice *
    549  1.1     skrll choose_abi_by_name (const char *name, unsigned int namelen)
    550  1.1     skrll {
    551  1.1     skrll   const struct mips_abi_choice *c;
    552  1.1     skrll   unsigned int i;
    553  1.1     skrll 
    554  1.1     skrll   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
    555  1.1     skrll     if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
    556  1.1     skrll 	&& strlen (mips_abi_choices[i].name) == namelen)
    557  1.1     skrll       c = &mips_abi_choices[i];
    558  1.1     skrll 
    559  1.1     skrll   return c;
    560  1.1     skrll }
    561  1.1     skrll 
    562  1.1     skrll static const struct mips_arch_choice *
    563  1.1     skrll choose_arch_by_name (const char *name, unsigned int namelen)
    564  1.1     skrll {
    565  1.1     skrll   const struct mips_arch_choice *c = NULL;
    566  1.1     skrll   unsigned int i;
    567  1.1     skrll 
    568  1.1     skrll   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
    569  1.1     skrll     if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
    570  1.1     skrll 	&& strlen (mips_arch_choices[i].name) == namelen)
    571  1.1     skrll       c = &mips_arch_choices[i];
    572  1.1     skrll 
    573  1.1     skrll   return c;
    574  1.1     skrll }
    575  1.1     skrll 
    576  1.1     skrll static const struct mips_arch_choice *
    577  1.1     skrll choose_arch_by_number (unsigned long mach)
    578  1.1     skrll {
    579  1.1     skrll   static unsigned long hint_bfd_mach;
    580  1.1     skrll   static const struct mips_arch_choice *hint_arch_choice;
    581  1.1     skrll   const struct mips_arch_choice *c;
    582  1.1     skrll   unsigned int i;
    583  1.1     skrll 
    584  1.1     skrll   /* We optimize this because even if the user specifies no
    585  1.1     skrll      flags, this will be done for every instruction!  */
    586  1.1     skrll   if (hint_bfd_mach == mach
    587  1.1     skrll       && hint_arch_choice != NULL
    588  1.1     skrll       && hint_arch_choice->bfd_mach == hint_bfd_mach)
    589  1.1     skrll     return hint_arch_choice;
    590  1.1     skrll 
    591  1.1     skrll   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
    592  1.1     skrll     {
    593  1.1     skrll       if (mips_arch_choices[i].bfd_mach_valid
    594  1.1     skrll 	  && mips_arch_choices[i].bfd_mach == mach)
    595  1.1     skrll 	{
    596  1.1     skrll 	  c = &mips_arch_choices[i];
    597  1.1     skrll 	  hint_bfd_mach = mach;
    598  1.1     skrll 	  hint_arch_choice = c;
    599  1.1     skrll 	}
    600  1.1     skrll     }
    601  1.1     skrll   return c;
    602  1.1     skrll }
    603  1.1     skrll 
    604  1.1     skrll /* Check if the object uses NewABI conventions.  */
    605  1.1     skrll 
    606  1.1     skrll static int
    607  1.1     skrll is_newabi (Elf_Internal_Ehdr *header)
    608  1.1     skrll {
    609  1.1     skrll   /* There are no old-style ABIs which use 64-bit ELF.  */
    610  1.1     skrll   if (header->e_ident[EI_CLASS] == ELFCLASS64)
    611  1.1     skrll     return 1;
    612  1.1     skrll 
    613  1.1     skrll   /* If a 32-bit ELF file, n32 is a new-style ABI.  */
    614  1.1     skrll   if ((header->e_flags & EF_MIPS_ABI2) != 0)
    615  1.1     skrll     return 1;
    616  1.1     skrll 
    617  1.1     skrll   return 0;
    618  1.1     skrll }
    619  1.1     skrll 
    620  1.1     skrll static void
    621  1.1     skrll set_default_mips_dis_options (struct disassemble_info *info)
    622  1.1     skrll {
    623  1.1     skrll   const struct mips_arch_choice *chosen_arch;
    624  1.1     skrll 
    625  1.1     skrll   /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names,
    626  1.1     skrll      and numeric FPR, CP0 register, and HWR names.  */
    627  1.1     skrll   mips_isa = ISA_MIPS3;
    628  1.1     skrll   mips_processor =  CPU_R3000;
    629  1.1     skrll   mips_gpr_names = mips_gpr_names_oldabi;
    630  1.1     skrll   mips_fpr_names = mips_fpr_names_numeric;
    631  1.1     skrll   mips_cp0_names = mips_cp0_names_numeric;
    632  1.1     skrll   mips_cp0sel_names = NULL;
    633  1.1     skrll   mips_cp0sel_names_len = 0;
    634  1.1     skrll   mips_hwr_names = mips_hwr_names_numeric;
    635  1.1     skrll   no_aliases = 0;
    636  1.1     skrll 
    637  1.1     skrll   /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
    638  1.1     skrll   if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
    639  1.1     skrll     {
    640  1.1     skrll       Elf_Internal_Ehdr *header;
    641  1.1     skrll 
    642  1.1     skrll       header = elf_elfheader (info->section->owner);
    643  1.1     skrll       if (is_newabi (header))
    644  1.1     skrll 	mips_gpr_names = mips_gpr_names_newabi;
    645  1.1     skrll     }
    646  1.1     skrll 
    647  1.1     skrll   /* Set ISA, architecture, and cp0 register names as best we can.  */
    648  1.1     skrll #if ! SYMTAB_AVAILABLE
    649  1.1     skrll   /* This is running out on a target machine, not in a host tool.
    650  1.1     skrll      FIXME: Where does mips_target_info come from?  */
    651  1.1     skrll   target_processor = mips_target_info.processor;
    652  1.1     skrll   mips_isa = mips_target_info.isa;
    653  1.1     skrll #else
    654  1.1     skrll   chosen_arch = choose_arch_by_number (info->mach);
    655  1.1     skrll   if (chosen_arch != NULL)
    656  1.1     skrll     {
    657  1.1     skrll       mips_processor = chosen_arch->processor;
    658  1.1     skrll       mips_isa = chosen_arch->isa;
    659  1.1     skrll       mips_cp0_names = chosen_arch->cp0_names;
    660  1.1     skrll       mips_cp0sel_names = chosen_arch->cp0sel_names;
    661  1.1     skrll       mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    662  1.1     skrll       mips_hwr_names = chosen_arch->hwr_names;
    663  1.1     skrll     }
    664  1.1     skrll #endif
    665  1.1     skrll }
    666  1.1     skrll 
    667  1.1     skrll static void
    668  1.1     skrll parse_mips_dis_option (const char *option, unsigned int len)
    669  1.1     skrll {
    670  1.1     skrll   unsigned int i, optionlen, vallen;
    671  1.1     skrll   const char *val;
    672  1.1     skrll   const struct mips_abi_choice *chosen_abi;
    673  1.1     skrll   const struct mips_arch_choice *chosen_arch;
    674  1.1     skrll 
    675  1.1     skrll   /* Try to match options that are simple flags */
    676  1.1     skrll   if (CONST_STRNEQ (option, "no-aliases"))
    677  1.1     skrll     {
    678  1.1     skrll       no_aliases = 1;
    679  1.1     skrll       return;
    680  1.1     skrll     }
    681  1.1     skrll 
    682  1.1     skrll   /* Look for the = that delimits the end of the option name.  */
    683  1.1     skrll   for (i = 0; i < len; i++)
    684  1.1     skrll     if (option[i] == '=')
    685  1.1     skrll       break;
    686  1.1     skrll 
    687  1.1     skrll   if (i == 0)		/* Invalid option: no name before '='.  */
    688  1.1     skrll     return;
    689  1.1     skrll   if (i == len)		/* Invalid option: no '='.  */
    690  1.1     skrll     return;
    691  1.1     skrll   if (i == (len - 1))	/* Invalid option: no value after '='.  */
    692  1.1     skrll     return;
    693  1.1     skrll 
    694  1.1     skrll   optionlen = i;
    695  1.1     skrll   val = option + (optionlen + 1);
    696  1.1     skrll   vallen = len - (optionlen + 1);
    697  1.1     skrll 
    698  1.1     skrll   if (strncmp ("gpr-names", option, optionlen) == 0
    699  1.1     skrll       && strlen ("gpr-names") == optionlen)
    700  1.1     skrll     {
    701  1.1     skrll       chosen_abi = choose_abi_by_name (val, vallen);
    702  1.1     skrll       if (chosen_abi != NULL)
    703  1.1     skrll 	mips_gpr_names = chosen_abi->gpr_names;
    704  1.1     skrll       return;
    705  1.1     skrll     }
    706  1.1     skrll 
    707  1.1     skrll   if (strncmp ("fpr-names", option, optionlen) == 0
    708  1.1     skrll       && strlen ("fpr-names") == optionlen)
    709  1.1     skrll     {
    710  1.1     skrll       chosen_abi = choose_abi_by_name (val, vallen);
    711  1.1     skrll       if (chosen_abi != NULL)
    712  1.1     skrll 	mips_fpr_names = chosen_abi->fpr_names;
    713  1.1     skrll       return;
    714  1.1     skrll     }
    715  1.1     skrll 
    716  1.1     skrll   if (strncmp ("cp0-names", option, optionlen) == 0
    717  1.1     skrll       && strlen ("cp0-names") == optionlen)
    718  1.1     skrll     {
    719  1.1     skrll       chosen_arch = choose_arch_by_name (val, vallen);
    720  1.1     skrll       if (chosen_arch != NULL)
    721  1.1     skrll 	{
    722  1.1     skrll 	  mips_cp0_names = chosen_arch->cp0_names;
    723  1.1     skrll 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
    724  1.1     skrll 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    725  1.1     skrll 	}
    726  1.1     skrll       return;
    727  1.1     skrll     }
    728  1.1     skrll 
    729  1.1     skrll   if (strncmp ("hwr-names", option, optionlen) == 0
    730  1.1     skrll       && strlen ("hwr-names") == optionlen)
    731  1.1     skrll     {
    732  1.1     skrll       chosen_arch = choose_arch_by_name (val, vallen);
    733  1.1     skrll       if (chosen_arch != NULL)
    734  1.1     skrll 	mips_hwr_names = chosen_arch->hwr_names;
    735  1.1     skrll       return;
    736  1.1     skrll     }
    737  1.1     skrll 
    738  1.1     skrll   if (strncmp ("reg-names", option, optionlen) == 0
    739  1.1     skrll       && strlen ("reg-names") == optionlen)
    740  1.1     skrll     {
    741  1.1     skrll       /* We check both ABI and ARCH here unconditionally, so
    742  1.1     skrll 	 that "numeric" will do the desirable thing: select
    743  1.1     skrll 	 numeric register names for all registers.  Other than
    744  1.1     skrll 	 that, a given name probably won't match both.  */
    745  1.1     skrll       chosen_abi = choose_abi_by_name (val, vallen);
    746  1.1     skrll       if (chosen_abi != NULL)
    747  1.1     skrll 	{
    748  1.1     skrll 	  mips_gpr_names = chosen_abi->gpr_names;
    749  1.1     skrll 	  mips_fpr_names = chosen_abi->fpr_names;
    750  1.1     skrll 	}
    751  1.1     skrll       chosen_arch = choose_arch_by_name (val, vallen);
    752  1.1     skrll       if (chosen_arch != NULL)
    753  1.1     skrll 	{
    754  1.1     skrll 	  mips_cp0_names = chosen_arch->cp0_names;
    755  1.1     skrll 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
    756  1.1     skrll 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    757  1.1     skrll 	  mips_hwr_names = chosen_arch->hwr_names;
    758  1.1     skrll 	}
    759  1.1     skrll       return;
    760  1.1     skrll     }
    761  1.1     skrll 
    762  1.1     skrll   /* Invalid option.  */
    763  1.1     skrll }
    764  1.1     skrll 
    765  1.1     skrll static void
    766  1.1     skrll parse_mips_dis_options (const char *options)
    767  1.1     skrll {
    768  1.1     skrll   const char *option_end;
    769  1.1     skrll 
    770  1.1     skrll   if (options == NULL)
    771  1.1     skrll     return;
    772  1.1     skrll 
    773  1.1     skrll   while (*options != '\0')
    774  1.1     skrll     {
    775  1.1     skrll       /* Skip empty options.  */
    776  1.1     skrll       if (*options == ',')
    777  1.1     skrll 	{
    778  1.1     skrll 	  options++;
    779  1.1     skrll 	  continue;
    780  1.1     skrll 	}
    781  1.1     skrll 
    782  1.1     skrll       /* We know that *options is neither NUL or a comma.  */
    783  1.1     skrll       option_end = options + 1;
    784  1.1     skrll       while (*option_end != ',' && *option_end != '\0')
    785  1.1     skrll 	option_end++;
    786  1.1     skrll 
    787  1.1     skrll       parse_mips_dis_option (options, option_end - options);
    788  1.1     skrll 
    789  1.1     skrll       /* Go on to the next one.  If option_end points to a comma, it
    790  1.1     skrll 	 will be skipped above.  */
    791  1.1     skrll       options = option_end;
    792  1.1     skrll     }
    793  1.1     skrll }
    794  1.1     skrll 
    795  1.1     skrll static const struct mips_cp0sel_name *
    796  1.1     skrll lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
    797  1.1     skrll 			 unsigned int len,
    798  1.1     skrll 			 unsigned int cp0reg,
    799  1.1     skrll 			 unsigned int sel)
    800  1.1     skrll {
    801  1.1     skrll   unsigned int i;
    802  1.1     skrll 
    803  1.1     skrll   for (i = 0; i < len; i++)
    804  1.1     skrll     if (names[i].cp0reg == cp0reg && names[i].sel == sel)
    805  1.1     skrll       return &names[i];
    806  1.1     skrll   return NULL;
    807  1.1     skrll }
    808  1.1     skrll 
    809  1.1     skrll /* Print insn arguments for 32/64-bit code.  */
    811  1.1     skrll 
    812  1.1     skrll static void
    813  1.1     skrll print_insn_args (const char *d,
    814  1.1     skrll 		 register unsigned long int l,
    815  1.1     skrll 		 bfd_vma pc,
    816  1.1     skrll 		 struct disassemble_info *info,
    817  1.1     skrll 		 const struct mips_opcode *opp)
    818  1.1     skrll {
    819  1.1     skrll   int op, delta;
    820  1.1     skrll   unsigned int lsb, msb, msbd;
    821  1.1     skrll 
    822  1.1     skrll   lsb = 0;
    823  1.1     skrll 
    824  1.1     skrll   for (; *d != '\0'; d++)
    825  1.1     skrll     {
    826  1.1     skrll       switch (*d)
    827  1.1     skrll 	{
    828  1.1     skrll 	case ',':
    829  1.1     skrll 	case '(':
    830  1.1     skrll 	case ')':
    831  1.1     skrll 	case '[':
    832  1.1     skrll 	case ']':
    833  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%c", *d);
    834  1.1     skrll 	  break;
    835  1.1     skrll 
    836  1.1     skrll 	case '+':
    837  1.1     skrll 	  /* Extension character; switch for second char.  */
    838  1.1     skrll 	  d++;
    839  1.1     skrll 	  switch (*d)
    840  1.1     skrll 	    {
    841  1.1     skrll 	    case '\0':
    842  1.1     skrll 	      /* xgettext:c-format */
    843  1.1     skrll 	      (*info->fprintf_func) (info->stream,
    844  1.1     skrll 				     _("# internal error, incomplete extension sequence (+)"));
    845  1.1     skrll 	      return;
    846  1.1     skrll 
    847  1.1     skrll 	    case 'A':
    848  1.1     skrll 	      lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT;
    849  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%x", lsb);
    850  1.1     skrll 	      break;
    851  1.1     skrll 
    852  1.1     skrll 	    case 'B':
    853  1.1     skrll 	      msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB;
    854  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
    855  1.1     skrll 	      break;
    856  1.1     skrll 
    857  1.1     skrll 	    case '1':
    858  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%lx",
    859  1.1     skrll 				     (l >> OP_SH_UDI1) & OP_MASK_UDI1);
    860  1.1     skrll 	      break;
    861  1.1     skrll 
    862  1.1     skrll 	    case '2':
    863  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%lx",
    864  1.1     skrll 				     (l >> OP_SH_UDI2) & OP_MASK_UDI2);
    865  1.1     skrll 	      break;
    866  1.1     skrll 
    867  1.1     skrll 	    case '3':
    868  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%lx",
    869  1.1     skrll 				     (l >> OP_SH_UDI3) & OP_MASK_UDI3);
    870  1.1     skrll 	      break;
    871  1.1     skrll 
    872  1.1     skrll 	    case '4':
    873  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%lx",
    874  1.1     skrll 				     (l >> OP_SH_UDI4) & OP_MASK_UDI4);
    875  1.1     skrll 	      break;
    876  1.1     skrll 
    877  1.1     skrll 	    case 'C':
    878  1.1     skrll 	    case 'H':
    879  1.1     skrll 	      msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
    880  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
    881  1.1     skrll 	      break;
    882  1.1     skrll 
    883  1.1     skrll 	    case 'D':
    884  1.1     skrll 	      {
    885  1.1     skrll 		const struct mips_cp0sel_name *n;
    886  1.1     skrll 		unsigned int cp0reg, sel;
    887  1.1     skrll 
    888  1.1     skrll 		cp0reg = (l >> OP_SH_RD) & OP_MASK_RD;
    889  1.1     skrll 		sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
    890  1.1     skrll 
    891  1.1     skrll 		/* CP0 register including 'sel' code for mtcN (et al.), to be
    892  1.1     skrll 		   printed textually if known.  If not known, print both
    893  1.1     skrll 		   CP0 register name and sel numerically since CP0 register
    894  1.1     skrll 		   with sel 0 may have a name unrelated to register being
    895  1.1     skrll 		   printed.  */
    896  1.1     skrll 		n = lookup_mips_cp0sel_name(mips_cp0sel_names,
    897  1.1     skrll 					    mips_cp0sel_names_len, cp0reg, sel);
    898  1.1     skrll 		if (n != NULL)
    899  1.1     skrll 		  (*info->fprintf_func) (info->stream, "%s", n->name);
    900  1.1     skrll 		else
    901  1.1     skrll 		  (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
    902  1.1     skrll 		break;
    903  1.1     skrll 	      }
    904  1.1     skrll 
    905  1.1     skrll 	    case 'E':
    906  1.1     skrll 	      lsb = ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT) + 32;
    907  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%x", lsb);
    908  1.1     skrll 	      break;
    909  1.1     skrll 
    910  1.1     skrll 	    case 'F':
    911  1.1     skrll 	      msb = ((l >> OP_SH_INSMSB) & OP_MASK_INSMSB) + 32;
    912  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
    913  1.1     skrll 	      break;
    914  1.1     skrll 
    915  1.1     skrll 	    case 'G':
    916  1.1     skrll 	      msbd = ((l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD) + 32;
    917  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
    918  1.1     skrll 	      break;
    919  1.1     skrll 
    920  1.1     skrll 	    case 't': /* Coprocessor 0 reg name */
    921  1.1     skrll 	      (*info->fprintf_func) (info->stream, "%s",
    922  1.1     skrll 				     mips_cp0_names[(l >> OP_SH_RT) &
    923  1.1     skrll 						     OP_MASK_RT]);
    924  1.1     skrll 	      break;
    925  1.1     skrll 
    926  1.1     skrll 	    case 'T': /* Coprocessor 0 reg name */
    927  1.1     skrll 	      {
    928  1.1     skrll 		const struct mips_cp0sel_name *n;
    929  1.1     skrll 		unsigned int cp0reg, sel;
    930  1.1     skrll 
    931  1.1     skrll 		cp0reg = (l >> OP_SH_RT) & OP_MASK_RT;
    932  1.1     skrll 		sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
    933  1.1     skrll 
    934  1.1     skrll 		/* CP0 register including 'sel' code for mftc0, to be
    935  1.1     skrll 		   printed textually if known.  If not known, print both
    936  1.1     skrll 		   CP0 register name and sel numerically since CP0 register
    937  1.1     skrll 		   with sel 0 may have a name unrelated to register being
    938  1.1     skrll 		   printed.  */
    939  1.1     skrll 		n = lookup_mips_cp0sel_name(mips_cp0sel_names,
    940  1.1     skrll 					    mips_cp0sel_names_len, cp0reg, sel);
    941  1.1     skrll 		if (n != NULL)
    942  1.1     skrll 		  (*info->fprintf_func) (info->stream, "%s", n->name);
    943  1.1     skrll 		else
    944  1.1     skrll 		  (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
    945  1.1     skrll 		break;
    946  1.1     skrll 	      }
    947  1.1     skrll 
    948  1.1     skrll 	    case 'x':		/* bbit bit index */
    949  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%lx",
    950  1.1     skrll 				     (l >> OP_SH_BBITIND) & OP_MASK_BBITIND);
    951  1.1     skrll 	      break;
    952  1.1     skrll 
    953  1.1     skrll 	    case 'p':		/* cins, cins32, exts and exts32 position */
    954  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%lx",
    955  1.1     skrll 				     (l >> OP_SH_CINSPOS) & OP_MASK_CINSPOS);
    956  1.1     skrll 	      break;
    957  1.1     skrll 
    958  1.1     skrll 	    case 's':		/* cins and exts length-minus-one */
    959  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%lx",
    960  1.1     skrll 				     (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1);
    961  1.1     skrll 	      break;
    962  1.1     skrll 
    963  1.1     skrll 	    case 'S':		/* cins32 and exts32 length-minus-one field */
    964  1.1     skrll 	      (*info->fprintf_func) (info->stream, "0x%lx",
    965  1.1     skrll 				     (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1);
    966  1.1     skrll 	      break;
    967  1.1     skrll 
    968  1.1     skrll 	    case 'Q':		/* seqi/snei immediate field */
    969  1.1     skrll 	      op = (l >> OP_SH_SEQI) & OP_MASK_SEQI;
    970  1.1     skrll 	      /* Sign-extend it.  */
    971  1.1     skrll 	      op = (op ^ 512) - 512;
    972  1.1     skrll 	      (*info->fprintf_func) (info->stream, "%d", op);
    973  1.1     skrll 	      break;
    974  1.1     skrll 
    975  1.1     skrll 	    default:
    976  1.1     skrll 	      /* xgettext:c-format */
    977  1.1     skrll 	      (*info->fprintf_func) (info->stream,
    978  1.1     skrll 				     _("# internal error, undefined extension sequence (+%c)"),
    979  1.1     skrll 				     *d);
    980  1.1     skrll 	      return;
    981  1.1     skrll 	    }
    982  1.1     skrll 	  break;
    983  1.1     skrll 
    984  1.1     skrll 	case '2':
    985  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
    986  1.1     skrll 				 (l >> OP_SH_BP) & OP_MASK_BP);
    987  1.1     skrll 	  break;
    988  1.1     skrll 
    989  1.1     skrll 	case '3':
    990  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
    991  1.1     skrll 				 (l >> OP_SH_SA3) & OP_MASK_SA3);
    992  1.1     skrll 	  break;
    993  1.1     skrll 
    994  1.1     skrll 	case '4':
    995  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
    996  1.1     skrll 				 (l >> OP_SH_SA4) & OP_MASK_SA4);
    997  1.1     skrll 	  break;
    998  1.1     skrll 
    999  1.1     skrll 	case '5':
   1000  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1001  1.1     skrll 				 (l >> OP_SH_IMM8) & OP_MASK_IMM8);
   1002  1.1     skrll 	  break;
   1003  1.1     skrll 
   1004  1.1     skrll 	case '6':
   1005  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1006  1.1     skrll 				 (l >> OP_SH_RS) & OP_MASK_RS);
   1007  1.1     skrll 	  break;
   1008  1.1     skrll 
   1009  1.1     skrll 	case '7':
   1010  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$ac%ld",
   1011  1.1     skrll 				 (l >> OP_SH_DSPACC) & OP_MASK_DSPACC);
   1012  1.1     skrll 	  break;
   1013  1.1     skrll 
   1014  1.1     skrll 	case '8':
   1015  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1016  1.1     skrll 				 (l >> OP_SH_WRDSP) & OP_MASK_WRDSP);
   1017  1.1     skrll 	  break;
   1018  1.1     skrll 
   1019  1.1     skrll 	case '9':
   1020  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$ac%ld",
   1021  1.1     skrll 				 (l >> OP_SH_DSPACC_S) & OP_MASK_DSPACC_S);
   1022  1.1     skrll 	  break;
   1023  1.1     skrll 
   1024  1.1     skrll 	case '0': /* dsp 6-bit signed immediate in bit 20 */
   1025  1.1     skrll 	  delta = ((l >> OP_SH_DSPSFT) & OP_MASK_DSPSFT);
   1026  1.1     skrll 	  if (delta & 0x20) /* test sign bit */
   1027  1.1     skrll 	    delta |= ~OP_MASK_DSPSFT;
   1028  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%d", delta);
   1029  1.1     skrll 	  break;
   1030  1.1     skrll 
   1031  1.1     skrll 	case ':': /* dsp 7-bit signed immediate in bit 19 */
   1032  1.1     skrll 	  delta = ((l >> OP_SH_DSPSFT_7) & OP_MASK_DSPSFT_7);
   1033  1.1     skrll 	  if (delta & 0x40) /* test sign bit */
   1034  1.1     skrll 	    delta |= ~OP_MASK_DSPSFT_7;
   1035  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%d", delta);
   1036  1.1     skrll 	  break;
   1037  1.1     skrll 
   1038  1.1     skrll 	case '\'':
   1039  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1040  1.1     skrll 				 (l >> OP_SH_RDDSP) & OP_MASK_RDDSP);
   1041  1.1     skrll 	  break;
   1042  1.1     skrll 
   1043  1.1     skrll 	case '@': /* dsp 10-bit signed immediate in bit 16 */
   1044  1.1     skrll 	  delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
   1045  1.1     skrll 	  if (delta & 0x200) /* test sign bit */
   1046  1.1     skrll 	    delta |= ~OP_MASK_IMM10;
   1047  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%d", delta);
   1048  1.1     skrll 	  break;
   1049  1.1     skrll 
   1050  1.1     skrll 	case '!':
   1051  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%ld",
   1052  1.1     skrll 				 (l >> OP_SH_MT_U) & OP_MASK_MT_U);
   1053  1.1     skrll 	  break;
   1054  1.1     skrll 
   1055  1.1     skrll 	case '$':
   1056  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%ld",
   1057  1.1     skrll 				 (l >> OP_SH_MT_H) & OP_MASK_MT_H);
   1058  1.1     skrll 	  break;
   1059  1.1     skrll 
   1060  1.1     skrll 	case '*':
   1061  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$ac%ld",
   1062  1.1     skrll 				 (l >> OP_SH_MTACC_T) & OP_MASK_MTACC_T);
   1063  1.1     skrll 	  break;
   1064  1.1     skrll 
   1065  1.1     skrll 	case '&':
   1066  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$ac%ld",
   1067  1.1     skrll 				 (l >> OP_SH_MTACC_D) & OP_MASK_MTACC_D);
   1068  1.1     skrll 	  break;
   1069  1.1     skrll 
   1070  1.1     skrll 	case 'g':
   1071  1.1     skrll 	  /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2.  */
   1072  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$%ld",
   1073  1.1     skrll 				 (l >> OP_SH_RD) & OP_MASK_RD);
   1074  1.1     skrll 	  break;
   1075  1.1     skrll 
   1076  1.1     skrll 	case 's':
   1077  1.1     skrll 	case 'b':
   1078  1.1     skrll 	case 'r':
   1079  1.1     skrll 	case 'v':
   1080  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s",
   1081  1.1     skrll 				 mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
   1082  1.1     skrll 	  break;
   1083  1.1     skrll 
   1084  1.1     skrll 	case 't':
   1085  1.1     skrll 	case 'w':
   1086  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s",
   1087  1.1     skrll 				 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
   1088  1.1     skrll 	  break;
   1089  1.1     skrll 
   1090  1.1     skrll 	case 'i':
   1091  1.1     skrll 	case 'u':
   1092  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1093  1.1     skrll 				 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
   1094  1.1     skrll 	  break;
   1095  1.1     skrll 
   1096  1.1     skrll 	case 'j': /* Same as i, but sign-extended.  */
   1097  1.1     skrll 	case 'o':
   1098  1.1     skrll 	  delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
   1099  1.1     skrll 	  if (delta & 0x8000)
   1100  1.1     skrll 	    delta |= ~0xffff;
   1101  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%d",
   1102  1.1     skrll 				 delta);
   1103  1.1     skrll 	  break;
   1104  1.1     skrll 
   1105  1.1     skrll 	case 'h':
   1106  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%x",
   1107  1.1     skrll 				 (unsigned int) ((l >> OP_SH_PREFX)
   1108  1.1     skrll 						 & OP_MASK_PREFX));
   1109  1.1     skrll 	  break;
   1110  1.1     skrll 
   1111  1.1     skrll 	case 'k':
   1112  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%x",
   1113  1.1     skrll 				 (unsigned int) ((l >> OP_SH_CACHE)
   1114  1.1     skrll 						 & OP_MASK_CACHE));
   1115  1.1     skrll 	  break;
   1116  1.1     skrll 
   1117  1.1     skrll 	case 'a':
   1118  1.1     skrll 	  info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
   1119  1.1     skrll 			  | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
   1120  1.1     skrll 	  /* For gdb disassembler, force odd address on jalx.  */
   1121  1.1     skrll 	  if (info->flavour == bfd_target_unknown_flavour
   1122  1.1     skrll 	      && strcmp (opp->name, "jalx") == 0)
   1123  1.1     skrll 	    info->target |= 1;
   1124  1.1     skrll 	  (*info->print_address_func) (info->target, info);
   1125  1.1     skrll 	  break;
   1126  1.1     skrll 
   1127  1.1     skrll 	case 'p':
   1128  1.1     skrll 	  /* Sign extend the displacement.  */
   1129  1.1     skrll 	  delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
   1130  1.1     skrll 	  if (delta & 0x8000)
   1131  1.1     skrll 	    delta |= ~0xffff;
   1132  1.1     skrll 	  info->target = (delta << 2) + pc + INSNLEN;
   1133  1.1     skrll 	  (*info->print_address_func) (info->target, info);
   1134  1.1     skrll 	  break;
   1135  1.1     skrll 
   1136  1.1     skrll 	case 'd':
   1137  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s",
   1138  1.1     skrll 				 mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
   1139  1.1     skrll 	  break;
   1140  1.1     skrll 
   1141  1.1     skrll 	case 'U':
   1142  1.1     skrll 	  {
   1143  1.1     skrll 	    /* First check for both rd and rt being equal.  */
   1144  1.1     skrll 	    unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
   1145  1.1     skrll 	    if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
   1146  1.1     skrll 	      (*info->fprintf_func) (info->stream, "%s",
   1147  1.1     skrll 				     mips_gpr_names[reg]);
   1148  1.1     skrll 	    else
   1149  1.1     skrll 	      {
   1150  1.1     skrll 		/* If one is zero use the other.  */
   1151  1.1     skrll 		if (reg == 0)
   1152  1.1     skrll 		  (*info->fprintf_func) (info->stream, "%s",
   1153  1.1     skrll 					 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
   1154  1.1     skrll 		else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
   1155  1.1     skrll 		  (*info->fprintf_func) (info->stream, "%s",
   1156  1.1     skrll 					 mips_gpr_names[reg]);
   1157  1.1     skrll 		else /* Bogus, result depends on processor.  */
   1158  1.1     skrll 		  (*info->fprintf_func) (info->stream, "%s or %s",
   1159  1.1     skrll 					 mips_gpr_names[reg],
   1160  1.1     skrll 					 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
   1161  1.1     skrll 	      }
   1162  1.1     skrll 	  }
   1163  1.1     skrll 	  break;
   1164  1.1     skrll 
   1165  1.1     skrll 	case 'z':
   1166  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
   1167  1.3  christos 	  break;
   1168  1.1     skrll 
   1169  1.1     skrll 	case '<':
   1170  1.1     skrll 	case '1':
   1171  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1172  1.1     skrll 				 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
   1173  1.1     skrll 	  break;
   1174  1.1     skrll 
   1175  1.1     skrll 	case 'c':
   1176  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1177  1.1     skrll 				 (l >> OP_SH_CODE) & OP_MASK_CODE);
   1178  1.1     skrll 	  break;
   1179  1.1     skrll 
   1180  1.1     skrll 	case 'q':
   1181  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1182  1.1     skrll 				 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
   1183  1.1     skrll 	  break;
   1184  1.1     skrll 
   1185  1.1     skrll 	case 'C':
   1186  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1187  1.1     skrll 				 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
   1188  1.1     skrll 	  break;
   1189  1.1     skrll 
   1190  1.1     skrll 	case 'B':
   1191  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1192  1.1     skrll 
   1193  1.1     skrll 				 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
   1194  1.1     skrll 	  break;
   1195  1.1     skrll 
   1196  1.1     skrll 	case 'J':
   1197  1.1     skrll 	  (*info->fprintf_func) (info->stream, "0x%lx",
   1198  1.1     skrll 				 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
   1199  1.1     skrll 	  break;
   1200  1.1     skrll 
   1201  1.1     skrll 	case 'S':
   1202  1.1     skrll 	case 'V':
   1203  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s",
   1204  1.1     skrll 				 mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
   1205  1.1     skrll 	  break;
   1206  1.1     skrll 
   1207  1.1     skrll 	case 'T':
   1208  1.1     skrll 	case 'W':
   1209  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s",
   1210  1.1     skrll 				 mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
   1211  1.1     skrll 	  break;
   1212  1.1     skrll 
   1213  1.1     skrll 	case 'D':
   1214  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s",
   1215  1.1     skrll 				 mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
   1216  1.1     skrll 	  break;
   1217  1.1     skrll 
   1218  1.1     skrll 	case 'R':
   1219  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s",
   1220  1.1     skrll 				 mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
   1221  1.1     skrll 	  break;
   1222  1.1     skrll 
   1223  1.1     skrll 	case 'E':
   1224  1.1     skrll 	  /* Coprocessor register for lwcN instructions, et al.
   1225  1.1     skrll 
   1226  1.1     skrll 	     Note that there is no load/store cp0 instructions, and
   1227  1.1     skrll 	     that FPU (cp1) instructions disassemble this field using
   1228  1.1     skrll 	     'T' format.  Therefore, until we gain understanding of
   1229  1.1     skrll 	     cp2 register names, we can simply print the register
   1230  1.1     skrll 	     numbers.  */
   1231  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$%ld",
   1232  1.1     skrll 				 (l >> OP_SH_RT) & OP_MASK_RT);
   1233  1.1     skrll 	  break;
   1234  1.1     skrll 
   1235  1.1     skrll 	case 'G':
   1236  1.1     skrll 	  /* Coprocessor register for mtcN instructions, et al.  Note
   1237  1.1     skrll 	     that FPU (cp1) instructions disassemble this field using
   1238  1.1     skrll 	     'S' format.  Therefore, we only need to worry about cp0,
   1239  1.1     skrll 	     cp2, and cp3.  */
   1240  1.1     skrll 	  op = (l >> OP_SH_OP) & OP_MASK_OP;
   1241  1.1     skrll 	  if (op == OP_OP_COP0)
   1242  1.1     skrll 	    (*info->fprintf_func) (info->stream, "%s",
   1243  1.1     skrll 				   mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
   1244  1.1     skrll 	  else
   1245  1.1     skrll 	    (*info->fprintf_func) (info->stream, "$%ld",
   1246  1.1     skrll 				   (l >> OP_SH_RD) & OP_MASK_RD);
   1247  1.1     skrll 	  break;
   1248  1.1     skrll 
   1249  1.1     skrll 	case 'K':
   1250  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s",
   1251  1.1     skrll 				 mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
   1252  1.1     skrll 	  break;
   1253  1.1     skrll 
   1254  1.1     skrll 	case 'N':
   1255  1.1     skrll 	  (*info->fprintf_func) (info->stream,
   1256  1.1     skrll 				 ((opp->pinfo & (FP_D | FP_S)) != 0
   1257  1.1     skrll 				  ? "$fcc%ld" : "$cc%ld"),
   1258  1.1     skrll 				 (l >> OP_SH_BCC) & OP_MASK_BCC);
   1259  1.1     skrll 	  break;
   1260  1.1     skrll 
   1261  1.1     skrll 	case 'M':
   1262  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$fcc%ld",
   1263  1.1     skrll 				 (l >> OP_SH_CCC) & OP_MASK_CCC);
   1264  1.1     skrll 	  break;
   1265  1.1     skrll 
   1266  1.1     skrll 	case 'P':
   1267  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%ld",
   1268  1.1     skrll 				 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
   1269  1.1     skrll 	  break;
   1270  1.1     skrll 
   1271  1.1     skrll 	case 'e':
   1272  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%ld",
   1273  1.1     skrll 				 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
   1274  1.1     skrll 	  break;
   1275  1.1     skrll 
   1276  1.1     skrll 	case '%':
   1277  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%ld",
   1278  1.1     skrll 				 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
   1279  1.1     skrll 	  break;
   1280  1.1     skrll 
   1281  1.1     skrll 	case 'H':
   1282  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%ld",
   1283  1.1     skrll 				 (l >> OP_SH_SEL) & OP_MASK_SEL);
   1284  1.1     skrll 	  break;
   1285  1.1     skrll 
   1286  1.1     skrll 	case 'O':
   1287  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%ld",
   1288  1.1     skrll 				 (l >> OP_SH_ALN) & OP_MASK_ALN);
   1289  1.1     skrll 	  break;
   1290  1.1     skrll 
   1291  1.1     skrll 	case 'Q':
   1292  1.1     skrll 	  {
   1293  1.1     skrll 	    unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
   1294  1.1     skrll 
   1295  1.1     skrll 	    if ((vsel & 0x10) == 0)
   1296  1.1     skrll 	      {
   1297  1.1     skrll 		int fmt;
   1298  1.1     skrll 
   1299  1.1     skrll 		vsel &= 0x0f;
   1300  1.1     skrll 		for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
   1301  1.1     skrll 		  if ((vsel & 1) == 0)
   1302  1.1     skrll 		    break;
   1303  1.1     skrll 		(*info->fprintf_func) (info->stream, "$v%ld[%d]",
   1304  1.1     skrll 				       (l >> OP_SH_FT) & OP_MASK_FT,
   1305  1.1     skrll 				       vsel >> 1);
   1306  1.1     skrll 	      }
   1307  1.1     skrll 	    else if ((vsel & 0x08) == 0)
   1308  1.1     skrll 	      {
   1309  1.1     skrll 		(*info->fprintf_func) (info->stream, "$v%ld",
   1310  1.1     skrll 				       (l >> OP_SH_FT) & OP_MASK_FT);
   1311  1.1     skrll 	      }
   1312  1.1     skrll 	    else
   1313  1.1     skrll 	      {
   1314  1.1     skrll 		(*info->fprintf_func) (info->stream, "0x%lx",
   1315  1.1     skrll 				       (l >> OP_SH_FT) & OP_MASK_FT);
   1316  1.1     skrll 	      }
   1317  1.1     skrll 	  }
   1318  1.1     skrll 	  break;
   1319  1.1     skrll 
   1320  1.1     skrll 	case 'X':
   1321  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$v%ld",
   1322  1.1     skrll 				 (l >> OP_SH_FD) & OP_MASK_FD);
   1323  1.1     skrll 	  break;
   1324  1.1     skrll 
   1325  1.1     skrll 	case 'Y':
   1326  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$v%ld",
   1327  1.1     skrll 				 (l >> OP_SH_FS) & OP_MASK_FS);
   1328  1.1     skrll 	  break;
   1329  1.1     skrll 
   1330  1.1     skrll 	case 'Z':
   1331  1.1     skrll 	  (*info->fprintf_func) (info->stream, "$v%ld",
   1332  1.1     skrll 				 (l >> OP_SH_FT) & OP_MASK_FT);
   1333  1.1     skrll 	  break;
   1334  1.1     skrll 
   1335  1.1     skrll 	default:
   1336  1.1     skrll 	  /* xgettext:c-format */
   1337  1.1     skrll 	  (*info->fprintf_func) (info->stream,
   1338  1.1     skrll 				 _("# internal error, undefined modifier (%c)"),
   1339  1.1     skrll 				 *d);
   1340  1.1     skrll 	  return;
   1341  1.1     skrll 	}
   1342  1.1     skrll     }
   1343  1.1     skrll }
   1344  1.1     skrll 
   1345  1.1     skrll /* Print the mips instruction at address MEMADDR in debugged memory,
   1347  1.1     skrll    on using INFO.  Returns length of the instruction, in bytes, which is
   1348  1.1     skrll    always INSNLEN.  BIGENDIAN must be 1 if this is big-endian code, 0 if
   1349  1.1     skrll    this is little-endian code.  */
   1350  1.1     skrll 
   1351  1.1     skrll static int
   1352  1.1     skrll print_insn_mips (bfd_vma memaddr,
   1353  1.1     skrll 		 unsigned long int word,
   1354  1.1     skrll 		 struct disassemble_info *info)
   1355  1.1     skrll {
   1356  1.1     skrll   const struct mips_opcode *op;
   1357  1.1     skrll   static bfd_boolean init = 0;
   1358  1.1     skrll   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
   1359  1.1     skrll 
   1360  1.1     skrll   /* Build a hash table to shorten the search time.  */
   1361  1.1     skrll   if (! init)
   1362  1.1     skrll     {
   1363  1.1     skrll       unsigned int i;
   1364  1.1     skrll 
   1365  1.1     skrll       for (i = 0; i <= OP_MASK_OP; i++)
   1366  1.1     skrll 	{
   1367  1.1     skrll 	  for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
   1368  1.1     skrll 	    {
   1369  1.1     skrll 	      if (op->pinfo == INSN_MACRO
   1370  1.1     skrll 		  || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
   1371  1.1     skrll 		continue;
   1372  1.1     skrll 	      if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
   1373  1.1     skrll 		{
   1374  1.1     skrll 		  mips_hash[i] = op;
   1375  1.1     skrll 		  break;
   1376  1.1     skrll 		}
   1377  1.1     skrll 	    }
   1378  1.1     skrll 	}
   1379  1.1     skrll 
   1380  1.1     skrll       init = 1;
   1381  1.1     skrll     }
   1382  1.1     skrll 
   1383  1.1     skrll   info->bytes_per_chunk = INSNLEN;
   1384  1.1     skrll   info->display_endian = info->endian;
   1385  1.1     skrll   info->insn_info_valid = 1;
   1386  1.1     skrll   info->branch_delay_insns = 0;
   1387  1.1     skrll   info->data_size = 0;
   1388  1.1     skrll   info->insn_type = dis_nonbranch;
   1389  1.1     skrll   info->target = 0;
   1390  1.1     skrll   info->target2 = 0;
   1391  1.1     skrll 
   1392  1.1     skrll   op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
   1393  1.1     skrll   if (op != NULL)
   1394  1.1     skrll     {
   1395  1.1     skrll       for (; op < &mips_opcodes[NUMOPCODES]; op++)
   1396  1.1     skrll 	{
   1397  1.1     skrll 	  if (op->pinfo != INSN_MACRO
   1398  1.1     skrll 	      && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   1399  1.1     skrll 	      && (word & op->mask) == op->match)
   1400  1.1     skrll 	    {
   1401  1.1     skrll 	      const char *d;
   1402  1.1     skrll 
   1403  1.1     skrll 	      /* We always allow to disassemble the jalx instruction.  */
   1404  1.1     skrll 	      if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
   1405  1.1     skrll 		  && strcmp (op->name, "jalx"))
   1406  1.1     skrll 		continue;
   1407  1.3  christos 
   1408  1.3  christos 	      /* Figure out instruction type and branch delay information.  */
   1409  1.1     skrll 	      if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
   1410  1.1     skrll 	        {
   1411  1.1     skrll 		  if ((op->pinfo & (INSN_WRITE_GPR_31
   1412  1.1     skrll 				    | INSN_WRITE_GPR_D)) != 0)
   1413  1.1     skrll 		    info->insn_type = dis_jsr;
   1414  1.1     skrll 		  else
   1415  1.1     skrll 		    info->insn_type = dis_branch;
   1416  1.1     skrll 		  info->branch_delay_insns = 1;
   1417  1.3  christos 		}
   1418  1.1     skrll 	      else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
   1419  1.1     skrll 				     | INSN_COND_BRANCH_LIKELY)) != 0)
   1420  1.1     skrll 		{
   1421  1.1     skrll 		  if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   1422  1.1     skrll 		    info->insn_type = dis_condjsr;
   1423  1.1     skrll 		  else
   1424  1.1     skrll 		    info->insn_type = dis_condbranch;
   1425  1.1     skrll 		  info->branch_delay_insns = 1;
   1426  1.1     skrll 		}
   1427  1.1     skrll 	      else if ((op->pinfo & (INSN_STORE_MEMORY
   1428  1.1     skrll 				     | INSN_LOAD_MEMORY_DELAY)) != 0)
   1429  1.1     skrll 		info->insn_type = dis_dref;
   1430  1.1     skrll 
   1431  1.1     skrll 	      (*info->fprintf_func) (info->stream, "%s", op->name);
   1432  1.1     skrll 
   1433  1.1     skrll 	      d = op->args;
   1434  1.1     skrll 	      if (d != NULL && *d != '\0')
   1435  1.1     skrll 		{
   1436  1.1     skrll 		  (*info->fprintf_func) (info->stream, "\t");
   1437  1.1     skrll 		  print_insn_args (d, word, memaddr, info, op);
   1438  1.1     skrll 		}
   1439  1.1     skrll 
   1440  1.1     skrll 	      return INSNLEN;
   1441  1.1     skrll 	    }
   1442  1.1     skrll 	}
   1443  1.1     skrll     }
   1444  1.1     skrll 
   1445  1.1     skrll   /* Handle undefined instructions.  */
   1446  1.1     skrll   info->insn_type = dis_noninsn;
   1447  1.1     skrll   (*info->fprintf_func) (info->stream, "0x%lx", word);
   1448  1.1     skrll   return INSNLEN;
   1449  1.1     skrll }
   1450  1.1     skrll 
   1451  1.1     skrll /* Disassemble an operand for a mips16 instruction.  */
   1453  1.1     skrll 
   1454  1.1     skrll static void
   1455  1.1     skrll print_mips16_insn_arg (char type,
   1456  1.1     skrll 		       const struct mips_opcode *op,
   1457  1.1     skrll 		       int l,
   1458  1.1     skrll 		       bfd_boolean use_extend,
   1459  1.1     skrll 		       int extend,
   1460  1.1     skrll 		       bfd_vma memaddr,
   1461  1.1     skrll 		       struct disassemble_info *info)
   1462  1.1     skrll {
   1463  1.1     skrll   switch (type)
   1464  1.1     skrll     {
   1465  1.1     skrll     case ',':
   1466  1.1     skrll     case '(':
   1467  1.1     skrll     case ')':
   1468  1.1     skrll       (*info->fprintf_func) (info->stream, "%c", type);
   1469  1.1     skrll       break;
   1470  1.1     skrll 
   1471  1.1     skrll     case 'y':
   1472  1.1     skrll     case 'w':
   1473  1.1     skrll       (*info->fprintf_func) (info->stream, "%s",
   1474  1.1     skrll 			     mips16_reg_names(((l >> MIPS16OP_SH_RY)
   1475  1.1     skrll 					       & MIPS16OP_MASK_RY)));
   1476  1.1     skrll       break;
   1477  1.1     skrll 
   1478  1.1     skrll     case 'x':
   1479  1.1     skrll     case 'v':
   1480  1.1     skrll       (*info->fprintf_func) (info->stream, "%s",
   1481  1.1     skrll 			     mips16_reg_names(((l >> MIPS16OP_SH_RX)
   1482  1.1     skrll 					       & MIPS16OP_MASK_RX)));
   1483  1.1     skrll       break;
   1484  1.1     skrll 
   1485  1.1     skrll     case 'z':
   1486  1.1     skrll       (*info->fprintf_func) (info->stream, "%s",
   1487  1.1     skrll 			     mips16_reg_names(((l >> MIPS16OP_SH_RZ)
   1488  1.1     skrll 					       & MIPS16OP_MASK_RZ)));
   1489  1.1     skrll       break;
   1490  1.1     skrll 
   1491  1.1     skrll     case 'Z':
   1492  1.1     skrll       (*info->fprintf_func) (info->stream, "%s",
   1493  1.1     skrll 			     mips16_reg_names(((l >> MIPS16OP_SH_MOVE32Z)
   1494  1.1     skrll 					       & MIPS16OP_MASK_MOVE32Z)));
   1495  1.1     skrll       break;
   1496  1.1     skrll 
   1497  1.1     skrll     case '0':
   1498  1.1     skrll       (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
   1499  1.1     skrll       break;
   1500  1.1     skrll 
   1501  1.1     skrll     case 'S':
   1502  1.1     skrll       (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]);
   1503  1.1     skrll       break;
   1504  1.1     skrll 
   1505  1.1     skrll     case 'P':
   1506  1.1     skrll       (*info->fprintf_func) (info->stream, "$pc");
   1507  1.1     skrll       break;
   1508  1.1     skrll 
   1509  1.1     skrll     case 'R':
   1510  1.1     skrll       (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]);
   1511  1.1     skrll       break;
   1512  1.1     skrll 
   1513  1.1     skrll     case 'X':
   1514  1.1     skrll       (*info->fprintf_func) (info->stream, "%s",
   1515  1.1     skrll 			     mips_gpr_names[((l >> MIPS16OP_SH_REGR32)
   1516  1.1     skrll 					    & MIPS16OP_MASK_REGR32)]);
   1517  1.1     skrll       break;
   1518  1.1     skrll 
   1519  1.1     skrll     case 'Y':
   1520  1.1     skrll       (*info->fprintf_func) (info->stream, "%s",
   1521  1.1     skrll 			     mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
   1522  1.1     skrll       break;
   1523  1.1     skrll 
   1524  1.1     skrll     case '<':
   1525  1.1     skrll     case '>':
   1526  1.1     skrll     case '[':
   1527  1.1     skrll     case ']':
   1528  1.1     skrll     case '4':
   1529  1.1     skrll     case '5':
   1530  1.1     skrll     case 'H':
   1531  1.1     skrll     case 'W':
   1532  1.1     skrll     case 'D':
   1533  1.1     skrll     case 'j':
   1534  1.1     skrll     case '6':
   1535  1.1     skrll     case '8':
   1536  1.1     skrll     case 'V':
   1537  1.1     skrll     case 'C':
   1538  1.1     skrll     case 'U':
   1539  1.1     skrll     case 'k':
   1540  1.1     skrll     case 'K':
   1541  1.1     skrll     case 'p':
   1542  1.1     skrll     case 'q':
   1543  1.1     skrll     case 'A':
   1544  1.1     skrll     case 'B':
   1545  1.1     skrll     case 'E':
   1546  1.1     skrll       {
   1547  1.1     skrll 	int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
   1548  1.1     skrll 
   1549  1.1     skrll 	shift = 0;
   1550  1.1     skrll 	signedp = 0;
   1551  1.1     skrll 	extbits = 16;
   1552  1.1     skrll 	pcrel = 0;
   1553  1.1     skrll 	extu = 0;
   1554  1.1     skrll 	branch = 0;
   1555  1.1     skrll 	switch (type)
   1556  1.1     skrll 	  {
   1557  1.1     skrll 	  case '<':
   1558  1.1     skrll 	    nbits = 3;
   1559  1.1     skrll 	    immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
   1560  1.1     skrll 	    extbits = 5;
   1561  1.1     skrll 	    extu = 1;
   1562  1.1     skrll 	    break;
   1563  1.1     skrll 	  case '>':
   1564  1.1     skrll 	    nbits = 3;
   1565  1.1     skrll 	    immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
   1566  1.1     skrll 	    extbits = 5;
   1567  1.1     skrll 	    extu = 1;
   1568  1.1     skrll 	    break;
   1569  1.1     skrll 	  case '[':
   1570  1.1     skrll 	    nbits = 3;
   1571  1.1     skrll 	    immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
   1572  1.1     skrll 	    extbits = 6;
   1573  1.1     skrll 	    extu = 1;
   1574  1.1     skrll 	    break;
   1575  1.1     skrll 	  case ']':
   1576  1.1     skrll 	    nbits = 3;
   1577  1.1     skrll 	    immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
   1578  1.1     skrll 	    extbits = 6;
   1579  1.1     skrll 	    extu = 1;
   1580  1.1     skrll 	    break;
   1581  1.1     skrll 	  case '4':
   1582  1.1     skrll 	    nbits = 4;
   1583  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
   1584  1.1     skrll 	    signedp = 1;
   1585  1.1     skrll 	    extbits = 15;
   1586  1.1     skrll 	    break;
   1587  1.1     skrll 	  case '5':
   1588  1.1     skrll 	    nbits = 5;
   1589  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
   1590  1.1     skrll 	    info->insn_type = dis_dref;
   1591  1.1     skrll 	    info->data_size = 1;
   1592  1.1     skrll 	    break;
   1593  1.1     skrll 	  case 'H':
   1594  1.1     skrll 	    nbits = 5;
   1595  1.1     skrll 	    shift = 1;
   1596  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
   1597  1.1     skrll 	    info->insn_type = dis_dref;
   1598  1.1     skrll 	    info->data_size = 2;
   1599  1.1     skrll 	    break;
   1600  1.1     skrll 	  case 'W':
   1601  1.1     skrll 	    nbits = 5;
   1602  1.1     skrll 	    shift = 2;
   1603  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
   1604  1.1     skrll 	    if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
   1605  1.1     skrll 		&& (op->pinfo & MIPS16_INSN_READ_SP) == 0)
   1606  1.1     skrll 	      {
   1607  1.1     skrll 		info->insn_type = dis_dref;
   1608  1.1     skrll 		info->data_size = 4;
   1609  1.1     skrll 	      }
   1610  1.1     skrll 	    break;
   1611  1.1     skrll 	  case 'D':
   1612  1.1     skrll 	    nbits = 5;
   1613  1.1     skrll 	    shift = 3;
   1614  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
   1615  1.1     skrll 	    info->insn_type = dis_dref;
   1616  1.1     skrll 	    info->data_size = 8;
   1617  1.1     skrll 	    break;
   1618  1.1     skrll 	  case 'j':
   1619  1.1     skrll 	    nbits = 5;
   1620  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
   1621  1.1     skrll 	    signedp = 1;
   1622  1.1     skrll 	    break;
   1623  1.1     skrll 	  case '6':
   1624  1.1     skrll 	    nbits = 6;
   1625  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
   1626  1.1     skrll 	    break;
   1627  1.1     skrll 	  case '8':
   1628  1.1     skrll 	    nbits = 8;
   1629  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
   1630  1.1     skrll 	    break;
   1631  1.1     skrll 	  case 'V':
   1632  1.1     skrll 	    nbits = 8;
   1633  1.1     skrll 	    shift = 2;
   1634  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
   1635  1.1     skrll 	    /* FIXME: This might be lw, or it might be addiu to $sp or
   1636  1.1     skrll                $pc.  We assume it's load.  */
   1637  1.1     skrll 	    info->insn_type = dis_dref;
   1638  1.1     skrll 	    info->data_size = 4;
   1639  1.1     skrll 	    break;
   1640  1.1     skrll 	  case 'C':
   1641  1.1     skrll 	    nbits = 8;
   1642  1.1     skrll 	    shift = 3;
   1643  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
   1644  1.1     skrll 	    info->insn_type = dis_dref;
   1645  1.1     skrll 	    info->data_size = 8;
   1646  1.1     skrll 	    break;
   1647  1.1     skrll 	  case 'U':
   1648  1.1     skrll 	    nbits = 8;
   1649  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
   1650  1.1     skrll 	    extu = 1;
   1651  1.1     skrll 	    break;
   1652  1.1     skrll 	  case 'k':
   1653  1.1     skrll 	    nbits = 8;
   1654  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
   1655  1.1     skrll 	    signedp = 1;
   1656  1.1     skrll 	    break;
   1657  1.1     skrll 	  case 'K':
   1658  1.1     skrll 	    nbits = 8;
   1659  1.1     skrll 	    shift = 3;
   1660  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
   1661  1.1     skrll 	    signedp = 1;
   1662  1.1     skrll 	    break;
   1663  1.1     skrll 	  case 'p':
   1664  1.1     skrll 	    nbits = 8;
   1665  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
   1666  1.1     skrll 	    signedp = 1;
   1667  1.1     skrll 	    pcrel = 1;
   1668  1.1     skrll 	    branch = 1;
   1669  1.1     skrll 	    break;
   1670  1.1     skrll 	  case 'q':
   1671  1.1     skrll 	    nbits = 11;
   1672  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
   1673  1.1     skrll 	    signedp = 1;
   1674  1.1     skrll 	    pcrel = 1;
   1675  1.1     skrll 	    branch = 1;
   1676  1.1     skrll 	    break;
   1677  1.1     skrll 	  case 'A':
   1678  1.1     skrll 	    nbits = 8;
   1679  1.1     skrll 	    shift = 2;
   1680  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
   1681  1.1     skrll 	    pcrel = 1;
   1682  1.1     skrll 	    /* FIXME: This can be lw or la.  We assume it is lw.  */
   1683  1.1     skrll 	    info->insn_type = dis_dref;
   1684  1.1     skrll 	    info->data_size = 4;
   1685  1.1     skrll 	    break;
   1686  1.1     skrll 	  case 'B':
   1687  1.1     skrll 	    nbits = 5;
   1688  1.1     skrll 	    shift = 3;
   1689  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
   1690  1.1     skrll 	    pcrel = 1;
   1691  1.1     skrll 	    info->insn_type = dis_dref;
   1692  1.1     skrll 	    info->data_size = 8;
   1693  1.1     skrll 	    break;
   1694  1.1     skrll 	  case 'E':
   1695  1.1     skrll 	    nbits = 5;
   1696  1.1     skrll 	    shift = 2;
   1697  1.1     skrll 	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
   1698  1.1     skrll 	    pcrel = 1;
   1699  1.1     skrll 	    break;
   1700  1.1     skrll 	  default:
   1701  1.1     skrll 	    abort ();
   1702  1.1     skrll 	  }
   1703  1.1     skrll 
   1704  1.1     skrll 	if (! use_extend)
   1705  1.1     skrll 	  {
   1706  1.1     skrll 	    if (signedp && immed >= (1 << (nbits - 1)))
   1707  1.1     skrll 	      immed -= 1 << nbits;
   1708  1.1     skrll 	    immed <<= shift;
   1709  1.1     skrll 	    if ((type == '<' || type == '>' || type == '[' || type == ']')
   1710  1.1     skrll 		&& immed == 0)
   1711  1.1     skrll 	      immed = 8;
   1712  1.1     skrll 	  }
   1713  1.1     skrll 	else
   1714  1.1     skrll 	  {
   1715  1.1     skrll 	    if (extbits == 16)
   1716  1.1     skrll 	      immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
   1717  1.1     skrll 	    else if (extbits == 15)
   1718  1.1     skrll 	      immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
   1719  1.1     skrll 	    else
   1720  1.1     skrll 	      immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
   1721  1.1     skrll 	    immed &= (1 << extbits) - 1;
   1722  1.1     skrll 	    if (! extu && immed >= (1 << (extbits - 1)))
   1723  1.1     skrll 	      immed -= 1 << extbits;
   1724  1.1     skrll 	  }
   1725  1.1     skrll 
   1726  1.1     skrll 	if (! pcrel)
   1727  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%d", immed);
   1728  1.1     skrll 	else
   1729  1.1     skrll 	  {
   1730  1.1     skrll 	    bfd_vma baseaddr;
   1731  1.1     skrll 
   1732  1.1     skrll 	    if (branch)
   1733  1.1     skrll 	      {
   1734  1.1     skrll 		immed *= 2;
   1735  1.1     skrll 		baseaddr = memaddr + 2;
   1736  1.1     skrll 	      }
   1737  1.1     skrll 	    else if (use_extend)
   1738  1.1     skrll 	      baseaddr = memaddr - 2;
   1739  1.1     skrll 	    else
   1740  1.1     skrll 	      {
   1741  1.1     skrll 		int status;
   1742  1.1     skrll 		bfd_byte buffer[2];
   1743  1.1     skrll 
   1744  1.1     skrll 		baseaddr = memaddr;
   1745  1.1     skrll 
   1746  1.1     skrll 		/* If this instruction is in the delay slot of a jr
   1747  1.1     skrll                    instruction, the base address is the address of the
   1748  1.1     skrll                    jr instruction.  If it is in the delay slot of jalr
   1749  1.1     skrll                    instruction, the base address is the address of the
   1750  1.1     skrll                    jalr instruction.  This test is unreliable: we have
   1751  1.1     skrll                    no way of knowing whether the previous word is
   1752  1.1     skrll                    instruction or data.  */
   1753  1.1     skrll 		status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
   1754  1.1     skrll 						    info);
   1755  1.1     skrll 		if (status == 0
   1756  1.1     skrll 		    && (((info->endian == BFD_ENDIAN_BIG
   1757  1.1     skrll 			  ? bfd_getb16 (buffer)
   1758  1.1     skrll 			  : bfd_getl16 (buffer))
   1759  1.1     skrll 			 & 0xf800) == 0x1800))
   1760  1.1     skrll 		  baseaddr = memaddr - 4;
   1761  1.1     skrll 		else
   1762  1.1     skrll 		  {
   1763  1.1     skrll 		    status = (*info->read_memory_func) (memaddr - 2, buffer,
   1764  1.1     skrll 							2, info);
   1765  1.1     skrll 		    if (status == 0
   1766  1.1     skrll 			&& (((info->endian == BFD_ENDIAN_BIG
   1767  1.1     skrll 			      ? bfd_getb16 (buffer)
   1768  1.1     skrll 			      : bfd_getl16 (buffer))
   1769  1.1     skrll 			     & 0xf81f) == 0xe800))
   1770  1.1     skrll 		      baseaddr = memaddr - 2;
   1771  1.1     skrll 		  }
   1772  1.1     skrll 	      }
   1773  1.1     skrll 	    info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
   1774  1.1     skrll 	    if (pcrel && branch
   1775  1.1     skrll 		&& info->flavour == bfd_target_unknown_flavour)
   1776  1.1     skrll 	      /* For gdb disassembler, maintain odd address.  */
   1777  1.1     skrll 	      info->target |= 1;
   1778  1.1     skrll 	    (*info->print_address_func) (info->target, info);
   1779  1.1     skrll 	  }
   1780  1.1     skrll       }
   1781  1.1     skrll       break;
   1782  1.1     skrll 
   1783  1.1     skrll     case 'a':
   1784  1.1     skrll       {
   1785  1.1     skrll 	int jalx = l & 0x400;
   1786  1.1     skrll 
   1787  1.1     skrll 	if (! use_extend)
   1788  1.1     skrll 	  extend = 0;
   1789  1.1     skrll 	l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
   1790  1.1     skrll 	if (!jalx && info->flavour == bfd_target_unknown_flavour)
   1791  1.1     skrll 	  /* For gdb disassembler, maintain odd address.  */
   1792  1.1     skrll 	  l |= 1;
   1793  1.1     skrll       }
   1794  1.1     skrll       info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
   1795  1.1     skrll       (*info->print_address_func) (info->target, info);
   1796  1.1     skrll       break;
   1797  1.1     skrll 
   1798  1.1     skrll     case 'l':
   1799  1.1     skrll     case 'L':
   1800  1.1     skrll       {
   1801  1.1     skrll 	int need_comma, amask, smask;
   1802  1.1     skrll 
   1803  1.1     skrll 	need_comma = 0;
   1804  1.1     skrll 
   1805  1.1     skrll 	l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
   1806  1.1     skrll 
   1807  1.1     skrll 	amask = (l >> 3) & 7;
   1808  1.1     skrll 
   1809  1.1     skrll 	if (amask > 0 && amask < 5)
   1810  1.1     skrll 	  {
   1811  1.1     skrll 	    (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
   1812  1.1     skrll 	    if (amask > 1)
   1813  1.1     skrll 	      (*info->fprintf_func) (info->stream, "-%s",
   1814  1.1     skrll 				     mips_gpr_names[amask + 3]);
   1815  1.1     skrll 	    need_comma = 1;
   1816  1.1     skrll 	  }
   1817  1.1     skrll 
   1818  1.1     skrll 	smask = (l >> 1) & 3;
   1819  1.1     skrll 	if (smask == 3)
   1820  1.1     skrll 	  {
   1821  1.1     skrll 	    (*info->fprintf_func) (info->stream, "%s??",
   1822  1.1     skrll 				   need_comma ? "," : "");
   1823  1.1     skrll 	    need_comma = 1;
   1824  1.1     skrll 	  }
   1825  1.1     skrll 	else if (smask > 0)
   1826  1.1     skrll 	  {
   1827  1.1     skrll 	    (*info->fprintf_func) (info->stream, "%s%s",
   1828  1.1     skrll 				   need_comma ? "," : "",
   1829  1.1     skrll 				   mips_gpr_names[16]);
   1830  1.1     skrll 	    if (smask > 1)
   1831  1.1     skrll 	      (*info->fprintf_func) (info->stream, "-%s",
   1832  1.1     skrll 				     mips_gpr_names[smask + 15]);
   1833  1.1     skrll 	    need_comma = 1;
   1834  1.1     skrll 	  }
   1835  1.1     skrll 
   1836  1.1     skrll 	if (l & 1)
   1837  1.1     skrll 	  {
   1838  1.1     skrll 	    (*info->fprintf_func) (info->stream, "%s%s",
   1839  1.1     skrll 				   need_comma ? "," : "",
   1840  1.1     skrll 				   mips_gpr_names[31]);
   1841  1.1     skrll 	    need_comma = 1;
   1842  1.1     skrll 	  }
   1843  1.1     skrll 
   1844  1.1     skrll 	if (amask == 5 || amask == 6)
   1845  1.1     skrll 	  {
   1846  1.1     skrll 	    (*info->fprintf_func) (info->stream, "%s$f0",
   1847  1.1     skrll 				   need_comma ? "," : "");
   1848  1.1     skrll 	    if (amask == 6)
   1849  1.1     skrll 	      (*info->fprintf_func) (info->stream, "-$f1");
   1850  1.1     skrll 	  }
   1851  1.1     skrll       }
   1852  1.1     skrll       break;
   1853  1.1     skrll 
   1854  1.1     skrll     case 'm':
   1855  1.1     skrll     case 'M':
   1856  1.1     skrll       /* MIPS16e save/restore.  */
   1857  1.1     skrll       {
   1858  1.1     skrll       int need_comma = 0;
   1859  1.1     skrll       int amask, args, statics;
   1860  1.1     skrll       int nsreg, smask;
   1861  1.1     skrll       int framesz;
   1862  1.1     skrll       int i, j;
   1863  1.1     skrll 
   1864  1.1     skrll       l = l & 0x7f;
   1865  1.1     skrll       if (use_extend)
   1866  1.1     skrll         l |= extend << 16;
   1867  1.1     skrll 
   1868  1.1     skrll       amask = (l >> 16) & 0xf;
   1869  1.1     skrll       if (amask == MIPS16_ALL_ARGS)
   1870  1.1     skrll         {
   1871  1.1     skrll           args = 4;
   1872  1.1     skrll           statics = 0;
   1873  1.1     skrll         }
   1874  1.1     skrll       else if (amask == MIPS16_ALL_STATICS)
   1875  1.1     skrll         {
   1876  1.1     skrll           args = 0;
   1877  1.1     skrll           statics = 4;
   1878  1.1     skrll         }
   1879  1.1     skrll       else
   1880  1.1     skrll         {
   1881  1.1     skrll           args = amask >> 2;
   1882  1.1     skrll           statics = amask & 3;
   1883  1.1     skrll         }
   1884  1.1     skrll 
   1885  1.1     skrll       if (args > 0) {
   1886  1.1     skrll           (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
   1887  1.1     skrll           if (args > 1)
   1888  1.1     skrll             (*info->fprintf_func) (info->stream, "-%s",
   1889  1.1     skrll                                    mips_gpr_names[4 + args - 1]);
   1890  1.1     skrll           need_comma = 1;
   1891  1.1     skrll       }
   1892  1.1     skrll 
   1893  1.1     skrll       framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
   1894  1.1     skrll       if (framesz == 0 && !use_extend)
   1895  1.1     skrll         framesz = 128;
   1896  1.1     skrll 
   1897  1.1     skrll       (*info->fprintf_func) (info->stream, "%s%d",
   1898  1.1     skrll                              need_comma ? "," : "",
   1899  1.1     skrll                              framesz);
   1900  1.1     skrll 
   1901  1.1     skrll       if (l & 0x40)                   /* $ra */
   1902  1.1     skrll         (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[31]);
   1903  1.1     skrll 
   1904  1.1     skrll       nsreg = (l >> 24) & 0x7;
   1905  1.1     skrll       smask = 0;
   1906  1.1     skrll       if (l & 0x20)                   /* $s0 */
   1907  1.1     skrll         smask |= 1 << 0;
   1908  1.1     skrll       if (l & 0x10)                   /* $s1 */
   1909  1.1     skrll         smask |= 1 << 1;
   1910  1.1     skrll       if (nsreg > 0)                  /* $s2-$s8 */
   1911  1.1     skrll         smask |= ((1 << nsreg) - 1) << 2;
   1912  1.1     skrll 
   1913  1.1     skrll       /* Find first set static reg bit.  */
   1914  1.1     skrll       for (i = 0; i < 9; i++)
   1915  1.1     skrll         {
   1916  1.1     skrll           if (smask & (1 << i))
   1917  1.1     skrll             {
   1918  1.1     skrll               (*info->fprintf_func) (info->stream, ",%s",
   1919  1.1     skrll                                      mips_gpr_names[i == 8 ? 30 : (16 + i)]);
   1920  1.1     skrll               /* Skip over string of set bits.  */
   1921  1.1     skrll               for (j = i; smask & (2 << j); j++)
   1922  1.1     skrll                 continue;
   1923  1.1     skrll               if (j > i)
   1924  1.1     skrll                 (*info->fprintf_func) (info->stream, "-%s",
   1925  1.1     skrll                                        mips_gpr_names[j == 8 ? 30 : (16 + j)]);
   1926  1.1     skrll               i = j + 1;
   1927  1.1     skrll             }
   1928  1.1     skrll         }
   1929  1.1     skrll 
   1930  1.1     skrll       /* Statics $ax - $a3.  */
   1931  1.1     skrll       if (statics == 1)
   1932  1.1     skrll         (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[7]);
   1933  1.1     skrll       else if (statics > 0)
   1934  1.1     skrll         (*info->fprintf_func) (info->stream, ",%s-%s",
   1935  1.1     skrll                                mips_gpr_names[7 - statics + 1],
   1936  1.1     skrll                                mips_gpr_names[7]);
   1937  1.1     skrll       }
   1938  1.1     skrll       break;
   1939  1.1     skrll 
   1940  1.1     skrll     default:
   1941  1.1     skrll       /* xgettext:c-format */
   1942  1.1     skrll       (*info->fprintf_func)
   1943  1.1     skrll 	(info->stream,
   1944  1.1     skrll 	 _("# internal disassembler error, unrecognised modifier (%c)"),
   1945  1.1     skrll 	 type);
   1946  1.1     skrll       abort ();
   1947  1.1     skrll     }
   1948  1.1     skrll }
   1949  1.1     skrll 
   1950  1.1     skrll /* Disassemble mips16 instructions.  */
   1951  1.1     skrll 
   1952  1.1     skrll static int
   1953  1.1     skrll print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
   1954  1.1     skrll {
   1955  1.1     skrll   int status;
   1956  1.1     skrll   bfd_byte buffer[2];
   1957  1.1     skrll   int length;
   1958  1.1     skrll   int insn;
   1959  1.1     skrll   bfd_boolean use_extend;
   1960  1.1     skrll   int extend = 0;
   1961  1.1     skrll   const struct mips_opcode *op, *opend;
   1962  1.1     skrll 
   1963  1.1     skrll   info->bytes_per_chunk = 2;
   1964  1.1     skrll   info->display_endian = info->endian;
   1965  1.1     skrll   info->insn_info_valid = 1;
   1966  1.1     skrll   info->branch_delay_insns = 0;
   1967  1.1     skrll   info->data_size = 0;
   1968  1.1     skrll   info->insn_type = dis_nonbranch;
   1969  1.1     skrll   info->target = 0;
   1970  1.1     skrll   info->target2 = 0;
   1971  1.1     skrll 
   1972  1.1     skrll   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   1973  1.1     skrll   if (status != 0)
   1974  1.1     skrll     {
   1975  1.1     skrll       (*info->memory_error_func) (status, memaddr, info);
   1976  1.1     skrll       return -1;
   1977  1.1     skrll     }
   1978  1.1     skrll 
   1979  1.1     skrll   length = 2;
   1980  1.1     skrll 
   1981  1.1     skrll   if (info->endian == BFD_ENDIAN_BIG)
   1982  1.1     skrll     insn = bfd_getb16 (buffer);
   1983  1.1     skrll   else
   1984  1.1     skrll     insn = bfd_getl16 (buffer);
   1985  1.1     skrll 
   1986  1.1     skrll   /* Handle the extend opcode specially.  */
   1987  1.1     skrll   use_extend = FALSE;
   1988  1.1     skrll   if ((insn & 0xf800) == 0xf000)
   1989  1.1     skrll     {
   1990  1.1     skrll       use_extend = TRUE;
   1991  1.1     skrll       extend = insn & 0x7ff;
   1992  1.1     skrll 
   1993  1.1     skrll       memaddr += 2;
   1994  1.1     skrll 
   1995  1.1     skrll       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   1996  1.1     skrll       if (status != 0)
   1997  1.1     skrll 	{
   1998  1.1     skrll 	  (*info->fprintf_func) (info->stream, "extend 0x%x",
   1999  1.1     skrll 				 (unsigned int) extend);
   2000  1.1     skrll 	  (*info->memory_error_func) (status, memaddr, info);
   2001  1.1     skrll 	  return -1;
   2002  1.1     skrll 	}
   2003  1.1     skrll 
   2004  1.1     skrll       if (info->endian == BFD_ENDIAN_BIG)
   2005  1.1     skrll 	insn = bfd_getb16 (buffer);
   2006  1.1     skrll       else
   2007  1.1     skrll 	insn = bfd_getl16 (buffer);
   2008  1.1     skrll 
   2009  1.1     skrll       /* Check for an extend opcode followed by an extend opcode.  */
   2010  1.1     skrll       if ((insn & 0xf800) == 0xf000)
   2011  1.1     skrll 	{
   2012  1.1     skrll 	  (*info->fprintf_func) (info->stream, "extend 0x%x",
   2013  1.1     skrll 				 (unsigned int) extend);
   2014  1.1     skrll 	  info->insn_type = dis_noninsn;
   2015  1.1     skrll 	  return length;
   2016  1.1     skrll 	}
   2017  1.1     skrll 
   2018  1.1     skrll       length += 2;
   2019  1.1     skrll     }
   2020  1.1     skrll 
   2021  1.1     skrll   /* FIXME: Should probably use a hash table on the major opcode here.  */
   2022  1.1     skrll 
   2023  1.1     skrll   opend = mips16_opcodes + bfd_mips16_num_opcodes;
   2024  1.1     skrll   for (op = mips16_opcodes; op < opend; op++)
   2025  1.1     skrll     {
   2026  1.1     skrll       if (op->pinfo != INSN_MACRO
   2027  1.1     skrll 	  && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   2028  1.1     skrll 	  && (insn & op->mask) == op->match)
   2029  1.1     skrll 	{
   2030  1.1     skrll 	  const char *s;
   2031  1.1     skrll 
   2032  1.1     skrll 	  if (strchr (op->args, 'a') != NULL)
   2033  1.1     skrll 	    {
   2034  1.1     skrll 	      if (use_extend)
   2035  1.1     skrll 		{
   2036  1.1     skrll 		  (*info->fprintf_func) (info->stream, "extend 0x%x",
   2037  1.1     skrll 					 (unsigned int) extend);
   2038  1.1     skrll 		  info->insn_type = dis_noninsn;
   2039  1.1     skrll 		  return length - 2;
   2040  1.1     skrll 		}
   2041  1.1     skrll 
   2042  1.1     skrll 	      use_extend = FALSE;
   2043  1.1     skrll 
   2044  1.1     skrll 	      memaddr += 2;
   2045  1.1     skrll 
   2046  1.1     skrll 	      status = (*info->read_memory_func) (memaddr, buffer, 2,
   2047  1.1     skrll 						  info);
   2048  1.1     skrll 	      if (status == 0)
   2049  1.1     skrll 		{
   2050  1.1     skrll 		  use_extend = TRUE;
   2051  1.1     skrll 		  if (info->endian == BFD_ENDIAN_BIG)
   2052  1.1     skrll 		    extend = bfd_getb16 (buffer);
   2053  1.1     skrll 		  else
   2054  1.1     skrll 		    extend = bfd_getl16 (buffer);
   2055  1.1     skrll 		  length += 2;
   2056  1.1     skrll 		}
   2057  1.1     skrll 	    }
   2058  1.1     skrll 
   2059  1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s", op->name);
   2060  1.1     skrll 	  if (op->args[0] != '\0')
   2061  1.1     skrll 	    (*info->fprintf_func) (info->stream, "\t");
   2062  1.1     skrll 
   2063  1.1     skrll 	  for (s = op->args; *s != '\0'; s++)
   2064  1.1     skrll 	    {
   2065  1.1     skrll 	      if (*s == ','
   2066  1.1     skrll 		  && s[1] == 'w'
   2067  1.1     skrll 		  && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
   2068  1.1     skrll 		      == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
   2069  1.1     skrll 		{
   2070  1.1     skrll 		  /* Skip the register and the comma.  */
   2071  1.1     skrll 		  ++s;
   2072  1.1     skrll 		  continue;
   2073  1.1     skrll 		}
   2074  1.1     skrll 	      if (*s == ','
   2075  1.1     skrll 		  && s[1] == 'v'
   2076  1.1     skrll 		  && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
   2077  1.1     skrll 		      == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
   2078  1.1     skrll 		{
   2079  1.1     skrll 		  /* Skip the register and the comma.  */
   2080  1.1     skrll 		  ++s;
   2081  1.1     skrll 		  continue;
   2082  1.3  christos 		}
   2083  1.1     skrll 	      print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
   2084  1.3  christos 				     info);
   2085  1.3  christos 	    }
   2086  1.3  christos 
   2087  1.1     skrll 	  /* Figure out branch instruction type and delay slot information.  */
   2088  1.3  christos 	  if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
   2089  1.3  christos 	    info->branch_delay_insns = 1;
   2090  1.3  christos 	  if ((op->pinfo & (INSN_UNCOND_BRANCH_DELAY
   2091  1.1     skrll 			    | MIPS16_INSN_UNCOND_BRANCH)) != 0)
   2092  1.1     skrll 	    {
   2093  1.3  christos 	      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   2094  1.3  christos 		info->insn_type = dis_jsr;
   2095  1.1     skrll 	      else
   2096  1.1     skrll 		info->insn_type = dis_branch;
   2097  1.1     skrll 	    }
   2098  1.1     skrll 	  else if ((op->pinfo & MIPS16_INSN_COND_BRANCH) != 0)
   2099  1.1     skrll 	    info->insn_type = dis_condbranch;
   2100  1.1     skrll 
   2101  1.1     skrll 	  return length;
   2102  1.1     skrll 	}
   2103  1.1     skrll     }
   2104  1.1     skrll 
   2105  1.1     skrll   if (use_extend)
   2106  1.1     skrll     (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
   2107  1.1     skrll   (*info->fprintf_func) (info->stream, "0x%x", insn);
   2108  1.1     skrll   info->insn_type = dis_noninsn;
   2109  1.1     skrll 
   2110  1.1     skrll   return length;
   2111  1.1     skrll }
   2112  1.1     skrll 
   2113  1.1     skrll /* In an environment where we do not know the symbol type of the
   2114  1.1     skrll    instruction we are forced to assume that the low order bit of the
   2115  1.1     skrll    instructions' address may mark it as a mips16 instruction.  If we
   2116  1.1     skrll    are single stepping, or the pc is within the disassembled function,
   2117  1.1     skrll    this works.  Otherwise, we need a clue.  Sometimes.  */
   2118  1.1     skrll 
   2119  1.1     skrll static int
   2120  1.1     skrll _print_insn_mips (bfd_vma memaddr,
   2121  1.1     skrll 		  struct disassemble_info *info,
   2122  1.1     skrll 		  enum bfd_endian endianness)
   2123  1.1     skrll {
   2124  1.1     skrll   bfd_byte buffer[INSNLEN];
   2125  1.1     skrll   int status;
   2126  1.1     skrll 
   2127  1.1     skrll   set_default_mips_dis_options (info);
   2128  1.1     skrll   parse_mips_dis_options (info->disassembler_options);
   2129  1.1     skrll 
   2130  1.1     skrll #if 1
   2131  1.1     skrll   /* FIXME: If odd address, this is CLEARLY a mips 16 instruction.  */
   2132  1.1     skrll   /* Only a few tools will work this way.  */
   2133  1.1     skrll   if (memaddr & 0x01)
   2134  1.1     skrll     return print_insn_mips16 (memaddr, info);
   2135  1.1     skrll #endif
   2136  1.1     skrll 
   2137  1.1     skrll #if SYMTAB_AVAILABLE
   2138  1.1     skrll   if (info->mach == bfd_mach_mips16
   2139  1.1     skrll       || (info->symbols != NULL
   2140  1.1     skrll 	  && bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
   2141  1.1     skrll 	  && ELF_ST_IS_MIPS16 ((*(elf_symbol_type **) info->symbols)
   2142  1.1     skrll 			       ->internal_elf_sym.st_other)))
   2143  1.1     skrll     return print_insn_mips16 (memaddr, info);
   2144  1.1     skrll #endif
   2145  1.1     skrll 
   2146  1.1     skrll   status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
   2147  1.1     skrll   if (status == 0)
   2148  1.1     skrll     {
   2149  1.1     skrll       unsigned long insn;
   2150  1.1     skrll 
   2151  1.1     skrll       if (endianness == BFD_ENDIAN_BIG)
   2152  1.1     skrll 	insn = (unsigned long) bfd_getb32 (buffer);
   2153  1.1     skrll       else
   2154  1.1     skrll 	insn = (unsigned long) bfd_getl32 (buffer);
   2155  1.1     skrll 
   2156  1.1     skrll       return print_insn_mips (memaddr, insn, info);
   2157  1.1     skrll     }
   2158  1.1     skrll   else
   2159  1.1     skrll     {
   2160  1.1     skrll       (*info->memory_error_func) (status, memaddr, info);
   2161  1.1     skrll       return -1;
   2162  1.1     skrll     }
   2163  1.1     skrll }
   2164  1.1     skrll 
   2165  1.1     skrll int
   2166  1.1     skrll print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
   2167  1.1     skrll {
   2168  1.1     skrll   return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
   2169  1.1     skrll }
   2170  1.1     skrll 
   2171  1.1     skrll int
   2172  1.1     skrll print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
   2173  1.1     skrll {
   2174  1.1     skrll   return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
   2175  1.1     skrll }
   2176  1.1     skrll 
   2177  1.1     skrll void
   2179  1.1     skrll print_mips_disassembler_options (FILE *stream)
   2180  1.1     skrll {
   2181  1.1     skrll   unsigned int i;
   2182  1.1     skrll 
   2183  1.1     skrll   fprintf (stream, _("\n\
   2184  1.1     skrll The following MIPS specific disassembler options are supported for use\n\
   2185  1.1     skrll with the -M switch (multiple options should be separated by commas):\n"));
   2186  1.1     skrll 
   2187  1.1     skrll   fprintf (stream, _("\n\
   2188  1.1     skrll   gpr-names=ABI            Print GPR names according to  specified ABI.\n\
   2189  1.1     skrll                            Default: based on binary being disassembled.\n"));
   2190  1.1     skrll 
   2191  1.1     skrll   fprintf (stream, _("\n\
   2192  1.1     skrll   fpr-names=ABI            Print FPR names according to specified ABI.\n\
   2193  1.1     skrll                            Default: numeric.\n"));
   2194  1.1     skrll 
   2195  1.1     skrll   fprintf (stream, _("\n\
   2196  1.1     skrll   cp0-names=ARCH           Print CP0 register names according to\n\
   2197  1.1     skrll                            specified architecture.\n\
   2198  1.1     skrll                            Default: based on binary being disassembled.\n"));
   2199  1.1     skrll 
   2200  1.1     skrll   fprintf (stream, _("\n\
   2201  1.1     skrll   hwr-names=ARCH           Print HWR names according to specified \n\
   2202  1.1     skrll 			   architecture.\n\
   2203  1.1     skrll                            Default: based on binary being disassembled.\n"));
   2204  1.1     skrll 
   2205  1.1     skrll   fprintf (stream, _("\n\
   2206  1.1     skrll   reg-names=ABI            Print GPR and FPR names according to\n\
   2207  1.1     skrll                            specified ABI.\n"));
   2208  1.1     skrll 
   2209  1.1     skrll   fprintf (stream, _("\n\
   2210  1.1     skrll   reg-names=ARCH           Print CP0 register and HWR names according to\n\
   2211  1.1     skrll                            specified architecture.\n"));
   2212  1.1     skrll 
   2213  1.1     skrll   fprintf (stream, _("\n\
   2214  1.1     skrll   For the options above, the following values are supported for \"ABI\":\n\
   2215  1.1     skrll    "));
   2216  1.1     skrll   for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
   2217  1.1     skrll     fprintf (stream, " %s", mips_abi_choices[i].name);
   2218  1.1     skrll   fprintf (stream, _("\n"));
   2219  1.1     skrll 
   2220  1.1     skrll   fprintf (stream, _("\n\
   2221  1.1     skrll   For the options above, The following values are supported for \"ARCH\":\n\
   2222  1.1     skrll    "));
   2223  1.1     skrll   for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
   2224                    if (*mips_arch_choices[i].name != '\0')
   2225                      fprintf (stream, " %s", mips_arch_choices[i].name);
   2226                  fprintf (stream, _("\n"));
   2227                
   2228                  fprintf (stream, _("\n"));
   2229                }
   2230