Home | History | Annotate | Line # | Download | only in opcodes
mips-dis.c revision 1.4
      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.4  christos    2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2012
      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.4  christos 
     61  1.4  christos /* The microMIPS registers with type b.  */
     62  1.4  christos #define micromips_to_32_reg_b_map	mips16_to_32_reg_map
     63  1.4  christos 
     64  1.4  christos /* The microMIPS registers with type c.  */
     65  1.4  christos #define micromips_to_32_reg_c_map	mips16_to_32_reg_map
     66  1.4  christos 
     67  1.4  christos /* The microMIPS registers with type d.  */
     68  1.4  christos #define micromips_to_32_reg_d_map	mips16_to_32_reg_map
     69  1.4  christos 
     70  1.4  christos /* The microMIPS registers with type e.  */
     71  1.4  christos #define micromips_to_32_reg_e_map	mips16_to_32_reg_map
     72  1.4  christos 
     73  1.4  christos /* The microMIPS registers with type f.  */
     74  1.4  christos #define micromips_to_32_reg_f_map	mips16_to_32_reg_map
     75  1.4  christos 
     76  1.4  christos /* The microMIPS registers with type g.  */
     77  1.4  christos #define micromips_to_32_reg_g_map	mips16_to_32_reg_map
     78  1.4  christos 
     79  1.4  christos /* The microMIPS registers with type h.  */
     80  1.4  christos static const unsigned int micromips_to_32_reg_h_map[] =
     81  1.4  christos {
     82  1.4  christos   5, 5, 6, 4, 4, 4, 4, 4
     83  1.4  christos };
     84  1.4  christos 
     85  1.4  christos /* The microMIPS registers with type i.  */
     86  1.4  christos static const unsigned int micromips_to_32_reg_i_map[] =
     87  1.4  christos {
     88  1.4  christos   6, 7, 7, 21, 22, 5, 6, 7
     89  1.4  christos };
     90  1.4  christos 
     91  1.4  christos /* The microMIPS registers with type j: 32 registers.  */
     92  1.4  christos 
     93  1.4  christos /* The microMIPS registers with type l.  */
     94  1.4  christos #define micromips_to_32_reg_l_map	mips16_to_32_reg_map
     95  1.4  christos 
     96  1.4  christos /* The microMIPS registers with type m.  */
     97  1.4  christos static const unsigned int micromips_to_32_reg_m_map[] =
     98  1.4  christos {
     99  1.4  christos   0, 17, 2, 3, 16, 18, 19, 20
    100  1.4  christos };
    101  1.4  christos 
    102  1.4  christos /* The microMIPS registers with type n.  */
    103  1.4  christos #define micromips_to_32_reg_n_map      micromips_to_32_reg_m_map
    104  1.4  christos 
    105  1.4  christos /* The microMIPS registers with type p: 32 registers.  */
    106  1.4  christos 
    107  1.4  christos /* The microMIPS registers with type q.  */
    108  1.4  christos static const unsigned int micromips_to_32_reg_q_map[] =
    109  1.4  christos {
    110  1.4  christos   0, 17, 2, 3, 4, 5, 6, 7
    111  1.4  christos };
    112  1.4  christos 
    113  1.4  christos /* reg type s is $29.  */
    114  1.4  christos 
    115  1.4  christos /* reg type t is the same as the last register.  */
    116  1.4  christos 
    117  1.4  christos /* reg type y is $31.  */
    118  1.4  christos 
    119  1.4  christos /* reg type z is $0.  */
    120  1.4  christos 
    121  1.4  christos /* micromips imm B type.  */
    122  1.4  christos static const int micromips_imm_b_map[8] =
    123  1.4  christos {
    124  1.4  christos   1, 4, 8, 12, 16, 20, 24, -1
    125  1.4  christos };
    126  1.4  christos 
    127  1.4  christos /* micromips imm C type.  */
    128  1.4  christos static const int micromips_imm_c_map[16] =
    129  1.4  christos {
    130  1.4  christos   128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 255, 32768, 65535
    131  1.4  christos };
    132  1.4  christos 
    133  1.4  christos /* micromips imm D type: (-512..511)<<1.  */
    134  1.4  christos /* micromips imm E type: (-64..63)<<1.  */
    135  1.4  christos /* micromips imm F type: (0..63).  */
    136  1.4  christos /* micromips imm G type: (-1..14).  */
    137  1.4  christos /* micromips imm H type: (0..15)<<1.  */
    138  1.4  christos /* micromips imm I type: (-1..126).  */
    139  1.4  christos /* micromips imm J type: (0..15)<<2.  */
    140  1.4  christos /* micromips imm L type: (0..15).  */
    141  1.4  christos /* micromips imm M type: (1..8).  */
    142  1.4  christos /* micromips imm W type: (0..63)<<2.  */
    143  1.4  christos /* micromips imm X type: (-8..7).  */
    144  1.4  christos /* micromips imm Y type: (-258..-3, 2..257)<<2.  */
    145  1.1     skrll 
    146  1.1     skrll #define mips16_reg_names(rn)	mips_gpr_names[mips16_to_32_reg_map[rn]]
    147  1.1     skrll 
    148  1.1     skrll 
    149  1.1     skrll static const char * const mips_gpr_names_numeric[32] =
    150  1.1     skrll {
    151  1.1     skrll   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    152  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    153  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    154  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    155  1.1     skrll };
    156  1.1     skrll 
    157  1.1     skrll static const char * const mips_gpr_names_oldabi[32] =
    158  1.1     skrll {
    159  1.1     skrll   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
    160  1.1     skrll   "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
    161  1.1     skrll   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
    162  1.1     skrll   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
    163  1.1     skrll };
    164  1.1     skrll 
    165  1.1     skrll static const char * const mips_gpr_names_newabi[32] =
    166  1.1     skrll {
    167  1.1     skrll   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
    168  1.1     skrll   "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3",
    169  1.1     skrll   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
    170  1.1     skrll   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
    171  1.1     skrll };
    172  1.1     skrll 
    173  1.1     skrll static const char * const mips_fpr_names_numeric[32] =
    174  1.1     skrll {
    175  1.1     skrll   "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
    176  1.1     skrll   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
    177  1.1     skrll   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
    178  1.1     skrll   "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
    179  1.1     skrll };
    180  1.1     skrll 
    181  1.1     skrll static const char * const mips_fpr_names_32[32] =
    182  1.1     skrll {
    183  1.1     skrll   "fv0",  "fv0f", "fv1",  "fv1f", "ft0",  "ft0f", "ft1",  "ft1f",
    184  1.1     skrll   "ft2",  "ft2f", "ft3",  "ft3f", "fa0",  "fa0f", "fa1",  "fa1f",
    185  1.1     skrll   "ft4",  "ft4f", "ft5",  "ft5f", "fs0",  "fs0f", "fs1",  "fs1f",
    186  1.1     skrll   "fs2",  "fs2f", "fs3",  "fs3f", "fs4",  "fs4f", "fs5",  "fs5f"
    187  1.1     skrll };
    188  1.1     skrll 
    189  1.1     skrll static const char * const mips_fpr_names_n32[32] =
    190  1.1     skrll {
    191  1.1     skrll   "fv0",  "ft14", "fv1",  "ft15", "ft0",  "ft1",  "ft2",  "ft3",
    192  1.1     skrll   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
    193  1.1     skrll   "fa4",  "fa5",  "fa6",  "fa7",  "fs0",  "ft8",  "fs1",  "ft9",
    194  1.1     skrll   "fs2",  "ft10", "fs3",  "ft11", "fs4",  "ft12", "fs5",  "ft13"
    195  1.1     skrll };
    196  1.1     skrll 
    197  1.1     skrll static const char * const mips_fpr_names_64[32] =
    198  1.1     skrll {
    199  1.1     skrll   "fv0",  "ft12", "fv1",  "ft13", "ft0",  "ft1",  "ft2",  "ft3",
    200  1.1     skrll   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
    201  1.1     skrll   "fa4",  "fa5",  "fa6",  "fa7",  "ft8",  "ft9",  "ft10", "ft11",
    202  1.1     skrll   "fs0",  "fs1",  "fs2",  "fs3",  "fs4",  "fs5",  "fs6",  "fs7"
    203  1.1     skrll };
    204  1.1     skrll 
    205  1.1     skrll static const char * const mips_cp0_names_numeric[32] =
    206  1.1     skrll {
    207  1.1     skrll   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    208  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    209  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    210  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    211  1.1     skrll };
    212  1.1     skrll 
    213  1.1     skrll static const char * const mips_cp0_names_r3000[32] =
    214  1.1     skrll {
    215  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo",   "$3",
    216  1.1     skrll   "c0_context",   "$5",           "$6",           "$7",
    217  1.1     skrll   "c0_badvaddr",  "$9",           "c0_entryhi",   "$11",
    218  1.1     skrll   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    219  1.1     skrll   "$16",          "$17",          "$18",          "$19",
    220  1.1     skrll   "$20",          "$21",          "$22",          "$23",
    221  1.1     skrll   "$24",          "$25",          "$26",          "$27",
    222  1.1     skrll   "$28",          "$29",          "$30",          "$31",
    223  1.1     skrll };
    224  1.1     skrll 
    225  1.1     skrll static const char * const mips_cp0_names_r4000[32] =
    226  1.1     skrll {
    227  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    228  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    229  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    230  1.1     skrll   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    231  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    232  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "$23",
    233  1.1     skrll   "$24",          "$25",          "c0_ecc",       "c0_cacheerr",
    234  1.1     skrll   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "$31",
    235  1.1     skrll };
    236  1.1     skrll 
    237  1.1     skrll static const char * const mips_cp0_names_mips3264[32] =
    238  1.1     skrll {
    239  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    240  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    241  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    242  1.1     skrll   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    243  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    244  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    245  1.1     skrll   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
    246  1.1     skrll   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
    247  1.1     skrll };
    248  1.1     skrll 
    249  1.1     skrll static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
    250  1.1     skrll {
    251  1.1     skrll   { 16, 1, "c0_config1"		},
    252  1.1     skrll   { 16, 2, "c0_config2"		},
    253  1.1     skrll   { 16, 3, "c0_config3"		},
    254  1.1     skrll   { 18, 1, "c0_watchlo,1"	},
    255  1.1     skrll   { 18, 2, "c0_watchlo,2"	},
    256  1.1     skrll   { 18, 3, "c0_watchlo,3"	},
    257  1.1     skrll   { 18, 4, "c0_watchlo,4"	},
    258  1.1     skrll   { 18, 5, "c0_watchlo,5"	},
    259  1.1     skrll   { 18, 6, "c0_watchlo,6"	},
    260  1.1     skrll   { 18, 7, "c0_watchlo,7"	},
    261  1.1     skrll   { 19, 1, "c0_watchhi,1"	},
    262  1.1     skrll   { 19, 2, "c0_watchhi,2"	},
    263  1.1     skrll   { 19, 3, "c0_watchhi,3"	},
    264  1.1     skrll   { 19, 4, "c0_watchhi,4"	},
    265  1.1     skrll   { 19, 5, "c0_watchhi,5"	},
    266  1.1     skrll   { 19, 6, "c0_watchhi,6"	},
    267  1.1     skrll   { 19, 7, "c0_watchhi,7"	},
    268  1.1     skrll   { 25, 1, "c0_perfcnt,1"	},
    269  1.1     skrll   { 25, 2, "c0_perfcnt,2"	},
    270  1.1     skrll   { 25, 3, "c0_perfcnt,3"	},
    271  1.1     skrll   { 25, 4, "c0_perfcnt,4"	},
    272  1.1     skrll   { 25, 5, "c0_perfcnt,5"	},
    273  1.1     skrll   { 25, 6, "c0_perfcnt,6"	},
    274  1.1     skrll   { 25, 7, "c0_perfcnt,7"	},
    275  1.1     skrll   { 27, 1, "c0_cacheerr,1"	},
    276  1.1     skrll   { 27, 2, "c0_cacheerr,2"	},
    277  1.1     skrll   { 27, 3, "c0_cacheerr,3"	},
    278  1.1     skrll   { 28, 1, "c0_datalo"		},
    279  1.1     skrll   { 29, 1, "c0_datahi"		}
    280  1.1     skrll };
    281  1.1     skrll 
    282  1.1     skrll static const char * const mips_cp0_names_mips3264r2[32] =
    283  1.1     skrll {
    284  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    285  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "c0_hwrena",
    286  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    287  1.1     skrll   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    288  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    289  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    290  1.1     skrll   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
    291  1.1     skrll   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
    292  1.1     skrll };
    293  1.1     skrll 
    294  1.1     skrll static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
    295  1.1     skrll {
    296  1.1     skrll   {  4, 1, "c0_contextconfig"	},
    297  1.1     skrll   {  0, 1, "c0_mvpcontrol"	},
    298  1.1     skrll   {  0, 2, "c0_mvpconf0"	},
    299  1.1     skrll   {  0, 3, "c0_mvpconf1"	},
    300  1.1     skrll   {  1, 1, "c0_vpecontrol"	},
    301  1.1     skrll   {  1, 2, "c0_vpeconf0"	},
    302  1.1     skrll   {  1, 3, "c0_vpeconf1"	},
    303  1.1     skrll   {  1, 4, "c0_yqmask"		},
    304  1.1     skrll   {  1, 5, "c0_vpeschedule"	},
    305  1.1     skrll   {  1, 6, "c0_vpeschefback"	},
    306  1.1     skrll   {  2, 1, "c0_tcstatus"	},
    307  1.1     skrll   {  2, 2, "c0_tcbind"		},
    308  1.1     skrll   {  2, 3, "c0_tcrestart"	},
    309  1.1     skrll   {  2, 4, "c0_tchalt"		},
    310  1.1     skrll   {  2, 5, "c0_tccontext"	},
    311  1.1     skrll   {  2, 6, "c0_tcschedule"	},
    312  1.1     skrll   {  2, 7, "c0_tcschefback"	},
    313  1.1     skrll   {  5, 1, "c0_pagegrain"	},
    314  1.1     skrll   {  6, 1, "c0_srsconf0"	},
    315  1.1     skrll   {  6, 2, "c0_srsconf1"	},
    316  1.1     skrll   {  6, 3, "c0_srsconf2"	},
    317  1.1     skrll   {  6, 4, "c0_srsconf3"	},
    318  1.1     skrll   {  6, 5, "c0_srsconf4"	},
    319  1.1     skrll   { 12, 1, "c0_intctl"		},
    320  1.1     skrll   { 12, 2, "c0_srsctl"		},
    321  1.1     skrll   { 12, 3, "c0_srsmap"		},
    322  1.1     skrll   { 15, 1, "c0_ebase"		},
    323  1.1     skrll   { 16, 1, "c0_config1"		},
    324  1.1     skrll   { 16, 2, "c0_config2"		},
    325  1.1     skrll   { 16, 3, "c0_config3"		},
    326  1.1     skrll   { 18, 1, "c0_watchlo,1"	},
    327  1.1     skrll   { 18, 2, "c0_watchlo,2"	},
    328  1.1     skrll   { 18, 3, "c0_watchlo,3"	},
    329  1.1     skrll   { 18, 4, "c0_watchlo,4"	},
    330  1.1     skrll   { 18, 5, "c0_watchlo,5"	},
    331  1.1     skrll   { 18, 6, "c0_watchlo,6"	},
    332  1.1     skrll   { 18, 7, "c0_watchlo,7"	},
    333  1.1     skrll   { 19, 1, "c0_watchhi,1"	},
    334  1.1     skrll   { 19, 2, "c0_watchhi,2"	},
    335  1.1     skrll   { 19, 3, "c0_watchhi,3"	},
    336  1.1     skrll   { 19, 4, "c0_watchhi,4"	},
    337  1.1     skrll   { 19, 5, "c0_watchhi,5"	},
    338  1.1     skrll   { 19, 6, "c0_watchhi,6"	},
    339  1.1     skrll   { 19, 7, "c0_watchhi,7"	},
    340  1.1     skrll   { 23, 1, "c0_tracecontrol"	},
    341  1.1     skrll   { 23, 2, "c0_tracecontrol2"	},
    342  1.1     skrll   { 23, 3, "c0_usertracedata"	},
    343  1.1     skrll   { 23, 4, "c0_tracebpc"	},
    344  1.1     skrll   { 25, 1, "c0_perfcnt,1"	},
    345  1.1     skrll   { 25, 2, "c0_perfcnt,2"	},
    346  1.1     skrll   { 25, 3, "c0_perfcnt,3"	},
    347  1.1     skrll   { 25, 4, "c0_perfcnt,4"	},
    348  1.1     skrll   { 25, 5, "c0_perfcnt,5"	},
    349  1.1     skrll   { 25, 6, "c0_perfcnt,6"	},
    350  1.1     skrll   { 25, 7, "c0_perfcnt,7"	},
    351  1.1     skrll   { 27, 1, "c0_cacheerr,1"	},
    352  1.1     skrll   { 27, 2, "c0_cacheerr,2"	},
    353  1.1     skrll   { 27, 3, "c0_cacheerr,3"	},
    354  1.1     skrll   { 28, 1, "c0_datalo"		},
    355  1.1     skrll   { 28, 2, "c0_taglo1"		},
    356  1.1     skrll   { 28, 3, "c0_datalo1"		},
    357  1.1     skrll   { 28, 4, "c0_taglo2"		},
    358  1.1     skrll   { 28, 5, "c0_datalo2"		},
    359  1.1     skrll   { 28, 6, "c0_taglo3"		},
    360  1.1     skrll   { 28, 7, "c0_datalo3"		},
    361  1.1     skrll   { 29, 1, "c0_datahi"		},
    362  1.1     skrll   { 29, 2, "c0_taghi1"		},
    363  1.1     skrll   { 29, 3, "c0_datahi1"		},
    364  1.1     skrll   { 29, 4, "c0_taghi2"		},
    365  1.1     skrll   { 29, 5, "c0_datahi2"		},
    366  1.1     skrll   { 29, 6, "c0_taghi3"		},
    367  1.1     skrll   { 29, 7, "c0_datahi3"		},
    368  1.1     skrll };
    369  1.1     skrll 
    370  1.1     skrll /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods.  */
    371  1.1     skrll static const char * const mips_cp0_names_sb1[32] =
    372  1.1     skrll {
    373  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    374  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    375  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    376  1.1     skrll   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    377  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    378  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    379  1.1     skrll   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
    380  1.1     skrll   "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
    381  1.1     skrll };
    382  1.1     skrll 
    383  1.1     skrll static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
    384  1.1     skrll {
    385  1.1     skrll   { 16, 1, "c0_config1"		},
    386  1.1     skrll   { 18, 1, "c0_watchlo,1"	},
    387  1.1     skrll   { 19, 1, "c0_watchhi,1"	},
    388  1.1     skrll   { 22, 0, "c0_perftrace"	},
    389  1.1     skrll   { 23, 3, "c0_edebug"		},
    390  1.1     skrll   { 25, 1, "c0_perfcnt,1"	},
    391  1.1     skrll   { 25, 2, "c0_perfcnt,2"	},
    392  1.1     skrll   { 25, 3, "c0_perfcnt,3"	},
    393  1.1     skrll   { 25, 4, "c0_perfcnt,4"	},
    394  1.1     skrll   { 25, 5, "c0_perfcnt,5"	},
    395  1.1     skrll   { 25, 6, "c0_perfcnt,6"	},
    396  1.1     skrll   { 25, 7, "c0_perfcnt,7"	},
    397  1.1     skrll   { 26, 1, "c0_buserr_pa"	},
    398  1.1     skrll   { 27, 1, "c0_cacheerr_d"	},
    399  1.1     skrll   { 27, 3, "c0_cacheerr_d_pa"	},
    400  1.1     skrll   { 28, 1, "c0_datalo_i"	},
    401  1.1     skrll   { 28, 2, "c0_taglo_d"		},
    402  1.1     skrll   { 28, 3, "c0_datalo_d"	},
    403  1.1     skrll   { 29, 1, "c0_datahi_i"	},
    404  1.1     skrll   { 29, 2, "c0_taghi_d"		},
    405  1.1     skrll   { 29, 3, "c0_datahi_d"	},
    406  1.1     skrll };
    407  1.2      matt 
    408  1.2      matt /* Xlr cop0 register names.  */
    409  1.2      matt static const char * const mips_cp0_names_xlr[32] = {
    410  1.3  christos   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    411  1.2      matt   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    412  1.2      matt   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    413  1.2      matt   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    414  1.3  christos   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    415  1.2      matt   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    416  1.2      matt   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
    417  1.2      matt   "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
    418  1.2      matt };
    419  1.2      matt 
    420  1.2      matt /* XLR's CP0 Select Registers.  */
    421  1.2      matt 
    422  1.2      matt static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
    423  1.2      matt   {  9, 6, "c0_extintreq"       },
    424  1.2      matt   {  9, 7, "c0_extintmask"      },
    425  1.2      matt   { 15, 1, "c0_ebase"           },
    426  1.2      matt   { 16, 1, "c0_config1"         },
    427  1.2      matt   { 16, 2, "c0_config2"         },
    428  1.2      matt   { 16, 3, "c0_config3"         },
    429  1.2      matt   { 16, 7, "c0_procid2"         },
    430  1.2      matt   { 18, 1, "c0_watchlo,1"       },
    431  1.2      matt   { 18, 2, "c0_watchlo,2"       },
    432  1.2      matt   { 18, 3, "c0_watchlo,3"       },
    433  1.2      matt   { 18, 4, "c0_watchlo,4"       },
    434  1.2      matt   { 18, 5, "c0_watchlo,5"       },
    435  1.2      matt   { 18, 6, "c0_watchlo,6"       },
    436  1.2      matt   { 18, 7, "c0_watchlo,7"       },
    437  1.2      matt   { 19, 1, "c0_watchhi,1"       },
    438  1.2      matt   { 19, 2, "c0_watchhi,2"       },
    439  1.2      matt   { 19, 3, "c0_watchhi,3"       },
    440  1.2      matt   { 19, 4, "c0_watchhi,4"       },
    441  1.2      matt   { 19, 5, "c0_watchhi,5"       },
    442  1.2      matt   { 19, 6, "c0_watchhi,6"       },
    443  1.2      matt   { 19, 7, "c0_watchhi,7"       },
    444  1.2      matt   { 25, 1, "c0_perfcnt,1"       },
    445  1.2      matt   { 25, 2, "c0_perfcnt,2"       },
    446  1.2      matt   { 25, 3, "c0_perfcnt,3"       },
    447  1.2      matt   { 25, 4, "c0_perfcnt,4"       },
    448  1.2      matt   { 25, 5, "c0_perfcnt,5"       },
    449  1.2      matt   { 25, 6, "c0_perfcnt,6"       },
    450  1.2      matt   { 25, 7, "c0_perfcnt,7"       },
    451  1.2      matt   { 27, 1, "c0_cacheerr,1"      },
    452  1.2      matt   { 27, 2, "c0_cacheerr,2"      },
    453  1.2      matt   { 27, 3, "c0_cacheerr,3"      },
    454  1.2      matt   { 28, 1, "c0_datalo"          },
    455  1.2      matt   { 29, 1, "c0_datahi"          }
    456  1.2      matt };
    457  1.1     skrll 
    458  1.1     skrll static const char * const mips_hwr_names_numeric[32] =
    459  1.1     skrll {
    460  1.1     skrll   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    461  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    462  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    463  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    464  1.1     skrll };
    465  1.1     skrll 
    466  1.1     skrll static const char * const mips_hwr_names_mips3264r2[32] =
    467  1.1     skrll {
    468  1.1     skrll   "hwr_cpunum",   "hwr_synci_step", "hwr_cc",     "hwr_ccres",
    469  1.1     skrll   "$4",          "$5",            "$6",           "$7",
    470  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    471  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    472  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    473  1.1     skrll };
    474  1.1     skrll 
    475  1.1     skrll struct mips_abi_choice
    476  1.1     skrll {
    477  1.1     skrll   const char * name;
    478  1.1     skrll   const char * const *gpr_names;
    479  1.1     skrll   const char * const *fpr_names;
    480  1.1     skrll };
    481  1.1     skrll 
    482  1.1     skrll struct mips_abi_choice mips_abi_choices[] =
    483  1.1     skrll {
    484  1.1     skrll   { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
    485  1.1     skrll   { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
    486  1.1     skrll   { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
    487  1.1     skrll   { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
    488  1.1     skrll };
    489  1.1     skrll 
    490  1.1     skrll struct mips_arch_choice
    491  1.1     skrll {
    492  1.1     skrll   const char *name;
    493  1.1     skrll   int bfd_mach_valid;
    494  1.1     skrll   unsigned long bfd_mach;
    495  1.1     skrll   int processor;
    496  1.1     skrll   int isa;
    497  1.1     skrll   const char * const *cp0_names;
    498  1.1     skrll   const struct mips_cp0sel_name *cp0sel_names;
    499  1.1     skrll   unsigned int cp0sel_names_len;
    500  1.1     skrll   const char * const *hwr_names;
    501  1.1     skrll };
    502  1.1     skrll 
    503  1.1     skrll const struct mips_arch_choice mips_arch_choices[] =
    504  1.1     skrll {
    505  1.1     skrll   { "numeric",	0, 0, 0, 0,
    506  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    507  1.1     skrll 
    508  1.1     skrll   { "r3000",	1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1,
    509  1.1     skrll     mips_cp0_names_r3000, NULL, 0, mips_hwr_names_numeric },
    510  1.1     skrll   { "r3900",	1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1,
    511  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    512  1.1     skrll   { "r4000",	1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3,
    513  1.1     skrll     mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
    514  1.1     skrll   { "r4010",	1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2,
    515  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    516  1.1     skrll   { "vr4100",	1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3,
    517  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    518  1.1     skrll   { "vr4111",	1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3,
    519  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    520  1.1     skrll   { "vr4120",	1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3,
    521  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    522  1.1     skrll   { "r4300",	1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3,
    523  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    524  1.1     skrll   { "r4400",	1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3,
    525  1.1     skrll     mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
    526  1.1     skrll   { "r4600",	1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3,
    527  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    528  1.1     skrll   { "r4650",	1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3,
    529  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    530  1.1     skrll   { "r5000",	1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4,
    531  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    532  1.1     skrll   { "vr5400",	1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4,
    533  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    534  1.1     skrll   { "vr5500",	1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4,
    535  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    536  1.1     skrll   { "r6000",	1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2,
    537  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    538  1.1     skrll   { "rm7000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
    539  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    540  1.1     skrll   { "rm9000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
    541  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    542  1.1     skrll   { "r8000",	1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4,
    543  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    544  1.1     skrll   { "r10000",	1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4,
    545  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    546  1.1     skrll   { "r12000",	1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4,
    547  1.3  christos     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    548  1.3  christos   { "r14000",	1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4,
    549  1.3  christos     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    550  1.3  christos   { "r16000",	1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4,
    551  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    552  1.1     skrll   { "mips5",	1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5,
    553  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    554  1.1     skrll 
    555  1.1     skrll   /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
    556  1.1     skrll      Note that MIPS-3D and MDMX are not applicable to MIPS32.  (See
    557  1.1     skrll      _MIPS32 Architecture For Programmers Volume I: Introduction to the
    558  1.1     skrll      MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
    559  1.1     skrll      page 1.  */
    560  1.3  christos   { "mips32",	1, bfd_mach_mipsisa32, CPU_MIPS32,
    561  1.1     skrll     ISA_MIPS32 | INSN_SMARTMIPS,
    562  1.1     skrll     mips_cp0_names_mips3264,
    563  1.1     skrll     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
    564  1.1     skrll     mips_hwr_names_numeric },
    565  1.1     skrll 
    566  1.3  christos   { "mips32r2",	1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
    567  1.4  christos     (ISA_MIPS32R2 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
    568  1.1     skrll      | INSN_MIPS3D | INSN_MT | INSN_MCU),
    569  1.1     skrll     mips_cp0_names_mips3264r2,
    570  1.1     skrll     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    571  1.1     skrll     mips_hwr_names_mips3264r2 },
    572  1.1     skrll 
    573  1.1     skrll   /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs.  */
    574  1.3  christos   { "mips64",	1, bfd_mach_mipsisa64, CPU_MIPS64,
    575  1.1     skrll     ISA_MIPS64 | INSN_MIPS3D | INSN_MDMX,
    576  1.1     skrll     mips_cp0_names_mips3264,
    577  1.1     skrll     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
    578  1.1     skrll     mips_hwr_names_numeric },
    579  1.1     skrll 
    580  1.3  christos   { "mips64r2",	1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
    581  1.4  christos     (ISA_MIPS64R2 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
    582  1.1     skrll      | INSN_DSP64 | INSN_MT | INSN_MDMX | INSN_MCU),
    583  1.1     skrll     mips_cp0_names_mips3264r2,
    584  1.1     skrll     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    585  1.1     skrll     mips_hwr_names_mips3264r2 },
    586  1.1     skrll 
    587  1.1     skrll   { "sb1",	1, bfd_mach_mips_sb1, CPU_SB1,
    588  1.1     skrll     ISA_MIPS64 | INSN_MIPS3D | INSN_SB1,
    589  1.1     skrll     mips_cp0_names_sb1,
    590  1.1     skrll     mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
    591  1.1     skrll     mips_hwr_names_numeric },
    592  1.1     skrll 
    593  1.1     skrll   { "loongson2e",   1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
    594  1.1     skrll     ISA_MIPS3 | INSN_LOONGSON_2E, mips_cp0_names_numeric,
    595  1.1     skrll     NULL, 0, mips_hwr_names_numeric },
    596  1.1     skrll 
    597  1.1     skrll   { "loongson2f",   1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
    598  1.1     skrll     ISA_MIPS3 | INSN_LOONGSON_2F, mips_cp0_names_numeric,
    599  1.1     skrll     NULL, 0, mips_hwr_names_numeric },
    600  1.4  christos 
    601  1.4  christos   { "loongson3a",   1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
    602  1.4  christos     ISA_MIPS64 | INSN_LOONGSON_3A, mips_cp0_names_numeric,
    603  1.4  christos     NULL, 0, mips_hwr_names_numeric },
    604  1.1     skrll 
    605  1.1     skrll   { "octeon",   1, bfd_mach_mips_octeon, CPU_OCTEON,
    606  1.1     skrll     ISA_MIPS64R2 | INSN_OCTEON, mips_cp0_names_numeric, NULL, 0,
    607  1.1     skrll     mips_hwr_names_numeric },
    608  1.4  christos 
    609  1.4  christos   { "octeon+",   1, bfd_mach_mips_octeonp, CPU_OCTEONP,
    610  1.4  christos     ISA_MIPS64R2 | INSN_OCTEONP, mips_cp0_names_numeric,
    611  1.4  christos     NULL, 0, mips_hwr_names_numeric },
    612  1.4  christos 
    613  1.4  christos   { "octeon2",   1, bfd_mach_mips_octeon2, CPU_OCTEON2,
    614  1.4  christos     ISA_MIPS64R2 | INSN_OCTEON2, mips_cp0_names_numeric,
    615  1.4  christos     NULL, 0, mips_hwr_names_numeric },
    616  1.2      matt 
    617  1.2      matt   { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
    618  1.2      matt     ISA_MIPS64 | INSN_XLR,
    619  1.2      matt     mips_cp0_names_xlr,
    620  1.2      matt     mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
    621  1.2      matt     mips_hwr_names_numeric },
    622  1.4  christos 
    623  1.4  christos   /* XLP is mostly like XLR, with the prominent exception it is being
    624  1.4  christos      MIPS64R2.  */
    625  1.4  christos   { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
    626  1.4  christos     ISA_MIPS64R2 | INSN_XLR,
    627  1.4  christos     mips_cp0_names_xlr,
    628  1.4  christos     mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
    629  1.4  christos     mips_hwr_names_numeric },
    630  1.1     skrll 
    631  1.1     skrll   /* This entry, mips16, is here only for ISA/processor selection; do
    632  1.3  christos      not print its name.  */
    633  1.1     skrll   { "",		1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3,
    634  1.1     skrll     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
    635  1.1     skrll };
    636  1.1     skrll 
    637  1.1     skrll /* ISA and processor type to disassemble for, and register names to use.
    638  1.1     skrll    set_default_mips_dis_options and parse_mips_dis_options fill in these
    639  1.1     skrll    values.  */
    640  1.1     skrll static int mips_processor;
    641  1.4  christos static int mips_isa;
    642  1.1     skrll static int micromips_ase;
    643  1.1     skrll static const char * const *mips_gpr_names;
    644  1.1     skrll static const char * const *mips_fpr_names;
    645  1.1     skrll static const char * const *mips_cp0_names;
    646  1.1     skrll static const struct mips_cp0sel_name *mips_cp0sel_names;
    647  1.1     skrll static int mips_cp0sel_names_len;
    648  1.1     skrll static const char * const *mips_hwr_names;
    649  1.1     skrll 
    650  1.1     skrll /* Other options */
    651  1.1     skrll static int no_aliases;	/* If set disassemble as most general inst.  */
    652  1.1     skrll 
    653  1.1     skrll static const struct mips_abi_choice *
    655  1.1     skrll choose_abi_by_name (const char *name, unsigned int namelen)
    656  1.1     skrll {
    657  1.1     skrll   const struct mips_abi_choice *c;
    658  1.1     skrll   unsigned int i;
    659  1.1     skrll 
    660  1.1     skrll   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
    661  1.1     skrll     if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
    662  1.1     skrll 	&& strlen (mips_abi_choices[i].name) == namelen)
    663  1.1     skrll       c = &mips_abi_choices[i];
    664  1.1     skrll 
    665  1.1     skrll   return c;
    666  1.1     skrll }
    667  1.1     skrll 
    668  1.1     skrll static const struct mips_arch_choice *
    669  1.1     skrll choose_arch_by_name (const char *name, unsigned int namelen)
    670  1.1     skrll {
    671  1.1     skrll   const struct mips_arch_choice *c = NULL;
    672  1.1     skrll   unsigned int i;
    673  1.1     skrll 
    674  1.1     skrll   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
    675  1.1     skrll     if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
    676  1.1     skrll 	&& strlen (mips_arch_choices[i].name) == namelen)
    677  1.1     skrll       c = &mips_arch_choices[i];
    678  1.1     skrll 
    679  1.1     skrll   return c;
    680  1.1     skrll }
    681  1.1     skrll 
    682  1.1     skrll static const struct mips_arch_choice *
    683  1.1     skrll choose_arch_by_number (unsigned long mach)
    684  1.1     skrll {
    685  1.1     skrll   static unsigned long hint_bfd_mach;
    686  1.1     skrll   static const struct mips_arch_choice *hint_arch_choice;
    687  1.1     skrll   const struct mips_arch_choice *c;
    688  1.1     skrll   unsigned int i;
    689  1.1     skrll 
    690  1.1     skrll   /* We optimize this because even if the user specifies no
    691  1.1     skrll      flags, this will be done for every instruction!  */
    692  1.1     skrll   if (hint_bfd_mach == mach
    693  1.1     skrll       && hint_arch_choice != NULL
    694  1.1     skrll       && hint_arch_choice->bfd_mach == hint_bfd_mach)
    695  1.1     skrll     return hint_arch_choice;
    696  1.1     skrll 
    697  1.1     skrll   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
    698  1.1     skrll     {
    699  1.1     skrll       if (mips_arch_choices[i].bfd_mach_valid
    700  1.1     skrll 	  && mips_arch_choices[i].bfd_mach == mach)
    701  1.1     skrll 	{
    702  1.1     skrll 	  c = &mips_arch_choices[i];
    703  1.1     skrll 	  hint_bfd_mach = mach;
    704  1.1     skrll 	  hint_arch_choice = c;
    705  1.1     skrll 	}
    706  1.1     skrll     }
    707  1.1     skrll   return c;
    708  1.1     skrll }
    709  1.1     skrll 
    710  1.1     skrll /* Check if the object uses NewABI conventions.  */
    711  1.1     skrll 
    712  1.1     skrll static int
    713  1.1     skrll is_newabi (Elf_Internal_Ehdr *header)
    714  1.1     skrll {
    715  1.1     skrll   /* There are no old-style ABIs which use 64-bit ELF.  */
    716  1.1     skrll   if (header->e_ident[EI_CLASS] == ELFCLASS64)
    717  1.1     skrll     return 1;
    718  1.1     skrll 
    719  1.1     skrll   /* If a 32-bit ELF file, n32 is a new-style ABI.  */
    720  1.1     skrll   if ((header->e_flags & EF_MIPS_ABI2) != 0)
    721  1.1     skrll     return 1;
    722  1.1     skrll 
    723  1.1     skrll   return 0;
    724  1.4  christos }
    725  1.4  christos 
    726  1.4  christos /* Check if the object has microMIPS ASE code.  */
    727  1.4  christos 
    728  1.4  christos static int
    729  1.4  christos is_micromips (Elf_Internal_Ehdr *header)
    730  1.4  christos {
    731  1.4  christos   if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
    732  1.4  christos     return 1;
    733  1.4  christos 
    734  1.4  christos   return 0;
    735  1.1     skrll }
    736  1.1     skrll 
    737  1.1     skrll static void
    738  1.1     skrll set_default_mips_dis_options (struct disassemble_info *info)
    739  1.1     skrll {
    740  1.4  christos   const struct mips_arch_choice *chosen_arch;
    741  1.4  christos 
    742  1.4  christos   /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
    743  1.1     skrll      is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
    744  1.4  christos      CP0 register, and HWR names.  */
    745  1.4  christos   mips_isa = ISA_MIPS3;
    746  1.1     skrll   mips_processor = CPU_R3000;
    747  1.1     skrll   micromips_ase = 0;
    748  1.1     skrll   mips_gpr_names = mips_gpr_names_oldabi;
    749  1.1     skrll   mips_fpr_names = mips_fpr_names_numeric;
    750  1.1     skrll   mips_cp0_names = mips_cp0_names_numeric;
    751  1.1     skrll   mips_cp0sel_names = NULL;
    752  1.1     skrll   mips_cp0sel_names_len = 0;
    753  1.1     skrll   mips_hwr_names = mips_hwr_names_numeric;
    754  1.4  christos   no_aliases = 0;
    755  1.1     skrll 
    756  1.1     skrll   /* Update settings according to the ELF file header flags.  */
    757  1.1     skrll   if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
    758  1.1     skrll     {
    759  1.1     skrll       Elf_Internal_Ehdr *header;
    760  1.4  christos 
    761  1.1     skrll       header = elf_elfheader (info->section->owner);
    762  1.1     skrll       /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
    763  1.4  christos       if (is_newabi (header))
    764  1.4  christos 	mips_gpr_names = mips_gpr_names_newabi;
    765  1.1     skrll       /* If a microMIPS binary, then don't use MIPS16 bindings.  */
    766  1.1     skrll       micromips_ase = is_micromips (header);
    767  1.1     skrll     }
    768  1.1     skrll 
    769  1.1     skrll   /* Set ISA, architecture, and cp0 register names as best we can.  */
    770  1.1     skrll #if ! SYMTAB_AVAILABLE
    771  1.1     skrll   /* This is running out on a target machine, not in a host tool.
    772  1.1     skrll      FIXME: Where does mips_target_info come from?  */
    773  1.1     skrll   target_processor = mips_target_info.processor;
    774  1.1     skrll   mips_isa = mips_target_info.isa;
    775  1.1     skrll #else
    776  1.1     skrll   chosen_arch = choose_arch_by_number (info->mach);
    777  1.1     skrll   if (chosen_arch != NULL)
    778  1.1     skrll     {
    779  1.1     skrll       mips_processor = chosen_arch->processor;
    780  1.1     skrll       mips_isa = chosen_arch->isa;
    781  1.1     skrll       mips_cp0_names = chosen_arch->cp0_names;
    782  1.1     skrll       mips_cp0sel_names = chosen_arch->cp0sel_names;
    783  1.1     skrll       mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    784  1.1     skrll       mips_hwr_names = chosen_arch->hwr_names;
    785  1.1     skrll     }
    786  1.1     skrll #endif
    787  1.1     skrll }
    788  1.1     skrll 
    789  1.1     skrll static void
    790  1.1     skrll parse_mips_dis_option (const char *option, unsigned int len)
    791  1.1     skrll {
    792  1.1     skrll   unsigned int i, optionlen, vallen;
    793  1.1     skrll   const char *val;
    794  1.1     skrll   const struct mips_abi_choice *chosen_abi;
    795  1.1     skrll   const struct mips_arch_choice *chosen_arch;
    796  1.1     skrll 
    797  1.1     skrll   /* Try to match options that are simple flags */
    798  1.1     skrll   if (CONST_STRNEQ (option, "no-aliases"))
    799  1.1     skrll     {
    800  1.1     skrll       no_aliases = 1;
    801  1.1     skrll       return;
    802  1.1     skrll     }
    803  1.1     skrll 
    804  1.1     skrll   /* Look for the = that delimits the end of the option name.  */
    805  1.1     skrll   for (i = 0; i < len; i++)
    806  1.1     skrll     if (option[i] == '=')
    807  1.1     skrll       break;
    808  1.1     skrll 
    809  1.1     skrll   if (i == 0)		/* Invalid option: no name before '='.  */
    810  1.1     skrll     return;
    811  1.1     skrll   if (i == len)		/* Invalid option: no '='.  */
    812  1.1     skrll     return;
    813  1.1     skrll   if (i == (len - 1))	/* Invalid option: no value after '='.  */
    814  1.1     skrll     return;
    815  1.1     skrll 
    816  1.1     skrll   optionlen = i;
    817  1.1     skrll   val = option + (optionlen + 1);
    818  1.1     skrll   vallen = len - (optionlen + 1);
    819  1.1     skrll 
    820  1.1     skrll   if (strncmp ("gpr-names", option, optionlen) == 0
    821  1.1     skrll       && strlen ("gpr-names") == optionlen)
    822  1.1     skrll     {
    823  1.1     skrll       chosen_abi = choose_abi_by_name (val, vallen);
    824  1.1     skrll       if (chosen_abi != NULL)
    825  1.1     skrll 	mips_gpr_names = chosen_abi->gpr_names;
    826  1.1     skrll       return;
    827  1.1     skrll     }
    828  1.1     skrll 
    829  1.1     skrll   if (strncmp ("fpr-names", option, optionlen) == 0
    830  1.1     skrll       && strlen ("fpr-names") == optionlen)
    831  1.1     skrll     {
    832  1.1     skrll       chosen_abi = choose_abi_by_name (val, vallen);
    833  1.1     skrll       if (chosen_abi != NULL)
    834  1.1     skrll 	mips_fpr_names = chosen_abi->fpr_names;
    835  1.1     skrll       return;
    836  1.1     skrll     }
    837  1.1     skrll 
    838  1.1     skrll   if (strncmp ("cp0-names", option, optionlen) == 0
    839  1.1     skrll       && strlen ("cp0-names") == optionlen)
    840  1.1     skrll     {
    841  1.1     skrll       chosen_arch = choose_arch_by_name (val, vallen);
    842  1.1     skrll       if (chosen_arch != NULL)
    843  1.1     skrll 	{
    844  1.1     skrll 	  mips_cp0_names = chosen_arch->cp0_names;
    845  1.1     skrll 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
    846  1.1     skrll 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    847  1.1     skrll 	}
    848  1.1     skrll       return;
    849  1.1     skrll     }
    850  1.1     skrll 
    851  1.1     skrll   if (strncmp ("hwr-names", option, optionlen) == 0
    852  1.1     skrll       && strlen ("hwr-names") == optionlen)
    853  1.1     skrll     {
    854  1.1     skrll       chosen_arch = choose_arch_by_name (val, vallen);
    855  1.1     skrll       if (chosen_arch != NULL)
    856  1.1     skrll 	mips_hwr_names = chosen_arch->hwr_names;
    857  1.1     skrll       return;
    858  1.1     skrll     }
    859  1.1     skrll 
    860  1.1     skrll   if (strncmp ("reg-names", option, optionlen) == 0
    861  1.1     skrll       && strlen ("reg-names") == optionlen)
    862  1.1     skrll     {
    863  1.1     skrll       /* We check both ABI and ARCH here unconditionally, so
    864  1.1     skrll 	 that "numeric" will do the desirable thing: select
    865  1.1     skrll 	 numeric register names for all registers.  Other than
    866  1.1     skrll 	 that, a given name probably won't match both.  */
    867  1.1     skrll       chosen_abi = choose_abi_by_name (val, vallen);
    868  1.1     skrll       if (chosen_abi != NULL)
    869  1.1     skrll 	{
    870  1.1     skrll 	  mips_gpr_names = chosen_abi->gpr_names;
    871  1.1     skrll 	  mips_fpr_names = chosen_abi->fpr_names;
    872  1.1     skrll 	}
    873  1.1     skrll       chosen_arch = choose_arch_by_name (val, vallen);
    874  1.1     skrll       if (chosen_arch != NULL)
    875  1.1     skrll 	{
    876  1.1     skrll 	  mips_cp0_names = chosen_arch->cp0_names;
    877  1.1     skrll 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
    878  1.1     skrll 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    879  1.1     skrll 	  mips_hwr_names = chosen_arch->hwr_names;
    880  1.1     skrll 	}
    881  1.1     skrll       return;
    882  1.1     skrll     }
    883  1.1     skrll 
    884  1.1     skrll   /* Invalid option.  */
    885  1.1     skrll }
    886  1.1     skrll 
    887  1.1     skrll static void
    888  1.1     skrll parse_mips_dis_options (const char *options)
    889  1.1     skrll {
    890  1.1     skrll   const char *option_end;
    891  1.1     skrll 
    892  1.1     skrll   if (options == NULL)
    893  1.1     skrll     return;
    894  1.1     skrll 
    895  1.1     skrll   while (*options != '\0')
    896  1.1     skrll     {
    897  1.1     skrll       /* Skip empty options.  */
    898  1.1     skrll       if (*options == ',')
    899  1.1     skrll 	{
    900  1.1     skrll 	  options++;
    901  1.1     skrll 	  continue;
    902  1.1     skrll 	}
    903  1.1     skrll 
    904  1.1     skrll       /* We know that *options is neither NUL or a comma.  */
    905  1.1     skrll       option_end = options + 1;
    906  1.1     skrll       while (*option_end != ',' && *option_end != '\0')
    907  1.1     skrll 	option_end++;
    908  1.1     skrll 
    909  1.1     skrll       parse_mips_dis_option (options, option_end - options);
    910  1.1     skrll 
    911  1.1     skrll       /* Go on to the next one.  If option_end points to a comma, it
    912  1.1     skrll 	 will be skipped above.  */
    913  1.1     skrll       options = option_end;
    914  1.1     skrll     }
    915  1.1     skrll }
    916  1.1     skrll 
    917  1.1     skrll static const struct mips_cp0sel_name *
    918  1.1     skrll lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
    919  1.1     skrll 			 unsigned int len,
    920  1.1     skrll 			 unsigned int cp0reg,
    921  1.1     skrll 			 unsigned int sel)
    922  1.1     skrll {
    923  1.1     skrll   unsigned int i;
    924  1.1     skrll 
    925  1.1     skrll   for (i = 0; i < len; i++)
    926  1.1     skrll     if (names[i].cp0reg == cp0reg && names[i].sel == sel)
    927  1.1     skrll       return &names[i];
    928  1.1     skrll   return NULL;
    929  1.1     skrll }
    930  1.1     skrll 
    931  1.1     skrll /* Print insn arguments for 32/64-bit code.  */
    933  1.4  christos 
    934  1.1     skrll static void
    935  1.1     skrll print_insn_args (const char *d,
    936  1.1     skrll 		 int l,
    937  1.1     skrll 		 bfd_vma pc,
    938  1.4  christos 		 struct disassemble_info *info,
    939  1.1     skrll 		 const struct mips_opcode *opp)
    940  1.4  christos {
    941  1.4  christos   const fprintf_ftype infprintf = info->fprintf_func;
    942  1.1     skrll   unsigned int lsb, msb, msbd;
    943  1.1     skrll   void *is = info->stream;
    944  1.1     skrll   int op;
    945  1.4  christos 
    946  1.4  christos   lsb = 0;
    947  1.4  christos 
    948  1.4  christos #define GET_OP(insn, field) \
    949  1.4  christos   (((insn) >> OP_SH_##field) & OP_MASK_##field)
    950  1.1     skrll #define GET_OP_S(insn, field) \
    951  1.1     skrll   ((GET_OP (insn, field) ^ ((OP_MASK_##field >> 1) + 1)) \
    952  1.1     skrll    - ((OP_MASK_##field >> 1) + 1))
    953  1.1     skrll   for (; *d != '\0'; d++)
    954  1.1     skrll     {
    955  1.1     skrll       switch (*d)
    956  1.1     skrll 	{
    957  1.1     skrll 	case ',':
    958  1.1     skrll 	case '(':
    959  1.4  christos 	case ')':
    960  1.1     skrll 	case '[':
    961  1.1     skrll 	case ']':
    962  1.1     skrll 	  infprintf (is, "%c", *d);
    963  1.1     skrll 	  break;
    964  1.1     skrll 
    965  1.1     skrll 	case '+':
    966  1.1     skrll 	  /* Extension character; switch for second char.  */
    967  1.1     skrll 	  d++;
    968  1.1     skrll 	  switch (*d)
    969  1.4  christos 	    {
    970  1.4  christos 	    case '\0':
    971  1.4  christos 	      /* xgettext:c-format */
    972  1.1     skrll 	      infprintf (is,
    973  1.1     skrll 			 _("# internal error, "
    974  1.1     skrll 			   "incomplete extension sequence (+)"));
    975  1.4  christos 	      return;
    976  1.4  christos 
    977  1.1     skrll 	    case 'A':
    978  1.1     skrll 	      lsb = GET_OP (l, SHAMT);
    979  1.1     skrll 	      infprintf (is, "0x%x", lsb);
    980  1.4  christos 	      break;
    981  1.4  christos 
    982  1.1     skrll 	    case 'B':
    983  1.1     skrll 	      msb = GET_OP (l, INSMSB);
    984  1.1     skrll 	      infprintf (is, "0x%x", msb - lsb + 1);
    985  1.4  christos 	      break;
    986  1.1     skrll 
    987  1.1     skrll 	    case '1':
    988  1.1     skrll 	      infprintf (is, "0x%x", GET_OP (l, UDI1));
    989  1.4  christos 	      break;
    990  1.1     skrll 
    991  1.1     skrll 	    case '2':
    992  1.1     skrll 	      infprintf (is, "0x%x", GET_OP (l, UDI2));
    993  1.4  christos 	      break;
    994  1.1     skrll 
    995  1.1     skrll 	    case '3':
    996  1.1     skrll 	      infprintf (is, "0x%x", GET_OP (l, UDI3));
    997  1.4  christos 	      break;
    998  1.1     skrll 
    999  1.1     skrll 	    case '4':
   1000  1.1     skrll 	      infprintf (is, "0x%x", GET_OP (l, UDI4));
   1001  1.1     skrll 	      break;
   1002  1.4  christos 
   1003  1.4  christos 	    case 'C':
   1004  1.1     skrll 	    case 'H':
   1005  1.1     skrll 	      msbd = GET_OP (l, EXTMSBD);
   1006  1.1     skrll 	      infprintf (is, "0x%x", msbd + 1);
   1007  1.1     skrll 	      break;
   1008  1.1     skrll 
   1009  1.1     skrll 	    case 'D':
   1010  1.1     skrll 	      {
   1011  1.4  christos 		const struct mips_cp0sel_name *n;
   1012  1.4  christos 		unsigned int cp0reg, sel;
   1013  1.1     skrll 
   1014  1.1     skrll 		cp0reg = GET_OP (l, RD);
   1015  1.1     skrll 		sel = GET_OP (l, SEL);
   1016  1.1     skrll 
   1017  1.1     skrll 		/* CP0 register including 'sel' code for mtcN (et al.), to be
   1018  1.1     skrll 		   printed textually if known.  If not known, print both
   1019  1.1     skrll 		   CP0 register name and sel numerically since CP0 register
   1020  1.1     skrll 		   with sel 0 may have a name unrelated to register being
   1021  1.1     skrll 		   printed.  */
   1022  1.4  christos 		n = lookup_mips_cp0sel_name(mips_cp0sel_names,
   1023  1.1     skrll 					    mips_cp0sel_names_len, cp0reg, sel);
   1024  1.4  christos 		if (n != NULL)
   1025  1.1     skrll 		  infprintf (is, "%s", n->name);
   1026  1.1     skrll 		else
   1027  1.1     skrll 		  infprintf (is, "$%d,%d", cp0reg, sel);
   1028  1.1     skrll 		break;
   1029  1.4  christos 	      }
   1030  1.4  christos 
   1031  1.1     skrll 	    case 'E':
   1032  1.1     skrll 	      lsb = GET_OP (l, SHAMT) + 32;
   1033  1.1     skrll 	      infprintf (is, "0x%x", lsb);
   1034  1.4  christos 	      break;
   1035  1.4  christos 
   1036  1.1     skrll 	    case 'F':
   1037  1.1     skrll 	      msb = GET_OP (l, INSMSB) + 32;
   1038  1.1     skrll 	      infprintf (is, "0x%x", msb - lsb + 1);
   1039  1.4  christos 	      break;
   1040  1.4  christos 
   1041  1.1     skrll 	    case 'G':
   1042  1.1     skrll 	      msbd = GET_OP (l, EXTMSBD) + 32;
   1043  1.1     skrll 	      infprintf (is, "0x%x", msbd + 1);
   1044  1.4  christos 	      break;
   1045  1.1     skrll 
   1046  1.1     skrll 	    case 't': /* Coprocessor 0 reg name */
   1047  1.1     skrll 	      infprintf (is, "%s", mips_cp0_names[GET_OP (l, RT)]);
   1048  1.1     skrll 	      break;
   1049  1.1     skrll 
   1050  1.1     skrll 	    case 'T': /* Coprocessor 0 reg name */
   1051  1.1     skrll 	      {
   1052  1.4  christos 		const struct mips_cp0sel_name *n;
   1053  1.4  christos 		unsigned int cp0reg, sel;
   1054  1.1     skrll 
   1055  1.1     skrll 		cp0reg = GET_OP (l, RT);
   1056  1.1     skrll 		sel = GET_OP (l, SEL);
   1057  1.1     skrll 
   1058  1.1     skrll 		/* CP0 register including 'sel' code for mftc0, to be
   1059  1.1     skrll 		   printed textually if known.  If not known, print both
   1060  1.1     skrll 		   CP0 register name and sel numerically since CP0 register
   1061  1.1     skrll 		   with sel 0 may have a name unrelated to register being
   1062  1.1     skrll 		   printed.  */
   1063  1.4  christos 		n = lookup_mips_cp0sel_name(mips_cp0sel_names,
   1064  1.1     skrll 					    mips_cp0sel_names_len, cp0reg, sel);
   1065  1.4  christos 		if (n != NULL)
   1066  1.1     skrll 		  infprintf (is, "%s", n->name);
   1067  1.1     skrll 		else
   1068  1.1     skrll 		  infprintf (is, "$%d,%d", cp0reg, sel);
   1069  1.1     skrll 		break;
   1070  1.4  christos 	      }
   1071  1.1     skrll 
   1072  1.1     skrll 	    case 'x':		/* bbit bit index */
   1073  1.1     skrll 	      infprintf (is, "0x%x", GET_OP (l, BBITIND));
   1074  1.4  christos 	      break;
   1075  1.1     skrll 
   1076  1.1     skrll 	    case 'p':		/* cins, cins32, exts and exts32 position */
   1077  1.1     skrll 	      infprintf (is, "0x%x", GET_OP (l, CINSPOS));
   1078  1.4  christos 	      break;
   1079  1.1     skrll 
   1080  1.1     skrll 	    case 's':		/* cins and exts length-minus-one */
   1081  1.1     skrll 	      infprintf (is, "0x%x", GET_OP (l, CINSLM1));
   1082  1.4  christos 	      break;
   1083  1.1     skrll 
   1084  1.1     skrll 	    case 'S':		/* cins32 and exts32 length-minus-one field */
   1085  1.1     skrll 	      infprintf (is, "0x%x", GET_OP (l, CINSLM1));
   1086  1.4  christos 	      break;
   1087  1.4  christos 
   1088  1.4  christos 	    case 'Q':		/* seqi/snei immediate field */
   1089  1.4  christos 	      infprintf (is, "%d", GET_OP_S (l, SEQI));
   1090  1.4  christos 	      break;
   1091  1.4  christos 
   1092  1.4  christos 	    case 'a':		/* 8-bit signed offset in bit 6 */
   1093  1.4  christos 	      infprintf (is, "%d", GET_OP_S (l, OFFSET_A));
   1094  1.4  christos 	      break;
   1095  1.4  christos 
   1096  1.4  christos 	    case 'b':		/* 8-bit signed offset in bit 3 */
   1097  1.4  christos 	      infprintf (is, "%d", GET_OP_S (l, OFFSET_B));
   1098  1.4  christos 	      break;
   1099  1.4  christos 
   1100  1.4  christos 	    case 'c':		/* 9-bit signed offset in bit 6 */
   1101  1.4  christos 	      /* Left shift 4 bits to print the real offset.  */
   1102  1.4  christos 	      infprintf (is, "%d", GET_OP_S (l, OFFSET_C) << 4);
   1103  1.4  christos 	      break;
   1104  1.4  christos 
   1105  1.4  christos 	    case 'z':
   1106  1.4  christos 	      infprintf (is, "%s", mips_gpr_names[GET_OP (l, RZ)]);
   1107  1.4  christos 	      break;
   1108  1.1     skrll 
   1109  1.1     skrll 	    case 'Z':
   1110  1.1     skrll 	      infprintf (is, "%s", mips_fpr_names[GET_OP (l, FZ)]);
   1111  1.1     skrll 	      break;
   1112  1.4  christos 
   1113  1.4  christos 	    default:
   1114  1.4  christos 	      /* xgettext:c-format */
   1115  1.4  christos 	      infprintf (is,
   1116  1.1     skrll 			 _("# internal error, "
   1117  1.1     skrll 			   "undefined extension sequence (+%c)"),
   1118  1.1     skrll 			 *d);
   1119  1.1     skrll 	      return;
   1120  1.1     skrll 	    }
   1121  1.4  christos 	  break;
   1122  1.1     skrll 
   1123  1.1     skrll 	case '2':
   1124  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, BP));
   1125  1.4  christos 	  break;
   1126  1.1     skrll 
   1127  1.1     skrll 	case '3':
   1128  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, SA3));
   1129  1.4  christos 	  break;
   1130  1.1     skrll 
   1131  1.1     skrll 	case '4':
   1132  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, SA4));
   1133  1.4  christos 	  break;
   1134  1.1     skrll 
   1135  1.1     skrll 	case '5':
   1136  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, IMM8));
   1137  1.4  christos 	  break;
   1138  1.1     skrll 
   1139  1.1     skrll 	case '6':
   1140  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, RS));
   1141  1.4  christos 	  break;
   1142  1.1     skrll 
   1143  1.1     skrll 	case '7':
   1144  1.1     skrll 	  infprintf (is, "$ac%d", GET_OP (l, DSPACC));
   1145  1.4  christos 	  break;
   1146  1.1     skrll 
   1147  1.1     skrll 	case '8':
   1148  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, WRDSP));
   1149  1.4  christos 	  break;
   1150  1.1     skrll 
   1151  1.1     skrll 	case '9':
   1152  1.1     skrll 	  infprintf (is, "$ac%d", GET_OP (l, DSPACC_S));
   1153  1.4  christos 	  break;
   1154  1.1     skrll 
   1155  1.1     skrll 	case '0': /* dsp 6-bit signed immediate in bit 20 */
   1156  1.1     skrll 	  infprintf (is, "%d", GET_OP_S (l, DSPSFT));
   1157  1.4  christos 	  break;
   1158  1.4  christos 
   1159  1.4  christos 	case ':': /* dsp 7-bit signed immediate in bit 19 */
   1160  1.4  christos 	  infprintf (is, "%d", GET_OP_S (l, DSPSFT_7));
   1161  1.4  christos 	  break;
   1162  1.4  christos 
   1163  1.4  christos 	case '~':
   1164  1.4  christos 	  infprintf (is, "%d", GET_OP_S (l, OFFSET12));
   1165  1.4  christos 	  break;
   1166  1.1     skrll 
   1167  1.1     skrll 	case '\\':
   1168  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, 3BITPOS));
   1169  1.4  christos 	  break;
   1170  1.1     skrll 
   1171  1.1     skrll 	case '\'':
   1172  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, RDDSP));
   1173  1.4  christos 	  break;
   1174  1.1     skrll 
   1175  1.1     skrll 	case '@': /* dsp 10-bit signed immediate in bit 16 */
   1176  1.1     skrll 	  infprintf (is, "%d", GET_OP_S (l, IMM10));
   1177  1.4  christos 	  break;
   1178  1.1     skrll 
   1179  1.1     skrll 	case '!':
   1180  1.1     skrll 	  infprintf (is, "%d", GET_OP (l, MT_U));
   1181  1.4  christos 	  break;
   1182  1.1     skrll 
   1183  1.1     skrll 	case '$':
   1184  1.1     skrll 	  infprintf (is, "%d", GET_OP (l, MT_H));
   1185  1.4  christos 	  break;
   1186  1.1     skrll 
   1187  1.1     skrll 	case '*':
   1188  1.1     skrll 	  infprintf (is, "$ac%d", GET_OP (l, MTACC_T));
   1189  1.4  christos 	  break;
   1190  1.1     skrll 
   1191  1.1     skrll 	case '&':
   1192  1.1     skrll 	  infprintf (is, "$ac%d", GET_OP (l, MTACC_D));
   1193  1.1     skrll 	  break;
   1194  1.4  christos 
   1195  1.1     skrll 	case 'g':
   1196  1.1     skrll 	  /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2.  */
   1197  1.1     skrll 	  infprintf (is, "$%d", GET_OP (l, RD));
   1198  1.1     skrll 	  break;
   1199  1.1     skrll 
   1200  1.1     skrll 	case 's':
   1201  1.4  christos 	case 'b':
   1202  1.1     skrll 	case 'r':
   1203  1.1     skrll 	case 'v':
   1204  1.1     skrll 	  infprintf (is, "%s", mips_gpr_names[GET_OP (l, RS)]);
   1205  1.1     skrll 	  break;
   1206  1.4  christos 
   1207  1.1     skrll 	case 't':
   1208  1.1     skrll 	case 'w':
   1209  1.1     skrll 	  infprintf (is, "%s", mips_gpr_names[GET_OP (l, RT)]);
   1210  1.1     skrll 	  break;
   1211  1.4  christos 
   1212  1.1     skrll 	case 'i':
   1213  1.1     skrll 	case 'u':
   1214  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, IMMEDIATE));
   1215  1.1     skrll 	  break;
   1216  1.4  christos 
   1217  1.1     skrll 	case 'j': /* Same as i, but sign-extended.  */
   1218  1.1     skrll 	case 'o':
   1219  1.1     skrll 	  infprintf (is, "%d", GET_OP_S (l, DELTA));
   1220  1.4  christos 	  break;
   1221  1.1     skrll 
   1222  1.1     skrll 	case 'h':
   1223  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, PREFX));
   1224  1.4  christos 	  break;
   1225  1.1     skrll 
   1226  1.1     skrll 	case 'k':
   1227  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, CACHE));
   1228  1.1     skrll 	  break;
   1229  1.4  christos 
   1230  1.1     skrll 	case 'a':
   1231  1.1     skrll 	  info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
   1232  1.1     skrll 			  | (GET_OP (l, TARGET) << 2));
   1233  1.1     skrll 	  /* For gdb disassembler, force odd address on jalx.  */
   1234  1.1     skrll 	  if (info->flavour == bfd_target_unknown_flavour
   1235  1.1     skrll 	      && strcmp (opp->name, "jalx") == 0)
   1236  1.1     skrll 	    info->target |= 1;
   1237  1.1     skrll 	  (*info->print_address_func) (info->target, info);
   1238  1.1     skrll 	  break;
   1239  1.4  christos 
   1240  1.1     skrll 	case 'p':
   1241  1.1     skrll 	  /* Sign extend the displacement.  */
   1242  1.1     skrll 	  info->target = (GET_OP_S (l, DELTA) << 2) + pc + INSNLEN;
   1243  1.1     skrll 	  (*info->print_address_func) (info->target, info);
   1244  1.4  christos 	  break;
   1245  1.1     skrll 
   1246  1.1     skrll 	case 'd':
   1247  1.1     skrll 	  infprintf (is, "%s", mips_gpr_names[GET_OP (l, RD)]);
   1248  1.1     skrll 	  break;
   1249  1.1     skrll 
   1250  1.4  christos 	case 'U':
   1251  1.4  christos 	  {
   1252  1.4  christos 	    /* First check for both rd and rt being equal.  */
   1253  1.1     skrll 	    unsigned int reg = GET_OP (l, RD);
   1254  1.1     skrll 	    if (reg == GET_OP (l, RT))
   1255  1.1     skrll 	      infprintf (is, "%s", mips_gpr_names[reg]);
   1256  1.1     skrll 	    else
   1257  1.4  christos 	      {
   1258  1.4  christos 		/* If one is zero use the other.  */
   1259  1.4  christos 		if (reg == 0)
   1260  1.1     skrll 		  infprintf (is, "%s", mips_gpr_names[GET_OP (l, RT)]);
   1261  1.4  christos 		else if (GET_OP (l, RT) == 0)
   1262  1.4  christos 		  infprintf (is, "%s", mips_gpr_names[reg]);
   1263  1.4  christos 		else /* Bogus, result depends on processor.  */
   1264  1.1     skrll 		  infprintf (is, "%s or %s",
   1265  1.1     skrll 			     mips_gpr_names[reg],
   1266  1.1     skrll 			     mips_gpr_names[GET_OP (l, RT)]);
   1267  1.1     skrll 	      }
   1268  1.1     skrll 	  }
   1269  1.4  christos 	  break;
   1270  1.1     skrll 
   1271  1.1     skrll 	case 'z':
   1272  1.1     skrll 	  infprintf (is, "%s", mips_gpr_names[0]);
   1273  1.3  christos 	  break;
   1274  1.4  christos 
   1275  1.1     skrll 	case '<':
   1276  1.1     skrll 	case '1':
   1277  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, SHAMT));
   1278  1.4  christos 	  break;
   1279  1.1     skrll 
   1280  1.1     skrll 	case 'c':
   1281  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, CODE));
   1282  1.4  christos 	  break;
   1283  1.1     skrll 
   1284  1.1     skrll 	case 'q':
   1285  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, CODE2));
   1286  1.4  christos 	  break;
   1287  1.1     skrll 
   1288  1.1     skrll 	case 'C':
   1289  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, COPZ));
   1290  1.4  christos 	  break;
   1291  1.1     skrll 
   1292  1.1     skrll 	case 'B':
   1293  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, CODE20));
   1294  1.4  christos 	  break;
   1295  1.1     skrll 
   1296  1.1     skrll 	case 'J':
   1297  1.1     skrll 	  infprintf (is, "0x%x", GET_OP (l, CODE19));
   1298  1.1     skrll 	  break;
   1299  1.4  christos 
   1300  1.1     skrll 	case 'S':
   1301  1.1     skrll 	case 'V':
   1302  1.1     skrll 	  infprintf (is, "%s", mips_fpr_names[GET_OP (l, FS)]);
   1303  1.1     skrll 	  break;
   1304  1.4  christos 
   1305  1.1     skrll 	case 'T':
   1306  1.1     skrll 	case 'W':
   1307  1.1     skrll 	  infprintf (is, "%s", mips_fpr_names[GET_OP (l, FT)]);
   1308  1.4  christos 	  break;
   1309  1.1     skrll 
   1310  1.1     skrll 	case 'D':
   1311  1.1     skrll 	  infprintf (is, "%s", mips_fpr_names[GET_OP (l, FD)]);
   1312  1.4  christos 	  break;
   1313  1.1     skrll 
   1314  1.1     skrll 	case 'R':
   1315  1.1     skrll 	  infprintf (is, "%s", mips_fpr_names[GET_OP (l, FR)]);
   1316  1.1     skrll 	  break;
   1317  1.1     skrll 
   1318  1.1     skrll 	case 'E':
   1319  1.1     skrll 	  /* Coprocessor register for lwcN instructions, et al.
   1320  1.1     skrll 
   1321  1.1     skrll 	     Note that there is no load/store cp0 instructions, and
   1322  1.1     skrll 	     that FPU (cp1) instructions disassemble this field using
   1323  1.4  christos 	     'T' format.  Therefore, until we gain understanding of
   1324  1.1     skrll 	     cp2 register names, we can simply print the register
   1325  1.1     skrll 	     numbers.  */
   1326  1.1     skrll 	  infprintf (is, "$%d", GET_OP (l, RT));
   1327  1.1     skrll 	  break;
   1328  1.1     skrll 
   1329  1.1     skrll 	case 'G':
   1330  1.1     skrll 	  /* Coprocessor register for mtcN instructions, et al.  Note
   1331  1.4  christos 	     that FPU (cp1) instructions disassemble this field using
   1332  1.1     skrll 	     'S' format.  Therefore, we only need to worry about cp0,
   1333  1.4  christos 	     cp2, and cp3.  */
   1334  1.1     skrll 	  op = GET_OP (l, OP);
   1335  1.4  christos 	  if (op == OP_OP_COP0)
   1336  1.1     skrll 	    infprintf (is, "%s", mips_cp0_names[GET_OP (l, RD)]);
   1337  1.1     skrll 	  else
   1338  1.1     skrll 	    infprintf (is, "$%d", GET_OP (l, RD));
   1339  1.4  christos 	  break;
   1340  1.1     skrll 
   1341  1.1     skrll 	case 'K':
   1342  1.1     skrll 	  infprintf (is, "%s", mips_hwr_names[GET_OP (l, RD)]);
   1343  1.4  christos 	  break;
   1344  1.4  christos 
   1345  1.4  christos 	case 'N':
   1346  1.1     skrll 	  infprintf (is,
   1347  1.1     skrll 		     (opp->pinfo & (FP_D | FP_S)) != 0 ? "$fcc%d" : "$cc%d",
   1348  1.1     skrll 		     GET_OP (l, BCC));
   1349  1.4  christos 	  break;
   1350  1.1     skrll 
   1351  1.1     skrll 	case 'M':
   1352  1.1     skrll 	  infprintf (is, "$fcc%d", GET_OP (l, CCC));
   1353  1.4  christos 	  break;
   1354  1.1     skrll 
   1355  1.1     skrll 	case 'P':
   1356  1.1     skrll 	  infprintf (is, "%d", GET_OP (l, PERFREG));
   1357  1.4  christos 	  break;
   1358  1.1     skrll 
   1359  1.1     skrll 	case 'e':
   1360  1.1     skrll 	  infprintf (is, "%d", GET_OP (l, VECBYTE));
   1361  1.4  christos 	  break;
   1362  1.1     skrll 
   1363  1.1     skrll 	case '%':
   1364  1.1     skrll 	  infprintf (is, "%d", GET_OP (l, VECALIGN));
   1365  1.4  christos 	  break;
   1366  1.1     skrll 
   1367  1.1     skrll 	case 'H':
   1368  1.1     skrll 	  infprintf (is, "%d", GET_OP (l, SEL));
   1369  1.4  christos 	  break;
   1370  1.1     skrll 
   1371  1.1     skrll 	case 'O':
   1372  1.1     skrll 	  infprintf (is, "%d", GET_OP (l, ALN));
   1373  1.1     skrll 	  break;
   1374  1.4  christos 
   1375  1.1     skrll 	case 'Q':
   1376  1.1     skrll 	  {
   1377  1.1     skrll 	    unsigned int vsel = GET_OP (l, VSEL);
   1378  1.1     skrll 
   1379  1.1     skrll 	    if ((vsel & 0x10) == 0)
   1380  1.1     skrll 	      {
   1381  1.1     skrll 		int fmt;
   1382  1.1     skrll 
   1383  1.1     skrll 		vsel &= 0x0f;
   1384  1.4  christos 		for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
   1385  1.1     skrll 		  if ((vsel & 1) == 0)
   1386  1.1     skrll 		    break;
   1387  1.1     skrll 		infprintf (is, "$v%d[%d]", GET_OP (l, FT), vsel >> 1);
   1388  1.4  christos 	      }
   1389  1.1     skrll 	    else if ((vsel & 0x08) == 0)
   1390  1.1     skrll 	      {
   1391  1.1     skrll 		infprintf (is, "$v%d", GET_OP (l, FT));
   1392  1.4  christos 	      }
   1393  1.1     skrll 	    else
   1394  1.1     skrll 	      {
   1395  1.1     skrll 		infprintf (is, "0x%x", GET_OP (l, FT));
   1396  1.1     skrll 	      }
   1397  1.1     skrll 	  }
   1398  1.4  christos 	  break;
   1399  1.1     skrll 
   1400  1.1     skrll 	case 'X':
   1401  1.1     skrll 	  infprintf (is, "$v%d", GET_OP (l, FD));
   1402  1.4  christos 	  break;
   1403  1.1     skrll 
   1404  1.1     skrll 	case 'Y':
   1405  1.1     skrll 	  infprintf (is, "$v%d", GET_OP (l, FS));
   1406  1.4  christos 	  break;
   1407  1.1     skrll 
   1408  1.1     skrll 	case 'Z':
   1409  1.1     skrll 	  infprintf (is, "$v%d", GET_OP (l, FT));
   1410  1.1     skrll 	  break;
   1411  1.4  christos 
   1412  1.1     skrll 	default:
   1413  1.1     skrll 	  /* xgettext:c-format */
   1414  1.1     skrll 	  infprintf (is, _("# internal error, undefined modifier (%c)"), *d);
   1415  1.1     skrll 	  return;
   1416  1.1     skrll 	}
   1417  1.1     skrll     }
   1418  1.1     skrll }
   1419  1.1     skrll 
   1420  1.1     skrll /* Print the mips instruction at address MEMADDR in debugged memory,
   1422  1.1     skrll    on using INFO.  Returns length of the instruction, in bytes, which is
   1423  1.1     skrll    always INSNLEN.  BIGENDIAN must be 1 if this is big-endian code, 0 if
   1424  1.4  christos    this is little-endian code.  */
   1425  1.1     skrll 
   1426  1.1     skrll static int
   1427  1.4  christos print_insn_mips (bfd_vma memaddr,
   1428  1.4  christos 		 int word,
   1429  1.1     skrll 		 struct disassemble_info *info)
   1430  1.1     skrll {
   1431  1.4  christos   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
   1432  1.1     skrll   const fprintf_ftype infprintf = info->fprintf_func;
   1433  1.1     skrll   const struct mips_opcode *op;
   1434  1.1     skrll   static bfd_boolean init = 0;
   1435  1.1     skrll   void *is = info->stream;
   1436  1.1     skrll 
   1437  1.1     skrll   /* Build a hash table to shorten the search time.  */
   1438  1.1     skrll   if (! init)
   1439  1.1     skrll     {
   1440  1.1     skrll       unsigned int i;
   1441  1.1     skrll 
   1442  1.1     skrll       for (i = 0; i <= OP_MASK_OP; i++)
   1443  1.1     skrll 	{
   1444  1.1     skrll 	  for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
   1445  1.4  christos 	    {
   1446  1.1     skrll 	      if (op->pinfo == INSN_MACRO
   1447  1.1     skrll 		  || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
   1448  1.1     skrll 		continue;
   1449  1.1     skrll 	      if (i == GET_OP (op->match, OP))
   1450  1.1     skrll 		{
   1451  1.1     skrll 		  mips_hash[i] = op;
   1452  1.1     skrll 		  break;
   1453  1.1     skrll 		}
   1454  1.1     skrll 	    }
   1455  1.1     skrll 	}
   1456  1.1     skrll 
   1457  1.1     skrll       init = 1;
   1458  1.1     skrll     }
   1459  1.1     skrll 
   1460  1.1     skrll   info->bytes_per_chunk = INSNLEN;
   1461  1.1     skrll   info->display_endian = info->endian;
   1462  1.1     skrll   info->insn_info_valid = 1;
   1463  1.1     skrll   info->branch_delay_insns = 0;
   1464  1.1     skrll   info->data_size = 0;
   1465  1.4  christos   info->insn_type = dis_nonbranch;
   1466  1.1     skrll   info->target = 0;
   1467  1.1     skrll   info->target2 = 0;
   1468  1.1     skrll 
   1469  1.1     skrll   op = mips_hash[GET_OP (word, OP)];
   1470  1.1     skrll   if (op != NULL)
   1471  1.1     skrll     {
   1472  1.1     skrll       for (; op < &mips_opcodes[NUMOPCODES]; op++)
   1473  1.1     skrll 	{
   1474  1.1     skrll 	  if (op->pinfo != INSN_MACRO
   1475  1.1     skrll 	      && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   1476  1.1     skrll 	      && (word & op->mask) == op->match)
   1477  1.4  christos 	    {
   1478  1.1     skrll 	      const char *d;
   1479  1.1     skrll 
   1480  1.1     skrll 	      /* We always allow to disassemble the jalx instruction.  */
   1481  1.1     skrll 	      if (!opcode_is_member (op, mips_isa, mips_processor)
   1482  1.1     skrll 		  && strcmp (op->name, "jalx"))
   1483  1.1     skrll 		continue;
   1484  1.3  christos 
   1485  1.3  christos 	      /* Figure out instruction type and branch delay information.  */
   1486  1.1     skrll 	      if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
   1487  1.1     skrll 	        {
   1488  1.1     skrll 		  if ((op->pinfo & (INSN_WRITE_GPR_31
   1489  1.1     skrll 				    | INSN_WRITE_GPR_D)) != 0)
   1490  1.1     skrll 		    info->insn_type = dis_jsr;
   1491  1.1     skrll 		  else
   1492  1.1     skrll 		    info->insn_type = dis_branch;
   1493  1.1     skrll 		  info->branch_delay_insns = 1;
   1494  1.3  christos 		}
   1495  1.1     skrll 	      else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
   1496  1.1     skrll 				     | INSN_COND_BRANCH_LIKELY)) != 0)
   1497  1.1     skrll 		{
   1498  1.1     skrll 		  if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   1499  1.1     skrll 		    info->insn_type = dis_condjsr;
   1500  1.1     skrll 		  else
   1501  1.1     skrll 		    info->insn_type = dis_condbranch;
   1502  1.1     skrll 		  info->branch_delay_insns = 1;
   1503  1.1     skrll 		}
   1504  1.4  christos 	      else if ((op->pinfo & (INSN_STORE_MEMORY
   1505  1.1     skrll 				     | INSN_LOAD_MEMORY_DELAY)) != 0)
   1506  1.1     skrll 		info->insn_type = dis_dref;
   1507  1.1     skrll 
   1508  1.1     skrll 	      infprintf (is, "%s", op->name);
   1509  1.4  christos 
   1510  1.1     skrll 	      d = op->args;
   1511  1.1     skrll 	      if (d != NULL && *d != '\0')
   1512  1.1     skrll 		{
   1513  1.1     skrll 		  infprintf (is, "\t");
   1514  1.1     skrll 		  print_insn_args (d, word, memaddr, info, op);
   1515  1.1     skrll 		}
   1516  1.1     skrll 
   1517  1.4  christos 	      return INSNLEN;
   1518  1.4  christos 	    }
   1519  1.1     skrll 	}
   1520  1.1     skrll     }
   1521  1.1     skrll #undef GET_OP_S
   1522  1.4  christos #undef GET_OP
   1523  1.1     skrll 
   1524  1.1     skrll   /* Handle undefined instructions.  */
   1525  1.1     skrll   info->insn_type = dis_noninsn;
   1526  1.1     skrll   infprintf (is, "0x%x", word);
   1527  1.1     skrll   return INSNLEN;
   1528  1.1     skrll }
   1529  1.1     skrll 
   1530  1.1     skrll /* Disassemble an operand for a mips16 instruction.  */
   1532  1.1     skrll 
   1533  1.1     skrll static void
   1534  1.1     skrll print_mips16_insn_arg (char type,
   1535  1.1     skrll 		       const struct mips_opcode *op,
   1536  1.1     skrll 		       int l,
   1537  1.4  christos 		       bfd_boolean use_extend,
   1538  1.4  christos 		       int extend,
   1539  1.4  christos 		       bfd_vma memaddr,
   1540  1.4  christos 		       struct disassemble_info *info)
   1541  1.4  christos {
   1542  1.4  christos   const fprintf_ftype infprintf = info->fprintf_func;
   1543  1.4  christos   void *is = info->stream;
   1544  1.4  christos 
   1545  1.1     skrll #define GET_OP(insn, field) \
   1546  1.1     skrll   (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
   1547  1.1     skrll #define GET_OP_S(insn, field) \
   1548  1.1     skrll   ((GET_OP (insn, field) ^ ((MIPS16OP_MASK_##field >> 1) + 1)) \
   1549  1.1     skrll    - ((MIPS16OP_MASK_##field >> 1) + 1))
   1550  1.4  christos   switch (type)
   1551  1.1     skrll     {
   1552  1.1     skrll     case ',':
   1553  1.1     skrll     case '(':
   1554  1.1     skrll     case ')':
   1555  1.4  christos       infprintf (is, "%c", type);
   1556  1.1     skrll       break;
   1557  1.1     skrll 
   1558  1.1     skrll     case 'y':
   1559  1.1     skrll     case 'w':
   1560  1.4  christos       infprintf (is, "%s", mips16_reg_names (GET_OP (l, RY)));
   1561  1.1     skrll       break;
   1562  1.1     skrll 
   1563  1.1     skrll     case 'x':
   1564  1.4  christos     case 'v':
   1565  1.1     skrll       infprintf (is, "%s", mips16_reg_names (GET_OP (l, RX)));
   1566  1.1     skrll       break;
   1567  1.1     skrll 
   1568  1.4  christos     case 'z':
   1569  1.1     skrll       infprintf (is, "%s", mips16_reg_names (GET_OP (l, RZ)));
   1570  1.1     skrll       break;
   1571  1.1     skrll 
   1572  1.4  christos     case 'Z':
   1573  1.1     skrll       infprintf (is, "%s", mips16_reg_names (GET_OP (l, MOVE32Z)));
   1574  1.1     skrll       break;
   1575  1.1     skrll 
   1576  1.4  christos     case '0':
   1577  1.1     skrll       infprintf (is, "%s", mips_gpr_names[0]);
   1578  1.1     skrll       break;
   1579  1.1     skrll 
   1580  1.4  christos     case 'S':
   1581  1.1     skrll       infprintf (is, "%s", mips_gpr_names[29]);
   1582  1.1     skrll       break;
   1583  1.1     skrll 
   1584  1.4  christos     case 'P':
   1585  1.1     skrll       infprintf (is, "$pc");
   1586  1.1     skrll       break;
   1587  1.1     skrll 
   1588  1.4  christos     case 'R':
   1589  1.1     skrll       infprintf (is, "%s", mips_gpr_names[31]);
   1590  1.1     skrll       break;
   1591  1.1     skrll 
   1592  1.4  christos     case 'X':
   1593  1.1     skrll       infprintf (is, "%s", mips_gpr_names[GET_OP (l, REGR32)]);
   1594  1.1     skrll       break;
   1595  1.1     skrll 
   1596  1.1     skrll     case 'Y':
   1597  1.1     skrll       infprintf (is, "%s", mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
   1598  1.1     skrll       break;
   1599  1.1     skrll 
   1600  1.1     skrll     case '<':
   1601  1.1     skrll     case '>':
   1602  1.1     skrll     case '[':
   1603  1.1     skrll     case ']':
   1604  1.1     skrll     case '4':
   1605  1.1     skrll     case '5':
   1606  1.1     skrll     case 'H':
   1607  1.1     skrll     case 'W':
   1608  1.1     skrll     case 'D':
   1609  1.1     skrll     case 'j':
   1610  1.1     skrll     case '6':
   1611  1.1     skrll     case '8':
   1612  1.1     skrll     case 'V':
   1613  1.1     skrll     case 'C':
   1614  1.1     skrll     case 'U':
   1615  1.1     skrll     case 'k':
   1616  1.1     skrll     case 'K':
   1617  1.1     skrll     case 'p':
   1618  1.1     skrll     case 'q':
   1619  1.1     skrll     case 'A':
   1620  1.1     skrll     case 'B':
   1621  1.1     skrll     case 'E':
   1622  1.1     skrll       {
   1623  1.1     skrll 	int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
   1624  1.1     skrll 
   1625  1.1     skrll 	shift = 0;
   1626  1.1     skrll 	signedp = 0;
   1627  1.1     skrll 	extbits = 16;
   1628  1.1     skrll 	pcrel = 0;
   1629  1.1     skrll 	extu = 0;
   1630  1.4  christos 	branch = 0;
   1631  1.1     skrll 	switch (type)
   1632  1.1     skrll 	  {
   1633  1.1     skrll 	  case '<':
   1634  1.1     skrll 	    nbits = 3;
   1635  1.1     skrll 	    immed = GET_OP (l, RZ);
   1636  1.4  christos 	    extbits = 5;
   1637  1.1     skrll 	    extu = 1;
   1638  1.1     skrll 	    break;
   1639  1.1     skrll 	  case '>':
   1640  1.1     skrll 	    nbits = 3;
   1641  1.1     skrll 	    immed = GET_OP (l, RX);
   1642  1.4  christos 	    extbits = 5;
   1643  1.1     skrll 	    extu = 1;
   1644  1.1     skrll 	    break;
   1645  1.1     skrll 	  case '[':
   1646  1.1     skrll 	    nbits = 3;
   1647  1.1     skrll 	    immed = GET_OP (l, RZ);
   1648  1.4  christos 	    extbits = 6;
   1649  1.1     skrll 	    extu = 1;
   1650  1.1     skrll 	    break;
   1651  1.1     skrll 	  case ']':
   1652  1.1     skrll 	    nbits = 3;
   1653  1.1     skrll 	    immed = GET_OP (l, RX);
   1654  1.4  christos 	    extbits = 6;
   1655  1.1     skrll 	    extu = 1;
   1656  1.1     skrll 	    break;
   1657  1.1     skrll 	  case '4':
   1658  1.1     skrll 	    nbits = 4;
   1659  1.1     skrll 	    immed = GET_OP (l, IMM4);
   1660  1.4  christos 	    signedp = 1;
   1661  1.1     skrll 	    extbits = 15;
   1662  1.1     skrll 	    break;
   1663  1.1     skrll 	  case '5':
   1664  1.1     skrll 	    nbits = 5;
   1665  1.1     skrll 	    immed = GET_OP (l, IMM5);
   1666  1.1     skrll 	    info->insn_type = dis_dref;
   1667  1.4  christos 	    info->data_size = 1;
   1668  1.1     skrll 	    break;
   1669  1.1     skrll 	  case 'H':
   1670  1.1     skrll 	    nbits = 5;
   1671  1.1     skrll 	    shift = 1;
   1672  1.1     skrll 	    immed = GET_OP (l, IMM5);
   1673  1.1     skrll 	    info->insn_type = dis_dref;
   1674  1.4  christos 	    info->data_size = 2;
   1675  1.1     skrll 	    break;
   1676  1.1     skrll 	  case 'W':
   1677  1.1     skrll 	    nbits = 5;
   1678  1.1     skrll 	    shift = 2;
   1679  1.1     skrll 	    immed = GET_OP (l, IMM5);
   1680  1.1     skrll 	    if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
   1681  1.1     skrll 		&& (op->pinfo & MIPS16_INSN_READ_SP) == 0)
   1682  1.1     skrll 	      {
   1683  1.1     skrll 		info->insn_type = dis_dref;
   1684  1.1     skrll 		info->data_size = 4;
   1685  1.4  christos 	      }
   1686  1.1     skrll 	    break;
   1687  1.1     skrll 	  case 'D':
   1688  1.1     skrll 	    nbits = 5;
   1689  1.1     skrll 	    shift = 3;
   1690  1.1     skrll 	    immed = GET_OP (l, IMM5);
   1691  1.4  christos 	    info->insn_type = dis_dref;
   1692  1.1     skrll 	    info->data_size = 8;
   1693  1.1     skrll 	    break;
   1694  1.1     skrll 	  case 'j':
   1695  1.1     skrll 	    nbits = 5;
   1696  1.4  christos 	    immed = GET_OP (l, IMM5);
   1697  1.1     skrll 	    signedp = 1;
   1698  1.1     skrll 	    break;
   1699  1.1     skrll 	  case '6':
   1700  1.4  christos 	    nbits = 6;
   1701  1.1     skrll 	    immed = GET_OP (l, IMM6);
   1702  1.1     skrll 	    break;
   1703  1.1     skrll 	  case '8':
   1704  1.1     skrll 	    nbits = 8;
   1705  1.4  christos 	    immed = GET_OP (l, IMM8);
   1706  1.1     skrll 	    break;
   1707  1.1     skrll 	  case 'V':
   1708  1.1     skrll 	    nbits = 8;
   1709  1.1     skrll 	    shift = 2;
   1710  1.1     skrll 	    immed = GET_OP (l, IMM8);
   1711  1.1     skrll 	    /* FIXME: This might be lw, or it might be addiu to $sp or
   1712  1.1     skrll                $pc.  We assume it's load.  */
   1713  1.1     skrll 	    info->insn_type = dis_dref;
   1714  1.4  christos 	    info->data_size = 4;
   1715  1.1     skrll 	    break;
   1716  1.1     skrll 	  case 'C':
   1717  1.1     skrll 	    nbits = 8;
   1718  1.1     skrll 	    shift = 3;
   1719  1.1     skrll 	    immed = GET_OP (l, IMM8);
   1720  1.4  christos 	    info->insn_type = dis_dref;
   1721  1.1     skrll 	    info->data_size = 8;
   1722  1.1     skrll 	    break;
   1723  1.1     skrll 	  case 'U':
   1724  1.1     skrll 	    nbits = 8;
   1725  1.4  christos 	    immed = GET_OP (l, IMM8);
   1726  1.1     skrll 	    extu = 1;
   1727  1.1     skrll 	    break;
   1728  1.1     skrll 	  case 'k':
   1729  1.1     skrll 	    nbits = 8;
   1730  1.1     skrll 	    immed = GET_OP (l, IMM8);
   1731  1.4  christos 	    signedp = 1;
   1732  1.1     skrll 	    break;
   1733  1.1     skrll 	  case 'K':
   1734  1.1     skrll 	    nbits = 8;
   1735  1.1     skrll 	    shift = 3;
   1736  1.4  christos 	    immed = GET_OP (l, IMM8);
   1737  1.1     skrll 	    signedp = 1;
   1738  1.1     skrll 	    break;
   1739  1.1     skrll 	  case 'p':
   1740  1.1     skrll 	    nbits = 8;
   1741  1.1     skrll 	    immed = GET_OP (l, IMM8);
   1742  1.1     skrll 	    signedp = 1;
   1743  1.4  christos 	    pcrel = 1;
   1744  1.1     skrll 	    branch = 1;
   1745  1.1     skrll 	    break;
   1746  1.1     skrll 	  case 'q':
   1747  1.1     skrll 	    nbits = 11;
   1748  1.1     skrll 	    immed = GET_OP (l, IMM11);
   1749  1.1     skrll 	    signedp = 1;
   1750  1.1     skrll 	    pcrel = 1;
   1751  1.4  christos 	    branch = 1;
   1752  1.1     skrll 	    break;
   1753  1.1     skrll 	  case 'A':
   1754  1.1     skrll 	    nbits = 8;
   1755  1.1     skrll 	    shift = 2;
   1756  1.1     skrll 	    immed = GET_OP (l, IMM8);
   1757  1.1     skrll 	    pcrel = 1;
   1758  1.1     skrll 	    /* FIXME: This can be lw or la.  We assume it is lw.  */
   1759  1.1     skrll 	    info->insn_type = dis_dref;
   1760  1.4  christos 	    info->data_size = 4;
   1761  1.1     skrll 	    break;
   1762  1.1     skrll 	  case 'B':
   1763  1.1     skrll 	    nbits = 5;
   1764  1.1     skrll 	    shift = 3;
   1765  1.1     skrll 	    immed = GET_OP (l, IMM5);
   1766  1.1     skrll 	    pcrel = 1;
   1767  1.1     skrll 	    info->insn_type = dis_dref;
   1768  1.4  christos 	    info->data_size = 8;
   1769  1.1     skrll 	    break;
   1770  1.1     skrll 	  case 'E':
   1771  1.1     skrll 	    nbits = 5;
   1772  1.1     skrll 	    shift = 2;
   1773  1.1     skrll 	    immed = GET_OP (l, IMM5);
   1774  1.1     skrll 	    pcrel = 1;
   1775  1.1     skrll 	    break;
   1776  1.1     skrll 	  default:
   1777  1.1     skrll 	    abort ();
   1778  1.1     skrll 	  }
   1779  1.1     skrll 
   1780  1.1     skrll 	if (! use_extend)
   1781  1.1     skrll 	  {
   1782  1.1     skrll 	    if (signedp && immed >= (1 << (nbits - 1)))
   1783  1.1     skrll 	      immed -= 1 << nbits;
   1784  1.1     skrll 	    immed <<= shift;
   1785  1.1     skrll 	    if ((type == '<' || type == '>' || type == '[' || type == ']')
   1786  1.1     skrll 		&& immed == 0)
   1787  1.1     skrll 	      immed = 8;
   1788  1.1     skrll 	  }
   1789  1.1     skrll 	else
   1790  1.1     skrll 	  {
   1791  1.1     skrll 	    if (extbits == 16)
   1792  1.1     skrll 	      immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
   1793  1.1     skrll 	    else if (extbits == 15)
   1794  1.1     skrll 	      immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
   1795  1.1     skrll 	    else
   1796  1.1     skrll 	      immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
   1797  1.1     skrll 	    immed &= (1 << extbits) - 1;
   1798  1.4  christos 	    if (! extu && immed >= (1 << (extbits - 1)))
   1799  1.1     skrll 	      immed -= 1 << extbits;
   1800  1.1     skrll 	  }
   1801  1.1     skrll 
   1802  1.1     skrll 	if (! pcrel)
   1803  1.1     skrll 	  infprintf (is, "%d", immed);
   1804  1.1     skrll 	else
   1805  1.1     skrll 	  {
   1806  1.1     skrll 	    bfd_vma baseaddr;
   1807  1.1     skrll 
   1808  1.1     skrll 	    if (branch)
   1809  1.1     skrll 	      {
   1810  1.1     skrll 		immed *= 2;
   1811  1.1     skrll 		baseaddr = memaddr + 2;
   1812  1.1     skrll 	      }
   1813  1.1     skrll 	    else if (use_extend)
   1814  1.1     skrll 	      baseaddr = memaddr - 2;
   1815  1.1     skrll 	    else
   1816  1.1     skrll 	      {
   1817  1.1     skrll 		int status;
   1818  1.1     skrll 		bfd_byte buffer[2];
   1819  1.1     skrll 
   1820  1.1     skrll 		baseaddr = memaddr;
   1821  1.1     skrll 
   1822  1.1     skrll 		/* If this instruction is in the delay slot of a jr
   1823  1.1     skrll                    instruction, the base address is the address of the
   1824  1.1     skrll                    jr instruction.  If it is in the delay slot of jalr
   1825  1.1     skrll                    instruction, the base address is the address of the
   1826  1.1     skrll                    jalr instruction.  This test is unreliable: we have
   1827  1.1     skrll                    no way of knowing whether the previous word is
   1828  1.1     skrll                    instruction or data.  */
   1829  1.1     skrll 		status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
   1830  1.1     skrll 						    info);
   1831  1.1     skrll 		if (status == 0
   1832  1.1     skrll 		    && (((info->endian == BFD_ENDIAN_BIG
   1833  1.1     skrll 			  ? bfd_getb16 (buffer)
   1834  1.1     skrll 			  : bfd_getl16 (buffer))
   1835  1.1     skrll 			 & 0xf800) == 0x1800))
   1836  1.1     skrll 		  baseaddr = memaddr - 4;
   1837  1.1     skrll 		else
   1838  1.1     skrll 		  {
   1839  1.1     skrll 		    status = (*info->read_memory_func) (memaddr - 2, buffer,
   1840  1.1     skrll 							2, info);
   1841  1.1     skrll 		    if (status == 0
   1842  1.1     skrll 			&& (((info->endian == BFD_ENDIAN_BIG
   1843  1.1     skrll 			      ? bfd_getb16 (buffer)
   1844  1.1     skrll 			      : bfd_getl16 (buffer))
   1845  1.1     skrll 			     & 0xf81f) == 0xe800))
   1846  1.1     skrll 		      baseaddr = memaddr - 2;
   1847  1.1     skrll 		  }
   1848  1.1     skrll 	      }
   1849  1.1     skrll 	    info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
   1850  1.1     skrll 	    if (pcrel && branch
   1851  1.1     skrll 		&& info->flavour == bfd_target_unknown_flavour)
   1852  1.1     skrll 	      /* For gdb disassembler, maintain odd address.  */
   1853  1.1     skrll 	      info->target |= 1;
   1854  1.1     skrll 	    (*info->print_address_func) (info->target, info);
   1855  1.1     skrll 	  }
   1856  1.1     skrll       }
   1857  1.1     skrll       break;
   1858  1.1     skrll 
   1859  1.1     skrll     case 'a':
   1860  1.1     skrll       {
   1861  1.1     skrll 	int jalx = l & 0x400;
   1862  1.1     skrll 
   1863  1.1     skrll 	if (! use_extend)
   1864  1.1     skrll 	  extend = 0;
   1865  1.1     skrll 	l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
   1866  1.1     skrll 	if (!jalx && info->flavour == bfd_target_unknown_flavour)
   1867  1.1     skrll 	  /* For gdb disassembler, maintain odd address.  */
   1868  1.1     skrll 	  l |= 1;
   1869  1.1     skrll       }
   1870  1.1     skrll       info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
   1871  1.1     skrll       (*info->print_address_func) (info->target, info);
   1872  1.1     skrll       break;
   1873  1.1     skrll 
   1874  1.1     skrll     case 'l':
   1875  1.1     skrll     case 'L':
   1876  1.4  christos       {
   1877  1.1     skrll 	int need_comma, amask, smask;
   1878  1.1     skrll 
   1879  1.1     skrll 	need_comma = 0;
   1880  1.1     skrll 
   1881  1.1     skrll 	l = GET_OP (l, IMM6);
   1882  1.4  christos 
   1883  1.1     skrll 	amask = (l >> 3) & 7;
   1884  1.4  christos 
   1885  1.1     skrll 	if (amask > 0 && amask < 5)
   1886  1.1     skrll 	  {
   1887  1.1     skrll 	    infprintf (is, "%s", mips_gpr_names[4]);
   1888  1.1     skrll 	    if (amask > 1)
   1889  1.1     skrll 	      infprintf (is, "-%s", mips_gpr_names[amask + 3]);
   1890  1.1     skrll 	    need_comma = 1;
   1891  1.4  christos 	  }
   1892  1.1     skrll 
   1893  1.1     skrll 	smask = (l >> 1) & 3;
   1894  1.1     skrll 	if (smask == 3)
   1895  1.1     skrll 	  {
   1896  1.4  christos 	    infprintf (is, "%s??", need_comma ? "," : "");
   1897  1.1     skrll 	    need_comma = 1;
   1898  1.4  christos 	  }
   1899  1.1     skrll 	else if (smask > 0)
   1900  1.1     skrll 	  {
   1901  1.1     skrll 	    infprintf (is, "%s%s", need_comma ? "," : "", mips_gpr_names[16]);
   1902  1.1     skrll 	    if (smask > 1)
   1903  1.1     skrll 	      infprintf (is, "-%s", mips_gpr_names[smask + 15]);
   1904  1.4  christos 	    need_comma = 1;
   1905  1.1     skrll 	  }
   1906  1.1     skrll 
   1907  1.1     skrll 	if (l & 1)
   1908  1.1     skrll 	  {
   1909  1.1     skrll 	    infprintf (is, "%s%s", need_comma ? "," : "", mips_gpr_names[31]);
   1910  1.4  christos 	    need_comma = 1;
   1911  1.1     skrll 	  }
   1912  1.4  christos 
   1913  1.1     skrll 	if (amask == 5 || amask == 6)
   1914  1.1     skrll 	  {
   1915  1.1     skrll 	    infprintf (is, "%s$f0", need_comma ? "," : "");
   1916  1.1     skrll 	    if (amask == 6)
   1917  1.1     skrll 	      infprintf (is, "-$f1");
   1918  1.1     skrll 	  }
   1919  1.1     skrll       }
   1920  1.1     skrll       break;
   1921  1.1     skrll 
   1922  1.1     skrll     case 'm':
   1923  1.1     skrll     case 'M':
   1924  1.1     skrll       /* MIPS16e save/restore.  */
   1925  1.1     skrll       {
   1926  1.1     skrll       int need_comma = 0;
   1927  1.1     skrll       int amask, args, statics;
   1928  1.1     skrll       int nsreg, smask;
   1929  1.1     skrll       int framesz;
   1930  1.1     skrll       int i, j;
   1931  1.1     skrll 
   1932  1.1     skrll       l = l & 0x7f;
   1933  1.1     skrll       if (use_extend)
   1934  1.1     skrll         l |= extend << 16;
   1935  1.1     skrll 
   1936  1.1     skrll       amask = (l >> 16) & 0xf;
   1937  1.1     skrll       if (amask == MIPS16_ALL_ARGS)
   1938  1.1     skrll         {
   1939  1.1     skrll           args = 4;
   1940  1.1     skrll           statics = 0;
   1941  1.1     skrll         }
   1942  1.1     skrll       else if (amask == MIPS16_ALL_STATICS)
   1943  1.1     skrll         {
   1944  1.1     skrll           args = 0;
   1945  1.1     skrll           statics = 4;
   1946  1.1     skrll         }
   1947  1.1     skrll       else
   1948  1.1     skrll         {
   1949  1.4  christos           args = amask >> 2;
   1950  1.1     skrll           statics = amask & 3;
   1951  1.4  christos         }
   1952  1.1     skrll 
   1953  1.1     skrll       if (args > 0) {
   1954  1.1     skrll 	  infprintf (is, "%s", mips_gpr_names[4]);
   1955  1.1     skrll           if (args > 1)
   1956  1.1     skrll 	    infprintf (is, "-%s", mips_gpr_names[4 + args - 1]);
   1957  1.1     skrll           need_comma = 1;
   1958  1.1     skrll       }
   1959  1.4  christos 
   1960  1.1     skrll       framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
   1961  1.1     skrll       if (framesz == 0 && !use_extend)
   1962  1.4  christos         framesz = 128;
   1963  1.1     skrll 
   1964  1.1     skrll       infprintf (is, "%s%d", need_comma ? "," : "", framesz);
   1965  1.1     skrll 
   1966  1.1     skrll       if (l & 0x40)                   /* $ra */
   1967  1.1     skrll 	infprintf (is, ",%s", mips_gpr_names[31]);
   1968  1.1     skrll 
   1969  1.1     skrll       nsreg = (l >> 24) & 0x7;
   1970  1.1     skrll       smask = 0;
   1971  1.1     skrll       if (l & 0x20)                   /* $s0 */
   1972  1.1     skrll         smask |= 1 << 0;
   1973  1.1     skrll       if (l & 0x10)                   /* $s1 */
   1974  1.1     skrll         smask |= 1 << 1;
   1975  1.1     skrll       if (nsreg > 0)                  /* $s2-$s8 */
   1976  1.1     skrll         smask |= ((1 << nsreg) - 1) << 2;
   1977  1.1     skrll 
   1978  1.4  christos       /* Find first set static reg bit.  */
   1979  1.1     skrll       for (i = 0; i < 9; i++)
   1980  1.1     skrll         {
   1981  1.1     skrll           if (smask & (1 << i))
   1982  1.1     skrll             {
   1983  1.4  christos 	      infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
   1984  1.1     skrll               /* Skip over string of set bits.  */
   1985  1.1     skrll               for (j = i; smask & (2 << j); j++)
   1986  1.1     skrll                 continue;
   1987  1.1     skrll               if (j > i)
   1988  1.1     skrll 		infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
   1989  1.1     skrll               i = j + 1;
   1990  1.4  christos             }
   1991  1.1     skrll         }
   1992  1.4  christos 
   1993  1.4  christos       /* Statics $ax - $a3.  */
   1994  1.4  christos       if (statics == 1)
   1995  1.1     skrll 	infprintf (is, ",%s", mips_gpr_names[7]);
   1996  1.1     skrll       else if (statics > 0)
   1997  1.1     skrll 	infprintf (is, ",%s-%s",
   1998  1.1     skrll 		   mips_gpr_names[7 - statics + 1],
   1999  1.1     skrll 		   mips_gpr_names[7]);
   2000  1.4  christos       }
   2001  1.4  christos       break;
   2002  1.4  christos 
   2003  1.4  christos     default:
   2004  1.1     skrll       /* xgettext:c-format */
   2005  1.1     skrll       infprintf (is,
   2006  1.1     skrll 		 _("# internal disassembler error, "
   2007  1.1     skrll 		   "unrecognised modifier (%c)"),
   2008  1.1     skrll 		 type);
   2009  1.1     skrll       abort ();
   2010  1.1     skrll     }
   2011  1.1     skrll }
   2012  1.1     skrll 
   2013  1.4  christos /* Disassemble mips16 instructions.  */
   2014  1.1     skrll 
   2015  1.1     skrll static int
   2016  1.1     skrll print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
   2017  1.1     skrll {
   2018  1.1     skrll   const fprintf_ftype infprintf = info->fprintf_func;
   2019  1.1     skrll   int status;
   2020  1.1     skrll   bfd_byte buffer[2];
   2021  1.4  christos   int length;
   2022  1.1     skrll   int insn;
   2023  1.1     skrll   bfd_boolean use_extend;
   2024  1.1     skrll   int extend = 0;
   2025  1.1     skrll   const struct mips_opcode *op, *opend;
   2026  1.1     skrll   void *is = info->stream;
   2027  1.1     skrll 
   2028  1.1     skrll   info->bytes_per_chunk = 2;
   2029  1.1     skrll   info->display_endian = info->endian;
   2030  1.1     skrll   info->insn_info_valid = 1;
   2031  1.1     skrll   info->branch_delay_insns = 0;
   2032  1.1     skrll   info->data_size = 0;
   2033  1.1     skrll   info->insn_type = dis_nonbranch;
   2034  1.1     skrll   info->target = 0;
   2035  1.1     skrll   info->target2 = 0;
   2036  1.1     skrll 
   2037  1.1     skrll   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   2038  1.1     skrll   if (status != 0)
   2039  1.1     skrll     {
   2040  1.1     skrll       (*info->memory_error_func) (status, memaddr, info);
   2041  1.1     skrll       return -1;
   2042  1.1     skrll     }
   2043  1.1     skrll 
   2044  1.1     skrll   length = 2;
   2045  1.1     skrll 
   2046  1.1     skrll   if (info->endian == BFD_ENDIAN_BIG)
   2047  1.1     skrll     insn = bfd_getb16 (buffer);
   2048  1.1     skrll   else
   2049  1.1     skrll     insn = bfd_getl16 (buffer);
   2050  1.1     skrll 
   2051  1.1     skrll   /* Handle the extend opcode specially.  */
   2052  1.1     skrll   use_extend = FALSE;
   2053  1.1     skrll   if ((insn & 0xf800) == 0xf000)
   2054  1.1     skrll     {
   2055  1.1     skrll       use_extend = TRUE;
   2056  1.1     skrll       extend = insn & 0x7ff;
   2057  1.1     skrll 
   2058  1.4  christos       memaddr += 2;
   2059  1.1     skrll 
   2060  1.1     skrll       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   2061  1.1     skrll       if (status != 0)
   2062  1.1     skrll 	{
   2063  1.1     skrll 	  infprintf (is, "extend 0x%x", (unsigned int) extend);
   2064  1.1     skrll 	  (*info->memory_error_func) (status, memaddr, info);
   2065  1.1     skrll 	  return -1;
   2066  1.1     skrll 	}
   2067  1.1     skrll 
   2068  1.1     skrll       if (info->endian == BFD_ENDIAN_BIG)
   2069  1.1     skrll 	insn = bfd_getb16 (buffer);
   2070  1.1     skrll       else
   2071  1.4  christos 	insn = bfd_getl16 (buffer);
   2072  1.1     skrll 
   2073  1.1     skrll       /* Check for an extend opcode followed by an extend opcode.  */
   2074  1.1     skrll       if ((insn & 0xf800) == 0xf000)
   2075  1.1     skrll 	{
   2076  1.1     skrll 	  infprintf (is, "extend 0x%x", (unsigned int) extend);
   2077  1.1     skrll 	  info->insn_type = dis_noninsn;
   2078  1.1     skrll 	  return length;
   2079  1.1     skrll 	}
   2080  1.1     skrll 
   2081  1.1     skrll       length += 2;
   2082  1.1     skrll     }
   2083  1.1     skrll 
   2084  1.1     skrll   /* FIXME: Should probably use a hash table on the major opcode here.  */
   2085  1.1     skrll 
   2086  1.1     skrll   opend = mips16_opcodes + bfd_mips16_num_opcodes;
   2087  1.1     skrll   for (op = mips16_opcodes; op < opend; op++)
   2088  1.1     skrll     {
   2089  1.1     skrll       if (op->pinfo != INSN_MACRO
   2090  1.1     skrll 	  && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   2091  1.1     skrll 	  && (insn & op->mask) == op->match)
   2092  1.1     skrll 	{
   2093  1.1     skrll 	  const char *s;
   2094  1.4  christos 
   2095  1.1     skrll 	  if (strchr (op->args, 'a') != NULL)
   2096  1.1     skrll 	    {
   2097  1.1     skrll 	      if (use_extend)
   2098  1.1     skrll 		{
   2099  1.1     skrll 		  infprintf (is, "extend 0x%x", (unsigned int) extend);
   2100  1.1     skrll 		  info->insn_type = dis_noninsn;
   2101  1.1     skrll 		  return length - 2;
   2102  1.1     skrll 		}
   2103  1.1     skrll 
   2104  1.1     skrll 	      use_extend = FALSE;
   2105  1.1     skrll 
   2106  1.1     skrll 	      memaddr += 2;
   2107  1.1     skrll 
   2108  1.1     skrll 	      status = (*info->read_memory_func) (memaddr, buffer, 2,
   2109  1.1     skrll 						  info);
   2110  1.1     skrll 	      if (status == 0)
   2111  1.1     skrll 		{
   2112  1.1     skrll 		  use_extend = TRUE;
   2113  1.1     skrll 		  if (info->endian == BFD_ENDIAN_BIG)
   2114  1.1     skrll 		    extend = bfd_getb16 (buffer);
   2115  1.1     skrll 		  else
   2116  1.4  christos 		    extend = bfd_getl16 (buffer);
   2117  1.1     skrll 		  length += 2;
   2118  1.4  christos 		}
   2119  1.1     skrll 	    }
   2120  1.1     skrll 
   2121  1.1     skrll 	  infprintf (is, "%s", op->name);
   2122  1.1     skrll 	  if (op->args[0] != '\0')
   2123  1.1     skrll 	    infprintf (is, "\t");
   2124  1.4  christos 
   2125  1.1     skrll 	  for (s = op->args; *s != '\0'; s++)
   2126  1.1     skrll 	    {
   2127  1.1     skrll 	      if (*s == ','
   2128  1.1     skrll 		  && s[1] == 'w'
   2129  1.1     skrll 		  && GET_OP (insn, RX) == GET_OP (insn, RY))
   2130  1.1     skrll 		{
   2131  1.1     skrll 		  /* Skip the register and the comma.  */
   2132  1.4  christos 		  ++s;
   2133  1.1     skrll 		  continue;
   2134  1.1     skrll 		}
   2135  1.1     skrll 	      if (*s == ','
   2136  1.1     skrll 		  && s[1] == 'v'
   2137  1.1     skrll 		  && GET_OP (insn, RZ) == GET_OP (insn, RX))
   2138  1.1     skrll 		{
   2139  1.1     skrll 		  /* Skip the register and the comma.  */
   2140  1.1     skrll 		  ++s;
   2141  1.1     skrll 		  continue;
   2142  1.3  christos 		}
   2143  1.1     skrll 	      print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
   2144  1.3  christos 				     info);
   2145  1.3  christos 	    }
   2146  1.3  christos 
   2147  1.1     skrll 	  /* Figure out branch instruction type and delay slot information.  */
   2148  1.3  christos 	  if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
   2149  1.3  christos 	    info->branch_delay_insns = 1;
   2150  1.3  christos 	  if ((op->pinfo & (INSN_UNCOND_BRANCH_DELAY
   2151  1.1     skrll 			    | MIPS16_INSN_UNCOND_BRANCH)) != 0)
   2152  1.1     skrll 	    {
   2153  1.3  christos 	      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   2154  1.3  christos 		info->insn_type = dis_jsr;
   2155  1.1     skrll 	      else
   2156  1.1     skrll 		info->insn_type = dis_branch;
   2157  1.1     skrll 	    }
   2158  1.1     skrll 	  else if ((op->pinfo & MIPS16_INSN_COND_BRANCH) != 0)
   2159  1.4  christos 	    info->insn_type = dis_condbranch;
   2160  1.4  christos 
   2161  1.1     skrll 	  return length;
   2162  1.1     skrll 	}
   2163  1.4  christos     }
   2164  1.4  christos #undef GET_OP_S
   2165  1.4  christos #undef GET_OP
   2166  1.4  christos 
   2167  1.4  christos   if (use_extend)
   2168  1.4  christos     infprintf (is, "0x%x", extend | 0xf000);
   2169  1.4  christos   infprintf (is, "0x%x", insn);
   2170  1.4  christos   info->insn_type = dis_noninsn;
   2171  1.4  christos 
   2172  1.4  christos   return length;
   2173  1.4  christos }
   2174  1.4  christos 
   2175  1.4  christos /* Disassemble microMIPS instructions.  */
   2176  1.4  christos 
   2177  1.4  christos static int
   2178  1.4  christos print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
   2179  1.4  christos {
   2180  1.4  christos   const fprintf_ftype infprintf = info->fprintf_func;
   2181  1.4  christos   const struct mips_opcode *op, *opend;
   2182  1.4  christos   unsigned int lsb, msbd, msb;
   2183  1.4  christos   void *is = info->stream;
   2184  1.4  christos   unsigned int regno;
   2185  1.4  christos   bfd_byte buffer[2];
   2186  1.4  christos   int lastregno = 0;
   2187  1.4  christos   int higher;
   2188  1.4  christos   int length;
   2189  1.4  christos   int status;
   2190  1.4  christos   int delta;
   2191  1.4  christos   int immed;
   2192  1.4  christos   int insn;
   2193  1.4  christos 
   2194  1.4  christos   lsb = 0;
   2195  1.4  christos 
   2196  1.4  christos   info->bytes_per_chunk = 2;
   2197  1.4  christos   info->display_endian = info->endian;
   2198  1.4  christos   info->insn_info_valid = 1;
   2199  1.4  christos   info->branch_delay_insns = 0;
   2200  1.4  christos   info->data_size = 0;
   2201  1.4  christos   info->insn_type = dis_nonbranch;
   2202  1.4  christos   info->target = 0;
   2203  1.4  christos   info->target2 = 0;
   2204  1.4  christos 
   2205  1.4  christos   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   2206  1.4  christos   if (status != 0)
   2207  1.4  christos     {
   2208  1.4  christos       (*info->memory_error_func) (status, memaddr, info);
   2209  1.4  christos       return -1;
   2210  1.4  christos     }
   2211  1.4  christos 
   2212  1.4  christos   length = 2;
   2213  1.4  christos 
   2214  1.4  christos   if (info->endian == BFD_ENDIAN_BIG)
   2215  1.4  christos     insn = bfd_getb16 (buffer);
   2216  1.4  christos   else
   2217  1.4  christos     insn = bfd_getl16 (buffer);
   2218  1.4  christos 
   2219  1.4  christos   if ((insn & 0xfc00) == 0x7c00)
   2220  1.4  christos     {
   2221  1.4  christos       /* This is a 48-bit microMIPS instruction.  */
   2222  1.4  christos       higher = insn;
   2223  1.4  christos 
   2224  1.4  christos       status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
   2225  1.4  christos       if (status != 0)
   2226  1.4  christos 	{
   2227  1.4  christos 	  infprintf (is, "micromips 0x%x", higher);
   2228  1.4  christos 	  (*info->memory_error_func) (status, memaddr + 2, info);
   2229  1.4  christos 	  return -1;
   2230  1.4  christos 	}
   2231  1.4  christos       if (info->endian == BFD_ENDIAN_BIG)
   2232  1.4  christos 	insn = bfd_getb16 (buffer);
   2233  1.4  christos       else
   2234  1.4  christos 	insn = bfd_getl16 (buffer);
   2235  1.4  christos       higher = (higher << 16) | insn;
   2236  1.4  christos 
   2237  1.4  christos       status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
   2238  1.4  christos       if (status != 0)
   2239  1.4  christos 	{
   2240  1.4  christos 	  infprintf (is, "micromips 0x%x", higher);
   2241  1.4  christos 	  (*info->memory_error_func) (status, memaddr + 4, info);
   2242  1.4  christos 	  return -1;
   2243  1.4  christos 	}
   2244  1.4  christos       if (info->endian == BFD_ENDIAN_BIG)
   2245  1.4  christos 	insn = bfd_getb16 (buffer);
   2246  1.4  christos       else
   2247  1.4  christos 	insn = bfd_getl16 (buffer);
   2248  1.4  christos       infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
   2249  1.4  christos 
   2250  1.4  christos       info->insn_type = dis_noninsn;
   2251  1.4  christos       return 6;
   2252  1.4  christos     }
   2253  1.4  christos   else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
   2254  1.4  christos     {
   2255  1.4  christos       /* This is a 32-bit microMIPS instruction.  */
   2256  1.4  christos       higher = insn;
   2257  1.4  christos 
   2258  1.4  christos       status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
   2259  1.4  christos       if (status != 0)
   2260  1.4  christos 	{
   2261  1.4  christos 	  infprintf (is, "micromips 0x%x", higher);
   2262  1.4  christos 	  (*info->memory_error_func) (status, memaddr + 2, info);
   2263  1.4  christos 	  return -1;
   2264  1.4  christos 	}
   2265  1.4  christos 
   2266  1.4  christos       if (info->endian == BFD_ENDIAN_BIG)
   2267  1.4  christos 	insn = bfd_getb16 (buffer);
   2268  1.4  christos       else
   2269  1.4  christos 	insn = bfd_getl16 (buffer);
   2270  1.4  christos 
   2271  1.4  christos       insn = insn | (higher << 16);
   2272  1.4  christos 
   2273  1.4  christos       length += 2;
   2274  1.4  christos     }
   2275  1.4  christos 
   2276  1.4  christos   /* FIXME: Should probably use a hash table on the major opcode here.  */
   2277  1.4  christos 
   2278  1.4  christos #define GET_OP(insn, field) \
   2279  1.4  christos   (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
   2280  1.4  christos #define GET_OP_S(insn, field) \
   2281  1.4  christos   ((GET_OP (insn, field) ^ ((MICROMIPSOP_MASK_##field >> 1) + 1)) \
   2282  1.4  christos    - ((MICROMIPSOP_MASK_##field >> 1) + 1))
   2283  1.4  christos   opend = micromips_opcodes + bfd_micromips_num_opcodes;
   2284  1.4  christos   for (op = micromips_opcodes; op < opend; op++)
   2285  1.4  christos     {
   2286  1.4  christos       if (op->pinfo != INSN_MACRO
   2287  1.4  christos 	  && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   2288  1.4  christos 	  && (insn & op->mask) == op->match
   2289  1.4  christos 	  && ((length == 2 && (op->mask & 0xffff0000) == 0)
   2290  1.4  christos 	      || (length == 4 && (op->mask & 0xffff0000) != 0)))
   2291  1.4  christos 	{
   2292  1.4  christos 	  const char *s;
   2293  1.4  christos 
   2294  1.4  christos 	  infprintf (is, "%s", op->name);
   2295  1.4  christos 	  if (op->args[0] != '\0')
   2296  1.4  christos 	    infprintf (is, "\t");
   2297  1.4  christos 
   2298  1.4  christos 	  for (s = op->args; *s != '\0'; s++)
   2299  1.4  christos 	    {
   2300  1.4  christos 	      switch (*s)
   2301  1.4  christos 		{
   2302  1.4  christos 		case ',':
   2303  1.4  christos 		case '(':
   2304  1.4  christos 		case ')':
   2305  1.4  christos 		  infprintf (is, "%c", *s);
   2306  1.4  christos 		  break;
   2307  1.4  christos 
   2308  1.4  christos 		case '.':
   2309  1.4  christos 		  infprintf (is, "%d", GET_OP_S (insn, OFFSET10));
   2310  1.4  christos 		  break;
   2311  1.4  christos 
   2312  1.4  christos 		case '1':
   2313  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, STYPE));
   2314  1.4  christos 		  break;
   2315  1.4  christos 
   2316  1.4  christos 		case '2':
   2317  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, BP));
   2318  1.4  christos 		  break;
   2319  1.4  christos 
   2320  1.4  christos 		case '3':
   2321  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, SA3));
   2322  1.4  christos 		  break;
   2323  1.4  christos 
   2324  1.4  christos 		case '4':
   2325  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, SA4));
   2326  1.4  christos 		  break;
   2327  1.4  christos 
   2328  1.4  christos 		case '5':
   2329  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, IMM8));
   2330  1.4  christos 		  break;
   2331  1.4  christos 
   2332  1.4  christos 		case '6':
   2333  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, RS));
   2334  1.4  christos 		  break;
   2335  1.4  christos 
   2336  1.4  christos 		case '7':
   2337  1.4  christos 		  infprintf (is, "$ac%d", GET_OP (insn, DSPACC));
   2338  1.4  christos 		  break;
   2339  1.4  christos 
   2340  1.4  christos 		case '8':
   2341  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, WRDSP));
   2342  1.4  christos 		  break;
   2343  1.4  christos 
   2344  1.4  christos 		case '0': /* DSP 6-bit signed immediate in bit 16.  */
   2345  1.4  christos 		  delta = (GET_OP (insn, DSPSFT) ^ 0x20) - 0x20;
   2346  1.4  christos 		  infprintf (is, "%d", delta);
   2347  1.4  christos 		  break;
   2348  1.4  christos 
   2349  1.4  christos 		case '<':
   2350  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, SHAMT));
   2351  1.4  christos 		  break;
   2352  1.4  christos 
   2353  1.4  christos 		case '\\':
   2354  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, 3BITPOS));
   2355  1.4  christos 		  break;
   2356  1.4  christos 
   2357  1.4  christos 		case '^':
   2358  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, RD));
   2359  1.4  christos 		  break;
   2360  1.4  christos 
   2361  1.4  christos 		case '|':
   2362  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, TRAP));
   2363  1.4  christos 		  break;
   2364  1.4  christos 
   2365  1.4  christos 		case '~':
   2366  1.4  christos 		  infprintf (is, "%d", GET_OP_S (insn, OFFSET12));
   2367  1.4  christos 		  break;
   2368  1.4  christos 
   2369  1.4  christos 		case 'a':
   2370  1.4  christos 		  if (strcmp (op->name, "jalx") == 0)
   2371  1.4  christos 		    info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff)
   2372  1.4  christos 				    | (GET_OP (insn, TARGET) << 2));
   2373  1.4  christos 		  else
   2374  1.4  christos 		    info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff)
   2375  1.4  christos 				    | (GET_OP (insn, TARGET) << 1));
   2376  1.4  christos 		  /* For gdb disassembler, force odd address on jalx.  */
   2377  1.4  christos 		  if (info->flavour == bfd_target_unknown_flavour
   2378  1.4  christos 		      && strcmp (op->name, "jalx") == 0)
   2379  1.4  christos 		    info->target |= 1;
   2380  1.4  christos 		  (*info->print_address_func) (info->target, info);
   2381  1.4  christos 		  break;
   2382  1.4  christos 
   2383  1.4  christos 		case 'b':
   2384  1.4  christos 		case 'r':
   2385  1.4  christos 		case 's':
   2386  1.4  christos 		case 'v':
   2387  1.4  christos 		  infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]);
   2388  1.4  christos 		  break;
   2389  1.4  christos 
   2390  1.4  christos 		case 'c':
   2391  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, CODE));
   2392  1.4  christos 		  break;
   2393  1.4  christos 
   2394  1.4  christos 		case 'd':
   2395  1.4  christos 		  infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]);
   2396  1.4  christos 		  break;
   2397  1.4  christos 
   2398  1.4  christos 		case 'h':
   2399  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, PREFX));
   2400  1.4  christos 		  break;
   2401  1.4  christos 
   2402  1.4  christos 		case 'i':
   2403  1.4  christos 		case 'u':
   2404  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, IMMEDIATE));
   2405  1.4  christos 		  break;
   2406  1.4  christos 
   2407  1.4  christos 		case 'j': /* Same as i, but sign-extended.  */
   2408  1.4  christos 		case 'o':
   2409  1.4  christos 		  infprintf (is, "%d", GET_OP_S (insn, DELTA));
   2410  1.4  christos 		  break;
   2411  1.4  christos 
   2412  1.4  christos 		case 'k':
   2413  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, CACHE));
   2414  1.4  christos 		  break;
   2415  1.4  christos 
   2416  1.4  christos 		case 'n':
   2417  1.4  christos 		  {
   2418  1.4  christos 		    int s_reg_encode;
   2419  1.4  christos 
   2420  1.4  christos 		    immed = GET_OP (insn, RT);
   2421  1.4  christos 		    s_reg_encode = immed & 0xf;
   2422  1.4  christos 		    if (s_reg_encode != 0)
   2423  1.4  christos 		      {
   2424  1.4  christos 			if (s_reg_encode == 1)
   2425  1.4  christos 			  infprintf (is, "%s", mips_gpr_names[16]);
   2426  1.4  christos 			else if (s_reg_encode < 9)
   2427  1.4  christos 			  infprintf (is, "%s-%s",
   2428  1.4  christos 				   mips_gpr_names[16],
   2429  1.4  christos 				   mips_gpr_names[15 + s_reg_encode]);
   2430  1.4  christos 			else if (s_reg_encode == 9)
   2431  1.4  christos 			  infprintf (is, "%s-%s,%s",
   2432  1.4  christos 				   mips_gpr_names[16],
   2433  1.4  christos 				   mips_gpr_names[23],
   2434  1.4  christos 				   mips_gpr_names[30]);
   2435  1.4  christos 			else
   2436  1.4  christos 			  infprintf (is, "UNKNOWN");
   2437  1.4  christos 		      }
   2438  1.4  christos 
   2439  1.4  christos 		    if (immed & 0x10) /* For ra.  */
   2440  1.4  christos 		      {
   2441  1.4  christos 			if (s_reg_encode == 0)
   2442  1.4  christos 			  infprintf (is, "%s", mips_gpr_names[31]);
   2443  1.4  christos 			else
   2444  1.4  christos 			  infprintf (is, ",%s", mips_gpr_names[31]);
   2445  1.4  christos 		      }
   2446  1.4  christos 		    break;
   2447  1.4  christos 		  }
   2448  1.4  christos 
   2449  1.4  christos 		case 'p':
   2450  1.4  christos 		  /* Sign-extend the displacement.  */
   2451  1.4  christos 		  delta = GET_OP_S (insn, DELTA);
   2452  1.4  christos 		  info->target = (delta << 1) + memaddr + length;
   2453  1.4  christos 		  (*info->print_address_func) (info->target, info);
   2454  1.4  christos 		  break;
   2455  1.4  christos 
   2456  1.4  christos 		case 'q':
   2457  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, CODE2));
   2458  1.4  christos 		  break;
   2459  1.4  christos 
   2460  1.4  christos 		case 't':
   2461  1.4  christos 		case 'w':
   2462  1.4  christos 		  infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]);
   2463  1.4  christos 		  break;
   2464  1.4  christos 
   2465  1.4  christos 		case 'y':
   2466  1.4  christos 		  infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]);
   2467  1.4  christos 		  break;
   2468  1.4  christos 
   2469  1.4  christos 		case 'z':
   2470  1.4  christos 		  infprintf (is, "%s", mips_gpr_names[0]);
   2471  1.4  christos 		  break;
   2472  1.4  christos 
   2473  1.4  christos 		case '@': /* DSP 10-bit signed immediate in bit 16.  */
   2474  1.4  christos 		  delta = (GET_OP (insn, IMM10) ^ 0x200) - 0x200;
   2475  1.4  christos 		  infprintf (is, "%d", delta);
   2476  1.4  christos 		  break;
   2477  1.4  christos 
   2478  1.4  christos 		case 'B':
   2479  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, CODE10));
   2480  1.4  christos 		  break;
   2481  1.4  christos 
   2482  1.4  christos 		case 'C':
   2483  1.4  christos 		  infprintf (is, "0x%x", GET_OP (insn, COPZ));
   2484  1.4  christos 		  break;
   2485  1.4  christos 
   2486  1.4  christos 		case 'D':
   2487  1.4  christos 		  infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]);
   2488  1.4  christos 		  break;
   2489  1.4  christos 
   2490  1.4  christos 		case 'E':
   2491  1.4  christos 		  /* Coprocessor register for lwcN instructions, et al.
   2492  1.4  christos 
   2493  1.4  christos 		    Note that there is no load/store cp0 instructions, and
   2494  1.4  christos 		    that FPU (cp1) instructions disassemble this field using
   2495  1.4  christos 		    'T' format.  Therefore, until we gain understanding of
   2496  1.4  christos 		    cp2 register names, we can simply print the register
   2497  1.4  christos 		    numbers.  */
   2498  1.4  christos 		  infprintf (is, "$%d", GET_OP (insn, RT));
   2499  1.4  christos 		  break;
   2500  1.4  christos 
   2501  1.4  christos 		case 'G':
   2502  1.4  christos 		  /* Coprocessor register for mtcN instructions, et al.  Note
   2503  1.4  christos 		     that FPU (cp1) instructions disassemble this field using
   2504  1.4  christos 		     'S' format.  Therefore, we only need to worry about cp0,
   2505  1.4  christos 		     cp2, and cp3.
   2506  1.4  christos 		     The microMIPS encoding does not have a coprocessor
   2507  1.4  christos 		     identifier field as such, so we must work out the
   2508  1.4  christos 		     coprocessor number by looking at the opcode.  */
   2509  1.4  christos 		  switch (insn
   2510  1.4  christos 			  & ~((MICROMIPSOP_MASK_RT << MICROMIPSOP_SH_RT)
   2511  1.4  christos 			      | (MICROMIPSOP_MASK_RS << MICROMIPSOP_SH_RS)))
   2512  1.4  christos 		    {
   2513  1.4  christos 		    case 0x000000fc:				/* mfc0  */
   2514  1.4  christos 		    case 0x000002fc:				/* mtc0  */
   2515  1.4  christos 		    case 0x580000fc:				/* dmfc0 */
   2516  1.4  christos 		    case 0x580002fc:				/* dmtc0 */
   2517  1.4  christos 		      infprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]);
   2518  1.4  christos 		      break;
   2519  1.4  christos 		    default:
   2520  1.4  christos 		      infprintf (is, "$%d", GET_OP (insn, RS));
   2521  1.4  christos 		      break;
   2522  1.4  christos 		    }
   2523  1.4  christos 		  break;
   2524  1.4  christos 
   2525  1.4  christos 		case 'H':
   2526  1.4  christos 		  infprintf (is, "%d", GET_OP (insn, SEL));
   2527  1.4  christos 		  break;
   2528  1.4  christos 
   2529  1.4  christos 		case 'K':
   2530  1.4  christos 		  infprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]);
   2531  1.4  christos 		  break;
   2532  1.4  christos 
   2533  1.4  christos 		case 'M':
   2534  1.4  christos 		  infprintf (is, "$fcc%d", GET_OP (insn, CCC));
   2535  1.4  christos 		  break;
   2536  1.4  christos 
   2537  1.4  christos 		case 'N':
   2538  1.4  christos 		  infprintf (is,
   2539  1.4  christos 			   (op->pinfo & (FP_D | FP_S)) != 0
   2540  1.4  christos 			   ? "$fcc%d" : "$cc%d",
   2541  1.4  christos 			   GET_OP (insn, BCC));
   2542  1.4  christos 		  break;
   2543  1.4  christos 
   2544  1.4  christos 		case 'R':
   2545  1.4  christos 		  infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]);
   2546  1.4  christos 		  break;
   2547  1.4  christos 
   2548  1.4  christos 		case 'S':
   2549  1.4  christos 		case 'V':
   2550  1.4  christos 		  infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]);
   2551  1.4  christos 		  break;
   2552  1.4  christos 
   2553  1.4  christos 		case 'T':
   2554  1.4  christos 		  infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]);
   2555  1.4  christos 		  break;
   2556  1.4  christos 
   2557  1.4  christos 		case '+':
   2558  1.4  christos 		  /* Extension character; switch for second char.  */
   2559  1.4  christos 		  s++;
   2560  1.4  christos 		  switch (*s)
   2561  1.4  christos 		    {
   2562  1.4  christos 		    case 'A':
   2563  1.4  christos 		      lsb = GET_OP (insn, EXTLSB);
   2564  1.4  christos 		      infprintf (is, "0x%x", lsb);
   2565  1.4  christos 		      break;
   2566  1.4  christos 
   2567  1.4  christos 		    case 'B':
   2568  1.4  christos 		      msb = GET_OP (insn, INSMSB);
   2569  1.4  christos 		      infprintf (is, "0x%x", msb - lsb + 1);
   2570  1.4  christos 		      break;
   2571  1.4  christos 
   2572  1.4  christos 		    case 'C':
   2573  1.4  christos 		    case 'H':
   2574  1.4  christos 		      msbd = GET_OP (insn, EXTMSBD);
   2575  1.4  christos 		      infprintf (is, "0x%x", msbd + 1);
   2576  1.4  christos 		      break;
   2577  1.4  christos 
   2578  1.4  christos 		    case 'D':
   2579  1.4  christos 		      {
   2580  1.4  christos 			const struct mips_cp0sel_name *n;
   2581  1.4  christos 			unsigned int cp0reg, sel;
   2582  1.4  christos 
   2583  1.4  christos 			cp0reg = GET_OP (insn, RS);
   2584  1.4  christos 			sel = GET_OP (insn, SEL);
   2585  1.4  christos 
   2586  1.4  christos 			/* CP0 register including 'sel' code for mtcN
   2587  1.4  christos 			   (et al.), to be printed textually if known.
   2588  1.4  christos 			   If not known, print both CP0 register name and
   2589  1.4  christos 			   sel numerically since CP0 register with sel 0 may
   2590  1.4  christos 			   have a name unrelated to register being printed.  */
   2591  1.4  christos 			n = lookup_mips_cp0sel_name (mips_cp0sel_names,
   2592  1.4  christos 						     mips_cp0sel_names_len,
   2593  1.4  christos 						     cp0reg, sel);
   2594  1.4  christos 			if (n != NULL)
   2595  1.4  christos 			  infprintf (is, "%s", n->name);
   2596  1.4  christos 			else
   2597  1.4  christos 			  infprintf (is, "$%d,%d", cp0reg, sel);
   2598  1.4  christos 			break;
   2599  1.4  christos 		      }
   2600  1.4  christos 
   2601  1.4  christos 		    case 'E':
   2602  1.4  christos 		      lsb = GET_OP (insn, EXTLSB) + 32;
   2603  1.4  christos 		      infprintf (is, "0x%x", lsb);
   2604  1.4  christos 		      break;
   2605  1.4  christos 
   2606  1.4  christos 		    case 'F':
   2607  1.4  christos 		      msb = GET_OP (insn, INSMSB) + 32;
   2608  1.4  christos 		      infprintf (is, "0x%x", msb - lsb + 1);
   2609  1.4  christos 		      break;
   2610  1.4  christos 
   2611  1.4  christos 		    case 'G':
   2612  1.4  christos 		      msbd = GET_OP (insn, EXTMSBD) + 32;
   2613  1.4  christos 		      infprintf (is, "0x%x", msbd + 1);
   2614  1.4  christos 		      break;
   2615  1.4  christos 
   2616  1.4  christos 		    default:
   2617  1.4  christos 		      /* xgettext:c-format */
   2618  1.4  christos 		      infprintf (is,
   2619  1.4  christos 			       _("# internal disassembler error, "
   2620  1.4  christos 				 "unrecognized modifier (+%c)"),
   2621  1.4  christos 			       *s);
   2622  1.4  christos 		      abort ();
   2623  1.4  christos 		    }
   2624  1.4  christos 		  break;
   2625  1.4  christos 
   2626  1.4  christos 		case 'm':
   2627  1.4  christos 		  /* Extension character; switch for second char.  */
   2628  1.4  christos 		  s++;
   2629  1.4  christos 		  switch (*s)
   2630  1.4  christos 		    {
   2631  1.4  christos 		    case 'a':	/* global pointer.  */
   2632  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[28]);
   2633  1.4  christos 		      break;
   2634  1.4  christos 
   2635  1.4  christos 		    case 'b':
   2636  1.4  christos 		      regno = micromips_to_32_reg_b_map[GET_OP (insn, MB)];
   2637  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2638  1.4  christos 		      break;
   2639  1.4  christos 
   2640  1.4  christos 		    case 'c':
   2641  1.4  christos 		      regno = micromips_to_32_reg_c_map[GET_OP (insn, MC)];
   2642  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2643  1.4  christos 		      break;
   2644  1.4  christos 
   2645  1.4  christos 		    case 'd':
   2646  1.4  christos 		      regno = micromips_to_32_reg_d_map[GET_OP (insn, MD)];
   2647  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2648  1.4  christos 		      break;
   2649  1.4  christos 
   2650  1.4  christos 		    case 'e':
   2651  1.4  christos 		      regno = micromips_to_32_reg_e_map[GET_OP (insn, ME)];
   2652  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2653  1.4  christos 		      break;
   2654  1.4  christos 
   2655  1.4  christos 		    case 'f':
   2656  1.4  christos 		      /* Save lastregno for "mt" to print out later.  */
   2657  1.4  christos 		      lastregno = micromips_to_32_reg_f_map[GET_OP (insn, MF)];
   2658  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[lastregno]);
   2659  1.4  christos 		      break;
   2660  1.4  christos 
   2661  1.4  christos 		    case 'g':
   2662  1.4  christos 		      regno = micromips_to_32_reg_g_map[GET_OP (insn, MG)];
   2663  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2664  1.4  christos 		      break;
   2665  1.4  christos 
   2666  1.4  christos 		    case 'h':
   2667  1.4  christos 		      regno = micromips_to_32_reg_h_map[GET_OP (insn, MH)];
   2668  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2669  1.4  christos 		      break;
   2670  1.4  christos 
   2671  1.4  christos 		    case 'i':
   2672  1.4  christos 		      regno = micromips_to_32_reg_i_map[GET_OP (insn, MI)];
   2673  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2674  1.4  christos 		      break;
   2675  1.4  christos 
   2676  1.4  christos 		    case 'j':
   2677  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]);
   2678  1.4  christos 		      break;
   2679  1.4  christos 
   2680  1.4  christos 		    case 'l':
   2681  1.4  christos 		      regno = micromips_to_32_reg_l_map[GET_OP (insn, ML)];
   2682  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2683  1.4  christos 		      break;
   2684  1.4  christos 
   2685  1.4  christos 		    case 'm':
   2686  1.4  christos 		      regno = micromips_to_32_reg_m_map[GET_OP (insn, MM)];
   2687  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2688  1.4  christos 		      break;
   2689  1.4  christos 
   2690  1.4  christos 		    case 'n':
   2691  1.4  christos 		      regno = micromips_to_32_reg_n_map[GET_OP (insn, MN)];
   2692  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2693  1.4  christos 		      break;
   2694  1.4  christos 
   2695  1.4  christos 		    case 'p':
   2696  1.4  christos 		      /* Save lastregno for "mt" to print out later.  */
   2697  1.4  christos 		      lastregno = GET_OP (insn, MP);
   2698  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[lastregno]);
   2699  1.4  christos 		      break;
   2700  1.4  christos 
   2701  1.4  christos 		    case 'q':
   2702  1.4  christos 		      regno = micromips_to_32_reg_q_map[GET_OP (insn, MQ)];
   2703  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[regno]);
   2704  1.4  christos 		      break;
   2705  1.4  christos 
   2706  1.4  christos 		    case 'r':	/* program counter.  */
   2707  1.4  christos 		      infprintf (is, "$pc");
   2708  1.4  christos 		      break;
   2709  1.4  christos 
   2710  1.4  christos 		    case 's':	/* stack pointer.  */
   2711  1.4  christos 		      lastregno = 29;
   2712  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[29]);
   2713  1.4  christos 		      break;
   2714  1.4  christos 
   2715  1.4  christos 		    case 't':
   2716  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[lastregno]);
   2717  1.4  christos 		      break;
   2718  1.4  christos 
   2719  1.4  christos 		    case 'z':	/* $0.  */
   2720  1.4  christos 		      infprintf (is, "%s", mips_gpr_names[0]);
   2721  1.4  christos 		      break;
   2722  1.4  christos 
   2723  1.4  christos 		    case 'A':
   2724  1.4  christos 		      /* Sign-extend the immediate.  */
   2725  1.4  christos 		      immed = GET_OP_S (insn, IMMA) << 2;
   2726  1.4  christos 		      infprintf (is, "%d", immed);
   2727  1.4  christos 		      break;
   2728  1.4  christos 
   2729  1.4  christos 		    case 'B':
   2730  1.4  christos 		      immed = micromips_imm_b_map[GET_OP (insn, IMMB)];
   2731  1.4  christos 		      infprintf (is, "%d", immed);
   2732  1.4  christos 		      break;
   2733  1.4  christos 
   2734  1.4  christos 		    case 'C':
   2735  1.4  christos 		      immed = micromips_imm_c_map[GET_OP (insn, IMMC)];
   2736  1.4  christos 		      infprintf (is, "0x%x", immed);
   2737  1.4  christos 		      break;
   2738  1.4  christos 
   2739  1.4  christos 		    case 'D':
   2740  1.4  christos 		      /* Sign-extend the displacement.  */
   2741  1.4  christos 		      delta = GET_OP_S (insn, IMMD);
   2742  1.4  christos 		      info->target = (delta << 1) + memaddr + length;
   2743  1.4  christos 		      (*info->print_address_func) (info->target, info);
   2744  1.4  christos 		      break;
   2745  1.4  christos 
   2746  1.4  christos 		    case 'E':
   2747  1.4  christos 		      /* Sign-extend the displacement.  */
   2748  1.4  christos 		      delta = GET_OP_S (insn, IMME);
   2749  1.4  christos 		      info->target = (delta << 1) + memaddr + length;
   2750  1.4  christos 		      (*info->print_address_func) (info->target, info);
   2751  1.4  christos 		      break;
   2752  1.4  christos 
   2753  1.4  christos 		    case 'F':
   2754  1.4  christos 		      immed = GET_OP (insn, IMMF);
   2755  1.4  christos 		      infprintf (is, "0x%x", immed);
   2756  1.4  christos 		      break;
   2757  1.4  christos 
   2758  1.4  christos 		    case 'G':
   2759  1.4  christos 		      immed = (insn >> MICROMIPSOP_SH_IMMG) + 1;
   2760  1.4  christos 		      immed = (immed & MICROMIPSOP_MASK_IMMG) - 1;
   2761  1.4  christos 		      infprintf (is, "%d", immed);
   2762  1.4  christos 		      break;
   2763  1.4  christos 
   2764  1.4  christos 		    case 'H':
   2765  1.4  christos 		      immed = GET_OP (insn, IMMH) << 1;
   2766  1.4  christos 		      infprintf (is, "%d", immed);
   2767  1.4  christos 		      break;
   2768  1.4  christos 
   2769  1.4  christos 		    case 'I':
   2770  1.4  christos 		      immed = (insn >> MICROMIPSOP_SH_IMMI) + 1;
   2771  1.4  christos 		      immed = (immed & MICROMIPSOP_MASK_IMMI) - 1;
   2772  1.4  christos 		      infprintf (is, "%d", immed);
   2773  1.4  christos 		      break;
   2774  1.4  christos 
   2775  1.4  christos 		    case 'J':
   2776  1.4  christos 		      immed = GET_OP (insn, IMMJ) << 2;
   2777  1.4  christos 		      infprintf (is, "%d", immed);
   2778  1.4  christos 		      break;
   2779  1.4  christos 
   2780  1.4  christos 		    case 'L':
   2781  1.4  christos 		      immed = GET_OP (insn, IMML);
   2782  1.4  christos 		      infprintf (is, "%d", immed);
   2783  1.4  christos 		      break;
   2784  1.4  christos 
   2785  1.4  christos 		    case 'M':
   2786  1.4  christos 		      immed = (insn >> MICROMIPSOP_SH_IMMM) - 1;
   2787  1.4  christos 		      immed = (immed & MICROMIPSOP_MASK_IMMM) + 1;
   2788  1.4  christos 		      infprintf (is, "%d", immed);
   2789  1.4  christos 		      break;
   2790  1.4  christos 
   2791  1.4  christos 		    case 'N':
   2792  1.4  christos 		      immed = GET_OP (insn, IMMN);
   2793  1.4  christos 		      if (immed == 0)
   2794  1.4  christos 			infprintf (is, "%s,%s",
   2795  1.4  christos 				 mips_gpr_names[16],
   2796  1.4  christos 				 mips_gpr_names[31]);
   2797  1.4  christos 		      else
   2798  1.4  christos 			infprintf (is, "%s-%s,%s",
   2799  1.4  christos 				 mips_gpr_names[16],
   2800  1.4  christos 				 mips_gpr_names[16 + immed],
   2801  1.4  christos 				 mips_gpr_names[31]);
   2802  1.4  christos 		      break;
   2803  1.4  christos 
   2804  1.4  christos 		    case 'O':
   2805  1.4  christos 		      immed = GET_OP (insn, IMMO);
   2806  1.4  christos 		      infprintf (is, "0x%x", immed);
   2807  1.4  christos 		      break;
   2808  1.4  christos 
   2809  1.4  christos 		    case 'P':
   2810  1.4  christos 		      immed = GET_OP (insn, IMMP) << 2;
   2811  1.4  christos 		      infprintf (is, "%d", immed);
   2812  1.4  christos 		      break;
   2813  1.4  christos 
   2814  1.4  christos 		    case 'Q':
   2815  1.4  christos 		      /* Sign-extend the immediate.  */
   2816  1.4  christos 		      immed = GET_OP_S (insn, IMMQ) << 2;
   2817  1.4  christos 		      infprintf (is, "%d", immed);
   2818  1.4  christos 		      break;
   2819  1.4  christos 
   2820  1.4  christos 		    case 'U':
   2821  1.4  christos 		      immed = GET_OP (insn, IMMU) << 2;
   2822  1.4  christos 		      infprintf (is, "%d", immed);
   2823  1.4  christos 		      break;
   2824  1.4  christos 
   2825  1.4  christos 		    case 'W':
   2826  1.4  christos 		      immed = GET_OP (insn, IMMW) << 2;
   2827  1.4  christos 		      infprintf (is, "%d", immed);
   2828  1.4  christos 		      break;
   2829  1.4  christos 
   2830  1.4  christos 		    case 'X':
   2831  1.4  christos 		      /* Sign-extend the immediate.  */
   2832  1.4  christos 		      immed = GET_OP_S (insn, IMMX);
   2833  1.4  christos 		      infprintf (is, "%d", immed);
   2834  1.4  christos 		      break;
   2835  1.4  christos 
   2836  1.4  christos 		    case 'Y':
   2837  1.4  christos 		      /* Sign-extend the immediate.  */
   2838  1.4  christos 		      immed = GET_OP_S (insn, IMMY) << 2;
   2839  1.4  christos 		      if ((unsigned int) (immed + 8) < 16)
   2840  1.4  christos 			immed ^= 0x400;
   2841  1.4  christos 		      infprintf (is, "%d", immed);
   2842  1.4  christos 		      break;
   2843  1.4  christos 
   2844  1.4  christos 		    default:
   2845  1.4  christos 		      /* xgettext:c-format */
   2846  1.4  christos 		      infprintf (is,
   2847  1.4  christos 			       _("# internal disassembler error, "
   2848  1.4  christos 				 "unrecognized modifier (m%c)"),
   2849  1.4  christos 			       *s);
   2850  1.4  christos 		      abort ();
   2851  1.4  christos 		    }
   2852  1.4  christos 		  break;
   2853  1.4  christos 
   2854  1.4  christos 		default:
   2855  1.4  christos 		  /* xgettext:c-format */
   2856  1.4  christos 		  infprintf (is,
   2857  1.4  christos 			   _("# internal disassembler error, "
   2858  1.4  christos 			     "unrecognized modifier (%c)"),
   2859  1.4  christos 			   *s);
   2860  1.4  christos 		  abort ();
   2861  1.4  christos 		}
   2862  1.4  christos 	    }
   2863  1.4  christos 
   2864  1.4  christos 	  /* Figure out instruction type and branch delay information.  */
   2865  1.4  christos 	  if ((op->pinfo
   2866  1.4  christos 	       & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
   2867  1.4  christos 	    info->branch_delay_insns = 1;
   2868  1.4  christos 	  if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
   2869  1.4  christos 	       | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
   2870  1.4  christos 	    {
   2871  1.4  christos 	      if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_GPR_T)) != 0)
   2872  1.4  christos 		info->insn_type = dis_jsr;
   2873  1.4  christos 	      else
   2874  1.4  christos 		info->insn_type = dis_branch;
   2875  1.4  christos 	    }
   2876  1.4  christos 	  else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
   2877  1.4  christos 		    | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
   2878  1.4  christos 	    {
   2879  1.4  christos 	      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   2880  1.4  christos 		info->insn_type = dis_condjsr;
   2881  1.4  christos 	      else
   2882  1.4  christos 		info->insn_type = dis_condbranch;
   2883  1.4  christos 	    }
   2884  1.4  christos 	  else if ((op->pinfo
   2885  1.4  christos 		    & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY_DELAY)) != 0)
   2886  1.4  christos 	    info->insn_type = dis_dref;
   2887  1.4  christos 
   2888  1.4  christos 	  return length;
   2889  1.4  christos 	}
   2890  1.1     skrll     }
   2891  1.1     skrll #undef GET_OP_S
   2892  1.1     skrll #undef GET_OP
   2893  1.1     skrll 
   2894  1.1     skrll   infprintf (is, "0x%x", insn);
   2895  1.4  christos   info->insn_type = dis_noninsn;
   2896  1.4  christos 
   2897  1.4  christos   return length;
   2898  1.4  christos }
   2899  1.4  christos 
   2900  1.4  christos /* Return 1 if a symbol associated with the location being disassembled
   2901  1.4  christos    indicates a compressed (MIPS16 or microMIPS) mode.  We iterate over
   2902  1.4  christos    all the symbols at the address being considered assuming if at least
   2903  1.4  christos    one of them indicates code compression, then such code has been
   2904  1.4  christos    genuinely produced here (other symbols could have been derived from
   2905  1.4  christos    function symbols defined elsewhere or could define data).  Otherwise,
   2906  1.4  christos    return 0.  */
   2907  1.4  christos 
   2908  1.4  christos static bfd_boolean
   2909  1.4  christos is_compressed_mode_p (struct disassemble_info *info)
   2910  1.4  christos {
   2911  1.4  christos   elf_symbol_type *symbol;
   2912  1.4  christos   int pos;
   2913  1.4  christos   int i;
   2914  1.4  christos 
   2915  1.4  christos   for (i = 0; i < info->num_symbols; i++)
   2916  1.4  christos     {
   2917  1.4  christos       pos = info->symtab_pos + i;
   2918  1.4  christos 
   2919  1.4  christos       if (bfd_asymbol_flavour (info->symtab[pos]) != bfd_target_elf_flavour)
   2920  1.4  christos 	continue;
   2921  1.4  christos 
   2922  1.4  christos       symbol = (elf_symbol_type *) info->symtab[pos];
   2923  1.4  christos       if ((!micromips_ase
   2924  1.4  christos 	   && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
   2925  1.4  christos 	  || (micromips_ase
   2926  1.4  christos 	      && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
   2927  1.4  christos 	    return 1;
   2928  1.1     skrll     }
   2929  1.1     skrll 
   2930  1.1     skrll   return 0;
   2931  1.1     skrll }
   2932  1.1     skrll 
   2933  1.1     skrll /* In an environment where we do not know the symbol type of the
   2934  1.1     skrll    instruction we are forced to assume that the low order bit of the
   2935  1.1     skrll    instructions' address may mark it as a mips16 instruction.  If we
   2936  1.1     skrll    are single stepping, or the pc is within the disassembled function,
   2937  1.1     skrll    this works.  Otherwise, we need a clue.  Sometimes.  */
   2938  1.1     skrll 
   2939  1.4  christos static int
   2940  1.1     skrll _print_insn_mips (bfd_vma memaddr,
   2941  1.1     skrll 		  struct disassemble_info *info,
   2942  1.1     skrll 		  enum bfd_endian endianness)
   2943  1.1     skrll {
   2944  1.1     skrll   int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
   2945  1.1     skrll   bfd_byte buffer[INSNLEN];
   2946  1.4  christos   int status;
   2947  1.4  christos 
   2948  1.4  christos   set_default_mips_dis_options (info);
   2949  1.4  christos   parse_mips_dis_options (info->disassembler_options);
   2950  1.4  christos 
   2951  1.4  christos   if (info->mach == bfd_mach_mips16)
   2952  1.4  christos     return print_insn_mips16 (memaddr, info);
   2953  1.1     skrll   if (info->mach == bfd_mach_mips_micromips)
   2954  1.4  christos     return print_insn_micromips (memaddr, info);
   2955  1.1     skrll 
   2956  1.1     skrll   print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
   2957  1.4  christos 
   2958  1.1     skrll #if 1
   2959  1.1     skrll   /* FIXME: If odd address, this is CLEARLY a compressed instruction.  */
   2960  1.1     skrll   /* Only a few tools will work this way.  */
   2961  1.4  christos   if (memaddr & 0x01)
   2962  1.4  christos     return print_insn_compr (memaddr, info);
   2963  1.1     skrll #endif
   2964  1.1     skrll 
   2965  1.1     skrll #if SYMTAB_AVAILABLE
   2966  1.1     skrll   if (is_compressed_mode_p (info))
   2967  1.1     skrll     return print_insn_compr (memaddr, info);
   2968  1.4  christos #endif
   2969  1.1     skrll 
   2970  1.1     skrll   status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
   2971  1.4  christos   if (status == 0)
   2972  1.1     skrll     {
   2973  1.4  christos       int insn;
   2974  1.1     skrll 
   2975  1.1     skrll       if (endianness == BFD_ENDIAN_BIG)
   2976  1.1     skrll 	insn = bfd_getb32 (buffer);
   2977  1.1     skrll       else
   2978  1.1     skrll 	insn = bfd_getl32 (buffer);
   2979  1.1     skrll 
   2980  1.1     skrll       return print_insn_mips (memaddr, insn, info);
   2981  1.1     skrll     }
   2982  1.1     skrll   else
   2983  1.1     skrll     {
   2984  1.1     skrll       (*info->memory_error_func) (status, memaddr, info);
   2985  1.1     skrll       return -1;
   2986  1.1     skrll     }
   2987  1.1     skrll }
   2988  1.1     skrll 
   2989  1.1     skrll int
   2990  1.1     skrll print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
   2991  1.1     skrll {
   2992  1.1     skrll   return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
   2993  1.1     skrll }
   2994  1.1     skrll 
   2995  1.1     skrll int
   2996  1.1     skrll print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
   2997  1.1     skrll {
   2998  1.1     skrll   return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
   2999  1.1     skrll }
   3000  1.1     skrll 
   3001  1.1     skrll void
   3003  1.1     skrll print_mips_disassembler_options (FILE *stream)
   3004  1.1     skrll {
   3005  1.1     skrll   unsigned int i;
   3006  1.1     skrll 
   3007  1.1     skrll   fprintf (stream, _("\n\
   3008  1.1     skrll The following MIPS specific disassembler options are supported for use\n\
   3009  1.1     skrll with the -M switch (multiple options should be separated by commas):\n"));
   3010  1.1     skrll 
   3011  1.1     skrll   fprintf (stream, _("\n\
   3012  1.1     skrll   gpr-names=ABI            Print GPR names according to  specified ABI.\n\
   3013  1.1     skrll                            Default: based on binary being disassembled.\n"));
   3014  1.1     skrll 
   3015  1.1     skrll   fprintf (stream, _("\n\
   3016  1.1     skrll   fpr-names=ABI            Print FPR names according to specified ABI.\n\
   3017  1.1     skrll                            Default: numeric.\n"));
   3018  1.1     skrll 
   3019  1.1     skrll   fprintf (stream, _("\n\
   3020  1.1     skrll   cp0-names=ARCH           Print CP0 register names according to\n\
   3021  1.1     skrll                            specified architecture.\n\
   3022  1.1     skrll                            Default: based on binary being disassembled.\n"));
   3023  1.1     skrll 
   3024  1.1     skrll   fprintf (stream, _("\n\
   3025  1.1     skrll   hwr-names=ARCH           Print HWR names according to specified \n\
   3026  1.1     skrll 			   architecture.\n\
   3027  1.1     skrll                            Default: based on binary being disassembled.\n"));
   3028  1.1     skrll 
   3029  1.1     skrll   fprintf (stream, _("\n\
   3030  1.1     skrll   reg-names=ABI            Print GPR and FPR names according to\n\
   3031  1.1     skrll                            specified ABI.\n"));
   3032  1.1     skrll 
   3033  1.1     skrll   fprintf (stream, _("\n\
   3034  1.1     skrll   reg-names=ARCH           Print CP0 register and HWR names according to\n\
   3035  1.1     skrll                            specified architecture.\n"));
   3036  1.1     skrll 
   3037  1.1     skrll   fprintf (stream, _("\n\
   3038  1.1     skrll   For the options above, the following values are supported for \"ABI\":\n\
   3039  1.1     skrll    "));
   3040  1.1     skrll   for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
   3041  1.1     skrll     fprintf (stream, " %s", mips_abi_choices[i].name);
   3042  1.1     skrll   fprintf (stream, _("\n"));
   3043  1.1     skrll 
   3044  1.1     skrll   fprintf (stream, _("\n\
   3045  1.1     skrll   For the options above, The following values are supported for \"ARCH\":\n\
   3046  1.1     skrll    "));
   3047  1.1     skrll   for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
   3048                    if (*mips_arch_choices[i].name != '\0')
   3049                      fprintf (stream, " %s", mips_arch_choices[i].name);
   3050                  fprintf (stream, _("\n"));
   3051                
   3052                  fprintf (stream, _("\n"));
   3053                }
   3054