Home | History | Annotate | Line # | Download | only in opcodes
mips-dis.c revision 1.1.1.10
      1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
      2    Copyright (C) 1989-2024 Free Software Foundation, Inc.
      3    Contributed by Nobuyuki Hikichi(hikichi (at) sra.co.jp).
      4 
      5    This file is part of the GNU opcodes library.
      6 
      7    This library is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    It is distributed in the hope that it will be useful, but WITHOUT
     13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     15    License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the Free Software
     19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20    MA 02110-1301, USA.  */
     21 
     22 #include "sysdep.h"
     23 #include "disassemble.h"
     24 #include "libiberty.h"
     25 #include "opcode/mips.h"
     26 #include "opintl.h"
     27 #include "elf-bfd.h"
     28 #include "elf/mips.h"
     29 #include "elfxx-mips.h"
     30 
     31 /* FIXME: These are needed to figure out if the code is mips16 or
     32    not. The low bit of the address is often a good indicator.  No
     33    symbol table is available when this code runs out in an embedded
     34    system as when it is used for disassembler support in a monitor.  */
     35 
     36 #if !defined(EMBEDDED_ENV)
     37 #define SYMTAB_AVAILABLE 1
     38 #endif
     39 
     40 /* Mips instructions are at maximum this many bytes long.  */
     41 #define INSNLEN 4
     42 
     43 
     44 /* FIXME: These should be shared with gdb somehow.  */
     46 
     47 struct mips_cp0sel_name
     48 {
     49   unsigned int cp0reg;
     50   unsigned int sel;
     51   const char * const name;
     52 };
     53 
     54 static const char * const mips_gpr_names_numeric[32] =
     55 {
     56   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
     57   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
     58   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
     59   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
     60 };
     61 
     62 static const char * const mips_gpr_names_oldabi[32] =
     63 {
     64   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
     65   "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
     66   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
     67   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
     68 };
     69 
     70 static const char * const mips_gpr_names_newabi[32] =
     71 {
     72   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
     73   "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3",
     74   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
     75   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
     76 };
     77 
     78 static const char * const mips_fpr_names_numeric[32] =
     79 {
     80   "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
     81   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
     82   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
     83   "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
     84 };
     85 
     86 static const char * const mips_fpr_names_32[32] =
     87 {
     88   "fv0",  "fv0f", "fv1",  "fv1f", "ft0",  "ft0f", "ft1",  "ft1f",
     89   "ft2",  "ft2f", "ft3",  "ft3f", "fa0",  "fa0f", "fa1",  "fa1f",
     90   "ft4",  "ft4f", "ft5",  "ft5f", "fs0",  "fs0f", "fs1",  "fs1f",
     91   "fs2",  "fs2f", "fs3",  "fs3f", "fs4",  "fs4f", "fs5",  "fs5f"
     92 };
     93 
     94 static const char * const mips_fpr_names_n32[32] =
     95 {
     96   "fv0",  "ft14", "fv1",  "ft15", "ft0",  "ft1",  "ft2",  "ft3",
     97   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
     98   "fa4",  "fa5",  "fa6",  "fa7",  "fs0",  "ft8",  "fs1",  "ft9",
     99   "fs2",  "ft10", "fs3",  "ft11", "fs4",  "ft12", "fs5",  "ft13"
    100 };
    101 
    102 static const char * const mips_fpr_names_64[32] =
    103 {
    104   "fv0",  "ft12", "fv1",  "ft13", "ft0",  "ft1",  "ft2",  "ft3",
    105   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
    106   "fa4",  "fa5",  "fa6",  "fa7",  "ft8",  "ft9",  "ft10", "ft11",
    107   "fs0",  "fs1",  "fs2",  "fs3",  "fs4",  "fs5",  "fs6",  "fs7"
    108 };
    109 
    110 static const char * const mips_cp0_names_numeric[32] =
    111 {
    112   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    113   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    114   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    115   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    116 };
    117 
    118 static const char * const mips_cp1_names_numeric[32] =
    119 {
    120   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    121   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    122   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    123   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    124 };
    125 
    126 static const char * const mips_cp0_names_r3900[32] =
    127 {
    128   "$0",           "$1",           "$2",           "c0_config",
    129   "$4",           "$5",           "$6",           "c0_cache",
    130   "c0_badvaddr",  "$9",           "$10",          "$11",
    131   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    132   "c0_debug",     "c0_depc",      "$18",          "$19",
    133   "$20",          "$21",          "$22",          "$23",
    134   "$24",          "$25",          "$26",          "$27",
    135   "$28",          "$29",          "$30",          "$31",
    136 };
    137 
    138 static const char * const mips_cp0_names_r3000[32] =
    139 {
    140   "c0_index",     "c0_random",    "c0_entrylo",   "$3",
    141   "c0_context",   "$5",           "$6",           "$7",
    142   "c0_badvaddr",  "$9",           "c0_entryhi",   "$11",
    143   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    144   "$16",          "$17",          "$18",          "$19",
    145   "$20",          "$21",          "$22",          "$23",
    146   "$24",          "$25",          "$26",          "$27",
    147   "$28",          "$29",          "$30",          "$31",
    148 };
    149 
    150 static const char * const mips_cp0_names_r4000[32] =
    151 {
    152   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    153   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    154   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    155   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    156   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    157   "c0_xcontext",  "$21",          "$22",          "$23",
    158   "$24",          "$25",          "c0_ecc",       "c0_cacheerr",
    159   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "$31",
    160 };
    161 
    162 static const char * const mips_cp0_names_r5900[32] =
    163 {
    164   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    165   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    166   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    167   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    168   "c0_config",    "$17",          "$18",          "$19",
    169   "$20",          "$21",          "$22",          "c0_badpaddr",
    170   "c0_depc",      "c0_perfcnt",   "$26",          "$27",
    171   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "$31"
    172 };
    173 
    174 static const char * const mips_cp0_names_mips3264[32] =
    175 {
    176   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    177   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    178   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    179   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    180   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    181   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    182   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
    183   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
    184 };
    185 
    186 static const char * const mips_cp1_names_mips[32] =
    187 {
    188   "c1_fir",       "$1",           "$2",           "$3",
    189   "$4",           "$5",           "$6",           "$7",
    190   "$8",           "$9",           "$10",          "$11",
    191   "$12",          "$13",          "$14",          "$15",
    192   "$16",          "$17",          "$18",          "$19",
    193   "$20",          "$21",          "$22",          "$23",
    194   "$24",          "$25",          "$26",          "$27",
    195   "$28",          "$29",          "$30",          "c1_fcsr"
    196 };
    197 
    198 static const char * const mips_cp1_names_mips3264[32] =
    199 {
    200   "c1_fir",       "c1_ufr",       "$2",           "$3",
    201   "c1_unfr",      "$5",           "$6",           "$7",
    202   "$8",           "$9",           "$10",          "$11",
    203   "$12",          "$13",          "$14",          "$15",
    204   "$16",          "$17",          "$18",          "$19",
    205   "$20",          "$21",          "$22",          "$23",
    206   "$24",          "c1_fccr",      "c1_fexr",      "$27",
    207   "c1_fenr",      "$29",          "$30",          "c1_fcsr"
    208 };
    209 
    210 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
    211 {
    212   { 16, 1, "c0_config1"		},
    213   { 16, 2, "c0_config2"		},
    214   { 16, 3, "c0_config3"		},
    215   { 18, 1, "c0_watchlo,1"	},
    216   { 18, 2, "c0_watchlo,2"	},
    217   { 18, 3, "c0_watchlo,3"	},
    218   { 18, 4, "c0_watchlo,4"	},
    219   { 18, 5, "c0_watchlo,5"	},
    220   { 18, 6, "c0_watchlo,6"	},
    221   { 18, 7, "c0_watchlo,7"	},
    222   { 19, 1, "c0_watchhi,1"	},
    223   { 19, 2, "c0_watchhi,2"	},
    224   { 19, 3, "c0_watchhi,3"	},
    225   { 19, 4, "c0_watchhi,4"	},
    226   { 19, 5, "c0_watchhi,5"	},
    227   { 19, 6, "c0_watchhi,6"	},
    228   { 19, 7, "c0_watchhi,7"	},
    229   { 25, 1, "c0_perfcnt,1"	},
    230   { 25, 2, "c0_perfcnt,2"	},
    231   { 25, 3, "c0_perfcnt,3"	},
    232   { 25, 4, "c0_perfcnt,4"	},
    233   { 25, 5, "c0_perfcnt,5"	},
    234   { 25, 6, "c0_perfcnt,6"	},
    235   { 25, 7, "c0_perfcnt,7"	},
    236   { 27, 1, "c0_cacheerr,1"	},
    237   { 27, 2, "c0_cacheerr,2"	},
    238   { 27, 3, "c0_cacheerr,3"	},
    239   { 28, 1, "c0_datalo"		},
    240   { 29, 1, "c0_datahi"		}
    241 };
    242 
    243 static const char * const mips_cp0_names_mips3264r2[32] =
    244 {
    245   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    246   "c0_context",   "c0_pagemask",  "c0_wired",     "c0_hwrena",
    247   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    248   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    249   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    250   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    251   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
    252   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
    253 };
    254 
    255 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
    256 {
    257   {  4, 1, "c0_contextconfig"	},
    258   {  0, 1, "c0_mvpcontrol"	},
    259   {  0, 2, "c0_mvpconf0"	},
    260   {  0, 3, "c0_mvpconf1"	},
    261   {  1, 1, "c0_vpecontrol"	},
    262   {  1, 2, "c0_vpeconf0"	},
    263   {  1, 3, "c0_vpeconf1"	},
    264   {  1, 4, "c0_yqmask"		},
    265   {  1, 5, "c0_vpeschedule"	},
    266   {  1, 6, "c0_vpeschefback"	},
    267   {  2, 1, "c0_tcstatus"	},
    268   {  2, 2, "c0_tcbind"		},
    269   {  2, 3, "c0_tcrestart"	},
    270   {  2, 4, "c0_tchalt"		},
    271   {  2, 5, "c0_tccontext"	},
    272   {  2, 6, "c0_tcschedule"	},
    273   {  2, 7, "c0_tcschefback"	},
    274   {  5, 1, "c0_pagegrain"	},
    275   {  6, 1, "c0_srsconf0"	},
    276   {  6, 2, "c0_srsconf1"	},
    277   {  6, 3, "c0_srsconf2"	},
    278   {  6, 4, "c0_srsconf3"	},
    279   {  6, 5, "c0_srsconf4"	},
    280   { 12, 1, "c0_intctl"		},
    281   { 12, 2, "c0_srsctl"		},
    282   { 12, 3, "c0_srsmap"		},
    283   { 15, 1, "c0_ebase"		},
    284   { 16, 1, "c0_config1"		},
    285   { 16, 2, "c0_config2"		},
    286   { 16, 3, "c0_config3"		},
    287   { 18, 1, "c0_watchlo,1"	},
    288   { 18, 2, "c0_watchlo,2"	},
    289   { 18, 3, "c0_watchlo,3"	},
    290   { 18, 4, "c0_watchlo,4"	},
    291   { 18, 5, "c0_watchlo,5"	},
    292   { 18, 6, "c0_watchlo,6"	},
    293   { 18, 7, "c0_watchlo,7"	},
    294   { 19, 1, "c0_watchhi,1"	},
    295   { 19, 2, "c0_watchhi,2"	},
    296   { 19, 3, "c0_watchhi,3"	},
    297   { 19, 4, "c0_watchhi,4"	},
    298   { 19, 5, "c0_watchhi,5"	},
    299   { 19, 6, "c0_watchhi,6"	},
    300   { 19, 7, "c0_watchhi,7"	},
    301   { 23, 1, "c0_tracecontrol"	},
    302   { 23, 2, "c0_tracecontrol2"	},
    303   { 23, 3, "c0_usertracedata"	},
    304   { 23, 4, "c0_tracebpc"	},
    305   { 25, 1, "c0_perfcnt,1"	},
    306   { 25, 2, "c0_perfcnt,2"	},
    307   { 25, 3, "c0_perfcnt,3"	},
    308   { 25, 4, "c0_perfcnt,4"	},
    309   { 25, 5, "c0_perfcnt,5"	},
    310   { 25, 6, "c0_perfcnt,6"	},
    311   { 25, 7, "c0_perfcnt,7"	},
    312   { 27, 1, "c0_cacheerr,1"	},
    313   { 27, 2, "c0_cacheerr,2"	},
    314   { 27, 3, "c0_cacheerr,3"	},
    315   { 28, 1, "c0_datalo"		},
    316   { 28, 2, "c0_taglo1"		},
    317   { 28, 3, "c0_datalo1"		},
    318   { 28, 4, "c0_taglo2"		},
    319   { 28, 5, "c0_datalo2"		},
    320   { 28, 6, "c0_taglo3"		},
    321   { 28, 7, "c0_datalo3"		},
    322   { 29, 1, "c0_datahi"		},
    323   { 29, 2, "c0_taghi1"		},
    324   { 29, 3, "c0_datahi1"		},
    325   { 29, 4, "c0_taghi2"		},
    326   { 29, 5, "c0_datahi2"		},
    327   { 29, 6, "c0_taghi3"		},
    328   { 29, 7, "c0_datahi3"		},
    329 };
    330 
    331 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods.  */
    332 static const char * const mips_cp0_names_sb1[32] =
    333 {
    334   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    335   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    336   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    337   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    338   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    339   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    340   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
    341   "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
    342 };
    343 
    344 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
    345 {
    346   { 16, 1, "c0_config1"		},
    347   { 18, 1, "c0_watchlo,1"	},
    348   { 19, 1, "c0_watchhi,1"	},
    349   { 22, 0, "c0_perftrace"	},
    350   { 23, 3, "c0_edebug"		},
    351   { 25, 1, "c0_perfcnt,1"	},
    352   { 25, 2, "c0_perfcnt,2"	},
    353   { 25, 3, "c0_perfcnt,3"	},
    354   { 25, 4, "c0_perfcnt,4"	},
    355   { 25, 5, "c0_perfcnt,5"	},
    356   { 25, 6, "c0_perfcnt,6"	},
    357   { 25, 7, "c0_perfcnt,7"	},
    358   { 26, 1, "c0_buserr_pa"	},
    359   { 27, 1, "c0_cacheerr_d"	},
    360   { 27, 3, "c0_cacheerr_d_pa"	},
    361   { 28, 1, "c0_datalo_i"	},
    362   { 28, 2, "c0_taglo_d"		},
    363   { 28, 3, "c0_datalo_d"	},
    364   { 29, 1, "c0_datahi_i"	},
    365   { 29, 2, "c0_taghi_d"		},
    366   { 29, 3, "c0_datahi_d"	},
    367 };
    368 
    369 /* Xlr cop0 register names.  */
    370 static const char * const mips_cp0_names_xlr[32] = {
    371   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    372   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    373   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    374   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    375   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    376   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    377   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
    378   "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
    379 };
    380 
    381 /* XLR's CP0 Select Registers.  */
    382 
    383 static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
    384   {  9, 6, "c0_extintreq"       },
    385   {  9, 7, "c0_extintmask"      },
    386   { 15, 1, "c0_ebase"           },
    387   { 16, 1, "c0_config1"         },
    388   { 16, 2, "c0_config2"         },
    389   { 16, 3, "c0_config3"         },
    390   { 16, 7, "c0_procid2"         },
    391   { 18, 1, "c0_watchlo,1"       },
    392   { 18, 2, "c0_watchlo,2"       },
    393   { 18, 3, "c0_watchlo,3"       },
    394   { 18, 4, "c0_watchlo,4"       },
    395   { 18, 5, "c0_watchlo,5"       },
    396   { 18, 6, "c0_watchlo,6"       },
    397   { 18, 7, "c0_watchlo,7"       },
    398   { 19, 1, "c0_watchhi,1"       },
    399   { 19, 2, "c0_watchhi,2"       },
    400   { 19, 3, "c0_watchhi,3"       },
    401   { 19, 4, "c0_watchhi,4"       },
    402   { 19, 5, "c0_watchhi,5"       },
    403   { 19, 6, "c0_watchhi,6"       },
    404   { 19, 7, "c0_watchhi,7"       },
    405   { 25, 1, "c0_perfcnt,1"       },
    406   { 25, 2, "c0_perfcnt,2"       },
    407   { 25, 3, "c0_perfcnt,3"       },
    408   { 25, 4, "c0_perfcnt,4"       },
    409   { 25, 5, "c0_perfcnt,5"       },
    410   { 25, 6, "c0_perfcnt,6"       },
    411   { 25, 7, "c0_perfcnt,7"       },
    412   { 27, 1, "c0_cacheerr,1"      },
    413   { 27, 2, "c0_cacheerr,2"      },
    414   { 27, 3, "c0_cacheerr,3"      },
    415   { 28, 1, "c0_datalo"          },
    416   { 29, 1, "c0_datahi"          }
    417 };
    418 
    419 static const char * const mips_hwr_names_numeric[32] =
    420 {
    421   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    422   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    423   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    424   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    425 };
    426 
    427 static const char * const mips_hwr_names_mips3264r2[32] =
    428 {
    429   "hwr_cpunum",   "hwr_synci_step", "hwr_cc",     "hwr_ccres",
    430   "$4",          "$5",            "$6",           "$7",
    431   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    432   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    433   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    434 };
    435 
    436 static const char * const msa_control_names[32] =
    437 {
    438   "msa_ir",	"msa_csr",	"msa_access",	"msa_save",
    439   "msa_modify",	"msa_request",	"msa_map",	"msa_unmap",
    440   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    441   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    442   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    443 };
    444 
    445 struct mips_abi_choice
    446 {
    447   const char * name;
    448   const char * const *gpr_names;
    449   const char * const *fpr_names;
    450 };
    451 
    452 struct mips_abi_choice mips_abi_choices[] =
    453 {
    454   { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
    455   { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
    456   { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
    457   { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
    458 };
    459 
    460 struct mips_arch_choice
    461 {
    462   const char *name;
    463   int bfd_mach_valid;
    464   unsigned long bfd_mach;
    465   int processor;
    466   int isa;
    467   int ase;
    468   const char * const *cp0_names;
    469   const struct mips_cp0sel_name *cp0sel_names;
    470   unsigned int cp0sel_names_len;
    471   const char * const *cp1_names;
    472   const char * const *hwr_names;
    473 };
    474 
    475 const struct mips_arch_choice mips_arch_choices[] =
    476 {
    477   { "numeric",	0, 0, 0, 0, 0,
    478     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    479     mips_hwr_names_numeric },
    480 
    481   { "r3000",	1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
    482     mips_cp0_names_r3000, NULL, 0, mips_cp1_names_mips,
    483     mips_hwr_names_numeric },
    484   { "r3900",	1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
    485     mips_cp0_names_r3900, NULL, 0, mips_cp1_names_numeric,
    486     mips_hwr_names_numeric },
    487   { "r4000",	1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
    488     mips_cp0_names_r4000, NULL, 0, mips_cp1_names_mips,
    489     mips_hwr_names_numeric },
    490   { "r4010",	1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
    491     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    492     mips_hwr_names_numeric },
    493   { "allegrex",	1, bfd_mach_mips_allegrex, CPU_ALLEGREX, ISA_MIPS2, 0,
    494     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    495     mips_hwr_names_numeric },
    496   { "vr4100",	1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
    497     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    498     mips_hwr_names_numeric },
    499   { "vr4111",	1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
    500     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    501     mips_hwr_names_numeric },
    502   { "vr4120",	1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
    503     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    504     mips_hwr_names_numeric },
    505   { "r4300",	1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
    506     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    507     mips_hwr_names_numeric },
    508   { "r4400",	1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
    509     mips_cp0_names_r4000, NULL, 0, mips_cp1_names_mips,
    510     mips_hwr_names_numeric },
    511   { "r4600",	1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
    512     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    513     mips_hwr_names_numeric },
    514   { "r4650",	1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
    515     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    516     mips_hwr_names_numeric },
    517   { "r5000",	1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
    518     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    519     mips_hwr_names_numeric },
    520   { "vr5400",	1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
    521     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    522     mips_hwr_names_numeric },
    523   { "vr5500",	1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
    524     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    525     mips_hwr_names_numeric },
    526   { "r5900",	1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
    527     mips_cp0_names_r5900, NULL, 0, mips_cp1_names_mips,
    528     mips_hwr_names_numeric },
    529   { "r6000",	1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
    530     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    531     mips_hwr_names_numeric },
    532   { "rm7000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
    533     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    534     mips_hwr_names_numeric },
    535   { "rm9000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
    536     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    537     mips_hwr_names_numeric },
    538   { "r8000",	1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
    539     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    540     mips_hwr_names_numeric },
    541   { "r10000",	1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
    542     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    543     mips_hwr_names_numeric },
    544   { "r12000",	1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
    545     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    546     mips_hwr_names_numeric },
    547   { "r14000",	1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
    548     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    549     mips_hwr_names_numeric },
    550   { "r16000",	1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
    551     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    552     mips_hwr_names_numeric },
    553   { "mips5",	1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
    554     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
    555     mips_hwr_names_numeric },
    556 
    557   /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
    558      Note that MIPS-3D and MDMX are not applicable to MIPS32.  (See
    559      _MIPS32 Architecture For Programmers Volume I: Introduction to the
    560      MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
    561      page 1.  */
    562   { "mips32",	1, bfd_mach_mipsisa32, CPU_MIPS32,
    563     ISA_MIPS32,  ASE_SMARTMIPS,
    564     mips_cp0_names_mips3264,
    565     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
    566     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    567 
    568   { "mips32r2",	1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
    569     ISA_MIPS32R2,
    570     (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
    571      | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
    572     mips_cp0_names_mips3264r2,
    573     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    574     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    575 
    576   { "mips32r3",	1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
    577     ISA_MIPS32R3,
    578     (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
    579      | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
    580     mips_cp0_names_mips3264r2,
    581     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    582     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    583 
    584   { "mips32r5",	1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
    585     ISA_MIPS32R5,
    586     (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
    587      | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
    588     mips_cp0_names_mips3264r2,
    589     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    590     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    591 
    592   { "mips32r6",	1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
    593     ISA_MIPS32R6,
    594     (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
    595      | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC | ASE_GINV),
    596     mips_cp0_names_mips3264r2,
    597     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    598     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    599 
    600   /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs.  */
    601   { "mips64",	1, bfd_mach_mipsisa64, CPU_MIPS64,
    602     ISA_MIPS64,  ASE_MIPS3D | ASE_MDMX,
    603     mips_cp0_names_mips3264,
    604     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
    605     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    606 
    607   { "mips64r2",	1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
    608     ISA_MIPS64R2,
    609     (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
    610      | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
    611     mips_cp0_names_mips3264r2,
    612     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    613     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    614 
    615   { "mips64r3",	1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
    616     ISA_MIPS64R3,
    617     (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
    618      | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
    619     mips_cp0_names_mips3264r2,
    620     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    621     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    622 
    623   { "mips64r5",	1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
    624     ISA_MIPS64R5,
    625     (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
    626      | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
    627     mips_cp0_names_mips3264r2,
    628     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    629     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    630 
    631   { "mips64r6",	1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
    632     ISA_MIPS64R6,
    633     (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
    634      | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC
    635      | ASE_CRC64 | ASE_GINV),
    636     mips_cp0_names_mips3264r2,
    637     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    638     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    639 
    640   { "interaptiv-mr2",	1, bfd_mach_mips_interaptiv_mr2, CPU_INTERAPTIV_MR2,
    641     ISA_MIPS32R3,
    642     ASE_MT | ASE_EVA | ASE_DSP | ASE_DSPR2 | ASE_MIPS16E2 | ASE_MIPS16E2_MT,
    643     mips_cp0_names_mips3264r2,
    644     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    645     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    646 
    647   { "sb1",	1, bfd_mach_mips_sb1, CPU_SB1,
    648     ISA_MIPS64 | INSN_SB1,  ASE_MIPS3D,
    649     mips_cp0_names_sb1,
    650     mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
    651     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    652 
    653   { "loongson2e",   1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
    654     ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
    655     NULL, 0, mips_cp1_names_mips, mips_hwr_names_numeric },
    656 
    657   { "loongson2f",   1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
    658     ISA_MIPS3 | INSN_LOONGSON_2F, ASE_LOONGSON_MMI, mips_cp0_names_numeric,
    659     NULL, 0, mips_cp1_names_mips, mips_hwr_names_numeric },
    660 
    661   /* The loongson3a is an alias of gs464 for compatibility */
    662   { "loongson3a",   1, bfd_mach_mips_gs464, CPU_GS464,
    663     ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
    664     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
    665     mips_hwr_names_numeric },
    666 
    667   { "gs464",   1, bfd_mach_mips_gs464, CPU_GS464,
    668     ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
    669     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
    670     mips_hwr_names_numeric },
    671 
    672   { "gs464e",   1, bfd_mach_mips_gs464e, CPU_GS464E,
    673     ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
    674     | ASE_LOONGSON_EXT2, mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
    675     mips_hwr_names_numeric },
    676 
    677   { "gs264e",   1, bfd_mach_mips_gs264e, CPU_GS264E,
    678     ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
    679     | ASE_LOONGSON_EXT2 | ASE_MSA | ASE_MSA64, mips_cp0_names_numeric, NULL,
    680     0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
    681 
    682   { "octeon",   1, bfd_mach_mips_octeon, CPU_OCTEON,
    683     ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
    684     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    685 
    686   { "octeon+",   1, bfd_mach_mips_octeonp, CPU_OCTEONP,
    687     ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
    688     NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
    689 
    690   { "octeon2",   1, bfd_mach_mips_octeon2, CPU_OCTEON2,
    691     ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
    692     NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
    693 
    694   { "octeon3",   1, bfd_mach_mips_octeon3, CPU_OCTEON3,
    695     ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
    696     mips_cp0_names_numeric,
    697     NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
    698 
    699   { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
    700     ISA_MIPS64 | INSN_XLR, 0,
    701     mips_cp0_names_xlr,
    702     mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
    703     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    704 
    705   /* XLP is mostly like XLR, with the prominent exception it is being
    706      MIPS64R2.  */
    707   { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
    708     ISA_MIPS64R2 | INSN_XLR, 0,
    709     mips_cp0_names_xlr,
    710     mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
    711     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    712 
    713   /* This entry, mips16, is here only for ISA/processor selection; do
    714      not print its name.  */
    715   { "",		1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
    716     ASE_MIPS16E2 | ASE_MIPS16E2_MT,
    717     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    718     mips_hwr_names_numeric },
    719 };
    720 
    721 /* ISA and processor type to disassemble for, and register names to use.
    722    set_default_mips_dis_options and parse_mips_dis_options fill in these
    723    values.  */
    724 static int mips_processor;
    725 static int mips_isa;
    726 static int mips_ase;
    727 static int micromips_ase;
    728 static const char * const *mips_gpr_names;
    729 static const char * const *mips_fpr_names;
    730 static const char * const *mips_cp0_names;
    731 static const struct mips_cp0sel_name *mips_cp0sel_names;
    732 static int mips_cp0sel_names_len;
    733 static const char * const *mips_cp1_names;
    734 static const char * const *mips_hwr_names;
    735 
    736 /* Other options */
    737 static int no_aliases;	/* If set disassemble as most general inst.  */
    738 
    739 static const struct mips_abi_choice *
    741 choose_abi_by_name (const char *name, unsigned int namelen)
    742 {
    743   const struct mips_abi_choice *c;
    744   unsigned int i;
    745 
    746   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
    747     if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
    748 	&& strlen (mips_abi_choices[i].name) == namelen)
    749       c = &mips_abi_choices[i];
    750 
    751   return c;
    752 }
    753 
    754 static const struct mips_arch_choice *
    755 choose_arch_by_name (const char *name, unsigned int namelen)
    756 {
    757   const struct mips_arch_choice *c = NULL;
    758   unsigned int i;
    759 
    760   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
    761     if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
    762 	&& strlen (mips_arch_choices[i].name) == namelen)
    763       c = &mips_arch_choices[i];
    764 
    765   return c;
    766 }
    767 
    768 static const struct mips_arch_choice *
    769 choose_arch_by_number (unsigned long mach)
    770 {
    771   static unsigned long hint_bfd_mach;
    772   static const struct mips_arch_choice *hint_arch_choice;
    773   const struct mips_arch_choice *c;
    774   unsigned int i;
    775 
    776   /* We optimize this because even if the user specifies no
    777      flags, this will be done for every instruction!  */
    778   if (hint_bfd_mach == mach
    779       && hint_arch_choice != NULL
    780       && hint_arch_choice->bfd_mach == hint_bfd_mach)
    781     return hint_arch_choice;
    782 
    783   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
    784     {
    785       if (mips_arch_choices[i].bfd_mach_valid
    786 	  && mips_arch_choices[i].bfd_mach == mach)
    787 	{
    788 	  c = &mips_arch_choices[i];
    789 	  hint_bfd_mach = mach;
    790 	  hint_arch_choice = c;
    791 	}
    792     }
    793   return c;
    794 }
    795 
    796 /* Check if the object uses NewABI conventions.  */
    797 
    798 static int
    799 is_newabi (Elf_Internal_Ehdr *header)
    800 {
    801   /* There are no old-style ABIs which use 64-bit ELF.  */
    802   if (header->e_ident[EI_CLASS] == ELFCLASS64)
    803     return 1;
    804 
    805   /* If a 32-bit ELF file, n32 is a new-style ABI.  */
    806   if ((header->e_flags & EF_MIPS_ABI2) != 0)
    807     return 1;
    808 
    809   return 0;
    810 }
    811 
    812 /* Check if the object has microMIPS ASE code.  */
    813 
    814 static int
    815 is_micromips (Elf_Internal_Ehdr *header)
    816 {
    817   if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
    818     return 1;
    819 
    820   return 0;
    821 }
    822 
    823 /* Convert ASE flags from .MIPS.abiflags to internal values.  */
    824 
    825 static unsigned long
    826 mips_convert_abiflags_ases (unsigned long afl_ases)
    827 {
    828   unsigned long opcode_ases = 0;
    829 
    830   if (afl_ases & AFL_ASE_DSP)
    831     opcode_ases |= ASE_DSP;
    832   if (afl_ases & AFL_ASE_DSPR2)
    833     opcode_ases |= ASE_DSPR2;
    834   if (afl_ases & AFL_ASE_EVA)
    835     opcode_ases |= ASE_EVA;
    836   if (afl_ases & AFL_ASE_MCU)
    837     opcode_ases |= ASE_MCU;
    838   if (afl_ases & AFL_ASE_MDMX)
    839     opcode_ases |= ASE_MDMX;
    840   if (afl_ases & AFL_ASE_MIPS3D)
    841     opcode_ases |= ASE_MIPS3D;
    842   if (afl_ases & AFL_ASE_MT)
    843     opcode_ases |= ASE_MT;
    844   if (afl_ases & AFL_ASE_SMARTMIPS)
    845     opcode_ases |= ASE_SMARTMIPS;
    846   if (afl_ases & AFL_ASE_VIRT)
    847     opcode_ases |= ASE_VIRT;
    848   if (afl_ases & AFL_ASE_MSA)
    849     opcode_ases |= ASE_MSA;
    850   if (afl_ases & AFL_ASE_XPA)
    851     opcode_ases |= ASE_XPA;
    852   if (afl_ases & AFL_ASE_DSPR3)
    853     opcode_ases |= ASE_DSPR3;
    854   if (afl_ases & AFL_ASE_MIPS16E2)
    855     opcode_ases |= ASE_MIPS16E2;
    856   return opcode_ases;
    857 }
    858 
    859 /* Calculate combination ASE flags from regular ASE flags.  */
    860 
    861 static unsigned long
    862 mips_calculate_combination_ases (int opcode_isa, unsigned long opcode_ases)
    863 {
    864   unsigned long combination_ases = 0;
    865 
    866   if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
    867     combination_ases |= ASE_XPA_VIRT;
    868   if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
    869     combination_ases |= ASE_MIPS16E2_MT;
    870   if ((opcode_ases & ASE_EVA)
    871       && ((opcode_isa & INSN_ISA_MASK) == ISA_MIPS64R6
    872 	  || (opcode_isa & INSN_ISA_MASK) == ISA_MIPS32R6))
    873     combination_ases |= ASE_EVA_R6;
    874   return combination_ases;
    875 }
    876 
    877 static void
    878 set_default_mips_dis_options (struct disassemble_info *info)
    879 {
    880   const struct mips_arch_choice *chosen_arch;
    881 
    882   /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
    883      is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
    884      CP0 register, and HWR names.  */
    885   mips_isa = ISA_MIPS3;
    886   mips_processor = CPU_R3000;
    887   micromips_ase = 0;
    888   mips_ase = 0;
    889   mips_gpr_names = mips_gpr_names_oldabi;
    890   mips_fpr_names = mips_fpr_names_numeric;
    891   mips_cp0_names = mips_cp0_names_numeric;
    892   mips_cp0sel_names = NULL;
    893   mips_cp0sel_names_len = 0;
    894   mips_cp1_names = mips_cp1_names_numeric;
    895   mips_hwr_names = mips_hwr_names_numeric;
    896   no_aliases = 0;
    897 
    898   /* Set ISA, architecture, and cp0 register names as best we can.  */
    899 #if ! SYMTAB_AVAILABLE
    900   /* This is running out on a target machine, not in a host tool.
    901      FIXME: Where does mips_target_info come from?  */
    902   target_processor = mips_target_info.processor;
    903   mips_isa = mips_target_info.isa;
    904   mips_ase = mips_target_info.ase;
    905 #else
    906   chosen_arch = choose_arch_by_number (info->mach);
    907   if (chosen_arch != NULL)
    908     {
    909       mips_processor = chosen_arch->processor;
    910       mips_isa = chosen_arch->isa;
    911       mips_ase = chosen_arch->ase;
    912       mips_cp0_names = chosen_arch->cp0_names;
    913       mips_cp0sel_names = chosen_arch->cp0sel_names;
    914       mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    915       mips_cp1_names = chosen_arch->cp1_names;
    916       mips_hwr_names = chosen_arch->hwr_names;
    917     }
    918 
    919   /* Update settings according to the ELF file header flags.  */
    920   if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
    921     {
    922       struct bfd *abfd = info->section->owner;
    923       Elf_Internal_Ehdr *header = elf_elfheader (abfd);
    924       Elf_Internal_ABIFlags_v0 *abiflags = NULL;
    925 
    926       /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
    927 	 because we won't then have a MIPS/ELF BFD, however we need
    928 	 to guard against a link error in a `--enable-targets=...'
    929 	 configuration with a 32-bit host where the MIPS target is
    930 	 a secondary, or with MIPS/ECOFF configurations.  */
    931 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
    932       abiflags = bfd_mips_elf_get_abiflags (abfd);
    933 #endif
    934       /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
    935       if (is_newabi (header))
    936 	mips_gpr_names = mips_gpr_names_newabi;
    937       /* If a microMIPS binary, then don't use MIPS16 bindings.  */
    938       micromips_ase = is_micromips (header);
    939       /* OR in any extra ASE flags set in ELF file structures.  */
    940       if (abiflags)
    941 	mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
    942       else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
    943 	mips_ase |= ASE_MDMX;
    944     }
    945 #endif
    946   mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
    947 }
    948 
    949 /* Parse an ASE disassembler option and set the corresponding global
    950    ASE flag(s).  Return TRUE if successful, FALSE otherwise.  */
    951 
    952 static bool
    953 parse_mips_ase_option (const char *option)
    954 {
    955   if (startswith (option, "msa"))
    956     {
    957       mips_ase |= ASE_MSA;
    958       if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
    959 	   || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
    960 	   || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
    961 	   || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
    962 	  mips_ase |= ASE_MSA64;
    963       return true;
    964     }
    965 
    966   if (startswith (option, "virt"))
    967     {
    968       mips_ase |= ASE_VIRT;
    969       if (mips_isa & ISA_MIPS64R2
    970 	  || mips_isa & ISA_MIPS64R3
    971 	  || mips_isa & ISA_MIPS64R5
    972 	  || mips_isa & ISA_MIPS64R6)
    973 	mips_ase |= ASE_VIRT64;
    974       return true;
    975     }
    976 
    977   if (startswith (option, "xpa"))
    978     {
    979       mips_ase |= ASE_XPA;
    980       return true;
    981     }
    982 
    983   if (startswith (option, "ginv"))
    984     {
    985       mips_ase |= ASE_GINV;
    986       return true;
    987     }
    988 
    989   if (startswith (option, "loongson-mmi"))
    990     {
    991       mips_ase |= ASE_LOONGSON_MMI;
    992       return true;
    993     }
    994 
    995   if (startswith (option, "loongson-cam"))
    996     {
    997       mips_ase |= ASE_LOONGSON_CAM;
    998       return true;
    999     }
   1000 
   1001   /* Put here for match ext2 frist */
   1002   if (startswith (option, "loongson-ext2"))
   1003     {
   1004       mips_ase |= ASE_LOONGSON_EXT2;
   1005       return true;
   1006     }
   1007 
   1008   if (startswith (option, "loongson-ext"))
   1009     {
   1010       mips_ase |= ASE_LOONGSON_EXT;
   1011       return true;
   1012     }
   1013 
   1014   return false;
   1015 }
   1016 
   1017 static void
   1018 parse_mips_dis_option (const char *option, unsigned int len)
   1019 {
   1020   unsigned int i, optionlen, vallen;
   1021   const char *val;
   1022   const struct mips_abi_choice *chosen_abi;
   1023   const struct mips_arch_choice *chosen_arch;
   1024 
   1025   /* Try to match options that are simple flags */
   1026   if (startswith (option, "no-aliases"))
   1027     {
   1028       no_aliases = 1;
   1029       return;
   1030     }
   1031 
   1032   if (parse_mips_ase_option (option))
   1033     {
   1034       mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
   1035       return;
   1036     }
   1037 
   1038   /* Look for the = that delimits the end of the option name.  */
   1039   for (i = 0; i < len; i++)
   1040     if (option[i] == '=')
   1041       break;
   1042 
   1043   if (i == 0)		/* Invalid option: no name before '='.  */
   1044     return;
   1045   if (i == len)		/* Invalid option: no '='.  */
   1046     return;
   1047   if (i == (len - 1))	/* Invalid option: no value after '='.  */
   1048     return;
   1049 
   1050   optionlen = i;
   1051   val = option + (optionlen + 1);
   1052   vallen = len - (optionlen + 1);
   1053 
   1054   if (strncmp ("gpr-names", option, optionlen) == 0
   1055       && strlen ("gpr-names") == optionlen)
   1056     {
   1057       chosen_abi = choose_abi_by_name (val, vallen);
   1058       if (chosen_abi != NULL)
   1059 	mips_gpr_names = chosen_abi->gpr_names;
   1060       return;
   1061     }
   1062 
   1063   if (strncmp ("fpr-names", option, optionlen) == 0
   1064       && strlen ("fpr-names") == optionlen)
   1065     {
   1066       chosen_abi = choose_abi_by_name (val, vallen);
   1067       if (chosen_abi != NULL)
   1068 	mips_fpr_names = chosen_abi->fpr_names;
   1069       return;
   1070     }
   1071 
   1072   if (strncmp ("cp0-names", option, optionlen) == 0
   1073       && strlen ("cp0-names") == optionlen)
   1074     {
   1075       chosen_arch = choose_arch_by_name (val, vallen);
   1076       if (chosen_arch != NULL)
   1077 	{
   1078 	  mips_cp0_names = chosen_arch->cp0_names;
   1079 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
   1080 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
   1081 	}
   1082       return;
   1083     }
   1084 
   1085   if (strncmp ("cp1-names", option, optionlen) == 0
   1086       && strlen ("cp1-names") == optionlen)
   1087     {
   1088       chosen_arch = choose_arch_by_name (val, vallen);
   1089       if (chosen_arch != NULL)
   1090 	mips_cp1_names = chosen_arch->cp1_names;
   1091       return;
   1092     }
   1093 
   1094   if (strncmp ("hwr-names", option, optionlen) == 0
   1095       && strlen ("hwr-names") == optionlen)
   1096     {
   1097       chosen_arch = choose_arch_by_name (val, vallen);
   1098       if (chosen_arch != NULL)
   1099 	mips_hwr_names = chosen_arch->hwr_names;
   1100       return;
   1101     }
   1102 
   1103   if (strncmp ("reg-names", option, optionlen) == 0
   1104       && strlen ("reg-names") == optionlen)
   1105     {
   1106       /* We check both ABI and ARCH here unconditionally, so
   1107 	 that "numeric" will do the desirable thing: select
   1108 	 numeric register names for all registers.  Other than
   1109 	 that, a given name probably won't match both.  */
   1110       chosen_abi = choose_abi_by_name (val, vallen);
   1111       if (chosen_abi != NULL)
   1112 	{
   1113 	  mips_gpr_names = chosen_abi->gpr_names;
   1114 	  mips_fpr_names = chosen_abi->fpr_names;
   1115 	}
   1116       chosen_arch = choose_arch_by_name (val, vallen);
   1117       if (chosen_arch != NULL)
   1118 	{
   1119 	  mips_cp0_names = chosen_arch->cp0_names;
   1120 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
   1121 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
   1122 	  mips_cp1_names = chosen_arch->cp1_names;
   1123 	  mips_hwr_names = chosen_arch->hwr_names;
   1124 	}
   1125       return;
   1126     }
   1127 
   1128   /* Invalid option.  */
   1129 }
   1130 
   1131 static void
   1132 parse_mips_dis_options (const char *options)
   1133 {
   1134   const char *option_end;
   1135 
   1136   if (options == NULL)
   1137     return;
   1138 
   1139   while (*options != '\0')
   1140     {
   1141       /* Skip empty options.  */
   1142       if (*options == ',')
   1143 	{
   1144 	  options++;
   1145 	  continue;
   1146 	}
   1147 
   1148       /* We know that *options is neither NUL or a comma.  */
   1149       option_end = options + 1;
   1150       while (*option_end != ',' && *option_end != '\0')
   1151 	option_end++;
   1152 
   1153       parse_mips_dis_option (options, option_end - options);
   1154 
   1155       /* Go on to the next one.  If option_end points to a comma, it
   1156 	 will be skipped above.  */
   1157       options = option_end;
   1158     }
   1159 }
   1160 
   1161 static const struct mips_cp0sel_name *
   1162 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
   1163 			 unsigned int len,
   1164 			 unsigned int cp0reg,
   1165 			 unsigned int sel)
   1166 {
   1167   unsigned int i;
   1168 
   1169   for (i = 0; i < len; i++)
   1170     if (names[i].cp0reg == cp0reg && names[i].sel == sel)
   1171       return &names[i];
   1172   return NULL;
   1173 }
   1174 
   1175 /* Print register REGNO, of type TYPE, for instruction OPCODE.  */
   1176 
   1177 static void
   1178 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
   1179 	   enum mips_reg_operand_type type, int regno)
   1180 {
   1181   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   1182 
   1183   switch (type)
   1184     {
   1185     case OP_REG_GP:
   1186       infprintf (info->stream, dis_style_register, "%s",
   1187 		 mips_gpr_names[regno]);
   1188       break;
   1189 
   1190     case OP_REG_FP:
   1191       infprintf (info->stream, dis_style_register, "%s",
   1192 		 mips_fpr_names[regno]);
   1193       break;
   1194 
   1195     case OP_REG_CCC:
   1196       if (opcode->pinfo & (FP_D | FP_S))
   1197 	infprintf (info->stream, dis_style_register, "$fcc%d", regno);
   1198       else
   1199 	infprintf (info->stream, dis_style_register, "$cc%d", regno);
   1200       break;
   1201 
   1202     case OP_REG_VEC:
   1203       if (opcode->membership & INSN_5400)
   1204 	infprintf (info->stream, dis_style_register, "$f%d", regno);
   1205       else
   1206 	infprintf (info->stream, dis_style_register, "$v%d", regno);
   1207       break;
   1208 
   1209     case OP_REG_ACC:
   1210       infprintf (info->stream, dis_style_register, "$ac%d", regno);
   1211       break;
   1212 
   1213     case OP_REG_COPRO:
   1214       if (opcode->name[strlen (opcode->name) - 1] == '0')
   1215 	infprintf (info->stream, dis_style_register, "%s", mips_cp0_names[regno]);
   1216       else
   1217 	infprintf (info->stream, dis_style_register, "$%d", regno);
   1218       break;
   1219 
   1220     case OP_REG_CONTROL:
   1221       if (opcode->name[strlen (opcode->name) - 1] == '1')
   1222 	infprintf (info->stream, dis_style_register, "%s", mips_cp1_names[regno]);
   1223       else
   1224 	infprintf (info->stream, dis_style_register, "$%d", regno);
   1225       break;
   1226 
   1227     case OP_REG_HW:
   1228       infprintf (info->stream, dis_style_register, "%s", mips_hwr_names[regno]);
   1229       break;
   1230 
   1231     case OP_REG_VF:
   1232       infprintf (info->stream, dis_style_register, "$vf%d", regno);
   1233       break;
   1234 
   1235     case OP_REG_VI:
   1236       infprintf (info->stream, dis_style_register, "$vi%d", regno);
   1237       break;
   1238 
   1239     case OP_REG_R5900_I:
   1240       infprintf (info->stream, dis_style_register, "$I");
   1241       break;
   1242 
   1243     case OP_REG_R5900_Q:
   1244       infprintf (info->stream, dis_style_register, "$Q");
   1245       break;
   1246 
   1247     case OP_REG_R5900_R:
   1248       infprintf (info->stream, dis_style_register, "$R");
   1249       break;
   1250 
   1251     case OP_REG_R5900_ACC:
   1252       infprintf (info->stream, dis_style_register, "$ACC");
   1253       break;
   1254 
   1255     case OP_REG_MSA:
   1256       infprintf (info->stream, dis_style_register, "$w%d", regno);
   1257       break;
   1258 
   1259     case OP_REG_MSA_CTRL:
   1260       infprintf (info->stream, dis_style_register, "%s",
   1261 		 msa_control_names[regno]);
   1262       break;
   1263 
   1264     }
   1265 }
   1266 
   1267 /* Used to track the state carried over from previous operands in
   1269    an instruction.  */
   1270 struct mips_print_arg_state {
   1271   /* The value of the last OP_INT seen.  We only use this for OP_MSB,
   1272      where the value is known to be unsigned and small.  */
   1273   unsigned int last_int;
   1274 
   1275   /* The type and number of the last OP_REG seen.  We only use this for
   1276      OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG.  */
   1277   enum mips_reg_operand_type last_reg_type;
   1278   unsigned int last_regno;
   1279   unsigned int dest_regno;
   1280   unsigned int seen_dest;
   1281 };
   1282 
   1283 /* Initialize STATE for the start of an instruction.  */
   1284 
   1285 static inline void
   1286 init_print_arg_state (struct mips_print_arg_state *state)
   1287 {
   1288   memset (state, 0, sizeof (*state));
   1289 }
   1290 
   1291 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
   1292    whose value is given by UVAL.  */
   1293 
   1294 static void
   1295 print_vu0_channel (struct disassemble_info *info,
   1296 		   const struct mips_operand *operand, unsigned int uval,
   1297 		   enum disassembler_style style)
   1298 {
   1299   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   1300 
   1301   if (operand->size == 4)
   1302     infprintf (info->stream, style, "%s%s%s%s",
   1303 			uval & 8 ? "x" : "",
   1304 			uval & 4 ? "y" : "",
   1305 			uval & 2 ? "z" : "",
   1306 			uval & 1 ? "w" : "");
   1307   else if (operand->size == 2)
   1308     infprintf (info->stream, style, "%c", "xyzw"[uval]);
   1309   else
   1310     abort ();
   1311 }
   1312 
   1313 /* Record information about a register operand.  */
   1314 
   1315 static void
   1316 mips_seen_register (struct mips_print_arg_state *state,
   1317 		    unsigned int regno,
   1318 		    enum mips_reg_operand_type reg_type)
   1319 {
   1320   state->last_reg_type = reg_type;
   1321   state->last_regno = regno;
   1322 
   1323   if (!state->seen_dest)
   1324     {
   1325       state->seen_dest = 1;
   1326       state->dest_regno = regno;
   1327     }
   1328 }
   1329 
   1330 /* Print SAVE/RESTORE instruction operands according to the argument
   1331    register mask AMASK, the number of static registers saved NSREG,
   1332    the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
   1333    and the frame size FRAME_SIZE.  */
   1334 
   1335 static void
   1336 mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
   1337 			 unsigned int nsreg, unsigned int ra,
   1338 			 unsigned int s0, unsigned int s1,
   1339 			 unsigned int frame_size)
   1340 {
   1341   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   1342   unsigned int nargs, nstatics, smask, i, j;
   1343   void *is = info->stream;
   1344   const char *sep;
   1345 
   1346   if (amask == MIPS_SVRS_ALL_ARGS)
   1347     {
   1348       nargs = 4;
   1349       nstatics = 0;
   1350     }
   1351   else if (amask == MIPS_SVRS_ALL_STATICS)
   1352     {
   1353       nargs = 0;
   1354       nstatics = 4;
   1355     }
   1356   else
   1357     {
   1358       nargs = amask >> 2;
   1359       nstatics = amask & 3;
   1360     }
   1361 
   1362   sep = "";
   1363   if (nargs > 0)
   1364     {
   1365       infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
   1366       if (nargs > 1)
   1367 	infprintf (is, dis_style_register, "-%s", mips_gpr_names[4 + nargs - 1]);
   1368       sep = ",";
   1369     }
   1370 
   1371   infprintf (is, dis_style_text, "%s", sep);
   1372   infprintf (is, dis_style_immediate, "%d", frame_size);
   1373 
   1374   if (ra)			/* $ra */
   1375     {
   1376       infprintf (is, dis_style_text, ",");
   1377       infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
   1378     }
   1379 
   1380   smask = 0;
   1381   if (s0)			/* $s0 */
   1382     smask |= 1 << 0;
   1383   if (s1)			/* $s1 */
   1384     smask |= 1 << 1;
   1385   if (nsreg > 0)		/* $s2-$s8 */
   1386     smask |= ((1 << nsreg) - 1) << 2;
   1387 
   1388   for (i = 0; i < 9; i++)
   1389     if (smask & (1 << i))
   1390       {
   1391 	infprintf (is, dis_style_text, ",");
   1392 	infprintf (is, dis_style_register, "%s",
   1393 		   mips_gpr_names[i == 8 ? 30 : (16 + i)]);
   1394 	/* Skip over string of set bits.  */
   1395 	for (j = i; smask & (2 << j); j++)
   1396 	  continue;
   1397 	if (j > i)
   1398 	  {
   1399 	    infprintf (is, dis_style_text, "-");
   1400 	    infprintf (is, dis_style_register, "%s",
   1401 		       mips_gpr_names[j == 8 ? 30 : (16 + j)]);
   1402 	  }
   1403 	i = j + 1;
   1404       }
   1405   /* Statics $ax - $a3.  */
   1406   if (nstatics == 1)
   1407     {
   1408       infprintf (is, dis_style_text, ",");
   1409       infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
   1410     }
   1411   else if (nstatics > 0)
   1412     {
   1413       infprintf (is, dis_style_text, ",");
   1414       infprintf (is, dis_style_register, "%s",
   1415 		 mips_gpr_names[7 - nstatics + 1]);
   1416       infprintf (is, dis_style_text, "-");
   1417       infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
   1418     }
   1419 }
   1420 
   1421 
   1422 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
   1423    UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
   1424    the base address for OP_PCREL operands.  */
   1425 
   1426 static void
   1427 print_insn_arg (struct disassemble_info *info,
   1428 		struct mips_print_arg_state *state,
   1429 		const struct mips_opcode *opcode,
   1430 		const struct mips_operand *operand,
   1431 		bfd_vma base_pc,
   1432 		unsigned int uval)
   1433 {
   1434   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   1435   void *is = info->stream;
   1436 
   1437   switch (operand->type)
   1438     {
   1439     case OP_INT:
   1440       {
   1441 	const struct mips_int_operand *int_op;
   1442 
   1443 	int_op = (const struct mips_int_operand *) operand;
   1444 	uval = mips_decode_int_operand (int_op, uval);
   1445 	state->last_int = uval;
   1446 	if (int_op->print_hex)
   1447 	  infprintf (is, dis_style_immediate, "0x%x", uval);
   1448 	else
   1449 	  infprintf (is, dis_style_immediate, "%d", uval);
   1450       }
   1451       break;
   1452 
   1453     case OP_MAPPED_INT:
   1454       {
   1455 	const struct mips_mapped_int_operand *mint_op;
   1456 
   1457 	mint_op = (const struct mips_mapped_int_operand *) operand;
   1458 	uval = mint_op->int_map[uval];
   1459 	state->last_int = uval;
   1460 	if (mint_op->print_hex)
   1461 	  infprintf (is, dis_style_immediate, "0x%x", uval);
   1462 	else
   1463 	  infprintf (is, dis_style_immediate, "%d", uval);
   1464       }
   1465       break;
   1466 
   1467     case OP_MSB:
   1468       {
   1469 	const struct mips_msb_operand *msb_op;
   1470 
   1471 	msb_op = (const struct mips_msb_operand *) operand;
   1472 	uval += msb_op->bias;
   1473 	if (msb_op->add_lsb)
   1474 	  uval -= state->last_int;
   1475 	infprintf (is, dis_style_immediate, "0x%x", uval);
   1476       }
   1477       break;
   1478 
   1479     case OP_REG:
   1480     case OP_OPTIONAL_REG:
   1481       {
   1482 	const struct mips_reg_operand *reg_op;
   1483 
   1484 	reg_op = (const struct mips_reg_operand *) operand;
   1485 	uval = mips_decode_reg_operand (reg_op, uval);
   1486 	print_reg (info, opcode, reg_op->reg_type, uval);
   1487 
   1488 	mips_seen_register (state, uval, reg_op->reg_type);
   1489       }
   1490       break;
   1491 
   1492     case OP_REG_PAIR:
   1493       {
   1494 	const struct mips_reg_pair_operand *pair_op;
   1495 
   1496 	pair_op = (const struct mips_reg_pair_operand *) operand;
   1497 	print_reg (info, opcode, pair_op->reg_type,
   1498 		   pair_op->reg1_map[uval]);
   1499 	infprintf (is, dis_style_text, ",");
   1500 	print_reg (info, opcode, pair_op->reg_type,
   1501 		   pair_op->reg2_map[uval]);
   1502       }
   1503       break;
   1504 
   1505     case OP_PCREL:
   1506       {
   1507 	const struct mips_pcrel_operand *pcrel_op;
   1508 
   1509 	pcrel_op = (const struct mips_pcrel_operand *) operand;
   1510 	info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
   1511 
   1512 	/* For jumps and branches clear the ISA bit except for
   1513 	   the GDB disassembler.  */
   1514 	if (pcrel_op->include_isa_bit
   1515 	    && info->flavour != bfd_target_unknown_flavour)
   1516 	  info->target &= -2;
   1517 
   1518 	(*info->print_address_func) (info->target, info);
   1519       }
   1520       break;
   1521 
   1522     case OP_PERF_REG:
   1523       infprintf (is, dis_style_register, "%d", uval);
   1524       break;
   1525 
   1526     case OP_ADDIUSP_INT:
   1527       {
   1528 	int sval;
   1529 
   1530 	sval = mips_signed_operand (operand, uval) * 4;
   1531 	if (sval >= -8 && sval < 8)
   1532 	  sval ^= 0x400;
   1533 	infprintf (is, dis_style_immediate, "%d", sval);
   1534 	break;
   1535       }
   1536 
   1537     case OP_CLO_CLZ_DEST:
   1538       {
   1539 	unsigned int reg1, reg2;
   1540 
   1541 	reg1 = uval & 31;
   1542 	reg2 = uval >> 5;
   1543 	/* If one is zero use the other.  */
   1544 	if (reg1 == reg2 || reg2 == 0)
   1545 	  infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
   1546 	else if (reg1 == 0)
   1547 	  infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
   1548 	else
   1549 	  {
   1550 	    /* Bogus, result depends on processor.  */
   1551 	    infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
   1552 	    infprintf (is, dis_style_text, " or ");
   1553 	    infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
   1554 	  }
   1555       }
   1556       break;
   1557 
   1558     case OP_SAME_RS_RT:
   1559     case OP_CHECK_PREV:
   1560     case OP_NON_ZERO_REG:
   1561       {
   1562 	print_reg (info, opcode, OP_REG_GP, uval & 31);
   1563 	mips_seen_register (state, uval, OP_REG_GP);
   1564       }
   1565       break;
   1566 
   1567     case OP_LWM_SWM_LIST:
   1568       if (operand->size == 2)
   1569 	{
   1570 	  if (uval == 0)
   1571 	    {
   1572 	      infprintf (is, dis_style_register, "%s",
   1573 			 mips_gpr_names[16]);
   1574 	      infprintf (is, dis_style_text, ",");
   1575 	      infprintf (is, dis_style_register, "%s",
   1576 			 mips_gpr_names[31]);
   1577 	    }
   1578 	  else
   1579 	    {
   1580 	      infprintf (is, dis_style_register, "%s",
   1581 			 mips_gpr_names[16]);
   1582 	      infprintf (is, dis_style_text, "-");
   1583 	      infprintf (is, dis_style_register, "%s",
   1584 			 mips_gpr_names[16 + uval]);
   1585 	      infprintf (is, dis_style_text, ",");
   1586 	      infprintf (is, dis_style_register, "%s",
   1587 			 mips_gpr_names[31]);
   1588 	    }
   1589 	}
   1590       else
   1591 	{
   1592 	  int s_reg_encode;
   1593 
   1594 	  s_reg_encode = uval & 0xf;
   1595 	  if (s_reg_encode != 0)
   1596 	    {
   1597 	      if (s_reg_encode == 1)
   1598 		infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
   1599 	      else if (s_reg_encode < 9)
   1600 		{
   1601 		  infprintf (is, dis_style_register, "%s",
   1602 			     mips_gpr_names[16]);
   1603 		  infprintf (is, dis_style_text, "-");
   1604 		  infprintf (is, dis_style_register, "%s",
   1605 			     mips_gpr_names[15 + s_reg_encode]);
   1606 		}
   1607 	      else if (s_reg_encode == 9)
   1608 		{
   1609 		  infprintf (is, dis_style_register, "%s",
   1610 			     mips_gpr_names[16]);
   1611 		  infprintf (is, dis_style_text, "-");
   1612 		  infprintf (is, dis_style_register, "%s",
   1613 			     mips_gpr_names[23]);
   1614 		  infprintf (is, dis_style_text, ",");
   1615 		  infprintf (is, dis_style_register, "%s",
   1616 			     mips_gpr_names[30]);
   1617 		}
   1618 	      else
   1619 		infprintf (is, dis_style_text, "UNKNOWN");
   1620 	    }
   1621 
   1622 	  if (uval & 0x10) /* For ra.  */
   1623 	    {
   1624 	      if (s_reg_encode == 0)
   1625 		infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
   1626 	      else
   1627 		{
   1628 		  infprintf (is, dis_style_text, ",");
   1629 		  infprintf (is, dis_style_register, "%s",
   1630 			     mips_gpr_names[31]);
   1631 		}
   1632 	    }
   1633 	}
   1634       break;
   1635 
   1636     case OP_ENTRY_EXIT_LIST:
   1637       {
   1638 	const char *sep;
   1639 	unsigned int amask, smask;
   1640 
   1641 	sep = "";
   1642 	amask = (uval >> 3) & 7;
   1643 	if (amask > 0 && amask < 5)
   1644 	  {
   1645 	    infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
   1646 	    if (amask > 1)
   1647 	      {
   1648 		infprintf (is, dis_style_text, "-");
   1649 		infprintf (is, dis_style_register, "%s",
   1650 			   mips_gpr_names[amask + 3]);
   1651 	      }
   1652 	    sep = ",";
   1653 	  }
   1654 
   1655 	smask = (uval >> 1) & 3;
   1656 	if (smask == 3)
   1657 	  {
   1658 	    infprintf (is, dis_style_text, "%s??", sep);
   1659 	    sep = ",";
   1660 	  }
   1661 	else if (smask > 0)
   1662 	  {
   1663 	    infprintf (is, dis_style_text, "%s", sep);
   1664 	    infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
   1665 	    if (smask > 1)
   1666 	      {
   1667 		infprintf (is, dis_style_text, "-");
   1668 		infprintf (is, dis_style_register, "%s",
   1669 			   mips_gpr_names[smask + 15]);
   1670 	      }
   1671 	    sep = ",";
   1672 	  }
   1673 
   1674 	if (uval & 1)
   1675 	  {
   1676 	    infprintf (is, dis_style_text, "%s", sep);
   1677 	    infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
   1678 	    sep = ",";
   1679 	  }
   1680 
   1681 	if (amask == 5 || amask == 6)
   1682 	  {
   1683 	    infprintf (is, dis_style_text, "%s", sep);
   1684 	    infprintf (is, dis_style_register, "%s", mips_fpr_names[0]);
   1685 	    if (amask == 6)
   1686 	      {
   1687 		infprintf (is, dis_style_text, "-");
   1688 		infprintf (is, dis_style_register, "%s", mips_fpr_names[1]);
   1689 	      }
   1690 	  }
   1691       }
   1692       break;
   1693 
   1694     case OP_SAVE_RESTORE_LIST:
   1695       /* Should be handled by the caller due to complex behavior.  */
   1696       abort ();
   1697 
   1698     case OP_MDMX_IMM_REG:
   1699       {
   1700 	unsigned int vsel;
   1701 
   1702 	vsel = uval >> 5;
   1703 	uval &= 31;
   1704 	if ((vsel & 0x10) == 0)
   1705 	  {
   1706 	    int fmt;
   1707 
   1708 	    vsel &= 0x0f;
   1709 	    for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
   1710 	      if ((vsel & 1) == 0)
   1711 		break;
   1712 	    print_reg (info, opcode, OP_REG_VEC, uval);
   1713 	    infprintf (is, dis_style_text, "[");
   1714 	    infprintf (is, dis_style_immediate, "%d", vsel >> 1);
   1715 	    infprintf (is, dis_style_text, "]");
   1716 	  }
   1717 	else if ((vsel & 0x08) == 0)
   1718 	  print_reg (info, opcode, OP_REG_VEC, uval);
   1719 	else
   1720 	  infprintf (is, dis_style_immediate, "0x%x", uval);
   1721       }
   1722       break;
   1723 
   1724     case OP_REPEAT_PREV_REG:
   1725       print_reg (info, opcode, state->last_reg_type, state->last_regno);
   1726       break;
   1727 
   1728     case OP_REPEAT_DEST_REG:
   1729       print_reg (info, opcode, state->last_reg_type, state->dest_regno);
   1730       break;
   1731 
   1732     case OP_PC:
   1733       infprintf (is, dis_style_register, "$pc");
   1734       break;
   1735 
   1736     case OP_REG28:
   1737       print_reg (info, opcode, OP_REG_GP, 28);
   1738       break;
   1739 
   1740     case OP_VU0_SUFFIX:
   1741     case OP_VU0_MATCH_SUFFIX:
   1742       print_vu0_channel (info, operand, uval, dis_style_register);
   1743       break;
   1744 
   1745     case OP_IMM_INDEX:
   1746       infprintf (is, dis_style_text, "[");
   1747       infprintf (is, dis_style_immediate, "%d", uval);
   1748       infprintf (is, dis_style_text, "]");
   1749       break;
   1750 
   1751     case OP_REG_INDEX:
   1752       infprintf (is, dis_style_text, "[");
   1753       print_reg (info, opcode, OP_REG_GP, uval);
   1754       infprintf (is, dis_style_text, "]");
   1755       break;
   1756     }
   1757 }
   1758 
   1759 /* Validate the arguments for INSN, which is described by OPCODE.
   1760    Use DECODE_OPERAND to get the encoding of each operand.  */
   1761 
   1762 static bool
   1763 validate_insn_args (const struct mips_opcode *opcode,
   1764 		    const struct mips_operand *(*decode_operand) (const char *),
   1765 		    unsigned int insn)
   1766 {
   1767   struct mips_print_arg_state state;
   1768   const struct mips_operand *operand;
   1769   const char *s;
   1770   unsigned int uval;
   1771 
   1772   init_print_arg_state (&state);
   1773   for (s = opcode->args; *s; ++s)
   1774     {
   1775       switch (*s)
   1776 	{
   1777 	case ',':
   1778 	case '(':
   1779 	case ')':
   1780 	  break;
   1781 
   1782 	case '#':
   1783 	  ++s;
   1784 	  break;
   1785 
   1786 	default:
   1787 	  operand = decode_operand (s);
   1788 
   1789 	  if (operand)
   1790 	    {
   1791 	      uval = mips_extract_operand (operand, insn);
   1792 	      switch (operand->type)
   1793 		{
   1794 		case OP_REG:
   1795 		case OP_OPTIONAL_REG:
   1796 		  {
   1797 		    const struct mips_reg_operand *reg_op;
   1798 
   1799 		    reg_op = (const struct mips_reg_operand *) operand;
   1800 		    uval = mips_decode_reg_operand (reg_op, uval);
   1801 		    mips_seen_register (&state, uval, reg_op->reg_type);
   1802 		  }
   1803 		break;
   1804 
   1805 		case OP_SAME_RS_RT:
   1806 		  {
   1807 		    unsigned int reg1, reg2;
   1808 
   1809 		    reg1 = uval & 31;
   1810 		    reg2 = uval >> 5;
   1811 
   1812 		    if (reg1 != reg2 || reg1 == 0)
   1813 		      return false;
   1814 		  }
   1815 		break;
   1816 
   1817 		case OP_CHECK_PREV:
   1818 		  {
   1819 		    const struct mips_check_prev_operand *prev_op;
   1820 
   1821 		    prev_op = (const struct mips_check_prev_operand *) operand;
   1822 
   1823 		    if (!prev_op->zero_ok && uval == 0)
   1824 		      return false;
   1825 
   1826 		    if (((prev_op->less_than_ok && uval < state.last_regno)
   1827 			|| (prev_op->greater_than_ok && uval > state.last_regno)
   1828 			|| (prev_op->equal_ok && uval == state.last_regno)))
   1829 		      break;
   1830 
   1831 		    return false;
   1832 		  }
   1833 
   1834 		case OP_NON_ZERO_REG:
   1835 		  {
   1836 		    if (uval == 0)
   1837 		      return false;
   1838 		  }
   1839 		break;
   1840 
   1841 		case OP_INT:
   1842 		case OP_MAPPED_INT:
   1843 		case OP_MSB:
   1844 		case OP_REG_PAIR:
   1845 		case OP_PCREL:
   1846 		case OP_PERF_REG:
   1847 		case OP_ADDIUSP_INT:
   1848 		case OP_CLO_CLZ_DEST:
   1849 		case OP_LWM_SWM_LIST:
   1850 		case OP_ENTRY_EXIT_LIST:
   1851 		case OP_MDMX_IMM_REG:
   1852 		case OP_REPEAT_PREV_REG:
   1853 		case OP_REPEAT_DEST_REG:
   1854 		case OP_PC:
   1855 		case OP_REG28:
   1856 		case OP_VU0_SUFFIX:
   1857 		case OP_VU0_MATCH_SUFFIX:
   1858 		case OP_IMM_INDEX:
   1859 		case OP_REG_INDEX:
   1860 		case OP_SAVE_RESTORE_LIST:
   1861 		  break;
   1862 		}
   1863 	    }
   1864 	  if (*s == 'm' || *s == '+' || *s == '-')
   1865 	    ++s;
   1866 	}
   1867     }
   1868   return true;
   1869 }
   1870 
   1871 /* Print the arguments for INSN, which is described by OPCODE.
   1872    Use DECODE_OPERAND to get the encoding of each operand.  Use BASE_PC
   1873    as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
   1874    operand is for a branch or jump.  */
   1875 
   1876 static void
   1877 print_insn_args (struct disassemble_info *info,
   1878 		 const struct mips_opcode *opcode,
   1879 		 const struct mips_operand *(*decode_operand) (const char *),
   1880 		 unsigned int insn, bfd_vma insn_pc, unsigned int length)
   1881 {
   1882   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   1883   void *is = info->stream;
   1884   struct mips_print_arg_state state;
   1885   const struct mips_operand *operand;
   1886   const char *s;
   1887 
   1888   init_print_arg_state (&state);
   1889   for (s = opcode->args; *s; ++s)
   1890     {
   1891       switch (*s)
   1892 	{
   1893 	case ',':
   1894 	case '(':
   1895 	case ')':
   1896 	  infprintf (is, dis_style_text, "%c", *s);
   1897 	  break;
   1898 
   1899 	case '#':
   1900 	  ++s;
   1901 	  infprintf (is, dis_style_text, "%c%c", *s, *s);
   1902 	  break;
   1903 
   1904 	default:
   1905 	  operand = decode_operand (s);
   1906 	  if (!operand)
   1907 	    {
   1908 	      /* xgettext:c-format */
   1909 	      infprintf (is, dis_style_text,
   1910 			 _("# internal error, undefined operand in `%s %s'"),
   1911 			 opcode->name, opcode->args);
   1912 	      return;
   1913 	    }
   1914 
   1915 	  if (operand->type == OP_SAVE_RESTORE_LIST)
   1916 	    {
   1917 	      /* Handle this case here because of the complex behavior.  */
   1918 	      unsigned int amask = (insn >> 15) & 0xf;
   1919 	      unsigned int nsreg = (insn >> 23) & 0x7;
   1920 	      unsigned int ra = insn & 0x1000;			/* $ra */
   1921 	      unsigned int s0 = insn & 0x800;			/* $s0 */
   1922 	      unsigned int s1 = insn & 0x400;			/* $s1 */
   1923 	      unsigned int frame_size = (((insn >> 15) & 0xf0)
   1924 					 | ((insn >> 6) & 0x0f)) * 8;
   1925 	      mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
   1926 				       frame_size);
   1927 	    }
   1928 	  else if (operand->type == OP_REG
   1929 		   && s[1] == ','
   1930 		   && s[2] == 'H'
   1931 		   && opcode->name[strlen (opcode->name) - 1] == '0')
   1932 	    {
   1933 	      /* Coprocessor register 0 with sel field.  */
   1934 	      const struct mips_cp0sel_name *n;
   1935 	      unsigned int reg, sel;
   1936 
   1937 	      reg = mips_extract_operand (operand, insn);
   1938 	      s += 2;
   1939 	      operand = decode_operand (s);
   1940 	      sel = mips_extract_operand (operand, insn);
   1941 
   1942 	      /* CP0 register including 'sel' code for mftc0, to be
   1943 		 printed textually if known.  If not known, print both
   1944 		 CP0 register name and sel numerically since CP0 register
   1945 		 with sel 0 may have a name unrelated to register being
   1946 		 printed.  */
   1947 	      n = lookup_mips_cp0sel_name (mips_cp0sel_names,
   1948 					   mips_cp0sel_names_len,
   1949 					   reg, sel);
   1950 	      if (n != NULL)
   1951 		infprintf (is, dis_style_register, "%s", n->name);
   1952 	      else
   1953 		{
   1954 		  infprintf (is, dis_style_register, "$%d", reg);
   1955 		  infprintf (is, dis_style_text, ",");
   1956 		  infprintf (is, dis_style_immediate, "%d", sel);
   1957 		}
   1958 	    }
   1959 	  else
   1960 	    {
   1961 	      bfd_vma base_pc = insn_pc;
   1962 
   1963 	      /* Adjust the PC relative base so that branch/jump insns use
   1964 		 the following PC as the base but genuinely PC relative
   1965 		 operands use the current PC.  */
   1966 	      if (operand->type == OP_PCREL)
   1967 		{
   1968 		  const struct mips_pcrel_operand *pcrel_op;
   1969 
   1970 		  pcrel_op = (const struct mips_pcrel_operand *) operand;
   1971 		  /* The include_isa_bit flag is sufficient to distinguish
   1972 		     branch/jump from other PC relative operands.  */
   1973 		  if (pcrel_op->include_isa_bit)
   1974 		    base_pc += length;
   1975 		}
   1976 
   1977 	      print_insn_arg (info, &state, opcode, operand, base_pc,
   1978 			      mips_extract_operand (operand, insn));
   1979 	    }
   1980 	  if (*s == 'm' || *s == '+' || *s == '-')
   1981 	    ++s;
   1982 	  break;
   1983 	}
   1984     }
   1985 }
   1986 
   1987 /* Print the mips instruction at address MEMADDR in debugged memory,
   1989    on using INFO.  Returns length of the instruction, in bytes, which is
   1990    always INSNLEN.  BIGENDIAN must be 1 if this is big-endian code, 0 if
   1991    this is little-endian code.  */
   1992 
   1993 static int
   1994 print_insn_mips (bfd_vma memaddr,
   1995 		 int word,
   1996 		 struct disassemble_info *info)
   1997 {
   1998 #define GET_OP(insn, field)			\
   1999   (((insn) >> OP_SH_##field) & OP_MASK_##field)
   2000   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
   2001   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   2002   const struct mips_opcode *op;
   2003   static bool init = 0;
   2004   void *is = info->stream;
   2005 
   2006   /* Build a hash table to shorten the search time.  */
   2007   if (! init)
   2008     {
   2009       unsigned int i;
   2010 
   2011       for (i = 0; i <= OP_MASK_OP; i++)
   2012 	{
   2013 	  for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
   2014 	    {
   2015 	      if (op->pinfo == INSN_MACRO
   2016 		  || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
   2017 		continue;
   2018 	      if (i == GET_OP (op->match, OP))
   2019 		{
   2020 		  mips_hash[i] = op;
   2021 		  break;
   2022 		}
   2023 	    }
   2024 	}
   2025 
   2026       init = 1;
   2027     }
   2028 
   2029   info->bytes_per_chunk = INSNLEN;
   2030   info->display_endian = info->endian;
   2031   info->insn_info_valid = 1;
   2032   info->branch_delay_insns = 0;
   2033   info->data_size = 0;
   2034   info->insn_type = dis_nonbranch;
   2035   info->target = 0;
   2036   info->target2 = 0;
   2037 
   2038   op = mips_hash[GET_OP (word, OP)];
   2039   if (op != NULL)
   2040     {
   2041       for (; op < &mips_opcodes[NUMOPCODES]; op++)
   2042 	{
   2043 	  if (op->pinfo != INSN_MACRO
   2044 	      && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   2045 	      && (word & op->mask) == op->match)
   2046 	    {
   2047 	      /* We always disassemble the jalx instruction, except for MIPS r6.  */
   2048 	      if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
   2049 		 && (strcmp (op->name, "jalx")
   2050 		     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
   2051 		     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
   2052 		continue;
   2053 
   2054 	      /* Figure out instruction type and branch delay information.  */
   2055 	      if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
   2056 	        {
   2057 		  if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
   2058 		    info->insn_type = dis_jsr;
   2059 		  else
   2060 		    info->insn_type = dis_branch;
   2061 		  info->branch_delay_insns = 1;
   2062 		}
   2063 	      else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
   2064 				     | INSN_COND_BRANCH_LIKELY)) != 0)
   2065 		{
   2066 		  if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   2067 		    info->insn_type = dis_condjsr;
   2068 		  else
   2069 		    info->insn_type = dis_condbranch;
   2070 		  info->branch_delay_insns = 1;
   2071 		}
   2072 	      else if ((op->pinfo & (INSN_STORE_MEMORY
   2073 				     | INSN_LOAD_MEMORY)) != 0)
   2074 		info->insn_type = dis_dref;
   2075 
   2076 	      if (!validate_insn_args (op, decode_mips_operand, word))
   2077 		continue;
   2078 
   2079 	      infprintf (is, dis_style_mnemonic, "%s", op->name);
   2080 	      if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
   2081 		{
   2082 		  unsigned int uval;
   2083 
   2084 		  infprintf (is, dis_style_mnemonic, ".");
   2085 		  uval = mips_extract_operand (&mips_vu0_channel_mask, word);
   2086 		  print_vu0_channel (info, &mips_vu0_channel_mask, uval,
   2087 				     dis_style_mnemonic);
   2088 		}
   2089 
   2090 	      if (op->args[0])
   2091 		{
   2092 		  infprintf (is, dis_style_text, "\t");
   2093 		  print_insn_args (info, op, decode_mips_operand, word,
   2094 				   memaddr, 4);
   2095 		}
   2096 
   2097 	      return INSNLEN;
   2098 	    }
   2099 	}
   2100     }
   2101 #undef GET_OP
   2102 
   2103   /* Handle undefined instructions.  */
   2104   info->insn_type = dis_noninsn;
   2105   infprintf (is, dis_style_assembler_directive, ".word");
   2106   infprintf (is, dis_style_text, "\t");
   2107   infprintf (is, dis_style_immediate, "0x%x", word);
   2108   return INSNLEN;
   2109 }
   2110 
   2111 /* Disassemble an operand for a mips16 instruction.  */
   2113 
   2114 static void
   2115 print_mips16_insn_arg (struct disassemble_info *info,
   2116 		       struct mips_print_arg_state *state,
   2117 		       const struct mips_opcode *opcode,
   2118 		       char type, bfd_vma memaddr,
   2119 		       unsigned insn, bool use_extend,
   2120 		       unsigned extend, bool is_offset)
   2121 {
   2122   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   2123   void *is = info->stream;
   2124   const struct mips_operand *operand, *ext_operand;
   2125   unsigned short ext_size;
   2126   unsigned int uval;
   2127   bfd_vma baseaddr;
   2128 
   2129   if (!use_extend)
   2130     extend = 0;
   2131 
   2132   switch (type)
   2133     {
   2134     case ',':
   2135     case '(':
   2136     case ')':
   2137       infprintf (is, dis_style_text, "%c", type);
   2138       break;
   2139 
   2140     default:
   2141       operand = decode_mips16_operand (type, false);
   2142       if (!operand)
   2143 	{
   2144 	  /* xgettext:c-format */
   2145 	  infprintf (is, dis_style_text, _("# internal error, undefined operand in `%s %s'"),
   2146 		     opcode->name, opcode->args);
   2147 	  return;
   2148 	}
   2149 
   2150       if (operand->type == OP_SAVE_RESTORE_LIST)
   2151 	{
   2152 	  /* Handle this case here because of the complex interaction
   2153 	     with the EXTEND opcode.  */
   2154 	  unsigned int amask = extend & 0xf;
   2155 	  unsigned int nsreg = (extend >> 8) & 0x7;
   2156 	  unsigned int ra = insn & 0x40;			/* $ra */
   2157 	  unsigned int s0 = insn & 0x20;			/* $s0 */
   2158 	  unsigned int s1 = insn & 0x10;			/* $s1 */
   2159 	  unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
   2160 	  if (frame_size == 0 && !use_extend)
   2161 	    frame_size = 128;
   2162 	  mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
   2163 	  break;
   2164 	}
   2165 
   2166       if (is_offset && operand->type == OP_INT)
   2167 	{
   2168 	  const struct mips_int_operand *int_op;
   2169 
   2170 	  int_op = (const struct mips_int_operand *) operand;
   2171 	  info->insn_type = dis_dref;
   2172 	  info->data_size = 1 << int_op->shift;
   2173 	}
   2174 
   2175       ext_size = 0;
   2176       if (use_extend)
   2177 	{
   2178 	  ext_operand = decode_mips16_operand (type, true);
   2179 	  if (ext_operand != operand
   2180 	      || (operand->type == OP_INT && operand->lsb == 0
   2181 		  && mips_opcode_32bit_p (opcode)))
   2182 	    {
   2183 	      ext_size = ext_operand->size;
   2184 	      operand = ext_operand;
   2185 	    }
   2186 	}
   2187       if (operand->size == 26)
   2188 	uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
   2189       else if (ext_size == 16 || ext_size == 9)
   2190 	uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
   2191       else if (ext_size == 15)
   2192 	uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
   2193       else if (ext_size == 6)
   2194 	uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
   2195       else
   2196 	uval = mips_extract_operand (operand, (extend << 16) | insn);
   2197       if (ext_size == 9)
   2198 	uval &= (1U << ext_size) - 1;
   2199 
   2200       baseaddr = memaddr + 2;
   2201       if (operand->type == OP_PCREL)
   2202 	{
   2203 	  const struct mips_pcrel_operand *pcrel_op;
   2204 
   2205 	  pcrel_op = (const struct mips_pcrel_operand *) operand;
   2206 	  if (!pcrel_op->include_isa_bit && use_extend)
   2207 	    baseaddr = memaddr - 2;
   2208 	  else if (!pcrel_op->include_isa_bit)
   2209 	    {
   2210 	      bfd_byte buffer[2];
   2211 
   2212 	      /* If this instruction is in the delay slot of a JAL/JALX
   2213 		 instruction, the base address is the address of the
   2214 		 JAL/JALX instruction.  If it is in the delay slot of
   2215 		 a JR/JALR instruction, the base address is the address
   2216 		 of the JR/JALR instruction.  This test is unreliable:
   2217 		 we have no way of knowing whether the previous word is
   2218 		 instruction or data.  */
   2219 	      if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
   2220 		  && (((info->endian == BFD_ENDIAN_BIG
   2221 			? bfd_getb16 (buffer)
   2222 			: bfd_getl16 (buffer))
   2223 		       & 0xf800) == 0x1800))
   2224 		baseaddr = memaddr - 4;
   2225 	      else if (info->read_memory_func (memaddr - 2, buffer, 2,
   2226 					       info) == 0
   2227 		       && (((info->endian == BFD_ENDIAN_BIG
   2228 			     ? bfd_getb16 (buffer)
   2229 			     : bfd_getl16 (buffer))
   2230 			    & 0xf89f) == 0xe800)
   2231 		       && (((info->endian == BFD_ENDIAN_BIG
   2232 			     ? bfd_getb16 (buffer)
   2233 			     : bfd_getl16 (buffer))
   2234 			    & 0x0060) != 0x0060))
   2235 		baseaddr = memaddr - 2;
   2236 	      else
   2237 		baseaddr = memaddr;
   2238 	    }
   2239 	}
   2240 
   2241       print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
   2242       break;
   2243     }
   2244 }
   2245 
   2246 
   2247 /* Check if the given address is the last word of a MIPS16 PLT entry.
   2248    This word is data and depending on the value it may interfere with
   2249    disassembly of further PLT entries.  We make use of the fact PLT
   2250    symbols are marked BSF_SYNTHETIC.  */
   2251 static bool
   2252 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
   2253 {
   2254   if (info->symbols
   2255       && info->symbols[0]
   2256       && (info->symbols[0]->flags & BSF_SYNTHETIC)
   2257       && addr == bfd_asymbol_value (info->symbols[0]) + 12)
   2258     return true;
   2259 
   2260   return false;
   2261 }
   2262 
   2263 /* Whether none, a 32-bit or a 16-bit instruction match has been done.  */
   2264 
   2265 enum match_kind
   2266 {
   2267   MATCH_NONE,
   2268   MATCH_FULL,
   2269   MATCH_SHORT
   2270 };
   2271 
   2272 /* Disassemble mips16 instructions.  */
   2273 
   2274 static int
   2275 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
   2276 {
   2277   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   2278   int status;
   2279   bfd_byte buffer[4];
   2280   const struct mips_opcode *op, *opend;
   2281   struct mips_print_arg_state state;
   2282   void *is = info->stream;
   2283   bool have_second;
   2284   bool extend_only;
   2285   unsigned int second;
   2286   unsigned int first;
   2287   unsigned int full;
   2288 
   2289   info->bytes_per_chunk = 2;
   2290   info->display_endian = info->endian;
   2291   info->insn_info_valid = 1;
   2292   info->branch_delay_insns = 0;
   2293   info->data_size = 0;
   2294   info->target = 0;
   2295   info->target2 = 0;
   2296 
   2297 #define GET_OP(insn, field) \
   2298   (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
   2299   /* Decode PLT entry's GOT slot address word.  */
   2300   if (is_mips16_plt_tail (info, memaddr))
   2301     {
   2302       info->insn_type = dis_noninsn;
   2303       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
   2304       if (status == 0)
   2305 	{
   2306 	  unsigned int gotslot;
   2307 
   2308 	  if (info->endian == BFD_ENDIAN_BIG)
   2309 	    gotslot = bfd_getb32 (buffer);
   2310 	  else
   2311 	    gotslot = bfd_getl32 (buffer);
   2312 	  infprintf (is, dis_style_assembler_directive, ".word");
   2313 	  infprintf (is, dis_style_text, "\t");
   2314 	  infprintf (is, dis_style_immediate, "0x%x", gotslot);
   2315 
   2316 	  return 4;
   2317 	}
   2318     }
   2319   else
   2320     {
   2321       info->insn_type = dis_nonbranch;
   2322       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   2323     }
   2324   if (status != 0)
   2325     {
   2326       (*info->memory_error_func) (status, memaddr, info);
   2327       return -1;
   2328     }
   2329 
   2330   extend_only = false;
   2331 
   2332   if (info->endian == BFD_ENDIAN_BIG)
   2333     first = bfd_getb16 (buffer);
   2334   else
   2335     first = bfd_getl16 (buffer);
   2336 
   2337   status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
   2338   if (status == 0)
   2339     {
   2340       have_second = true;
   2341       if (info->endian == BFD_ENDIAN_BIG)
   2342 	second = bfd_getb16 (buffer);
   2343       else
   2344 	second = bfd_getl16 (buffer);
   2345       full = (first << 16) | second;
   2346     }
   2347   else
   2348     {
   2349       have_second = false;
   2350       second = 0;
   2351       full = first;
   2352     }
   2353 
   2354   /* FIXME: Should probably use a hash table on the major opcode here.  */
   2355 
   2356   opend = mips16_opcodes + bfd_mips16_num_opcodes;
   2357   for (op = mips16_opcodes; op < opend; op++)
   2358     {
   2359       enum match_kind match;
   2360 
   2361       if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
   2362 	continue;
   2363 
   2364       if (op->pinfo == INSN_MACRO
   2365 	  || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
   2366 	match = MATCH_NONE;
   2367       else if (mips_opcode_32bit_p (op))
   2368 	{
   2369 	  if (have_second
   2370 	      && (full & op->mask) == op->match)
   2371 	    match = MATCH_FULL;
   2372 	  else
   2373 	    match = MATCH_NONE;
   2374 	}
   2375       else if ((first & op->mask) == op->match)
   2376 	{
   2377 	  match = MATCH_SHORT;
   2378 	  second = 0;
   2379 	  full = first;
   2380 	}
   2381       else if ((first & 0xf800) == 0xf000
   2382 	       && have_second
   2383 	       && !extend_only
   2384 	       && (second & op->mask) == op->match)
   2385 	{
   2386 	  if (op->pinfo2 & INSN2_SHORT_ONLY)
   2387 	    {
   2388 	      match = MATCH_NONE;
   2389 	      extend_only = true;
   2390 	    }
   2391 	  else
   2392 	    match = MATCH_FULL;
   2393 	}
   2394       else
   2395 	match = MATCH_NONE;
   2396 
   2397       if (match != MATCH_NONE)
   2398 	{
   2399 	  const char *s;
   2400 
   2401 	  infprintf (is, dis_style_mnemonic, "%s", op->name);
   2402 	  if (op->args[0] != '\0')
   2403 	    infprintf (is, dis_style_text, "\t");
   2404 
   2405 	  init_print_arg_state (&state);
   2406 	  for (s = op->args; *s != '\0'; s++)
   2407 	    {
   2408 	      if (*s == ','
   2409 		  && s[1] == 'w'
   2410 		  && GET_OP (full, RX) == GET_OP (full, RY))
   2411 		{
   2412 		  /* Skip the register and the comma.  */
   2413 		  ++s;
   2414 		  continue;
   2415 		}
   2416 	      if (*s == ','
   2417 		  && s[1] == 'v'
   2418 		  && GET_OP (full, RZ) == GET_OP (full, RX))
   2419 		{
   2420 		  /* Skip the register and the comma.  */
   2421 		  ++s;
   2422 		  continue;
   2423 		}
   2424 	      if (s[0] == 'N'
   2425 		  && s[1] == ','
   2426 		  && s[2] == 'O'
   2427 		  && op->name[strlen (op->name) - 1] == '0')
   2428 		{
   2429 		  /* Coprocessor register 0 with sel field.  */
   2430 		  const struct mips_cp0sel_name *n;
   2431 		  const struct mips_operand *operand;
   2432 		  unsigned int reg, sel;
   2433 
   2434 		  operand = decode_mips16_operand (*s, true);
   2435 		  reg = mips_extract_operand (operand, (first << 16) | second);
   2436 		  s += 2;
   2437 		  operand = decode_mips16_operand (*s, true);
   2438 		  sel = mips_extract_operand (operand, (first << 16) | second);
   2439 
   2440 		  /* CP0 register including 'sel' code for mftc0, to be
   2441 		     printed textually if known.  If not known, print both
   2442 		     CP0 register name and sel numerically since CP0 register
   2443 		     with sel 0 may have a name unrelated to register being
   2444 		     printed.  */
   2445 		  n = lookup_mips_cp0sel_name (mips_cp0sel_names,
   2446 					       mips_cp0sel_names_len,
   2447 					       reg, sel);
   2448 		  if (n != NULL)
   2449 		    infprintf (is, dis_style_register, "%s", n->name);
   2450 		  else
   2451 		    {
   2452 		      infprintf (is, dis_style_register, "$%d", reg);
   2453 		      infprintf (is, dis_style_text, ",");
   2454 		      infprintf (is, dis_style_immediate, "%d", sel);
   2455 		    }
   2456 		}
   2457 	      else
   2458 		switch (match)
   2459 		  {
   2460 		    case MATCH_FULL:
   2461 		      print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
   2462 					     second, true, first, s[1] == '(');
   2463 		      break;
   2464 		    case MATCH_SHORT:
   2465 		      print_mips16_insn_arg (info, &state, op, *s, memaddr,
   2466 					     first, false, 0, s[1] == '(');
   2467 		      break;
   2468 		    case MATCH_NONE:	/* Stop the compiler complaining.  */
   2469 		      break;
   2470 		  }
   2471 	    }
   2472 
   2473 	  /* Figure out branch instruction type and delay slot information.  */
   2474 	  if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
   2475 	    info->branch_delay_insns = 1;
   2476 	  if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
   2477 	      || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
   2478 	    {
   2479 	      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   2480 		info->insn_type = dis_jsr;
   2481 	      else
   2482 		info->insn_type = dis_branch;
   2483 	    }
   2484 	  else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
   2485 	    info->insn_type = dis_condbranch;
   2486 
   2487 	  return match == MATCH_FULL ? 4 : 2;
   2488 	}
   2489     }
   2490 #undef GET_OP
   2491 
   2492   infprintf (is, dis_style_assembler_directive, ".short");
   2493   infprintf (is, dis_style_text, "\t");
   2494   infprintf (is, dis_style_immediate, "0x%x", first);
   2495   info->insn_type = dis_noninsn;
   2496 
   2497   return 2;
   2498 }
   2499 
   2500 /* Disassemble microMIPS instructions.  */
   2501 
   2502 static int
   2503 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
   2504 {
   2505   const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
   2506   const struct mips_opcode *op, *opend;
   2507   void *is = info->stream;
   2508   bfd_byte buffer[2];
   2509   unsigned int higher;
   2510   unsigned int length;
   2511   int status;
   2512   unsigned int insn;
   2513 
   2514   info->bytes_per_chunk = 2;
   2515   info->display_endian = info->endian;
   2516   info->insn_info_valid = 1;
   2517   info->branch_delay_insns = 0;
   2518   info->data_size = 0;
   2519   info->insn_type = dis_nonbranch;
   2520   info->target = 0;
   2521   info->target2 = 0;
   2522 
   2523   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   2524   if (status != 0)
   2525     {
   2526       (*info->memory_error_func) (status, memaddr, info);
   2527       return -1;
   2528     }
   2529 
   2530   length = 2;
   2531 
   2532   if (info->endian == BFD_ENDIAN_BIG)
   2533     insn = bfd_getb16 (buffer);
   2534   else
   2535     insn = bfd_getl16 (buffer);
   2536 
   2537   if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
   2538     {
   2539       /* This is a 32-bit microMIPS instruction.  */
   2540       higher = insn;
   2541 
   2542       status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
   2543       if (status != 0)
   2544 	{
   2545 	  infprintf (is, dis_style_text, "micromips 0x%x", higher);
   2546 	  (*info->memory_error_func) (status, memaddr + 2, info);
   2547 	  return -1;
   2548 	}
   2549 
   2550       if (info->endian == BFD_ENDIAN_BIG)
   2551 	insn = bfd_getb16 (buffer);
   2552       else
   2553 	insn = bfd_getl16 (buffer);
   2554 
   2555       insn = insn | (higher << 16);
   2556 
   2557       length += 2;
   2558     }
   2559 
   2560   /* FIXME: Should probably use a hash table on the major opcode here.  */
   2561 
   2562   opend = micromips_opcodes + bfd_micromips_num_opcodes;
   2563   for (op = micromips_opcodes; op < opend; op++)
   2564     {
   2565       if (op->pinfo != INSN_MACRO
   2566 	  && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   2567 	  && (insn & op->mask) == op->match
   2568 	  && ((length == 2 && (op->mask & 0xffff0000) == 0)
   2569 	      || (length == 4 && (op->mask & 0xffff0000) != 0)))
   2570 	{
   2571 	  if (!validate_insn_args (op, decode_micromips_operand, insn))
   2572 	    continue;
   2573 
   2574 	  infprintf (is, dis_style_mnemonic, "%s", op->name);
   2575 
   2576 	  if (op->args[0])
   2577 	    {
   2578 	      infprintf (is, dis_style_text, "\t");
   2579 	      print_insn_args (info, op, decode_micromips_operand, insn,
   2580 			       memaddr + 1, length);
   2581 	    }
   2582 
   2583 	  /* Figure out instruction type and branch delay information.  */
   2584 	  if ((op->pinfo
   2585 	       & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
   2586 	    info->branch_delay_insns = 1;
   2587 	  if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
   2588 	       | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
   2589 	    {
   2590 	      if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
   2591 		info->insn_type = dis_jsr;
   2592 	      else
   2593 		info->insn_type = dis_branch;
   2594 	    }
   2595 	  else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
   2596 		    | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
   2597 	    {
   2598 	      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   2599 		info->insn_type = dis_condjsr;
   2600 	      else
   2601 		info->insn_type = dis_condbranch;
   2602 	    }
   2603 	  else if ((op->pinfo
   2604 		    & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
   2605 	    info->insn_type = dis_dref;
   2606 
   2607 	  return length;
   2608 	}
   2609     }
   2610 
   2611   infprintf (is, dis_style_assembler_directive, ".short");
   2612   infprintf (is, dis_style_text, "\t");
   2613   if (length != 2)
   2614     {
   2615       infprintf (is, dis_style_immediate, "0x%x", (insn >> 16) & 0xffff);
   2616       infprintf (is, dis_style_text, ", ");
   2617     }
   2618   infprintf (is, dis_style_immediate, "0x%x", (insn & 0xffff));
   2619 
   2620   info->insn_type = dis_noninsn;
   2621 
   2622   return length;
   2623 }
   2624 
   2625 /* Return 1 if a symbol associated with the location being disassembled
   2626    indicates a compressed mode, either MIPS16 or microMIPS, according to
   2627    MICROMIPS_P.  We iterate over all the symbols at the address being
   2628    considered assuming if at least one of them indicates code compression,
   2629    then such code has been genuinely produced here (other symbols could
   2630    have been derived from function symbols defined elsewhere or could
   2631    define data).  Otherwise, return 0.  */
   2632 
   2633 static bool
   2634 is_compressed_mode_p (struct disassemble_info *info, bool micromips_p)
   2635 {
   2636   int i;
   2637   int l;
   2638 
   2639   for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
   2640     if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
   2641 	&& ((!micromips_p
   2642 	     && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
   2643 	    || (micromips_p
   2644 		&& ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
   2645       return 1;
   2646     else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
   2647 	      && info->symtab[i]->section == info->section)
   2648       {
   2649 	elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
   2650 	if ((!micromips_p
   2651 	     && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
   2652 	    || (micromips_p
   2653 		&& ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
   2654 	  return 1;
   2655       }
   2656 
   2657   return 0;
   2658 }
   2659 
   2660 /* In an environment where we do not know the symbol type of the
   2661    instruction we are forced to assume that the low order bit of the
   2662    instructions' address may mark it as a mips16 instruction.  If we
   2663    are single stepping, or the pc is within the disassembled function,
   2664    this works.  Otherwise, we need a clue.  Sometimes.  */
   2665 
   2666 static int
   2667 _print_insn_mips (bfd_vma memaddr,
   2668 		  struct disassemble_info *info,
   2669 		  enum bfd_endian endianness)
   2670 {
   2671   bfd_byte buffer[INSNLEN];
   2672   int status;
   2673 
   2674   set_default_mips_dis_options (info);
   2675   parse_mips_dis_options (info->disassembler_options);
   2676 
   2677   if (info->mach == bfd_mach_mips16)
   2678     return print_insn_mips16 (memaddr, info);
   2679   if (info->mach == bfd_mach_mips_micromips)
   2680     return print_insn_micromips (memaddr, info);
   2681 
   2682 #if 1
   2683   /* FIXME: If odd address, this is CLEARLY a compressed instruction.  */
   2684   /* Only a few tools will work this way.  */
   2685   if (memaddr & 0x01)
   2686     {
   2687       if (micromips_ase)
   2688 	return print_insn_micromips (memaddr, info);
   2689       else
   2690 	return print_insn_mips16 (memaddr, info);
   2691     }
   2692 #endif
   2693 
   2694 #if SYMTAB_AVAILABLE
   2695   if (is_compressed_mode_p (info, true))
   2696     return print_insn_micromips (memaddr, info);
   2697   if (is_compressed_mode_p (info, false))
   2698     return print_insn_mips16 (memaddr, info);
   2699 #endif
   2700 
   2701   status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
   2702   if (status == 0)
   2703     {
   2704       int insn;
   2705 
   2706       if (endianness == BFD_ENDIAN_BIG)
   2707 	insn = bfd_getb32 (buffer);
   2708       else
   2709 	insn = bfd_getl32 (buffer);
   2710 
   2711       return print_insn_mips (memaddr, insn, info);
   2712     }
   2713   else
   2714     {
   2715       (*info->memory_error_func) (status, memaddr, info);
   2716       return -1;
   2717     }
   2718 }
   2719 
   2720 int
   2721 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
   2722 {
   2723   return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
   2724 }
   2725 
   2726 int
   2727 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
   2728 {
   2729   return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
   2730 }
   2731 
   2732 /* Indices into option argument vector for options accepting an argument.
   2734    Use MIPS_OPTION_ARG_NONE for options accepting no argument.  */
   2735 typedef enum
   2736 {
   2737   MIPS_OPTION_ARG_NONE = -1,
   2738   MIPS_OPTION_ARG_ABI,
   2739   MIPS_OPTION_ARG_ARCH,
   2740   MIPS_OPTION_ARG_SIZE
   2741 } mips_option_arg_t;
   2742 
   2743 /* Valid MIPS disassembler options.  */
   2744 static struct
   2745 {
   2746   const char *name;
   2747   const char *description;
   2748   mips_option_arg_t arg;
   2749 } mips_options[] =
   2750 {
   2751   { "no-aliases", N_("Use canonical instruction forms.\n"),
   2752 		  MIPS_OPTION_ARG_NONE },
   2753   { "msa",        N_("Recognize MSA instructions.\n"),
   2754 		  MIPS_OPTION_ARG_NONE },
   2755   { "virt",       N_("Recognize the virtualization ASE instructions.\n"),
   2756 		  MIPS_OPTION_ARG_NONE },
   2757   { "xpa",        N_("Recognize the eXtended Physical Address (XPA) ASE\n\
   2758                   instructions.\n"),
   2759 		  MIPS_OPTION_ARG_NONE },
   2760   { "ginv",       N_("Recognize the Global INValidate (GINV) ASE "
   2761 		     "instructions.\n"),
   2762 		  MIPS_OPTION_ARG_NONE },
   2763   { "loongson-mmi",
   2764 		  N_("Recognize the Loongson MultiMedia extensions "
   2765 		     "Instructions (MMI) ASE instructions.\n"),
   2766 		  MIPS_OPTION_ARG_NONE },
   2767   { "loongson-cam",
   2768 		  N_("Recognize the Loongson Content Address Memory (CAM) "
   2769 		     " instructions.\n"),
   2770 		  MIPS_OPTION_ARG_NONE },
   2771   { "loongson-ext",
   2772 		  N_("Recognize the Loongson EXTensions (EXT) "
   2773 		     " instructions.\n"),
   2774 		  MIPS_OPTION_ARG_NONE },
   2775   { "loongson-ext2",
   2776 		  N_("Recognize the Loongson EXTensions R2 (EXT2) "
   2777 		     " instructions.\n"),
   2778 		  MIPS_OPTION_ARG_NONE },
   2779   { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
   2780                   Default: based on binary being disassembled.\n"),
   2781 		  MIPS_OPTION_ARG_ABI },
   2782   { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
   2783                   Default: numeric.\n"),
   2784 		  MIPS_OPTION_ARG_ABI },
   2785   { "cp0-names=", N_("Print CP0 register names according to specified "
   2786 		     "architecture.\n\
   2787                   Default: based on binary being disassembled.\n"),
   2788 		  MIPS_OPTION_ARG_ARCH },
   2789   { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
   2790                   Default: based on binary being disassembled.\n"),
   2791 		  MIPS_OPTION_ARG_ARCH },
   2792   { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
   2793 		  MIPS_OPTION_ARG_ABI },
   2794   { "reg-names=", N_("Print CP0 register and HWR names according to "
   2795 		     "specified\n\
   2796                   architecture."),
   2797 		  MIPS_OPTION_ARG_ARCH }
   2798 };
   2799 
   2800 /* Build the structure representing valid MIPS disassembler options.
   2801    This is done dynamically for maintenance ease purpose; a static
   2802    initializer would be unreadable.  */
   2803 
   2804 const disasm_options_and_args_t *
   2805 disassembler_options_mips (void)
   2806 {
   2807   static disasm_options_and_args_t *opts_and_args;
   2808 
   2809   if (opts_and_args == NULL)
   2810     {
   2811       size_t num_options = ARRAY_SIZE (mips_options);
   2812       size_t num_args = MIPS_OPTION_ARG_SIZE;
   2813       disasm_option_arg_t *args;
   2814       disasm_options_t *opts;
   2815       size_t i;
   2816       size_t j;
   2817 
   2818       args = XNEWVEC (disasm_option_arg_t, num_args + 1);
   2819 
   2820       args[MIPS_OPTION_ARG_ABI].name = "ABI";
   2821       args[MIPS_OPTION_ARG_ABI].values
   2822 	= XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1);
   2823       for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
   2824 	args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name;
   2825       /* The array we return must be NULL terminated.  */
   2826       args[MIPS_OPTION_ARG_ABI].values[i] = NULL;
   2827 
   2828       args[MIPS_OPTION_ARG_ARCH].name = "ARCH";
   2829       args[MIPS_OPTION_ARG_ARCH].values
   2830 	= XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1);
   2831       for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
   2832 	if (*mips_arch_choices[i].name != '\0')
   2833 	  args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name;
   2834       /* The array we return must be NULL terminated.  */
   2835       args[MIPS_OPTION_ARG_ARCH].values[j] = NULL;
   2836 
   2837       /* The array we return must be NULL terminated.  */
   2838       args[MIPS_OPTION_ARG_SIZE].name = NULL;
   2839       args[MIPS_OPTION_ARG_SIZE].values = NULL;
   2840 
   2841       opts_and_args = XNEW (disasm_options_and_args_t);
   2842       opts_and_args->args = args;
   2843 
   2844       opts = &opts_and_args->options;
   2845       opts->name = XNEWVEC (const char *, num_options + 1);
   2846       opts->description = XNEWVEC (const char *, num_options + 1);
   2847       opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
   2848       for (i = 0; i < num_options; i++)
   2849 	{
   2850 	  opts->name[i] = mips_options[i].name;
   2851 	  opts->description[i] = _(mips_options[i].description);
   2852 	  if (mips_options[i].arg != MIPS_OPTION_ARG_NONE)
   2853 	    opts->arg[i] = &args[mips_options[i].arg];
   2854 	  else
   2855 	    opts->arg[i] = NULL;
   2856 	}
   2857       /* The array we return must be NULL terminated.  */
   2858       opts->name[i] = NULL;
   2859       opts->description[i] = NULL;
   2860       opts->arg[i] = NULL;
   2861     }
   2862 
   2863   return opts_and_args;
   2864 }
   2865 
   2866 void
   2867 print_mips_disassembler_options (FILE *stream)
   2868 {
   2869   const disasm_options_and_args_t *opts_and_args;
   2870   const disasm_option_arg_t *args;
   2871   const disasm_options_t *opts;
   2872   size_t max_len = 0;
   2873   size_t i;
   2874   size_t j;
   2875 
   2876   opts_and_args = disassembler_options_mips ();
   2877   opts = &opts_and_args->options;
   2878   args = opts_and_args->args;
   2879 
   2880   fprintf (stream, _("\n\
   2881 The following MIPS specific disassembler options are supported for use\n\
   2882 with the -M switch (multiple options should be separated by commas):\n\n"));
   2883 
   2884   /* Compute the length of the longest option name.  */
   2885   for (i = 0; opts->name[i] != NULL; i++)
   2886     {
   2887       size_t len = strlen (opts->name[i]);
   2888 
   2889       if (opts->arg[i] != NULL)
   2890 	len += strlen (opts->arg[i]->name);
   2891       if (max_len < len)
   2892 	max_len = len;
   2893     }
   2894 
   2895   for (i = 0, max_len++; opts->name[i] != NULL; i++)
   2896     {
   2897       fprintf (stream, "  %s", opts->name[i]);
   2898       if (opts->arg[i] != NULL)
   2899 	fprintf (stream, "%s", opts->arg[i]->name);
   2900       if (opts->description[i] != NULL)
   2901 	{
   2902 	  size_t len = strlen (opts->name[i]);
   2903 
   2904 	  if (opts->arg[i] != NULL)
   2905 	    len += strlen (opts->arg[i]->name);
   2906 	  fprintf (stream,
   2907 		   "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
   2908 	}
   2909       fprintf (stream, _("\n"));
   2910     }
   2911 
   2912   for (i = 0; args[i].name != NULL; i++)
   2913     {
   2914       if (args[i].values == NULL)
   2915 	continue;
   2916       fprintf (stream, _("\n\
   2917   For the options above, the following values are supported for \"%s\":\n   "),
   2918 	       args[i].name);
   2919       for (j = 0; args[i].values[j] != NULL; j++)
   2920 	fprintf (stream, " %s", args[i].values[j]);
   2921       fprintf (stream, _("\n"));
   2922     }
   2923 
   2924   fprintf (stream, _("\n"));
   2925 }
   2926