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