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