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