Copyright update for binutils
[deliverable/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),
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),
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 static void
768 set_default_mips_dis_options (struct disassemble_info *info)
769 {
770 const struct mips_arch_choice *chosen_arch;
771
772 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
773 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
774 CP0 register, and HWR names. */
775 mips_isa = ISA_MIPS3;
776 mips_processor = CPU_R3000;
777 micromips_ase = 0;
778 mips_ase = 0;
779 mips_gpr_names = mips_gpr_names_oldabi;
780 mips_fpr_names = mips_fpr_names_numeric;
781 mips_cp0_names = mips_cp0_names_numeric;
782 mips_cp0sel_names = NULL;
783 mips_cp0sel_names_len = 0;
784 mips_cp1_names = mips_cp1_names_numeric;
785 mips_hwr_names = mips_hwr_names_numeric;
786 no_aliases = 0;
787
788 /* Update settings according to the ELF file header flags. */
789 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
790 {
791 Elf_Internal_Ehdr *header;
792
793 header = elf_elfheader (info->section->owner);
794 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
795 if (is_newabi (header))
796 mips_gpr_names = mips_gpr_names_newabi;
797 /* If a microMIPS binary, then don't use MIPS16 bindings. */
798 micromips_ase = is_micromips (header);
799 }
800
801 /* Set ISA, architecture, and cp0 register names as best we can. */
802 #if ! SYMTAB_AVAILABLE
803 /* This is running out on a target machine, not in a host tool.
804 FIXME: Where does mips_target_info come from? */
805 target_processor = mips_target_info.processor;
806 mips_isa = mips_target_info.isa;
807 mips_ase = mips_target_info.ase;
808 #else
809 chosen_arch = choose_arch_by_number (info->mach);
810 if (chosen_arch != NULL)
811 {
812 mips_processor = chosen_arch->processor;
813 mips_isa = chosen_arch->isa;
814 mips_ase = chosen_arch->ase;
815 mips_cp0_names = chosen_arch->cp0_names;
816 mips_cp0sel_names = chosen_arch->cp0sel_names;
817 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
818 mips_cp1_names = chosen_arch->cp1_names;
819 mips_hwr_names = chosen_arch->hwr_names;
820 }
821 #endif
822 }
823
824 static void
825 parse_mips_dis_option (const char *option, unsigned int len)
826 {
827 unsigned int i, optionlen, vallen;
828 const char *val;
829 const struct mips_abi_choice *chosen_abi;
830 const struct mips_arch_choice *chosen_arch;
831
832 /* Try to match options that are simple flags */
833 if (CONST_STRNEQ (option, "no-aliases"))
834 {
835 no_aliases = 1;
836 return;
837 }
838
839 if (CONST_STRNEQ (option, "msa"))
840 {
841 mips_ase |= ASE_MSA;
842 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
843 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
844 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
845 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
846 mips_ase |= ASE_MSA64;
847 return;
848 }
849
850 if (CONST_STRNEQ (option, "virt"))
851 {
852 mips_ase |= ASE_VIRT;
853 if (mips_isa & ISA_MIPS64R2
854 || mips_isa & ISA_MIPS64R3
855 || mips_isa & ISA_MIPS64R5
856 || mips_isa & ISA_MIPS64R6)
857 mips_ase |= ASE_VIRT64;
858 return;
859 }
860
861 if (CONST_STRNEQ (option, "xpa"))
862 {
863 mips_ase |= ASE_XPA;
864 return;
865 }
866
867
868 /* Look for the = that delimits the end of the option name. */
869 for (i = 0; i < len; i++)
870 if (option[i] == '=')
871 break;
872
873 if (i == 0) /* Invalid option: no name before '='. */
874 return;
875 if (i == len) /* Invalid option: no '='. */
876 return;
877 if (i == (len - 1)) /* Invalid option: no value after '='. */
878 return;
879
880 optionlen = i;
881 val = option + (optionlen + 1);
882 vallen = len - (optionlen + 1);
883
884 if (strncmp ("gpr-names", option, optionlen) == 0
885 && strlen ("gpr-names") == optionlen)
886 {
887 chosen_abi = choose_abi_by_name (val, vallen);
888 if (chosen_abi != NULL)
889 mips_gpr_names = chosen_abi->gpr_names;
890 return;
891 }
892
893 if (strncmp ("fpr-names", option, optionlen) == 0
894 && strlen ("fpr-names") == optionlen)
895 {
896 chosen_abi = choose_abi_by_name (val, vallen);
897 if (chosen_abi != NULL)
898 mips_fpr_names = chosen_abi->fpr_names;
899 return;
900 }
901
902 if (strncmp ("cp0-names", option, optionlen) == 0
903 && strlen ("cp0-names") == optionlen)
904 {
905 chosen_arch = choose_arch_by_name (val, vallen);
906 if (chosen_arch != NULL)
907 {
908 mips_cp0_names = chosen_arch->cp0_names;
909 mips_cp0sel_names = chosen_arch->cp0sel_names;
910 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
911 }
912 return;
913 }
914
915 if (strncmp ("cp1-names", option, optionlen) == 0
916 && strlen ("cp1-names") == optionlen)
917 {
918 chosen_arch = choose_arch_by_name (val, vallen);
919 if (chosen_arch != NULL)
920 mips_cp1_names = chosen_arch->cp1_names;
921 return;
922 }
923
924 if (strncmp ("hwr-names", option, optionlen) == 0
925 && strlen ("hwr-names") == optionlen)
926 {
927 chosen_arch = choose_arch_by_name (val, vallen);
928 if (chosen_arch != NULL)
929 mips_hwr_names = chosen_arch->hwr_names;
930 return;
931 }
932
933 if (strncmp ("reg-names", option, optionlen) == 0
934 && strlen ("reg-names") == optionlen)
935 {
936 /* We check both ABI and ARCH here unconditionally, so
937 that "numeric" will do the desirable thing: select
938 numeric register names for all registers. Other than
939 that, a given name probably won't match both. */
940 chosen_abi = choose_abi_by_name (val, vallen);
941 if (chosen_abi != NULL)
942 {
943 mips_gpr_names = chosen_abi->gpr_names;
944 mips_fpr_names = chosen_abi->fpr_names;
945 }
946 chosen_arch = choose_arch_by_name (val, vallen);
947 if (chosen_arch != NULL)
948 {
949 mips_cp0_names = chosen_arch->cp0_names;
950 mips_cp0sel_names = chosen_arch->cp0sel_names;
951 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
952 mips_cp1_names = chosen_arch->cp1_names;
953 mips_hwr_names = chosen_arch->hwr_names;
954 }
955 return;
956 }
957
958 /* Invalid option. */
959 }
960
961 static void
962 parse_mips_dis_options (const char *options)
963 {
964 const char *option_end;
965
966 if (options == NULL)
967 return;
968
969 while (*options != '\0')
970 {
971 /* Skip empty options. */
972 if (*options == ',')
973 {
974 options++;
975 continue;
976 }
977
978 /* We know that *options is neither NUL or a comma. */
979 option_end = options + 1;
980 while (*option_end != ',' && *option_end != '\0')
981 option_end++;
982
983 parse_mips_dis_option (options, option_end - options);
984
985 /* Go on to the next one. If option_end points to a comma, it
986 will be skipped above. */
987 options = option_end;
988 }
989 }
990
991 static const struct mips_cp0sel_name *
992 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
993 unsigned int len,
994 unsigned int cp0reg,
995 unsigned int sel)
996 {
997 unsigned int i;
998
999 for (i = 0; i < len; i++)
1000 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1001 return &names[i];
1002 return NULL;
1003 }
1004
1005 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1006
1007 static void
1008 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1009 enum mips_reg_operand_type type, int regno)
1010 {
1011 switch (type)
1012 {
1013 case OP_REG_GP:
1014 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1015 break;
1016
1017 case OP_REG_FP:
1018 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1019 break;
1020
1021 case OP_REG_CCC:
1022 if (opcode->pinfo & (FP_D | FP_S))
1023 info->fprintf_func (info->stream, "$fcc%d", regno);
1024 else
1025 info->fprintf_func (info->stream, "$cc%d", regno);
1026 break;
1027
1028 case OP_REG_VEC:
1029 if (opcode->membership & INSN_5400)
1030 info->fprintf_func (info->stream, "$f%d", regno);
1031 else
1032 info->fprintf_func (info->stream, "$v%d", regno);
1033 break;
1034
1035 case OP_REG_ACC:
1036 info->fprintf_func (info->stream, "$ac%d", regno);
1037 break;
1038
1039 case OP_REG_COPRO:
1040 if (opcode->name[strlen (opcode->name) - 1] == '0')
1041 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
1042 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1043 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
1044 else
1045 info->fprintf_func (info->stream, "$%d", regno);
1046 break;
1047
1048 case OP_REG_HW:
1049 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1050 break;
1051
1052 case OP_REG_VF:
1053 info->fprintf_func (info->stream, "$vf%d", regno);
1054 break;
1055
1056 case OP_REG_VI:
1057 info->fprintf_func (info->stream, "$vi%d", regno);
1058 break;
1059
1060 case OP_REG_R5900_I:
1061 info->fprintf_func (info->stream, "$I");
1062 break;
1063
1064 case OP_REG_R5900_Q:
1065 info->fprintf_func (info->stream, "$Q");
1066 break;
1067
1068 case OP_REG_R5900_R:
1069 info->fprintf_func (info->stream, "$R");
1070 break;
1071
1072 case OP_REG_R5900_ACC:
1073 info->fprintf_func (info->stream, "$ACC");
1074 break;
1075
1076 case OP_REG_MSA:
1077 info->fprintf_func (info->stream, "$w%d", regno);
1078 break;
1079
1080 case OP_REG_MSA_CTRL:
1081 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1082 break;
1083
1084 }
1085 }
1086 \f
1087 /* Used to track the state carried over from previous operands in
1088 an instruction. */
1089 struct mips_print_arg_state {
1090 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1091 where the value is known to be unsigned and small. */
1092 unsigned int last_int;
1093
1094 /* The type and number of the last OP_REG seen. We only use this for
1095 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1096 enum mips_reg_operand_type last_reg_type;
1097 unsigned int last_regno;
1098 unsigned int dest_regno;
1099 unsigned int seen_dest;
1100 };
1101
1102 /* Initialize STATE for the start of an instruction. */
1103
1104 static inline void
1105 init_print_arg_state (struct mips_print_arg_state *state)
1106 {
1107 memset (state, 0, sizeof (*state));
1108 }
1109
1110 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1111 whose value is given by UVAL. */
1112
1113 static void
1114 print_vu0_channel (struct disassemble_info *info,
1115 const struct mips_operand *operand, unsigned int uval)
1116 {
1117 if (operand->size == 4)
1118 info->fprintf_func (info->stream, "%s%s%s%s",
1119 uval & 8 ? "x" : "",
1120 uval & 4 ? "y" : "",
1121 uval & 2 ? "z" : "",
1122 uval & 1 ? "w" : "");
1123 else if (operand->size == 2)
1124 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1125 else
1126 abort ();
1127 }
1128
1129 /* Record information about a register operand. */
1130
1131 static void
1132 mips_seen_register (struct mips_print_arg_state *state,
1133 unsigned int regno,
1134 enum mips_reg_operand_type reg_type)
1135 {
1136 state->last_reg_type = reg_type;
1137 state->last_regno = regno;
1138
1139 if (!state->seen_dest)
1140 {
1141 state->seen_dest = 1;
1142 state->dest_regno = regno;
1143 }
1144 }
1145
1146 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1147 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1148 the base address for OP_PCREL operands. */
1149
1150 static void
1151 print_insn_arg (struct disassemble_info *info,
1152 struct mips_print_arg_state *state,
1153 const struct mips_opcode *opcode,
1154 const struct mips_operand *operand,
1155 bfd_vma base_pc,
1156 unsigned int uval)
1157 {
1158 const fprintf_ftype infprintf = info->fprintf_func;
1159 void *is = info->stream;
1160
1161 switch (operand->type)
1162 {
1163 case OP_INT:
1164 {
1165 const struct mips_int_operand *int_op;
1166
1167 int_op = (const struct mips_int_operand *) operand;
1168 uval = mips_decode_int_operand (int_op, uval);
1169 state->last_int = uval;
1170 if (int_op->print_hex)
1171 infprintf (is, "0x%x", uval);
1172 else
1173 infprintf (is, "%d", uval);
1174 }
1175 break;
1176
1177 case OP_MAPPED_INT:
1178 {
1179 const struct mips_mapped_int_operand *mint_op;
1180
1181 mint_op = (const struct mips_mapped_int_operand *) operand;
1182 uval = mint_op->int_map[uval];
1183 state->last_int = uval;
1184 if (mint_op->print_hex)
1185 infprintf (is, "0x%x", uval);
1186 else
1187 infprintf (is, "%d", uval);
1188 }
1189 break;
1190
1191 case OP_MSB:
1192 {
1193 const struct mips_msb_operand *msb_op;
1194
1195 msb_op = (const struct mips_msb_operand *) operand;
1196 uval += msb_op->bias;
1197 if (msb_op->add_lsb)
1198 uval -= state->last_int;
1199 infprintf (is, "0x%x", uval);
1200 }
1201 break;
1202
1203 case OP_REG:
1204 case OP_OPTIONAL_REG:
1205 {
1206 const struct mips_reg_operand *reg_op;
1207
1208 reg_op = (const struct mips_reg_operand *) operand;
1209 uval = mips_decode_reg_operand (reg_op, uval);
1210 print_reg (info, opcode, reg_op->reg_type, uval);
1211
1212 mips_seen_register (state, uval, reg_op->reg_type);
1213 }
1214 break;
1215
1216 case OP_REG_PAIR:
1217 {
1218 const struct mips_reg_pair_operand *pair_op;
1219
1220 pair_op = (const struct mips_reg_pair_operand *) operand;
1221 print_reg (info, opcode, pair_op->reg_type,
1222 pair_op->reg1_map[uval]);
1223 infprintf (is, ",");
1224 print_reg (info, opcode, pair_op->reg_type,
1225 pair_op->reg2_map[uval]);
1226 }
1227 break;
1228
1229 case OP_PCREL:
1230 {
1231 const struct mips_pcrel_operand *pcrel_op;
1232
1233 pcrel_op = (const struct mips_pcrel_operand *) operand;
1234 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1235
1236 /* Preserve the ISA bit for the GDB disassembler,
1237 otherwise clear it. */
1238 if (info->flavour != bfd_target_unknown_flavour)
1239 info->target &= -2;
1240
1241 (*info->print_address_func) (info->target, info);
1242 }
1243 break;
1244
1245 case OP_PERF_REG:
1246 infprintf (is, "%d", uval);
1247 break;
1248
1249 case OP_ADDIUSP_INT:
1250 {
1251 int sval;
1252
1253 sval = mips_signed_operand (operand, uval) * 4;
1254 if (sval >= -8 && sval < 8)
1255 sval ^= 0x400;
1256 infprintf (is, "%d", sval);
1257 break;
1258 }
1259
1260 case OP_CLO_CLZ_DEST:
1261 {
1262 unsigned int reg1, reg2;
1263
1264 reg1 = uval & 31;
1265 reg2 = uval >> 5;
1266 /* If one is zero use the other. */
1267 if (reg1 == reg2 || reg2 == 0)
1268 infprintf (is, "%s", mips_gpr_names[reg1]);
1269 else if (reg1 == 0)
1270 infprintf (is, "%s", mips_gpr_names[reg2]);
1271 else
1272 /* Bogus, result depends on processor. */
1273 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1274 mips_gpr_names[reg2]);
1275 }
1276 break;
1277
1278 case OP_SAME_RS_RT:
1279 case OP_CHECK_PREV:
1280 case OP_NON_ZERO_REG:
1281 {
1282 print_reg (info, opcode, OP_REG_GP, uval & 31);
1283 mips_seen_register (state, uval, OP_REG_GP);
1284 }
1285 break;
1286
1287 case OP_LWM_SWM_LIST:
1288 if (operand->size == 2)
1289 {
1290 if (uval == 0)
1291 infprintf (is, "%s,%s",
1292 mips_gpr_names[16],
1293 mips_gpr_names[31]);
1294 else
1295 infprintf (is, "%s-%s,%s",
1296 mips_gpr_names[16],
1297 mips_gpr_names[16 + uval],
1298 mips_gpr_names[31]);
1299 }
1300 else
1301 {
1302 int s_reg_encode;
1303
1304 s_reg_encode = uval & 0xf;
1305 if (s_reg_encode != 0)
1306 {
1307 if (s_reg_encode == 1)
1308 infprintf (is, "%s", mips_gpr_names[16]);
1309 else if (s_reg_encode < 9)
1310 infprintf (is, "%s-%s",
1311 mips_gpr_names[16],
1312 mips_gpr_names[15 + s_reg_encode]);
1313 else if (s_reg_encode == 9)
1314 infprintf (is, "%s-%s,%s",
1315 mips_gpr_names[16],
1316 mips_gpr_names[23],
1317 mips_gpr_names[30]);
1318 else
1319 infprintf (is, "UNKNOWN");
1320 }
1321
1322 if (uval & 0x10) /* For ra. */
1323 {
1324 if (s_reg_encode == 0)
1325 infprintf (is, "%s", mips_gpr_names[31]);
1326 else
1327 infprintf (is, ",%s", mips_gpr_names[31]);
1328 }
1329 }
1330 break;
1331
1332 case OP_ENTRY_EXIT_LIST:
1333 {
1334 const char *sep;
1335 unsigned int amask, smask;
1336
1337 sep = "";
1338 amask = (uval >> 3) & 7;
1339 if (amask > 0 && amask < 5)
1340 {
1341 infprintf (is, "%s", mips_gpr_names[4]);
1342 if (amask > 1)
1343 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1344 sep = ",";
1345 }
1346
1347 smask = (uval >> 1) & 3;
1348 if (smask == 3)
1349 {
1350 infprintf (is, "%s??", sep);
1351 sep = ",";
1352 }
1353 else if (smask > 0)
1354 {
1355 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1356 if (smask > 1)
1357 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1358 sep = ",";
1359 }
1360
1361 if (uval & 1)
1362 {
1363 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1364 sep = ",";
1365 }
1366
1367 if (amask == 5 || amask == 6)
1368 {
1369 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1370 if (amask == 6)
1371 infprintf (is, "-%s", mips_fpr_names[1]);
1372 }
1373 }
1374 break;
1375
1376 case OP_SAVE_RESTORE_LIST:
1377 /* Should be handled by the caller due to extend behavior. */
1378 abort ();
1379
1380 case OP_MDMX_IMM_REG:
1381 {
1382 unsigned int vsel;
1383
1384 vsel = uval >> 5;
1385 uval &= 31;
1386 if ((vsel & 0x10) == 0)
1387 {
1388 int fmt;
1389
1390 vsel &= 0x0f;
1391 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1392 if ((vsel & 1) == 0)
1393 break;
1394 print_reg (info, opcode, OP_REG_VEC, uval);
1395 infprintf (is, "[%d]", vsel >> 1);
1396 }
1397 else if ((vsel & 0x08) == 0)
1398 print_reg (info, opcode, OP_REG_VEC, uval);
1399 else
1400 infprintf (is, "0x%x", uval);
1401 }
1402 break;
1403
1404 case OP_REPEAT_PREV_REG:
1405 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1406 break;
1407
1408 case OP_REPEAT_DEST_REG:
1409 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1410 break;
1411
1412 case OP_PC:
1413 infprintf (is, "$pc");
1414 break;
1415
1416 case OP_VU0_SUFFIX:
1417 case OP_VU0_MATCH_SUFFIX:
1418 print_vu0_channel (info, operand, uval);
1419 break;
1420
1421 case OP_IMM_INDEX:
1422 infprintf (is, "[%d]", uval);
1423 break;
1424
1425 case OP_REG_INDEX:
1426 infprintf (is, "[");
1427 print_reg (info, opcode, OP_REG_GP, uval);
1428 infprintf (is, "]");
1429 break;
1430 }
1431 }
1432
1433 /* Validate the arguments for INSN, which is described by OPCODE.
1434 Use DECODE_OPERAND to get the encoding of each operand. */
1435
1436 static bfd_boolean
1437 validate_insn_args (const struct mips_opcode *opcode,
1438 const struct mips_operand *(*decode_operand) (const char *),
1439 unsigned int insn)
1440 {
1441 struct mips_print_arg_state state;
1442 const struct mips_operand *operand;
1443 const char *s;
1444 unsigned int uval;
1445
1446 init_print_arg_state (&state);
1447 for (s = opcode->args; *s; ++s)
1448 {
1449 switch (*s)
1450 {
1451 case ',':
1452 case '(':
1453 case ')':
1454 break;
1455
1456 case '#':
1457 ++s;
1458 break;
1459
1460 default:
1461 operand = decode_operand (s);
1462
1463 if (operand)
1464 {
1465 uval = mips_extract_operand (operand, insn);
1466 switch (operand->type)
1467 {
1468 case OP_REG:
1469 case OP_OPTIONAL_REG:
1470 {
1471 const struct mips_reg_operand *reg_op;
1472
1473 reg_op = (const struct mips_reg_operand *) operand;
1474 uval = mips_decode_reg_operand (reg_op, uval);
1475 mips_seen_register (&state, uval, reg_op->reg_type);
1476 }
1477 break;
1478
1479 case OP_SAME_RS_RT:
1480 {
1481 unsigned int reg1, reg2;
1482
1483 reg1 = uval & 31;
1484 reg2 = uval >> 5;
1485
1486 if (reg1 != reg2 || reg1 == 0)
1487 return FALSE;
1488 }
1489 break;
1490
1491 case OP_CHECK_PREV:
1492 {
1493 const struct mips_check_prev_operand *prev_op;
1494
1495 prev_op = (const struct mips_check_prev_operand *) operand;
1496
1497 if (!prev_op->zero_ok && uval == 0)
1498 return FALSE;
1499
1500 if (((prev_op->less_than_ok && uval < state.last_regno)
1501 || (prev_op->greater_than_ok && uval > state.last_regno)
1502 || (prev_op->equal_ok && uval == state.last_regno)))
1503 break;
1504
1505 return FALSE;
1506 }
1507
1508 case OP_NON_ZERO_REG:
1509 {
1510 if (uval == 0)
1511 return FALSE;
1512 }
1513 break;
1514
1515 case OP_INT:
1516 case OP_MAPPED_INT:
1517 case OP_MSB:
1518 case OP_REG_PAIR:
1519 case OP_PCREL:
1520 case OP_PERF_REG:
1521 case OP_ADDIUSP_INT:
1522 case OP_CLO_CLZ_DEST:
1523 case OP_LWM_SWM_LIST:
1524 case OP_ENTRY_EXIT_LIST:
1525 case OP_MDMX_IMM_REG:
1526 case OP_REPEAT_PREV_REG:
1527 case OP_REPEAT_DEST_REG:
1528 case OP_PC:
1529 case OP_VU0_SUFFIX:
1530 case OP_VU0_MATCH_SUFFIX:
1531 case OP_IMM_INDEX:
1532 case OP_REG_INDEX:
1533 break;
1534
1535 case OP_SAVE_RESTORE_LIST:
1536 /* Should be handled by the caller due to extend behavior. */
1537 abort ();
1538 }
1539 }
1540 if (*s == 'm' || *s == '+' || *s == '-')
1541 ++s;
1542 }
1543 }
1544 return TRUE;
1545 }
1546
1547 /* Print the arguments for INSN, which is described by OPCODE.
1548 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1549 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1550 operand is for a branch or jump. */
1551
1552 static void
1553 print_insn_args (struct disassemble_info *info,
1554 const struct mips_opcode *opcode,
1555 const struct mips_operand *(*decode_operand) (const char *),
1556 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1557 {
1558 const fprintf_ftype infprintf = info->fprintf_func;
1559 void *is = info->stream;
1560 struct mips_print_arg_state state;
1561 const struct mips_operand *operand;
1562 const char *s;
1563
1564 init_print_arg_state (&state);
1565 for (s = opcode->args; *s; ++s)
1566 {
1567 switch (*s)
1568 {
1569 case ',':
1570 case '(':
1571 case ')':
1572 infprintf (is, "%c", *s);
1573 break;
1574
1575 case '#':
1576 ++s;
1577 infprintf (is, "%c%c", *s, *s);
1578 break;
1579
1580 default:
1581 operand = decode_operand (s);
1582 if (!operand)
1583 {
1584 /* xgettext:c-format */
1585 infprintf (is,
1586 _("# internal error, undefined operand in `%s %s'"),
1587 opcode->name, opcode->args);
1588 return;
1589 }
1590 if (operand->type == OP_REG
1591 && s[1] == ','
1592 && s[2] == 'H'
1593 && opcode->name[strlen (opcode->name) - 1] == '0')
1594 {
1595 /* Coprocessor register 0 with sel field (MT ASE). */
1596 const struct mips_cp0sel_name *n;
1597 unsigned int reg, sel;
1598
1599 reg = mips_extract_operand (operand, insn);
1600 s += 2;
1601 operand = decode_operand (s);
1602 sel = mips_extract_operand (operand, insn);
1603
1604 /* CP0 register including 'sel' code for mftc0, to be
1605 printed textually if known. If not known, print both
1606 CP0 register name and sel numerically since CP0 register
1607 with sel 0 may have a name unrelated to register being
1608 printed. */
1609 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1610 mips_cp0sel_names_len,
1611 reg, sel);
1612 if (n != NULL)
1613 infprintf (is, "%s", n->name);
1614 else
1615 infprintf (is, "$%d,%d", reg, sel);
1616 }
1617 else
1618 {
1619 bfd_vma base_pc = insn_pc;
1620
1621 /* Adjust the PC relative base so that branch/jump insns use
1622 the following PC as the base but genuinely PC relative
1623 operands use the current PC. */
1624 if (operand->type == OP_PCREL)
1625 {
1626 const struct mips_pcrel_operand *pcrel_op;
1627
1628 pcrel_op = (const struct mips_pcrel_operand *) operand;
1629 /* The include_isa_bit flag is sufficient to distinguish
1630 branch/jump from other PC relative operands. */
1631 if (pcrel_op->include_isa_bit)
1632 base_pc += length;
1633 }
1634
1635 print_insn_arg (info, &state, opcode, operand, base_pc,
1636 mips_extract_operand (operand, insn));
1637 }
1638 if (*s == 'm' || *s == '+' || *s == '-')
1639 ++s;
1640 break;
1641 }
1642 }
1643 }
1644 \f
1645 /* Print the mips instruction at address MEMADDR in debugged memory,
1646 on using INFO. Returns length of the instruction, in bytes, which is
1647 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1648 this is little-endian code. */
1649
1650 static int
1651 print_insn_mips (bfd_vma memaddr,
1652 int word,
1653 struct disassemble_info *info)
1654 {
1655 #define GET_OP(insn, field) \
1656 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1657 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1658 const fprintf_ftype infprintf = info->fprintf_func;
1659 const struct mips_opcode *op;
1660 static bfd_boolean init = 0;
1661 void *is = info->stream;
1662
1663 /* Build a hash table to shorten the search time. */
1664 if (! init)
1665 {
1666 unsigned int i;
1667
1668 for (i = 0; i <= OP_MASK_OP; i++)
1669 {
1670 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1671 {
1672 if (op->pinfo == INSN_MACRO
1673 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1674 continue;
1675 if (i == GET_OP (op->match, OP))
1676 {
1677 mips_hash[i] = op;
1678 break;
1679 }
1680 }
1681 }
1682
1683 init = 1;
1684 }
1685
1686 info->bytes_per_chunk = INSNLEN;
1687 info->display_endian = info->endian;
1688 info->insn_info_valid = 1;
1689 info->branch_delay_insns = 0;
1690 info->data_size = 0;
1691 info->insn_type = dis_nonbranch;
1692 info->target = 0;
1693 info->target2 = 0;
1694
1695 op = mips_hash[GET_OP (word, OP)];
1696 if (op != NULL)
1697 {
1698 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1699 {
1700 if (op->pinfo != INSN_MACRO
1701 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1702 && (word & op->mask) == op->match)
1703 {
1704 /* We always disassemble the jalx instruction, except for MIPS r6. */
1705 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1706 && (strcmp (op->name, "jalx")
1707 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1708 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
1709 continue;
1710
1711 /* Figure out instruction type and branch delay information. */
1712 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1713 {
1714 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
1715 info->insn_type = dis_jsr;
1716 else
1717 info->insn_type = dis_branch;
1718 info->branch_delay_insns = 1;
1719 }
1720 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1721 | INSN_COND_BRANCH_LIKELY)) != 0)
1722 {
1723 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1724 info->insn_type = dis_condjsr;
1725 else
1726 info->insn_type = dis_condbranch;
1727 info->branch_delay_insns = 1;
1728 }
1729 else if ((op->pinfo & (INSN_STORE_MEMORY
1730 | INSN_LOAD_MEMORY)) != 0)
1731 info->insn_type = dis_dref;
1732
1733 if (!validate_insn_args (op, decode_mips_operand, word))
1734 continue;
1735
1736 infprintf (is, "%s", op->name);
1737 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1738 {
1739 unsigned int uval;
1740
1741 infprintf (is, ".");
1742 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1743 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1744 }
1745
1746 if (op->args[0])
1747 {
1748 infprintf (is, "\t");
1749 print_insn_args (info, op, decode_mips_operand, word,
1750 memaddr, 4);
1751 }
1752
1753 return INSNLEN;
1754 }
1755 }
1756 }
1757 #undef GET_OP
1758
1759 /* Handle undefined instructions. */
1760 info->insn_type = dis_noninsn;
1761 infprintf (is, "0x%x", word);
1762 return INSNLEN;
1763 }
1764 \f
1765 /* Disassemble an operand for a mips16 instruction. */
1766
1767 static void
1768 print_mips16_insn_arg (struct disassemble_info *info,
1769 struct mips_print_arg_state *state,
1770 const struct mips_opcode *opcode,
1771 char type, bfd_vma memaddr,
1772 unsigned insn, bfd_boolean use_extend,
1773 unsigned extend, bfd_boolean is_offset)
1774 {
1775 const fprintf_ftype infprintf = info->fprintf_func;
1776 void *is = info->stream;
1777 const struct mips_operand *operand, *ext_operand;
1778 unsigned int uval;
1779 bfd_vma baseaddr;
1780
1781 if (!use_extend)
1782 extend = 0;
1783
1784 switch (type)
1785 {
1786 case ',':
1787 case '(':
1788 case ')':
1789 infprintf (is, "%c", type);
1790 break;
1791
1792 default:
1793 operand = decode_mips16_operand (type, FALSE);
1794 if (!operand)
1795 {
1796 /* xgettext:c-format */
1797 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1798 opcode->name, opcode->args);
1799 return;
1800 }
1801
1802 if (operand->type == OP_SAVE_RESTORE_LIST)
1803 {
1804 /* Handle this case here because of the complex interation
1805 with the EXTEND opcode. */
1806 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1807 const char *sep;
1808
1809 amask = extend & 0xf;
1810 if (amask == MIPS16_ALL_ARGS)
1811 {
1812 nargs = 4;
1813 nstatics = 0;
1814 }
1815 else if (amask == MIPS16_ALL_STATICS)
1816 {
1817 nargs = 0;
1818 nstatics = 4;
1819 }
1820 else
1821 {
1822 nargs = amask >> 2;
1823 nstatics = amask & 3;
1824 }
1825
1826 sep = "";
1827 if (nargs > 0)
1828 {
1829 infprintf (is, "%s", mips_gpr_names[4]);
1830 if (nargs > 1)
1831 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1832 sep = ",";
1833 }
1834
1835 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1836 if (frame_size == 0 && !use_extend)
1837 frame_size = 128;
1838 infprintf (is, "%s%d", sep, frame_size);
1839
1840 if (insn & 0x40) /* $ra */
1841 infprintf (is, ",%s", mips_gpr_names[31]);
1842
1843 nsreg = (extend >> 8) & 0x7;
1844 smask = 0;
1845 if (insn & 0x20) /* $s0 */
1846 smask |= 1 << 0;
1847 if (insn & 0x10) /* $s1 */
1848 smask |= 1 << 1;
1849 if (nsreg > 0) /* $s2-$s8 */
1850 smask |= ((1 << nsreg) - 1) << 2;
1851
1852 for (i = 0; i < 9; i++)
1853 if (smask & (1 << i))
1854 {
1855 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1856 /* Skip over string of set bits. */
1857 for (j = i; smask & (2 << j); j++)
1858 continue;
1859 if (j > i)
1860 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1861 i = j + 1;
1862 }
1863 /* Statics $ax - $a3. */
1864 if (nstatics == 1)
1865 infprintf (is, ",%s", mips_gpr_names[7]);
1866 else if (nstatics > 0)
1867 infprintf (is, ",%s-%s",
1868 mips_gpr_names[7 - nstatics + 1],
1869 mips_gpr_names[7]);
1870 break;
1871 }
1872
1873 if (is_offset && operand->type == OP_INT)
1874 {
1875 const struct mips_int_operand *int_op;
1876
1877 int_op = (const struct mips_int_operand *) operand;
1878 info->insn_type = dis_dref;
1879 info->data_size = 1 << int_op->shift;
1880 }
1881
1882 if (operand->size == 26)
1883 /* In this case INSN is the first two bytes of the instruction
1884 and EXTEND is the second two bytes. */
1885 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
1886 else
1887 {
1888 /* Calculate the full field value. */
1889 uval = mips_extract_operand (operand, insn);
1890 if (use_extend)
1891 {
1892 ext_operand = decode_mips16_operand (type, TRUE);
1893 if (ext_operand != operand)
1894 {
1895 operand = ext_operand;
1896 if (operand->size == 16)
1897 uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1898 else if (operand->size == 15)
1899 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1900 else
1901 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
1902 }
1903 }
1904 }
1905
1906 baseaddr = memaddr + 2;
1907 if (operand->type == OP_PCREL)
1908 {
1909 const struct mips_pcrel_operand *pcrel_op;
1910
1911 pcrel_op = (const struct mips_pcrel_operand *) operand;
1912 if (!pcrel_op->include_isa_bit && use_extend)
1913 baseaddr = memaddr - 2;
1914 else if (!pcrel_op->include_isa_bit)
1915 {
1916 bfd_byte buffer[2];
1917
1918 /* If this instruction is in the delay slot of a JR
1919 instruction, the base address is the address of the
1920 JR instruction. If it is in the delay slot of a JALR
1921 instruction, the base address is the address of the
1922 JALR instruction. This test is unreliable: we have
1923 no way of knowing whether the previous word is
1924 instruction or data. */
1925 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1926 && (((info->endian == BFD_ENDIAN_BIG
1927 ? bfd_getb16 (buffer)
1928 : bfd_getl16 (buffer))
1929 & 0xf800) == 0x1800))
1930 baseaddr = memaddr - 4;
1931 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1932 info) == 0
1933 && (((info->endian == BFD_ENDIAN_BIG
1934 ? bfd_getb16 (buffer)
1935 : bfd_getl16 (buffer))
1936 & 0xf81f) == 0xe800))
1937 baseaddr = memaddr - 2;
1938 else
1939 baseaddr = memaddr;
1940 }
1941 }
1942
1943 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
1944 break;
1945 }
1946 }
1947
1948
1949 /* Check if the given address is the last word of a MIPS16 PLT entry.
1950 This word is data and depending on the value it may interfere with
1951 disassembly of further PLT entries. We make use of the fact PLT
1952 symbols are marked BSF_SYNTHETIC. */
1953 static bfd_boolean
1954 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
1955 {
1956 if (info->symbols
1957 && info->symbols[0]
1958 && (info->symbols[0]->flags & BSF_SYNTHETIC)
1959 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
1960 return TRUE;
1961
1962 return FALSE;
1963 }
1964
1965 /* Disassemble mips16 instructions. */
1966
1967 static int
1968 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1969 {
1970 const fprintf_ftype infprintf = info->fprintf_func;
1971 int status;
1972 bfd_byte buffer[4];
1973 int length;
1974 int insn;
1975 bfd_boolean use_extend;
1976 int extend = 0;
1977 const struct mips_opcode *op, *opend;
1978 struct mips_print_arg_state state;
1979 void *is = info->stream;
1980
1981 info->bytes_per_chunk = 2;
1982 info->display_endian = info->endian;
1983 info->insn_info_valid = 1;
1984 info->branch_delay_insns = 0;
1985 info->data_size = 0;
1986 info->target = 0;
1987 info->target2 = 0;
1988
1989 #define GET_OP(insn, field) \
1990 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1991 /* Decode PLT entry's GOT slot address word. */
1992 if (is_mips16_plt_tail (info, memaddr))
1993 {
1994 info->insn_type = dis_noninsn;
1995 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
1996 if (status == 0)
1997 {
1998 unsigned int gotslot;
1999
2000 if (info->endian == BFD_ENDIAN_BIG)
2001 gotslot = bfd_getb32 (buffer);
2002 else
2003 gotslot = bfd_getl32 (buffer);
2004 infprintf (is, ".word\t0x%x", gotslot);
2005
2006 return 4;
2007 }
2008 }
2009 else
2010 {
2011 info->insn_type = dis_nonbranch;
2012 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2013 }
2014 if (status != 0)
2015 {
2016 (*info->memory_error_func) (status, memaddr, info);
2017 return -1;
2018 }
2019
2020 length = 2;
2021
2022 if (info->endian == BFD_ENDIAN_BIG)
2023 insn = bfd_getb16 (buffer);
2024 else
2025 insn = bfd_getl16 (buffer);
2026
2027 /* Handle the extend opcode specially. */
2028 use_extend = FALSE;
2029 if ((insn & 0xf800) == 0xf000)
2030 {
2031 use_extend = TRUE;
2032 extend = insn & 0x7ff;
2033
2034 memaddr += 2;
2035
2036 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2037 if (status != 0)
2038 {
2039 infprintf (is, "extend 0x%x", (unsigned int) extend);
2040 (*info->memory_error_func) (status, memaddr, info);
2041 return -1;
2042 }
2043
2044 if (info->endian == BFD_ENDIAN_BIG)
2045 insn = bfd_getb16 (buffer);
2046 else
2047 insn = bfd_getl16 (buffer);
2048
2049 /* Check for an extend opcode followed by an extend opcode. */
2050 if ((insn & 0xf800) == 0xf000)
2051 {
2052 infprintf (is, "extend 0x%x", (unsigned int) extend);
2053 info->insn_type = dis_noninsn;
2054 return length;
2055 }
2056
2057 length += 2;
2058 }
2059
2060 /* FIXME: Should probably use a hash table on the major opcode here. */
2061
2062 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2063 for (op = mips16_opcodes; op < opend; op++)
2064 {
2065 if (op->pinfo != INSN_MACRO
2066 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2067 && (insn & op->mask) == op->match)
2068 {
2069 const char *s;
2070
2071 if (op->args[0] == 'a' || op->args[0] == 'i')
2072 {
2073 if (use_extend)
2074 {
2075 infprintf (is, "extend 0x%x", (unsigned int) extend);
2076 info->insn_type = dis_noninsn;
2077 return length - 2;
2078 }
2079
2080 use_extend = FALSE;
2081
2082 memaddr += 2;
2083
2084 status = (*info->read_memory_func) (memaddr, buffer, 2,
2085 info);
2086 if (status == 0)
2087 {
2088 use_extend = TRUE;
2089 if (info->endian == BFD_ENDIAN_BIG)
2090 extend = bfd_getb16 (buffer);
2091 else
2092 extend = bfd_getl16 (buffer);
2093 length += 2;
2094 }
2095 }
2096
2097 infprintf (is, "%s", op->name);
2098 if (op->args[0] != '\0')
2099 infprintf (is, "\t");
2100
2101 init_print_arg_state (&state);
2102 for (s = op->args; *s != '\0'; s++)
2103 {
2104 if (*s == ','
2105 && s[1] == 'w'
2106 && GET_OP (insn, RX) == GET_OP (insn, RY))
2107 {
2108 /* Skip the register and the comma. */
2109 ++s;
2110 continue;
2111 }
2112 if (*s == ','
2113 && s[1] == 'v'
2114 && GET_OP (insn, RZ) == GET_OP (insn, RX))
2115 {
2116 /* Skip the register and the comma. */
2117 ++s;
2118 continue;
2119 }
2120 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
2121 use_extend, extend, s[1] == '(');
2122 }
2123
2124 /* Figure out branch instruction type and delay slot information. */
2125 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2126 info->branch_delay_insns = 1;
2127 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2128 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2129 {
2130 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2131 info->insn_type = dis_jsr;
2132 else
2133 info->insn_type = dis_branch;
2134 }
2135 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2136 info->insn_type = dis_condbranch;
2137
2138 return length;
2139 }
2140 }
2141 #undef GET_OP
2142
2143 if (use_extend)
2144 infprintf (is, "0x%x", extend | 0xf000);
2145 infprintf (is, "0x%x", insn);
2146 info->insn_type = dis_noninsn;
2147
2148 return length;
2149 }
2150
2151 /* Disassemble microMIPS instructions. */
2152
2153 static int
2154 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2155 {
2156 const fprintf_ftype infprintf = info->fprintf_func;
2157 const struct mips_opcode *op, *opend;
2158 void *is = info->stream;
2159 bfd_byte buffer[2];
2160 unsigned int higher;
2161 unsigned int length;
2162 int status;
2163 unsigned int insn;
2164
2165 info->bytes_per_chunk = 2;
2166 info->display_endian = info->endian;
2167 info->insn_info_valid = 1;
2168 info->branch_delay_insns = 0;
2169 info->data_size = 0;
2170 info->insn_type = dis_nonbranch;
2171 info->target = 0;
2172 info->target2 = 0;
2173
2174 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2175 if (status != 0)
2176 {
2177 (*info->memory_error_func) (status, memaddr, info);
2178 return -1;
2179 }
2180
2181 length = 2;
2182
2183 if (info->endian == BFD_ENDIAN_BIG)
2184 insn = bfd_getb16 (buffer);
2185 else
2186 insn = bfd_getl16 (buffer);
2187
2188 if ((insn & 0xfc00) == 0x7c00)
2189 {
2190 /* This is a 48-bit microMIPS instruction. */
2191 higher = insn;
2192
2193 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2194 if (status != 0)
2195 {
2196 infprintf (is, "micromips 0x%x", higher);
2197 (*info->memory_error_func) (status, memaddr + 2, info);
2198 return -1;
2199 }
2200 if (info->endian == BFD_ENDIAN_BIG)
2201 insn = bfd_getb16 (buffer);
2202 else
2203 insn = bfd_getl16 (buffer);
2204 higher = (higher << 16) | insn;
2205
2206 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
2207 if (status != 0)
2208 {
2209 infprintf (is, "micromips 0x%x", higher);
2210 (*info->memory_error_func) (status, memaddr + 4, info);
2211 return -1;
2212 }
2213 if (info->endian == BFD_ENDIAN_BIG)
2214 insn = bfd_getb16 (buffer);
2215 else
2216 insn = bfd_getl16 (buffer);
2217 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
2218
2219 info->insn_type = dis_noninsn;
2220 return 6;
2221 }
2222 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2223 {
2224 /* This is a 32-bit microMIPS instruction. */
2225 higher = insn;
2226
2227 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2228 if (status != 0)
2229 {
2230 infprintf (is, "micromips 0x%x", higher);
2231 (*info->memory_error_func) (status, memaddr + 2, info);
2232 return -1;
2233 }
2234
2235 if (info->endian == BFD_ENDIAN_BIG)
2236 insn = bfd_getb16 (buffer);
2237 else
2238 insn = bfd_getl16 (buffer);
2239
2240 insn = insn | (higher << 16);
2241
2242 length += 2;
2243 }
2244
2245 /* FIXME: Should probably use a hash table on the major opcode here. */
2246
2247 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2248 for (op = micromips_opcodes; op < opend; op++)
2249 {
2250 if (op->pinfo != INSN_MACRO
2251 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2252 && (insn & op->mask) == op->match
2253 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2254 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2255 {
2256 if (!validate_insn_args (op, decode_micromips_operand, insn))
2257 continue;
2258
2259 infprintf (is, "%s", op->name);
2260
2261 if (op->args[0])
2262 {
2263 infprintf (is, "\t");
2264 print_insn_args (info, op, decode_micromips_operand, insn,
2265 memaddr + 1, length);
2266 }
2267
2268 /* Figure out instruction type and branch delay information. */
2269 if ((op->pinfo
2270 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2271 info->branch_delay_insns = 1;
2272 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2273 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2274 {
2275 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2276 info->insn_type = dis_jsr;
2277 else
2278 info->insn_type = dis_branch;
2279 }
2280 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2281 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2282 {
2283 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2284 info->insn_type = dis_condjsr;
2285 else
2286 info->insn_type = dis_condbranch;
2287 }
2288 else if ((op->pinfo
2289 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2290 info->insn_type = dis_dref;
2291
2292 return length;
2293 }
2294 }
2295
2296 infprintf (is, "0x%x", insn);
2297 info->insn_type = dis_noninsn;
2298
2299 return length;
2300 }
2301
2302 /* Return 1 if a symbol associated with the location being disassembled
2303 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2304 all the symbols at the address being considered assuming if at least
2305 one of them indicates code compression, then such code has been
2306 genuinely produced here (other symbols could have been derived from
2307 function symbols defined elsewhere or could define data). Otherwise,
2308 return 0. */
2309
2310 static bfd_boolean
2311 is_compressed_mode_p (struct disassemble_info *info)
2312 {
2313 int i;
2314 int l;
2315
2316 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2317 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2318 && ((!micromips_ase
2319 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2320 || (micromips_ase
2321 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2322 return 1;
2323 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2324 && info->symtab[i]->section == info->section)
2325 {
2326 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2327 if ((!micromips_ase
2328 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2329 || (micromips_ase
2330 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2331 return 1;
2332 }
2333
2334 return 0;
2335 }
2336
2337 /* In an environment where we do not know the symbol type of the
2338 instruction we are forced to assume that the low order bit of the
2339 instructions' address may mark it as a mips16 instruction. If we
2340 are single stepping, or the pc is within the disassembled function,
2341 this works. Otherwise, we need a clue. Sometimes. */
2342
2343 static int
2344 _print_insn_mips (bfd_vma memaddr,
2345 struct disassemble_info *info,
2346 enum bfd_endian endianness)
2347 {
2348 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
2349 bfd_byte buffer[INSNLEN];
2350 int status;
2351
2352 set_default_mips_dis_options (info);
2353 parse_mips_dis_options (info->disassembler_options);
2354
2355 if (info->mach == bfd_mach_mips16)
2356 return print_insn_mips16 (memaddr, info);
2357 if (info->mach == bfd_mach_mips_micromips)
2358 return print_insn_micromips (memaddr, info);
2359
2360 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
2361
2362 #if 1
2363 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2364 /* Only a few tools will work this way. */
2365 if (memaddr & 0x01)
2366 return print_insn_compr (memaddr, info);
2367 #endif
2368
2369 #if SYMTAB_AVAILABLE
2370 if (is_compressed_mode_p (info))
2371 return print_insn_compr (memaddr, info);
2372 #endif
2373
2374 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2375 if (status == 0)
2376 {
2377 int insn;
2378
2379 if (endianness == BFD_ENDIAN_BIG)
2380 insn = bfd_getb32 (buffer);
2381 else
2382 insn = bfd_getl32 (buffer);
2383
2384 return print_insn_mips (memaddr, insn, info);
2385 }
2386 else
2387 {
2388 (*info->memory_error_func) (status, memaddr, info);
2389 return -1;
2390 }
2391 }
2392
2393 int
2394 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2395 {
2396 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2397 }
2398
2399 int
2400 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2401 {
2402 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2403 }
2404 \f
2405 void
2406 print_mips_disassembler_options (FILE *stream)
2407 {
2408 unsigned int i;
2409
2410 fprintf (stream, _("\n\
2411 The following MIPS specific disassembler options are supported for use\n\
2412 with the -M switch (multiple options should be separated by commas):\n"));
2413
2414 fprintf (stream, _("\n\
2415 msa Recognize MSA instructions.\n"));
2416
2417 fprintf (stream, _("\n\
2418 virt Recognize the virtualization ASE instructions.\n"));
2419
2420 fprintf (stream, _("\n\
2421 xpa Recognize the eXtended Physical Address (XPA) ASE instructions.\n"));
2422
2423 fprintf (stream, _("\n\
2424 gpr-names=ABI Print GPR names according to specified ABI.\n\
2425 Default: based on binary being disassembled.\n"));
2426
2427 fprintf (stream, _("\n\
2428 fpr-names=ABI Print FPR names according to specified ABI.\n\
2429 Default: numeric.\n"));
2430
2431 fprintf (stream, _("\n\
2432 cp0-names=ARCH Print CP0 register names according to\n\
2433 specified architecture.\n\
2434 Default: based on binary being disassembled.\n"));
2435
2436 fprintf (stream, _("\n\
2437 hwr-names=ARCH Print HWR names according to specified \n\
2438 architecture.\n\
2439 Default: based on binary being disassembled.\n"));
2440
2441 fprintf (stream, _("\n\
2442 reg-names=ABI Print GPR and FPR names according to\n\
2443 specified ABI.\n"));
2444
2445 fprintf (stream, _("\n\
2446 reg-names=ARCH Print CP0 register and HWR names according to\n\
2447 specified architecture.\n"));
2448
2449 fprintf (stream, _("\n\
2450 For the options above, the following values are supported for \"ABI\":\n\
2451 "));
2452 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2453 fprintf (stream, " %s", mips_abi_choices[i].name);
2454 fprintf (stream, _("\n"));
2455
2456 fprintf (stream, _("\n\
2457 For the options above, The following values are supported for \"ARCH\":\n\
2458 "));
2459 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2460 if (*mips_arch_choices[i].name != '\0')
2461 fprintf (stream, " %s", mips_arch_choices[i].name);
2462 fprintf (stream, _("\n"));
2463
2464 fprintf (stream, _("\n"));
2465 }
This page took 0.120834 seconds and 5 git commands to generate.