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