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