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