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