MIPS/opcodes: Remove an incorrect MT ASE reference in MFC0/MTC0 decoding
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
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@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_MIPS64, 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
843 /* Update settings according to the ELF file header flags. */
844 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
845 {
846 struct bfd *abfd = info->section->owner;
847 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
848 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
849
850 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
851 because we won't then have a MIPS/ELF BFD, however we need
852 to guard against a link error in a `--enable-targets=...'
853 configuration with a 32-bit host where the MIPS target is
854 a secondary, or with MIPS/ECOFF configurations. */
855 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
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 #endif
870 }
871
872 static void
873 parse_mips_dis_option (const char *option, unsigned int len)
874 {
875 unsigned int i, optionlen, vallen;
876 const char *val;
877 const struct mips_abi_choice *chosen_abi;
878 const struct mips_arch_choice *chosen_arch;
879
880 /* Try to match options that are simple flags */
881 if (CONST_STRNEQ (option, "no-aliases"))
882 {
883 no_aliases = 1;
884 return;
885 }
886
887 if (CONST_STRNEQ (option, "msa"))
888 {
889 mips_ase |= ASE_MSA;
890 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
891 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
892 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
893 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
894 mips_ase |= ASE_MSA64;
895 return;
896 }
897
898 if (CONST_STRNEQ (option, "virt"))
899 {
900 mips_ase |= ASE_VIRT;
901 if (mips_isa & ISA_MIPS64R2
902 || mips_isa & ISA_MIPS64R3
903 || mips_isa & ISA_MIPS64R5
904 || mips_isa & ISA_MIPS64R6)
905 mips_ase |= ASE_VIRT64;
906 return;
907 }
908
909 if (CONST_STRNEQ (option, "xpa"))
910 {
911 mips_ase |= ASE_XPA;
912 return;
913 }
914
915
916 /* Look for the = that delimits the end of the option name. */
917 for (i = 0; i < len; i++)
918 if (option[i] == '=')
919 break;
920
921 if (i == 0) /* Invalid option: no name before '='. */
922 return;
923 if (i == len) /* Invalid option: no '='. */
924 return;
925 if (i == (len - 1)) /* Invalid option: no value after '='. */
926 return;
927
928 optionlen = i;
929 val = option + (optionlen + 1);
930 vallen = len - (optionlen + 1);
931
932 if (strncmp ("gpr-names", option, optionlen) == 0
933 && strlen ("gpr-names") == optionlen)
934 {
935 chosen_abi = choose_abi_by_name (val, vallen);
936 if (chosen_abi != NULL)
937 mips_gpr_names = chosen_abi->gpr_names;
938 return;
939 }
940
941 if (strncmp ("fpr-names", option, optionlen) == 0
942 && strlen ("fpr-names") == optionlen)
943 {
944 chosen_abi = choose_abi_by_name (val, vallen);
945 if (chosen_abi != NULL)
946 mips_fpr_names = chosen_abi->fpr_names;
947 return;
948 }
949
950 if (strncmp ("cp0-names", option, optionlen) == 0
951 && strlen ("cp0-names") == optionlen)
952 {
953 chosen_arch = choose_arch_by_name (val, vallen);
954 if (chosen_arch != NULL)
955 {
956 mips_cp0_names = chosen_arch->cp0_names;
957 mips_cp0sel_names = chosen_arch->cp0sel_names;
958 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
959 }
960 return;
961 }
962
963 if (strncmp ("cp1-names", option, optionlen) == 0
964 && strlen ("cp1-names") == optionlen)
965 {
966 chosen_arch = choose_arch_by_name (val, vallen);
967 if (chosen_arch != NULL)
968 mips_cp1_names = chosen_arch->cp1_names;
969 return;
970 }
971
972 if (strncmp ("hwr-names", option, optionlen) == 0
973 && strlen ("hwr-names") == optionlen)
974 {
975 chosen_arch = choose_arch_by_name (val, vallen);
976 if (chosen_arch != NULL)
977 mips_hwr_names = chosen_arch->hwr_names;
978 return;
979 }
980
981 if (strncmp ("reg-names", option, optionlen) == 0
982 && strlen ("reg-names") == optionlen)
983 {
984 /* We check both ABI and ARCH here unconditionally, so
985 that "numeric" will do the desirable thing: select
986 numeric register names for all registers. Other than
987 that, a given name probably won't match both. */
988 chosen_abi = choose_abi_by_name (val, vallen);
989 if (chosen_abi != NULL)
990 {
991 mips_gpr_names = chosen_abi->gpr_names;
992 mips_fpr_names = chosen_abi->fpr_names;
993 }
994 chosen_arch = choose_arch_by_name (val, vallen);
995 if (chosen_arch != NULL)
996 {
997 mips_cp0_names = chosen_arch->cp0_names;
998 mips_cp0sel_names = chosen_arch->cp0sel_names;
999 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1000 mips_cp1_names = chosen_arch->cp1_names;
1001 mips_hwr_names = chosen_arch->hwr_names;
1002 }
1003 return;
1004 }
1005
1006 /* Invalid option. */
1007 }
1008
1009 static void
1010 parse_mips_dis_options (const char *options)
1011 {
1012 const char *option_end;
1013
1014 if (options == NULL)
1015 return;
1016
1017 while (*options != '\0')
1018 {
1019 /* Skip empty options. */
1020 if (*options == ',')
1021 {
1022 options++;
1023 continue;
1024 }
1025
1026 /* We know that *options is neither NUL or a comma. */
1027 option_end = options + 1;
1028 while (*option_end != ',' && *option_end != '\0')
1029 option_end++;
1030
1031 parse_mips_dis_option (options, option_end - options);
1032
1033 /* Go on to the next one. If option_end points to a comma, it
1034 will be skipped above. */
1035 options = option_end;
1036 }
1037 }
1038
1039 static const struct mips_cp0sel_name *
1040 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1041 unsigned int len,
1042 unsigned int cp0reg,
1043 unsigned int sel)
1044 {
1045 unsigned int i;
1046
1047 for (i = 0; i < len; i++)
1048 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1049 return &names[i];
1050 return NULL;
1051 }
1052
1053 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1054
1055 static void
1056 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1057 enum mips_reg_operand_type type, int regno)
1058 {
1059 switch (type)
1060 {
1061 case OP_REG_GP:
1062 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1063 break;
1064
1065 case OP_REG_FP:
1066 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1067 break;
1068
1069 case OP_REG_CCC:
1070 if (opcode->pinfo & (FP_D | FP_S))
1071 info->fprintf_func (info->stream, "$fcc%d", regno);
1072 else
1073 info->fprintf_func (info->stream, "$cc%d", regno);
1074 break;
1075
1076 case OP_REG_VEC:
1077 if (opcode->membership & INSN_5400)
1078 info->fprintf_func (info->stream, "$f%d", regno);
1079 else
1080 info->fprintf_func (info->stream, "$v%d", regno);
1081 break;
1082
1083 case OP_REG_ACC:
1084 info->fprintf_func (info->stream, "$ac%d", regno);
1085 break;
1086
1087 case OP_REG_COPRO:
1088 if (opcode->name[strlen (opcode->name) - 1] == '0')
1089 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
1090 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1091 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
1092 else
1093 info->fprintf_func (info->stream, "$%d", regno);
1094 break;
1095
1096 case OP_REG_HW:
1097 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1098 break;
1099
1100 case OP_REG_VF:
1101 info->fprintf_func (info->stream, "$vf%d", regno);
1102 break;
1103
1104 case OP_REG_VI:
1105 info->fprintf_func (info->stream, "$vi%d", regno);
1106 break;
1107
1108 case OP_REG_R5900_I:
1109 info->fprintf_func (info->stream, "$I");
1110 break;
1111
1112 case OP_REG_R5900_Q:
1113 info->fprintf_func (info->stream, "$Q");
1114 break;
1115
1116 case OP_REG_R5900_R:
1117 info->fprintf_func (info->stream, "$R");
1118 break;
1119
1120 case OP_REG_R5900_ACC:
1121 info->fprintf_func (info->stream, "$ACC");
1122 break;
1123
1124 case OP_REG_MSA:
1125 info->fprintf_func (info->stream, "$w%d", regno);
1126 break;
1127
1128 case OP_REG_MSA_CTRL:
1129 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1130 break;
1131
1132 }
1133 }
1134 \f
1135 /* Used to track the state carried over from previous operands in
1136 an instruction. */
1137 struct mips_print_arg_state {
1138 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1139 where the value is known to be unsigned and small. */
1140 unsigned int last_int;
1141
1142 /* The type and number of the last OP_REG seen. We only use this for
1143 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1144 enum mips_reg_operand_type last_reg_type;
1145 unsigned int last_regno;
1146 unsigned int dest_regno;
1147 unsigned int seen_dest;
1148 };
1149
1150 /* Initialize STATE for the start of an instruction. */
1151
1152 static inline void
1153 init_print_arg_state (struct mips_print_arg_state *state)
1154 {
1155 memset (state, 0, sizeof (*state));
1156 }
1157
1158 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1159 whose value is given by UVAL. */
1160
1161 static void
1162 print_vu0_channel (struct disassemble_info *info,
1163 const struct mips_operand *operand, unsigned int uval)
1164 {
1165 if (operand->size == 4)
1166 info->fprintf_func (info->stream, "%s%s%s%s",
1167 uval & 8 ? "x" : "",
1168 uval & 4 ? "y" : "",
1169 uval & 2 ? "z" : "",
1170 uval & 1 ? "w" : "");
1171 else if (operand->size == 2)
1172 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1173 else
1174 abort ();
1175 }
1176
1177 /* Record information about a register operand. */
1178
1179 static void
1180 mips_seen_register (struct mips_print_arg_state *state,
1181 unsigned int regno,
1182 enum mips_reg_operand_type reg_type)
1183 {
1184 state->last_reg_type = reg_type;
1185 state->last_regno = regno;
1186
1187 if (!state->seen_dest)
1188 {
1189 state->seen_dest = 1;
1190 state->dest_regno = regno;
1191 }
1192 }
1193
1194 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1195 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1196 the base address for OP_PCREL operands. */
1197
1198 static void
1199 print_insn_arg (struct disassemble_info *info,
1200 struct mips_print_arg_state *state,
1201 const struct mips_opcode *opcode,
1202 const struct mips_operand *operand,
1203 bfd_vma base_pc,
1204 unsigned int uval)
1205 {
1206 const fprintf_ftype infprintf = info->fprintf_func;
1207 void *is = info->stream;
1208
1209 switch (operand->type)
1210 {
1211 case OP_INT:
1212 {
1213 const struct mips_int_operand *int_op;
1214
1215 int_op = (const struct mips_int_operand *) operand;
1216 uval = mips_decode_int_operand (int_op, uval);
1217 state->last_int = uval;
1218 if (int_op->print_hex)
1219 infprintf (is, "0x%x", uval);
1220 else
1221 infprintf (is, "%d", uval);
1222 }
1223 break;
1224
1225 case OP_MAPPED_INT:
1226 {
1227 const struct mips_mapped_int_operand *mint_op;
1228
1229 mint_op = (const struct mips_mapped_int_operand *) operand;
1230 uval = mint_op->int_map[uval];
1231 state->last_int = uval;
1232 if (mint_op->print_hex)
1233 infprintf (is, "0x%x", uval);
1234 else
1235 infprintf (is, "%d", uval);
1236 }
1237 break;
1238
1239 case OP_MSB:
1240 {
1241 const struct mips_msb_operand *msb_op;
1242
1243 msb_op = (const struct mips_msb_operand *) operand;
1244 uval += msb_op->bias;
1245 if (msb_op->add_lsb)
1246 uval -= state->last_int;
1247 infprintf (is, "0x%x", uval);
1248 }
1249 break;
1250
1251 case OP_REG:
1252 case OP_OPTIONAL_REG:
1253 {
1254 const struct mips_reg_operand *reg_op;
1255
1256 reg_op = (const struct mips_reg_operand *) operand;
1257 uval = mips_decode_reg_operand (reg_op, uval);
1258 print_reg (info, opcode, reg_op->reg_type, uval);
1259
1260 mips_seen_register (state, uval, reg_op->reg_type);
1261 }
1262 break;
1263
1264 case OP_REG_PAIR:
1265 {
1266 const struct mips_reg_pair_operand *pair_op;
1267
1268 pair_op = (const struct mips_reg_pair_operand *) operand;
1269 print_reg (info, opcode, pair_op->reg_type,
1270 pair_op->reg1_map[uval]);
1271 infprintf (is, ",");
1272 print_reg (info, opcode, pair_op->reg_type,
1273 pair_op->reg2_map[uval]);
1274 }
1275 break;
1276
1277 case OP_PCREL:
1278 {
1279 const struct mips_pcrel_operand *pcrel_op;
1280
1281 pcrel_op = (const struct mips_pcrel_operand *) operand;
1282 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1283
1284 /* For jumps and branches clear the ISA bit except for
1285 the GDB disassembler. */
1286 if (pcrel_op->include_isa_bit
1287 && info->flavour != bfd_target_unknown_flavour)
1288 info->target &= -2;
1289
1290 (*info->print_address_func) (info->target, info);
1291 }
1292 break;
1293
1294 case OP_PERF_REG:
1295 infprintf (is, "%d", uval);
1296 break;
1297
1298 case OP_ADDIUSP_INT:
1299 {
1300 int sval;
1301
1302 sval = mips_signed_operand (operand, uval) * 4;
1303 if (sval >= -8 && sval < 8)
1304 sval ^= 0x400;
1305 infprintf (is, "%d", sval);
1306 break;
1307 }
1308
1309 case OP_CLO_CLZ_DEST:
1310 {
1311 unsigned int reg1, reg2;
1312
1313 reg1 = uval & 31;
1314 reg2 = uval >> 5;
1315 /* If one is zero use the other. */
1316 if (reg1 == reg2 || reg2 == 0)
1317 infprintf (is, "%s", mips_gpr_names[reg1]);
1318 else if (reg1 == 0)
1319 infprintf (is, "%s", mips_gpr_names[reg2]);
1320 else
1321 /* Bogus, result depends on processor. */
1322 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1323 mips_gpr_names[reg2]);
1324 }
1325 break;
1326
1327 case OP_SAME_RS_RT:
1328 case OP_CHECK_PREV:
1329 case OP_NON_ZERO_REG:
1330 {
1331 print_reg (info, opcode, OP_REG_GP, uval & 31);
1332 mips_seen_register (state, uval, OP_REG_GP);
1333 }
1334 break;
1335
1336 case OP_LWM_SWM_LIST:
1337 if (operand->size == 2)
1338 {
1339 if (uval == 0)
1340 infprintf (is, "%s,%s",
1341 mips_gpr_names[16],
1342 mips_gpr_names[31]);
1343 else
1344 infprintf (is, "%s-%s,%s",
1345 mips_gpr_names[16],
1346 mips_gpr_names[16 + uval],
1347 mips_gpr_names[31]);
1348 }
1349 else
1350 {
1351 int s_reg_encode;
1352
1353 s_reg_encode = uval & 0xf;
1354 if (s_reg_encode != 0)
1355 {
1356 if (s_reg_encode == 1)
1357 infprintf (is, "%s", mips_gpr_names[16]);
1358 else if (s_reg_encode < 9)
1359 infprintf (is, "%s-%s",
1360 mips_gpr_names[16],
1361 mips_gpr_names[15 + s_reg_encode]);
1362 else if (s_reg_encode == 9)
1363 infprintf (is, "%s-%s,%s",
1364 mips_gpr_names[16],
1365 mips_gpr_names[23],
1366 mips_gpr_names[30]);
1367 else
1368 infprintf (is, "UNKNOWN");
1369 }
1370
1371 if (uval & 0x10) /* For ra. */
1372 {
1373 if (s_reg_encode == 0)
1374 infprintf (is, "%s", mips_gpr_names[31]);
1375 else
1376 infprintf (is, ",%s", mips_gpr_names[31]);
1377 }
1378 }
1379 break;
1380
1381 case OP_ENTRY_EXIT_LIST:
1382 {
1383 const char *sep;
1384 unsigned int amask, smask;
1385
1386 sep = "";
1387 amask = (uval >> 3) & 7;
1388 if (amask > 0 && amask < 5)
1389 {
1390 infprintf (is, "%s", mips_gpr_names[4]);
1391 if (amask > 1)
1392 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1393 sep = ",";
1394 }
1395
1396 smask = (uval >> 1) & 3;
1397 if (smask == 3)
1398 {
1399 infprintf (is, "%s??", sep);
1400 sep = ",";
1401 }
1402 else if (smask > 0)
1403 {
1404 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1405 if (smask > 1)
1406 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1407 sep = ",";
1408 }
1409
1410 if (uval & 1)
1411 {
1412 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1413 sep = ",";
1414 }
1415
1416 if (amask == 5 || amask == 6)
1417 {
1418 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1419 if (amask == 6)
1420 infprintf (is, "-%s", mips_fpr_names[1]);
1421 }
1422 }
1423 break;
1424
1425 case OP_SAVE_RESTORE_LIST:
1426 /* Should be handled by the caller due to extend behavior. */
1427 abort ();
1428
1429 case OP_MDMX_IMM_REG:
1430 {
1431 unsigned int vsel;
1432
1433 vsel = uval >> 5;
1434 uval &= 31;
1435 if ((vsel & 0x10) == 0)
1436 {
1437 int fmt;
1438
1439 vsel &= 0x0f;
1440 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1441 if ((vsel & 1) == 0)
1442 break;
1443 print_reg (info, opcode, OP_REG_VEC, uval);
1444 infprintf (is, "[%d]", vsel >> 1);
1445 }
1446 else if ((vsel & 0x08) == 0)
1447 print_reg (info, opcode, OP_REG_VEC, uval);
1448 else
1449 infprintf (is, "0x%x", uval);
1450 }
1451 break;
1452
1453 case OP_REPEAT_PREV_REG:
1454 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1455 break;
1456
1457 case OP_REPEAT_DEST_REG:
1458 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1459 break;
1460
1461 case OP_PC:
1462 infprintf (is, "$pc");
1463 break;
1464
1465 case OP_VU0_SUFFIX:
1466 case OP_VU0_MATCH_SUFFIX:
1467 print_vu0_channel (info, operand, uval);
1468 break;
1469
1470 case OP_IMM_INDEX:
1471 infprintf (is, "[%d]", uval);
1472 break;
1473
1474 case OP_REG_INDEX:
1475 infprintf (is, "[");
1476 print_reg (info, opcode, OP_REG_GP, uval);
1477 infprintf (is, "]");
1478 break;
1479 }
1480 }
1481
1482 /* Validate the arguments for INSN, which is described by OPCODE.
1483 Use DECODE_OPERAND to get the encoding of each operand. */
1484
1485 static bfd_boolean
1486 validate_insn_args (const struct mips_opcode *opcode,
1487 const struct mips_operand *(*decode_operand) (const char *),
1488 unsigned int insn)
1489 {
1490 struct mips_print_arg_state state;
1491 const struct mips_operand *operand;
1492 const char *s;
1493 unsigned int uval;
1494
1495 init_print_arg_state (&state);
1496 for (s = opcode->args; *s; ++s)
1497 {
1498 switch (*s)
1499 {
1500 case ',':
1501 case '(':
1502 case ')':
1503 break;
1504
1505 case '#':
1506 ++s;
1507 break;
1508
1509 default:
1510 operand = decode_operand (s);
1511
1512 if (operand)
1513 {
1514 uval = mips_extract_operand (operand, insn);
1515 switch (operand->type)
1516 {
1517 case OP_REG:
1518 case OP_OPTIONAL_REG:
1519 {
1520 const struct mips_reg_operand *reg_op;
1521
1522 reg_op = (const struct mips_reg_operand *) operand;
1523 uval = mips_decode_reg_operand (reg_op, uval);
1524 mips_seen_register (&state, uval, reg_op->reg_type);
1525 }
1526 break;
1527
1528 case OP_SAME_RS_RT:
1529 {
1530 unsigned int reg1, reg2;
1531
1532 reg1 = uval & 31;
1533 reg2 = uval >> 5;
1534
1535 if (reg1 != reg2 || reg1 == 0)
1536 return FALSE;
1537 }
1538 break;
1539
1540 case OP_CHECK_PREV:
1541 {
1542 const struct mips_check_prev_operand *prev_op;
1543
1544 prev_op = (const struct mips_check_prev_operand *) operand;
1545
1546 if (!prev_op->zero_ok && uval == 0)
1547 return FALSE;
1548
1549 if (((prev_op->less_than_ok && uval < state.last_regno)
1550 || (prev_op->greater_than_ok && uval > state.last_regno)
1551 || (prev_op->equal_ok && uval == state.last_regno)))
1552 break;
1553
1554 return FALSE;
1555 }
1556
1557 case OP_NON_ZERO_REG:
1558 {
1559 if (uval == 0)
1560 return FALSE;
1561 }
1562 break;
1563
1564 case OP_INT:
1565 case OP_MAPPED_INT:
1566 case OP_MSB:
1567 case OP_REG_PAIR:
1568 case OP_PCREL:
1569 case OP_PERF_REG:
1570 case OP_ADDIUSP_INT:
1571 case OP_CLO_CLZ_DEST:
1572 case OP_LWM_SWM_LIST:
1573 case OP_ENTRY_EXIT_LIST:
1574 case OP_MDMX_IMM_REG:
1575 case OP_REPEAT_PREV_REG:
1576 case OP_REPEAT_DEST_REG:
1577 case OP_PC:
1578 case OP_VU0_SUFFIX:
1579 case OP_VU0_MATCH_SUFFIX:
1580 case OP_IMM_INDEX:
1581 case OP_REG_INDEX:
1582 break;
1583
1584 case OP_SAVE_RESTORE_LIST:
1585 /* Should be handled by the caller due to extend behavior. */
1586 abort ();
1587 }
1588 }
1589 if (*s == 'm' || *s == '+' || *s == '-')
1590 ++s;
1591 }
1592 }
1593 return TRUE;
1594 }
1595
1596 /* Print the arguments for INSN, which is described by OPCODE.
1597 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1598 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1599 operand is for a branch or jump. */
1600
1601 static void
1602 print_insn_args (struct disassemble_info *info,
1603 const struct mips_opcode *opcode,
1604 const struct mips_operand *(*decode_operand) (const char *),
1605 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1606 {
1607 const fprintf_ftype infprintf = info->fprintf_func;
1608 void *is = info->stream;
1609 struct mips_print_arg_state state;
1610 const struct mips_operand *operand;
1611 const char *s;
1612
1613 init_print_arg_state (&state);
1614 for (s = opcode->args; *s; ++s)
1615 {
1616 switch (*s)
1617 {
1618 case ',':
1619 case '(':
1620 case ')':
1621 infprintf (is, "%c", *s);
1622 break;
1623
1624 case '#':
1625 ++s;
1626 infprintf (is, "%c%c", *s, *s);
1627 break;
1628
1629 default:
1630 operand = decode_operand (s);
1631 if (!operand)
1632 {
1633 /* xgettext:c-format */
1634 infprintf (is,
1635 _("# internal error, undefined operand in `%s %s'"),
1636 opcode->name, opcode->args);
1637 return;
1638 }
1639 if (operand->type == OP_REG
1640 && s[1] == ','
1641 && s[2] == 'H'
1642 && opcode->name[strlen (opcode->name) - 1] == '0')
1643 {
1644 /* Coprocessor register 0 with sel field. */
1645 const struct mips_cp0sel_name *n;
1646 unsigned int reg, sel;
1647
1648 reg = mips_extract_operand (operand, insn);
1649 s += 2;
1650 operand = decode_operand (s);
1651 sel = mips_extract_operand (operand, insn);
1652
1653 /* CP0 register including 'sel' code for mftc0, to be
1654 printed textually if known. If not known, print both
1655 CP0 register name and sel numerically since CP0 register
1656 with sel 0 may have a name unrelated to register being
1657 printed. */
1658 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1659 mips_cp0sel_names_len,
1660 reg, sel);
1661 if (n != NULL)
1662 infprintf (is, "%s", n->name);
1663 else
1664 infprintf (is, "$%d,%d", reg, sel);
1665 }
1666 else
1667 {
1668 bfd_vma base_pc = insn_pc;
1669
1670 /* Adjust the PC relative base so that branch/jump insns use
1671 the following PC as the base but genuinely PC relative
1672 operands use the current PC. */
1673 if (operand->type == OP_PCREL)
1674 {
1675 const struct mips_pcrel_operand *pcrel_op;
1676
1677 pcrel_op = (const struct mips_pcrel_operand *) operand;
1678 /* The include_isa_bit flag is sufficient to distinguish
1679 branch/jump from other PC relative operands. */
1680 if (pcrel_op->include_isa_bit)
1681 base_pc += length;
1682 }
1683
1684 print_insn_arg (info, &state, opcode, operand, base_pc,
1685 mips_extract_operand (operand, insn));
1686 }
1687 if (*s == 'm' || *s == '+' || *s == '-')
1688 ++s;
1689 break;
1690 }
1691 }
1692 }
1693 \f
1694 /* Print the mips instruction at address MEMADDR in debugged memory,
1695 on using INFO. Returns length of the instruction, in bytes, which is
1696 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1697 this is little-endian code. */
1698
1699 static int
1700 print_insn_mips (bfd_vma memaddr,
1701 int word,
1702 struct disassemble_info *info)
1703 {
1704 #define GET_OP(insn, field) \
1705 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1706 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1707 const fprintf_ftype infprintf = info->fprintf_func;
1708 const struct mips_opcode *op;
1709 static bfd_boolean init = 0;
1710 void *is = info->stream;
1711
1712 /* Build a hash table to shorten the search time. */
1713 if (! init)
1714 {
1715 unsigned int i;
1716
1717 for (i = 0; i <= OP_MASK_OP; i++)
1718 {
1719 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1720 {
1721 if (op->pinfo == INSN_MACRO
1722 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1723 continue;
1724 if (i == GET_OP (op->match, OP))
1725 {
1726 mips_hash[i] = op;
1727 break;
1728 }
1729 }
1730 }
1731
1732 init = 1;
1733 }
1734
1735 info->bytes_per_chunk = INSNLEN;
1736 info->display_endian = info->endian;
1737 info->insn_info_valid = 1;
1738 info->branch_delay_insns = 0;
1739 info->data_size = 0;
1740 info->insn_type = dis_nonbranch;
1741 info->target = 0;
1742 info->target2 = 0;
1743
1744 op = mips_hash[GET_OP (word, OP)];
1745 if (op != NULL)
1746 {
1747 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1748 {
1749 if (op->pinfo != INSN_MACRO
1750 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1751 && (word & op->mask) == op->match)
1752 {
1753 /* We always disassemble the jalx instruction, except for MIPS r6. */
1754 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1755 && (strcmp (op->name, "jalx")
1756 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1757 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
1758 continue;
1759
1760 /* Figure out instruction type and branch delay information. */
1761 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1762 {
1763 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
1764 info->insn_type = dis_jsr;
1765 else
1766 info->insn_type = dis_branch;
1767 info->branch_delay_insns = 1;
1768 }
1769 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1770 | INSN_COND_BRANCH_LIKELY)) != 0)
1771 {
1772 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1773 info->insn_type = dis_condjsr;
1774 else
1775 info->insn_type = dis_condbranch;
1776 info->branch_delay_insns = 1;
1777 }
1778 else if ((op->pinfo & (INSN_STORE_MEMORY
1779 | INSN_LOAD_MEMORY)) != 0)
1780 info->insn_type = dis_dref;
1781
1782 if (!validate_insn_args (op, decode_mips_operand, word))
1783 continue;
1784
1785 infprintf (is, "%s", op->name);
1786 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1787 {
1788 unsigned int uval;
1789
1790 infprintf (is, ".");
1791 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1792 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1793 }
1794
1795 if (op->args[0])
1796 {
1797 infprintf (is, "\t");
1798 print_insn_args (info, op, decode_mips_operand, word,
1799 memaddr, 4);
1800 }
1801
1802 return INSNLEN;
1803 }
1804 }
1805 }
1806 #undef GET_OP
1807
1808 /* Handle undefined instructions. */
1809 info->insn_type = dis_noninsn;
1810 infprintf (is, "0x%x", word);
1811 return INSNLEN;
1812 }
1813 \f
1814 /* Disassemble an operand for a mips16 instruction. */
1815
1816 static void
1817 print_mips16_insn_arg (struct disassemble_info *info,
1818 struct mips_print_arg_state *state,
1819 const struct mips_opcode *opcode,
1820 char type, bfd_vma memaddr,
1821 unsigned insn, bfd_boolean use_extend,
1822 unsigned extend, bfd_boolean is_offset)
1823 {
1824 const fprintf_ftype infprintf = info->fprintf_func;
1825 void *is = info->stream;
1826 const struct mips_operand *operand, *ext_operand;
1827 unsigned short ext_size;
1828 unsigned int uval;
1829 bfd_vma baseaddr;
1830
1831 if (!use_extend)
1832 extend = 0;
1833
1834 switch (type)
1835 {
1836 case ',':
1837 case '(':
1838 case ')':
1839 infprintf (is, "%c", type);
1840 break;
1841
1842 default:
1843 operand = decode_mips16_operand (type, FALSE);
1844 if (!operand)
1845 {
1846 /* xgettext:c-format */
1847 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1848 opcode->name, opcode->args);
1849 return;
1850 }
1851
1852 if (operand->type == OP_SAVE_RESTORE_LIST)
1853 {
1854 /* Handle this case here because of the complex interaction
1855 with the EXTEND opcode. */
1856 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1857 const char *sep;
1858
1859 amask = extend & 0xf;
1860 if (amask == MIPS16_ALL_ARGS)
1861 {
1862 nargs = 4;
1863 nstatics = 0;
1864 }
1865 else if (amask == MIPS16_ALL_STATICS)
1866 {
1867 nargs = 0;
1868 nstatics = 4;
1869 }
1870 else
1871 {
1872 nargs = amask >> 2;
1873 nstatics = amask & 3;
1874 }
1875
1876 sep = "";
1877 if (nargs > 0)
1878 {
1879 infprintf (is, "%s", mips_gpr_names[4]);
1880 if (nargs > 1)
1881 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1882 sep = ",";
1883 }
1884
1885 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1886 if (frame_size == 0 && !use_extend)
1887 frame_size = 128;
1888 infprintf (is, "%s%d", sep, frame_size);
1889
1890 if (insn & 0x40) /* $ra */
1891 infprintf (is, ",%s", mips_gpr_names[31]);
1892
1893 nsreg = (extend >> 8) & 0x7;
1894 smask = 0;
1895 if (insn & 0x20) /* $s0 */
1896 smask |= 1 << 0;
1897 if (insn & 0x10) /* $s1 */
1898 smask |= 1 << 1;
1899 if (nsreg > 0) /* $s2-$s8 */
1900 smask |= ((1 << nsreg) - 1) << 2;
1901
1902 for (i = 0; i < 9; i++)
1903 if (smask & (1 << i))
1904 {
1905 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1906 /* Skip over string of set bits. */
1907 for (j = i; smask & (2 << j); j++)
1908 continue;
1909 if (j > i)
1910 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1911 i = j + 1;
1912 }
1913 /* Statics $ax - $a3. */
1914 if (nstatics == 1)
1915 infprintf (is, ",%s", mips_gpr_names[7]);
1916 else if (nstatics > 0)
1917 infprintf (is, ",%s-%s",
1918 mips_gpr_names[7 - nstatics + 1],
1919 mips_gpr_names[7]);
1920 break;
1921 }
1922
1923 if (is_offset && operand->type == OP_INT)
1924 {
1925 const struct mips_int_operand *int_op;
1926
1927 int_op = (const struct mips_int_operand *) operand;
1928 info->insn_type = dis_dref;
1929 info->data_size = 1 << int_op->shift;
1930 }
1931
1932 ext_size = 0;
1933 if (use_extend)
1934 {
1935 ext_operand = decode_mips16_operand (type, TRUE);
1936 if (ext_operand != operand)
1937 {
1938 ext_size = ext_operand->size;
1939 operand = ext_operand;
1940 }
1941 }
1942 if (operand->size == 26)
1943 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
1944 else if (ext_size == 16)
1945 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
1946 else if (ext_size == 15)
1947 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
1948 else if (ext_size == 6)
1949 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
1950 else
1951 uval = mips_extract_operand (operand, (extend << 16) | insn);
1952
1953 baseaddr = memaddr + 2;
1954 if (operand->type == OP_PCREL)
1955 {
1956 const struct mips_pcrel_operand *pcrel_op;
1957
1958 pcrel_op = (const struct mips_pcrel_operand *) operand;
1959 if (!pcrel_op->include_isa_bit && use_extend)
1960 baseaddr = memaddr - 2;
1961 else if (!pcrel_op->include_isa_bit)
1962 {
1963 bfd_byte buffer[2];
1964
1965 /* If this instruction is in the delay slot of a JAL/JALX
1966 instruction, the base address is the address of the
1967 JAL/JALX instruction. If it is in the delay slot of
1968 a JR/JALR instruction, the base address is the address
1969 of the JR/JALR instruction. This test is unreliable:
1970 we have no way of knowing whether the previous word is
1971 instruction or data. */
1972 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1973 && (((info->endian == BFD_ENDIAN_BIG
1974 ? bfd_getb16 (buffer)
1975 : bfd_getl16 (buffer))
1976 & 0xf800) == 0x1800))
1977 baseaddr = memaddr - 4;
1978 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1979 info) == 0
1980 && (((info->endian == BFD_ENDIAN_BIG
1981 ? bfd_getb16 (buffer)
1982 : bfd_getl16 (buffer))
1983 & 0xf89f) == 0xe800)
1984 && (((info->endian == BFD_ENDIAN_BIG
1985 ? bfd_getb16 (buffer)
1986 : bfd_getl16 (buffer))
1987 & 0x0060) != 0x0060))
1988 baseaddr = memaddr - 2;
1989 else
1990 baseaddr = memaddr;
1991 }
1992 }
1993
1994 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
1995 break;
1996 }
1997 }
1998
1999
2000 /* Check if the given address is the last word of a MIPS16 PLT entry.
2001 This word is data and depending on the value it may interfere with
2002 disassembly of further PLT entries. We make use of the fact PLT
2003 symbols are marked BSF_SYNTHETIC. */
2004 static bfd_boolean
2005 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2006 {
2007 if (info->symbols
2008 && info->symbols[0]
2009 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2010 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2011 return TRUE;
2012
2013 return FALSE;
2014 }
2015
2016 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2017
2018 enum match_kind
2019 {
2020 MATCH_NONE,
2021 MATCH_FULL,
2022 MATCH_SHORT
2023 };
2024
2025 /* Disassemble mips16 instructions. */
2026
2027 static int
2028 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2029 {
2030 const fprintf_ftype infprintf = info->fprintf_func;
2031 int status;
2032 bfd_byte buffer[4];
2033 const struct mips_opcode *op, *opend;
2034 struct mips_print_arg_state state;
2035 void *is = info->stream;
2036 bfd_boolean have_second;
2037 unsigned int second;
2038 unsigned int first;
2039 unsigned int full;
2040
2041 info->bytes_per_chunk = 2;
2042 info->display_endian = info->endian;
2043 info->insn_info_valid = 1;
2044 info->branch_delay_insns = 0;
2045 info->data_size = 0;
2046 info->target = 0;
2047 info->target2 = 0;
2048
2049 #define GET_OP(insn, field) \
2050 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2051 /* Decode PLT entry's GOT slot address word. */
2052 if (is_mips16_plt_tail (info, memaddr))
2053 {
2054 info->insn_type = dis_noninsn;
2055 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2056 if (status == 0)
2057 {
2058 unsigned int gotslot;
2059
2060 if (info->endian == BFD_ENDIAN_BIG)
2061 gotslot = bfd_getb32 (buffer);
2062 else
2063 gotslot = bfd_getl32 (buffer);
2064 infprintf (is, ".word\t0x%x", gotslot);
2065
2066 return 4;
2067 }
2068 }
2069 else
2070 {
2071 info->insn_type = dis_nonbranch;
2072 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2073 }
2074 if (status != 0)
2075 {
2076 (*info->memory_error_func) (status, memaddr, info);
2077 return -1;
2078 }
2079
2080 if (info->endian == BFD_ENDIAN_BIG)
2081 first = bfd_getb16 (buffer);
2082 else
2083 first = bfd_getl16 (buffer);
2084
2085 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2086 if (status == 0)
2087 {
2088 have_second = TRUE;
2089 if (info->endian == BFD_ENDIAN_BIG)
2090 second = bfd_getb16 (buffer);
2091 else
2092 second = bfd_getl16 (buffer);
2093 full = (first << 16) | second;
2094 }
2095 else
2096 {
2097 have_second = FALSE;
2098 second = 0;
2099 full = first;
2100 }
2101
2102 /* FIXME: Should probably use a hash table on the major opcode here. */
2103
2104 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2105 for (op = mips16_opcodes; op < opend; op++)
2106 {
2107 enum match_kind match;
2108
2109 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2110 continue;
2111
2112 if (op->pinfo == INSN_MACRO
2113 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2114 match = MATCH_NONE;
2115 else if (mips_opcode_32bit_p (op))
2116 {
2117 if (have_second
2118 && (full & op->mask) == op->match)
2119 match = MATCH_FULL;
2120 else
2121 match = MATCH_NONE;
2122 }
2123 else if ((first & op->mask) == op->match)
2124 {
2125 match = MATCH_SHORT;
2126 second = 0;
2127 full = first;
2128 }
2129 else if ((first & 0xf800) == 0xf000
2130 && have_second
2131 && !(op->pinfo2 & INSN2_SHORT_ONLY)
2132 && (second & op->mask) == op->match)
2133 match = MATCH_FULL;
2134 else
2135 match = MATCH_NONE;
2136
2137 if (match != MATCH_NONE)
2138 {
2139 const char *s;
2140
2141 infprintf (is, "%s", op->name);
2142 if (op->args[0] != '\0')
2143 infprintf (is, "\t");
2144
2145 init_print_arg_state (&state);
2146 for (s = op->args; *s != '\0'; s++)
2147 {
2148 if (*s == ','
2149 && s[1] == 'w'
2150 && GET_OP (full, RX) == GET_OP (full, RY))
2151 {
2152 /* Skip the register and the comma. */
2153 ++s;
2154 continue;
2155 }
2156 if (*s == ','
2157 && s[1] == 'v'
2158 && GET_OP (full, RZ) == GET_OP (full, RX))
2159 {
2160 /* Skip the register and the comma. */
2161 ++s;
2162 continue;
2163 }
2164 switch (match)
2165 {
2166 case MATCH_FULL:
2167 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2168 second, TRUE, first, s[1] == '(');
2169 break;
2170 case MATCH_SHORT:
2171 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2172 first, FALSE, 0, s[1] == '(');
2173 break;
2174 case MATCH_NONE: /* Stop the compiler complaining. */
2175 break;
2176 }
2177 }
2178
2179 /* Figure out branch instruction type and delay slot information. */
2180 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2181 info->branch_delay_insns = 1;
2182 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2183 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2184 {
2185 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2186 info->insn_type = dis_jsr;
2187 else
2188 info->insn_type = dis_branch;
2189 }
2190 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2191 info->insn_type = dis_condbranch;
2192
2193 return match == MATCH_FULL ? 4 : 2;
2194 }
2195 }
2196 #undef GET_OP
2197
2198 infprintf (is, "0x%x", first);
2199 info->insn_type = dis_noninsn;
2200
2201 return 2;
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 no-aliases Use canonical instruction forms.\n"));
2439
2440 fprintf (stream, _("\n\
2441 msa Recognize MSA instructions.\n"));
2442
2443 fprintf (stream, _("\n\
2444 virt Recognize the virtualization ASE instructions.\n"));
2445
2446 fprintf (stream, _("\n\
2447 xpa Recognize the eXtended Physical Address (XPA)\n\
2448 ASE instructions.\n"));
2449
2450 fprintf (stream, _("\n\
2451 gpr-names=ABI Print GPR names according to specified ABI.\n\
2452 Default: based on binary being disassembled.\n"));
2453
2454 fprintf (stream, _("\n\
2455 fpr-names=ABI Print FPR names according to specified ABI.\n\
2456 Default: numeric.\n"));
2457
2458 fprintf (stream, _("\n\
2459 cp0-names=ARCH Print CP0 register names according to\n\
2460 specified architecture.\n\
2461 Default: based on binary being disassembled.\n"));
2462
2463 fprintf (stream, _("\n\
2464 hwr-names=ARCH Print HWR names according to specified \n\
2465 architecture.\n\
2466 Default: based on binary being disassembled.\n"));
2467
2468 fprintf (stream, _("\n\
2469 reg-names=ABI Print GPR and FPR names according to\n\
2470 specified ABI.\n"));
2471
2472 fprintf (stream, _("\n\
2473 reg-names=ARCH Print CP0 register and HWR names according to\n\
2474 specified architecture.\n"));
2475
2476 fprintf (stream, _("\n\
2477 For the options above, the following values are supported for \"ABI\":\n\
2478 "));
2479 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2480 fprintf (stream, " %s", mips_abi_choices[i].name);
2481 fprintf (stream, _("\n"));
2482
2483 fprintf (stream, _("\n\
2484 For the options above, The following values are supported for \"ARCH\":\n\
2485 "));
2486 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2487 if (*mips_arch_choices[i].name != '\0')
2488 fprintf (stream, " %s", mips_arch_choices[i].name);
2489 fprintf (stream, _("\n"));
2490
2491 fprintf (stream, _("\n"));
2492 }
This page took 0.080662 seconds and 5 git commands to generate.