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