Automatic date update in version.in
[binutils-gdb.git] / opcodes / mips-dis.c
blob9db604ffb39f5d2d8d65bfef68334c74f4ee8b8c
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2022 Free Software Foundation, Inc.
3 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
5 This file is part of the GNU opcodes library.
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.
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.
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. */
22 #include "sysdep.h"
23 #include "disassemble.h"
24 #include "libiberty.h"
25 #include "opcode/mips.h"
26 #include "opintl.h"
27 #include "elf-bfd.h"
28 #include "elf/mips.h"
29 #include "elfxx-mips.h"
31 /* FIXME: These are needed to figure out if the code is mips16 or
32 not. The low bit of the address is often a good indicator. No
33 symbol table is available when this code runs out in an embedded
34 system as when it is used for disassembler support in a monitor. */
36 #if !defined(EMBEDDED_ENV)
37 #define SYMTAB_AVAILABLE 1
38 #endif
40 /* Mips instructions are at maximum this many bytes long. */
41 #define INSNLEN 4
44 /* FIXME: These should be shared with gdb somehow. */
46 struct mips_cp0sel_name
48 unsigned int cp0reg;
49 unsigned int sel;
50 const char * const name;
53 static const char * const mips_gpr_names_numeric[32] =
55 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
56 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
57 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
58 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
61 static const char * const mips_gpr_names_oldabi[32] =
63 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
64 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
65 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
66 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
69 static const char * const mips_gpr_names_newabi[32] =
71 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
72 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
73 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
74 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
77 static const char * const mips_fpr_names_numeric[32] =
79 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
80 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
81 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
82 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
85 static const char * const mips_fpr_names_32[32] =
87 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
88 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
89 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
90 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
93 static const char * const mips_fpr_names_n32[32] =
95 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
96 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
97 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
98 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
101 static const char * const mips_fpr_names_64[32] =
103 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
104 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
105 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
106 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
109 static const char * const mips_cp0_names_numeric[32] =
111 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
112 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
113 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
114 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
117 static const char * const mips_cp1_names_numeric[32] =
119 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
120 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
121 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
122 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
125 static const char * const mips_cp0_names_r3900[32] =
127 "$0", "$1", "$2", "c0_config",
128 "$4", "$5", "$6", "c0_cache",
129 "c0_badvaddr", "$9", "$10", "$11",
130 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
131 "c0_debug", "c0_depc", "$18", "$19",
132 "$20", "$21", "$22", "$23",
133 "$24", "$25", "$26", "$27",
134 "$28", "$29", "$30", "$31",
137 static const char * const mips_cp0_names_r3000[32] =
139 "c0_index", "c0_random", "c0_entrylo", "$3",
140 "c0_context", "$5", "$6", "$7",
141 "c0_badvaddr", "$9", "c0_entryhi", "$11",
142 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
143 "$16", "$17", "$18", "$19",
144 "$20", "$21", "$22", "$23",
145 "$24", "$25", "$26", "$27",
146 "$28", "$29", "$30", "$31",
149 static const char * const mips_cp0_names_r4000[32] =
151 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
152 "c0_context", "c0_pagemask", "c0_wired", "$7",
153 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
154 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
155 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
156 "c0_xcontext", "$21", "$22", "$23",
157 "$24", "$25", "c0_ecc", "c0_cacheerr",
158 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
161 static const char * const mips_cp0_names_r5900[32] =
163 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
164 "c0_context", "c0_pagemask", "c0_wired", "$7",
165 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
166 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
167 "c0_config", "$17", "$18", "$19",
168 "$20", "$21", "$22", "c0_badpaddr",
169 "c0_depc", "c0_perfcnt", "$26", "$27",
170 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
173 static const char * const mips_cp0_names_mips3264[32] =
175 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
176 "c0_context", "c0_pagemask", "c0_wired", "$7",
177 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
178 "c0_status", "c0_cause", "c0_epc", "c0_prid",
179 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
180 "c0_xcontext", "$21", "$22", "c0_debug",
181 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
182 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
185 static const char * const mips_cp1_names_mips[32] =
187 "c1_fir", "$1", "$2", "$3",
188 "$4", "$5", "$6", "$7",
189 "$8", "$9", "$10", "$11",
190 "$12", "$13", "$14", "$15",
191 "$16", "$17", "$18", "$19",
192 "$20", "$21", "$22", "$23",
193 "$24", "$25", "$26", "$27",
194 "$28", "$29", "$30", "c1_fcsr"
197 static const char * const mips_cp1_names_mips3264[32] =
199 "c1_fir", "c1_ufr", "$2", "$3",
200 "c1_unfr", "$5", "$6", "$7",
201 "$8", "$9", "$10", "$11",
202 "$12", "$13", "$14", "$15",
203 "$16", "$17", "$18", "$19",
204 "$20", "$21", "$22", "$23",
205 "$24", "c1_fccr", "c1_fexr", "$27",
206 "c1_fenr", "$29", "$30", "c1_fcsr"
209 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
211 { 16, 1, "c0_config1" },
212 { 16, 2, "c0_config2" },
213 { 16, 3, "c0_config3" },
214 { 18, 1, "c0_watchlo,1" },
215 { 18, 2, "c0_watchlo,2" },
216 { 18, 3, "c0_watchlo,3" },
217 { 18, 4, "c0_watchlo,4" },
218 { 18, 5, "c0_watchlo,5" },
219 { 18, 6, "c0_watchlo,6" },
220 { 18, 7, "c0_watchlo,7" },
221 { 19, 1, "c0_watchhi,1" },
222 { 19, 2, "c0_watchhi,2" },
223 { 19, 3, "c0_watchhi,3" },
224 { 19, 4, "c0_watchhi,4" },
225 { 19, 5, "c0_watchhi,5" },
226 { 19, 6, "c0_watchhi,6" },
227 { 19, 7, "c0_watchhi,7" },
228 { 25, 1, "c0_perfcnt,1" },
229 { 25, 2, "c0_perfcnt,2" },
230 { 25, 3, "c0_perfcnt,3" },
231 { 25, 4, "c0_perfcnt,4" },
232 { 25, 5, "c0_perfcnt,5" },
233 { 25, 6, "c0_perfcnt,6" },
234 { 25, 7, "c0_perfcnt,7" },
235 { 27, 1, "c0_cacheerr,1" },
236 { 27, 2, "c0_cacheerr,2" },
237 { 27, 3, "c0_cacheerr,3" },
238 { 28, 1, "c0_datalo" },
239 { 29, 1, "c0_datahi" }
242 static const char * const mips_cp0_names_mips3264r2[32] =
244 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
245 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
246 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
247 "c0_status", "c0_cause", "c0_epc", "c0_prid",
248 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
249 "c0_xcontext", "$21", "$22", "c0_debug",
250 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
251 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
254 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
256 { 4, 1, "c0_contextconfig" },
257 { 0, 1, "c0_mvpcontrol" },
258 { 0, 2, "c0_mvpconf0" },
259 { 0, 3, "c0_mvpconf1" },
260 { 1, 1, "c0_vpecontrol" },
261 { 1, 2, "c0_vpeconf0" },
262 { 1, 3, "c0_vpeconf1" },
263 { 1, 4, "c0_yqmask" },
264 { 1, 5, "c0_vpeschedule" },
265 { 1, 6, "c0_vpeschefback" },
266 { 2, 1, "c0_tcstatus" },
267 { 2, 2, "c0_tcbind" },
268 { 2, 3, "c0_tcrestart" },
269 { 2, 4, "c0_tchalt" },
270 { 2, 5, "c0_tccontext" },
271 { 2, 6, "c0_tcschedule" },
272 { 2, 7, "c0_tcschefback" },
273 { 5, 1, "c0_pagegrain" },
274 { 6, 1, "c0_srsconf0" },
275 { 6, 2, "c0_srsconf1" },
276 { 6, 3, "c0_srsconf2" },
277 { 6, 4, "c0_srsconf3" },
278 { 6, 5, "c0_srsconf4" },
279 { 12, 1, "c0_intctl" },
280 { 12, 2, "c0_srsctl" },
281 { 12, 3, "c0_srsmap" },
282 { 15, 1, "c0_ebase" },
283 { 16, 1, "c0_config1" },
284 { 16, 2, "c0_config2" },
285 { 16, 3, "c0_config3" },
286 { 18, 1, "c0_watchlo,1" },
287 { 18, 2, "c0_watchlo,2" },
288 { 18, 3, "c0_watchlo,3" },
289 { 18, 4, "c0_watchlo,4" },
290 { 18, 5, "c0_watchlo,5" },
291 { 18, 6, "c0_watchlo,6" },
292 { 18, 7, "c0_watchlo,7" },
293 { 19, 1, "c0_watchhi,1" },
294 { 19, 2, "c0_watchhi,2" },
295 { 19, 3, "c0_watchhi,3" },
296 { 19, 4, "c0_watchhi,4" },
297 { 19, 5, "c0_watchhi,5" },
298 { 19, 6, "c0_watchhi,6" },
299 { 19, 7, "c0_watchhi,7" },
300 { 23, 1, "c0_tracecontrol" },
301 { 23, 2, "c0_tracecontrol2" },
302 { 23, 3, "c0_usertracedata" },
303 { 23, 4, "c0_tracebpc" },
304 { 25, 1, "c0_perfcnt,1" },
305 { 25, 2, "c0_perfcnt,2" },
306 { 25, 3, "c0_perfcnt,3" },
307 { 25, 4, "c0_perfcnt,4" },
308 { 25, 5, "c0_perfcnt,5" },
309 { 25, 6, "c0_perfcnt,6" },
310 { 25, 7, "c0_perfcnt,7" },
311 { 27, 1, "c0_cacheerr,1" },
312 { 27, 2, "c0_cacheerr,2" },
313 { 27, 3, "c0_cacheerr,3" },
314 { 28, 1, "c0_datalo" },
315 { 28, 2, "c0_taglo1" },
316 { 28, 3, "c0_datalo1" },
317 { 28, 4, "c0_taglo2" },
318 { 28, 5, "c0_datalo2" },
319 { 28, 6, "c0_taglo3" },
320 { 28, 7, "c0_datalo3" },
321 { 29, 1, "c0_datahi" },
322 { 29, 2, "c0_taghi1" },
323 { 29, 3, "c0_datahi1" },
324 { 29, 4, "c0_taghi2" },
325 { 29, 5, "c0_datahi2" },
326 { 29, 6, "c0_taghi3" },
327 { 29, 7, "c0_datahi3" },
330 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
331 static const char * const mips_cp0_names_sb1[32] =
333 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
334 "c0_context", "c0_pagemask", "c0_wired", "$7",
335 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
336 "c0_status", "c0_cause", "c0_epc", "c0_prid",
337 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
338 "c0_xcontext", "$21", "$22", "c0_debug",
339 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
340 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
343 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
345 { 16, 1, "c0_config1" },
346 { 18, 1, "c0_watchlo,1" },
347 { 19, 1, "c0_watchhi,1" },
348 { 22, 0, "c0_perftrace" },
349 { 23, 3, "c0_edebug" },
350 { 25, 1, "c0_perfcnt,1" },
351 { 25, 2, "c0_perfcnt,2" },
352 { 25, 3, "c0_perfcnt,3" },
353 { 25, 4, "c0_perfcnt,4" },
354 { 25, 5, "c0_perfcnt,5" },
355 { 25, 6, "c0_perfcnt,6" },
356 { 25, 7, "c0_perfcnt,7" },
357 { 26, 1, "c0_buserr_pa" },
358 { 27, 1, "c0_cacheerr_d" },
359 { 27, 3, "c0_cacheerr_d_pa" },
360 { 28, 1, "c0_datalo_i" },
361 { 28, 2, "c0_taglo_d" },
362 { 28, 3, "c0_datalo_d" },
363 { 29, 1, "c0_datahi_i" },
364 { 29, 2, "c0_taghi_d" },
365 { 29, 3, "c0_datahi_d" },
368 /* Xlr cop0 register names. */
369 static const char * const mips_cp0_names_xlr[32] = {
370 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
371 "c0_context", "c0_pagemask", "c0_wired", "$7",
372 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
373 "c0_status", "c0_cause", "c0_epc", "c0_prid",
374 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
375 "c0_xcontext", "$21", "$22", "c0_debug",
376 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
377 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
380 /* XLR's CP0 Select Registers. */
382 static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
383 { 9, 6, "c0_extintreq" },
384 { 9, 7, "c0_extintmask" },
385 { 15, 1, "c0_ebase" },
386 { 16, 1, "c0_config1" },
387 { 16, 2, "c0_config2" },
388 { 16, 3, "c0_config3" },
389 { 16, 7, "c0_procid2" },
390 { 18, 1, "c0_watchlo,1" },
391 { 18, 2, "c0_watchlo,2" },
392 { 18, 3, "c0_watchlo,3" },
393 { 18, 4, "c0_watchlo,4" },
394 { 18, 5, "c0_watchlo,5" },
395 { 18, 6, "c0_watchlo,6" },
396 { 18, 7, "c0_watchlo,7" },
397 { 19, 1, "c0_watchhi,1" },
398 { 19, 2, "c0_watchhi,2" },
399 { 19, 3, "c0_watchhi,3" },
400 { 19, 4, "c0_watchhi,4" },
401 { 19, 5, "c0_watchhi,5" },
402 { 19, 6, "c0_watchhi,6" },
403 { 19, 7, "c0_watchhi,7" },
404 { 25, 1, "c0_perfcnt,1" },
405 { 25, 2, "c0_perfcnt,2" },
406 { 25, 3, "c0_perfcnt,3" },
407 { 25, 4, "c0_perfcnt,4" },
408 { 25, 5, "c0_perfcnt,5" },
409 { 25, 6, "c0_perfcnt,6" },
410 { 25, 7, "c0_perfcnt,7" },
411 { 27, 1, "c0_cacheerr,1" },
412 { 27, 2, "c0_cacheerr,2" },
413 { 27, 3, "c0_cacheerr,3" },
414 { 28, 1, "c0_datalo" },
415 { 29, 1, "c0_datahi" }
418 static const char * const mips_hwr_names_numeric[32] =
420 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
421 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
422 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
423 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
426 static const char * const mips_hwr_names_mips3264r2[32] =
428 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
429 "$4", "$5", "$6", "$7",
430 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
431 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
432 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
435 static const char * const msa_control_names[32] =
437 "msa_ir", "msa_csr", "msa_access", "msa_save",
438 "msa_modify", "msa_request", "msa_map", "msa_unmap",
439 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
440 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
441 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
444 struct mips_abi_choice
446 const char * name;
447 const char * const *gpr_names;
448 const char * const *fpr_names;
451 struct mips_abi_choice mips_abi_choices[] =
453 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
454 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
455 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
456 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
459 struct mips_arch_choice
461 const char *name;
462 int bfd_mach_valid;
463 unsigned long bfd_mach;
464 int processor;
465 int isa;
466 int ase;
467 const char * const *cp0_names;
468 const struct mips_cp0sel_name *cp0sel_names;
469 unsigned int cp0sel_names_len;
470 const char * const *cp1_names;
471 const char * const *hwr_names;
474 const struct mips_arch_choice mips_arch_choices[] =
476 { "numeric", 0, 0, 0, 0, 0,
477 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
478 mips_hwr_names_numeric },
480 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
481 mips_cp0_names_r3000, NULL, 0, mips_cp1_names_mips,
482 mips_hwr_names_numeric },
483 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
484 mips_cp0_names_r3900, NULL, 0, mips_cp1_names_numeric,
485 mips_hwr_names_numeric },
486 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
487 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_mips,
488 mips_hwr_names_numeric },
489 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
490 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
491 mips_hwr_names_numeric },
492 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
493 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
494 mips_hwr_names_numeric },
495 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
496 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
497 mips_hwr_names_numeric },
498 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
499 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
500 mips_hwr_names_numeric },
501 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
502 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
503 mips_hwr_names_numeric },
504 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
505 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_mips,
506 mips_hwr_names_numeric },
507 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
508 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
509 mips_hwr_names_numeric },
510 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
511 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
512 mips_hwr_names_numeric },
513 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
514 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
515 mips_hwr_names_numeric },
516 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
517 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
518 mips_hwr_names_numeric },
519 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
520 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
521 mips_hwr_names_numeric },
522 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
523 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_mips,
524 mips_hwr_names_numeric },
525 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
526 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
527 mips_hwr_names_numeric },
528 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
529 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
530 mips_hwr_names_numeric },
531 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
532 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
533 mips_hwr_names_numeric },
534 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
535 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
536 mips_hwr_names_numeric },
537 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
538 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
539 mips_hwr_names_numeric },
540 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
541 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
542 mips_hwr_names_numeric },
543 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
544 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
545 mips_hwr_names_numeric },
546 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
547 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
548 mips_hwr_names_numeric },
549 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
550 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
551 mips_hwr_names_numeric },
553 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
554 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
555 _MIPS32 Architecture For Programmers Volume I: Introduction to the
556 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
557 page 1. */
558 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
559 ISA_MIPS32, ASE_SMARTMIPS,
560 mips_cp0_names_mips3264,
561 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
562 mips_cp1_names_mips3264, mips_hwr_names_numeric },
564 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
565 ISA_MIPS32R2,
566 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
567 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
568 mips_cp0_names_mips3264r2,
569 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
570 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
572 { "mips32r3", 1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
573 ISA_MIPS32R3,
574 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
575 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
576 mips_cp0_names_mips3264r2,
577 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
578 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
580 { "mips32r5", 1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
581 ISA_MIPS32R5,
582 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
583 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
584 mips_cp0_names_mips3264r2,
585 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
586 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
588 { "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
589 ISA_MIPS32R6,
590 (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
591 | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC | ASE_GINV),
592 mips_cp0_names_mips3264r2,
593 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
594 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
596 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
597 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
598 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
599 mips_cp0_names_mips3264,
600 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
601 mips_cp1_names_mips3264, mips_hwr_names_numeric },
603 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
604 ISA_MIPS64R2,
605 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
606 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
607 mips_cp0_names_mips3264r2,
608 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
609 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
611 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
612 ISA_MIPS64R3,
613 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
614 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
615 mips_cp0_names_mips3264r2,
616 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
617 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
619 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
620 ISA_MIPS64R5,
621 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
622 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
623 mips_cp0_names_mips3264r2,
624 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
625 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
627 { "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
628 ISA_MIPS64R6,
629 (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
630 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC
631 | ASE_CRC64 | ASE_GINV),
632 mips_cp0_names_mips3264r2,
633 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
634 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
636 { "interaptiv-mr2", 1, bfd_mach_mips_interaptiv_mr2, CPU_INTERAPTIV_MR2,
637 ISA_MIPS32R3,
638 ASE_MT | ASE_EVA | ASE_DSP | ASE_DSPR2 | ASE_MIPS16E2 | ASE_MIPS16E2_MT,
639 mips_cp0_names_mips3264r2,
640 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
641 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
643 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
644 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
645 mips_cp0_names_sb1,
646 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
647 mips_cp1_names_mips3264, mips_hwr_names_numeric },
649 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
650 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
651 NULL, 0, mips_cp1_names_mips, mips_hwr_names_numeric },
653 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
654 ISA_MIPS3 | INSN_LOONGSON_2F, ASE_LOONGSON_MMI, mips_cp0_names_numeric,
655 NULL, 0, mips_cp1_names_mips, mips_hwr_names_numeric },
657 /* The loongson3a is an alias of gs464 for compatibility */
658 { "loongson3a", 1, bfd_mach_mips_gs464, CPU_GS464,
659 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
660 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
661 mips_hwr_names_numeric },
663 { "gs464", 1, bfd_mach_mips_gs464, CPU_GS464,
664 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
665 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
666 mips_hwr_names_numeric },
668 { "gs464e", 1, bfd_mach_mips_gs464e, CPU_GS464E,
669 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
670 | ASE_LOONGSON_EXT2, mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
671 mips_hwr_names_numeric },
673 { "gs264e", 1, bfd_mach_mips_gs264e, CPU_GS264E,
674 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
675 | ASE_LOONGSON_EXT2 | ASE_MSA | ASE_MSA64, mips_cp0_names_numeric, NULL,
676 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
678 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
679 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
680 mips_cp1_names_mips3264, mips_hwr_names_numeric },
682 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
683 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
684 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
686 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
687 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
688 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
690 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
691 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
692 mips_cp0_names_numeric,
693 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
695 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
696 ISA_MIPS64 | INSN_XLR, 0,
697 mips_cp0_names_xlr,
698 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
699 mips_cp1_names_mips3264, mips_hwr_names_numeric },
701 /* XLP is mostly like XLR, with the prominent exception it is being
702 MIPS64R2. */
703 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
704 ISA_MIPS64R2 | INSN_XLR, 0,
705 mips_cp0_names_xlr,
706 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
707 mips_cp1_names_mips3264, mips_hwr_names_numeric },
709 /* This entry, mips16, is here only for ISA/processor selection; do
710 not print its name. */
711 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
712 ASE_MIPS16E2 | ASE_MIPS16E2_MT,
713 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
714 mips_hwr_names_numeric },
717 /* ISA and processor type to disassemble for, and register names to use.
718 set_default_mips_dis_options and parse_mips_dis_options fill in these
719 values. */
720 static int mips_processor;
721 static int mips_isa;
722 static int mips_ase;
723 static int micromips_ase;
724 static const char * const *mips_gpr_names;
725 static const char * const *mips_fpr_names;
726 static const char * const *mips_cp0_names;
727 static const struct mips_cp0sel_name *mips_cp0sel_names;
728 static int mips_cp0sel_names_len;
729 static const char * const *mips_cp1_names;
730 static const char * const *mips_hwr_names;
732 /* Other options */
733 static int no_aliases; /* If set disassemble as most general inst. */
735 static const struct mips_abi_choice *
736 choose_abi_by_name (const char *name, unsigned int namelen)
738 const struct mips_abi_choice *c;
739 unsigned int i;
741 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
742 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
743 && strlen (mips_abi_choices[i].name) == namelen)
744 c = &mips_abi_choices[i];
746 return c;
749 static const struct mips_arch_choice *
750 choose_arch_by_name (const char *name, unsigned int namelen)
752 const struct mips_arch_choice *c = NULL;
753 unsigned int i;
755 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
756 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
757 && strlen (mips_arch_choices[i].name) == namelen)
758 c = &mips_arch_choices[i];
760 return c;
763 static const struct mips_arch_choice *
764 choose_arch_by_number (unsigned long mach)
766 static unsigned long hint_bfd_mach;
767 static const struct mips_arch_choice *hint_arch_choice;
768 const struct mips_arch_choice *c;
769 unsigned int i;
771 /* We optimize this because even if the user specifies no
772 flags, this will be done for every instruction! */
773 if (hint_bfd_mach == mach
774 && hint_arch_choice != NULL
775 && hint_arch_choice->bfd_mach == hint_bfd_mach)
776 return hint_arch_choice;
778 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
780 if (mips_arch_choices[i].bfd_mach_valid
781 && mips_arch_choices[i].bfd_mach == mach)
783 c = &mips_arch_choices[i];
784 hint_bfd_mach = mach;
785 hint_arch_choice = c;
788 return c;
791 /* Check if the object uses NewABI conventions. */
793 static int
794 is_newabi (Elf_Internal_Ehdr *header)
796 /* There are no old-style ABIs which use 64-bit ELF. */
797 if (header->e_ident[EI_CLASS] == ELFCLASS64)
798 return 1;
800 /* If a 32-bit ELF file, n32 is a new-style ABI. */
801 if ((header->e_flags & EF_MIPS_ABI2) != 0)
802 return 1;
804 return 0;
807 /* Check if the object has microMIPS ASE code. */
809 static int
810 is_micromips (Elf_Internal_Ehdr *header)
812 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
813 return 1;
815 return 0;
818 /* Convert ASE flags from .MIPS.abiflags to internal values. */
820 static unsigned long
821 mips_convert_abiflags_ases (unsigned long afl_ases)
823 unsigned long opcode_ases = 0;
825 if (afl_ases & AFL_ASE_DSP)
826 opcode_ases |= ASE_DSP;
827 if (afl_ases & AFL_ASE_DSPR2)
828 opcode_ases |= ASE_DSPR2;
829 if (afl_ases & AFL_ASE_EVA)
830 opcode_ases |= ASE_EVA;
831 if (afl_ases & AFL_ASE_MCU)
832 opcode_ases |= ASE_MCU;
833 if (afl_ases & AFL_ASE_MDMX)
834 opcode_ases |= ASE_MDMX;
835 if (afl_ases & AFL_ASE_MIPS3D)
836 opcode_ases |= ASE_MIPS3D;
837 if (afl_ases & AFL_ASE_MT)
838 opcode_ases |= ASE_MT;
839 if (afl_ases & AFL_ASE_SMARTMIPS)
840 opcode_ases |= ASE_SMARTMIPS;
841 if (afl_ases & AFL_ASE_VIRT)
842 opcode_ases |= ASE_VIRT;
843 if (afl_ases & AFL_ASE_MSA)
844 opcode_ases |= ASE_MSA;
845 if (afl_ases & AFL_ASE_XPA)
846 opcode_ases |= ASE_XPA;
847 if (afl_ases & AFL_ASE_DSPR3)
848 opcode_ases |= ASE_DSPR3;
849 if (afl_ases & AFL_ASE_MIPS16E2)
850 opcode_ases |= ASE_MIPS16E2;
851 return opcode_ases;
854 /* Calculate combination ASE flags from regular ASE flags. */
856 static unsigned long
857 mips_calculate_combination_ases (int opcode_isa, unsigned long opcode_ases)
859 unsigned long combination_ases = 0;
861 if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
862 combination_ases |= ASE_XPA_VIRT;
863 if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
864 combination_ases |= ASE_MIPS16E2_MT;
865 if ((opcode_ases & ASE_EVA)
866 && ((opcode_isa & INSN_ISA_MASK) == ISA_MIPS64R6
867 || (opcode_isa & INSN_ISA_MASK) == ISA_MIPS32R6))
868 combination_ases |= ASE_EVA_R6;
869 return combination_ases;
872 static void
873 set_default_mips_dis_options (struct disassemble_info *info)
875 const struct mips_arch_choice *chosen_arch;
877 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
878 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
879 CP0 register, and HWR names. */
880 mips_isa = ISA_MIPS3;
881 mips_processor = CPU_R3000;
882 micromips_ase = 0;
883 mips_ase = 0;
884 mips_gpr_names = mips_gpr_names_oldabi;
885 mips_fpr_names = mips_fpr_names_numeric;
886 mips_cp0_names = mips_cp0_names_numeric;
887 mips_cp0sel_names = NULL;
888 mips_cp0sel_names_len = 0;
889 mips_cp1_names = mips_cp1_names_numeric;
890 mips_hwr_names = mips_hwr_names_numeric;
891 no_aliases = 0;
893 /* Set ISA, architecture, and cp0 register names as best we can. */
894 #if ! SYMTAB_AVAILABLE
895 /* This is running out on a target machine, not in a host tool.
896 FIXME: Where does mips_target_info come from? */
897 target_processor = mips_target_info.processor;
898 mips_isa = mips_target_info.isa;
899 mips_ase = mips_target_info.ase;
900 #else
901 chosen_arch = choose_arch_by_number (info->mach);
902 if (chosen_arch != NULL)
904 mips_processor = chosen_arch->processor;
905 mips_isa = chosen_arch->isa;
906 mips_ase = chosen_arch->ase;
907 mips_cp0_names = chosen_arch->cp0_names;
908 mips_cp0sel_names = chosen_arch->cp0sel_names;
909 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
910 mips_cp1_names = chosen_arch->cp1_names;
911 mips_hwr_names = chosen_arch->hwr_names;
914 /* Update settings according to the ELF file header flags. */
915 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
917 struct bfd *abfd = info->section->owner;
918 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
919 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
921 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
922 because we won't then have a MIPS/ELF BFD, however we need
923 to guard against a link error in a `--enable-targets=...'
924 configuration with a 32-bit host where the MIPS target is
925 a secondary, or with MIPS/ECOFF configurations. */
926 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
927 abiflags = bfd_mips_elf_get_abiflags (abfd);
928 #endif
929 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
930 if (is_newabi (header))
931 mips_gpr_names = mips_gpr_names_newabi;
932 /* If a microMIPS binary, then don't use MIPS16 bindings. */
933 micromips_ase = is_micromips (header);
934 /* OR in any extra ASE flags set in ELF file structures. */
935 if (abiflags)
936 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
937 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
938 mips_ase |= ASE_MDMX;
940 #endif
941 mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
944 /* Parse an ASE disassembler option and set the corresponding global
945 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
947 static bool
948 parse_mips_ase_option (const char *option)
950 if (startswith (option, "msa"))
952 mips_ase |= ASE_MSA;
953 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
954 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
955 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
956 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
957 mips_ase |= ASE_MSA64;
958 return true;
961 if (startswith (option, "virt"))
963 mips_ase |= ASE_VIRT;
964 if (mips_isa & ISA_MIPS64R2
965 || mips_isa & ISA_MIPS64R3
966 || mips_isa & ISA_MIPS64R5
967 || mips_isa & ISA_MIPS64R6)
968 mips_ase |= ASE_VIRT64;
969 return true;
972 if (startswith (option, "xpa"))
974 mips_ase |= ASE_XPA;
975 return true;
978 if (startswith (option, "ginv"))
980 mips_ase |= ASE_GINV;
981 return true;
984 if (startswith (option, "loongson-mmi"))
986 mips_ase |= ASE_LOONGSON_MMI;
987 return true;
990 if (startswith (option, "loongson-cam"))
992 mips_ase |= ASE_LOONGSON_CAM;
993 return true;
996 /* Put here for match ext2 frist */
997 if (startswith (option, "loongson-ext2"))
999 mips_ase |= ASE_LOONGSON_EXT2;
1000 return true;
1003 if (startswith (option, "loongson-ext"))
1005 mips_ase |= ASE_LOONGSON_EXT;
1006 return true;
1009 return false;
1012 static void
1013 parse_mips_dis_option (const char *option, unsigned int len)
1015 unsigned int i, optionlen, vallen;
1016 const char *val;
1017 const struct mips_abi_choice *chosen_abi;
1018 const struct mips_arch_choice *chosen_arch;
1020 /* Try to match options that are simple flags */
1021 if (startswith (option, "no-aliases"))
1023 no_aliases = 1;
1024 return;
1027 if (parse_mips_ase_option (option))
1029 mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
1030 return;
1033 /* Look for the = that delimits the end of the option name. */
1034 for (i = 0; i < len; i++)
1035 if (option[i] == '=')
1036 break;
1038 if (i == 0) /* Invalid option: no name before '='. */
1039 return;
1040 if (i == len) /* Invalid option: no '='. */
1041 return;
1042 if (i == (len - 1)) /* Invalid option: no value after '='. */
1043 return;
1045 optionlen = i;
1046 val = option + (optionlen + 1);
1047 vallen = len - (optionlen + 1);
1049 if (strncmp ("gpr-names", option, optionlen) == 0
1050 && strlen ("gpr-names") == optionlen)
1052 chosen_abi = choose_abi_by_name (val, vallen);
1053 if (chosen_abi != NULL)
1054 mips_gpr_names = chosen_abi->gpr_names;
1055 return;
1058 if (strncmp ("fpr-names", option, optionlen) == 0
1059 && strlen ("fpr-names") == optionlen)
1061 chosen_abi = choose_abi_by_name (val, vallen);
1062 if (chosen_abi != NULL)
1063 mips_fpr_names = chosen_abi->fpr_names;
1064 return;
1067 if (strncmp ("cp0-names", option, optionlen) == 0
1068 && strlen ("cp0-names") == optionlen)
1070 chosen_arch = choose_arch_by_name (val, vallen);
1071 if (chosen_arch != NULL)
1073 mips_cp0_names = chosen_arch->cp0_names;
1074 mips_cp0sel_names = chosen_arch->cp0sel_names;
1075 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1077 return;
1080 if (strncmp ("cp1-names", option, optionlen) == 0
1081 && strlen ("cp1-names") == optionlen)
1083 chosen_arch = choose_arch_by_name (val, vallen);
1084 if (chosen_arch != NULL)
1085 mips_cp1_names = chosen_arch->cp1_names;
1086 return;
1089 if (strncmp ("hwr-names", option, optionlen) == 0
1090 && strlen ("hwr-names") == optionlen)
1092 chosen_arch = choose_arch_by_name (val, vallen);
1093 if (chosen_arch != NULL)
1094 mips_hwr_names = chosen_arch->hwr_names;
1095 return;
1098 if (strncmp ("reg-names", option, optionlen) == 0
1099 && strlen ("reg-names") == optionlen)
1101 /* We check both ABI and ARCH here unconditionally, so
1102 that "numeric" will do the desirable thing: select
1103 numeric register names for all registers. Other than
1104 that, a given name probably won't match both. */
1105 chosen_abi = choose_abi_by_name (val, vallen);
1106 if (chosen_abi != NULL)
1108 mips_gpr_names = chosen_abi->gpr_names;
1109 mips_fpr_names = chosen_abi->fpr_names;
1111 chosen_arch = choose_arch_by_name (val, vallen);
1112 if (chosen_arch != NULL)
1114 mips_cp0_names = chosen_arch->cp0_names;
1115 mips_cp0sel_names = chosen_arch->cp0sel_names;
1116 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1117 mips_cp1_names = chosen_arch->cp1_names;
1118 mips_hwr_names = chosen_arch->hwr_names;
1120 return;
1123 /* Invalid option. */
1126 static void
1127 parse_mips_dis_options (const char *options)
1129 const char *option_end;
1131 if (options == NULL)
1132 return;
1134 while (*options != '\0')
1136 /* Skip empty options. */
1137 if (*options == ',')
1139 options++;
1140 continue;
1143 /* We know that *options is neither NUL or a comma. */
1144 option_end = options + 1;
1145 while (*option_end != ',' && *option_end != '\0')
1146 option_end++;
1148 parse_mips_dis_option (options, option_end - options);
1150 /* Go on to the next one. If option_end points to a comma, it
1151 will be skipped above. */
1152 options = option_end;
1156 static const struct mips_cp0sel_name *
1157 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1158 unsigned int len,
1159 unsigned int cp0reg,
1160 unsigned int sel)
1162 unsigned int i;
1164 for (i = 0; i < len; i++)
1165 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1166 return &names[i];
1167 return NULL;
1170 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1172 static void
1173 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1174 enum mips_reg_operand_type type, int regno)
1176 switch (type)
1178 case OP_REG_GP:
1179 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1180 break;
1182 case OP_REG_FP:
1183 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1184 break;
1186 case OP_REG_CCC:
1187 if (opcode->pinfo & (FP_D | FP_S))
1188 info->fprintf_func (info->stream, "$fcc%d", regno);
1189 else
1190 info->fprintf_func (info->stream, "$cc%d", regno);
1191 break;
1193 case OP_REG_VEC:
1194 if (opcode->membership & INSN_5400)
1195 info->fprintf_func (info->stream, "$f%d", regno);
1196 else
1197 info->fprintf_func (info->stream, "$v%d", regno);
1198 break;
1200 case OP_REG_ACC:
1201 info->fprintf_func (info->stream, "$ac%d", regno);
1202 break;
1204 case OP_REG_COPRO:
1205 if (opcode->name[strlen (opcode->name) - 1] == '0')
1206 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
1207 else
1208 info->fprintf_func (info->stream, "$%d", regno);
1209 break;
1211 case OP_REG_CONTROL:
1212 if (opcode->name[strlen (opcode->name) - 1] == '1')
1213 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
1214 else
1215 info->fprintf_func (info->stream, "$%d", regno);
1216 break;
1218 case OP_REG_HW:
1219 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1220 break;
1222 case OP_REG_VF:
1223 info->fprintf_func (info->stream, "$vf%d", regno);
1224 break;
1226 case OP_REG_VI:
1227 info->fprintf_func (info->stream, "$vi%d", regno);
1228 break;
1230 case OP_REG_R5900_I:
1231 info->fprintf_func (info->stream, "$I");
1232 break;
1234 case OP_REG_R5900_Q:
1235 info->fprintf_func (info->stream, "$Q");
1236 break;
1238 case OP_REG_R5900_R:
1239 info->fprintf_func (info->stream, "$R");
1240 break;
1242 case OP_REG_R5900_ACC:
1243 info->fprintf_func (info->stream, "$ACC");
1244 break;
1246 case OP_REG_MSA:
1247 info->fprintf_func (info->stream, "$w%d", regno);
1248 break;
1250 case OP_REG_MSA_CTRL:
1251 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1252 break;
1257 /* Used to track the state carried over from previous operands in
1258 an instruction. */
1259 struct mips_print_arg_state {
1260 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1261 where the value is known to be unsigned and small. */
1262 unsigned int last_int;
1264 /* The type and number of the last OP_REG seen. We only use this for
1265 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1266 enum mips_reg_operand_type last_reg_type;
1267 unsigned int last_regno;
1268 unsigned int dest_regno;
1269 unsigned int seen_dest;
1272 /* Initialize STATE for the start of an instruction. */
1274 static inline void
1275 init_print_arg_state (struct mips_print_arg_state *state)
1277 memset (state, 0, sizeof (*state));
1280 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1281 whose value is given by UVAL. */
1283 static void
1284 print_vu0_channel (struct disassemble_info *info,
1285 const struct mips_operand *operand, unsigned int uval)
1287 if (operand->size == 4)
1288 info->fprintf_func (info->stream, "%s%s%s%s",
1289 uval & 8 ? "x" : "",
1290 uval & 4 ? "y" : "",
1291 uval & 2 ? "z" : "",
1292 uval & 1 ? "w" : "");
1293 else if (operand->size == 2)
1294 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1295 else
1296 abort ();
1299 /* Record information about a register operand. */
1301 static void
1302 mips_seen_register (struct mips_print_arg_state *state,
1303 unsigned int regno,
1304 enum mips_reg_operand_type reg_type)
1306 state->last_reg_type = reg_type;
1307 state->last_regno = regno;
1309 if (!state->seen_dest)
1311 state->seen_dest = 1;
1312 state->dest_regno = regno;
1316 /* Print SAVE/RESTORE instruction operands according to the argument
1317 register mask AMASK, the number of static registers saved NSREG,
1318 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1319 and the frame size FRAME_SIZE. */
1321 static void
1322 mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
1323 unsigned int nsreg, unsigned int ra,
1324 unsigned int s0, unsigned int s1,
1325 unsigned int frame_size)
1327 const fprintf_ftype infprintf = info->fprintf_func;
1328 unsigned int nargs, nstatics, smask, i, j;
1329 void *is = info->stream;
1330 const char *sep;
1332 if (amask == MIPS_SVRS_ALL_ARGS)
1334 nargs = 4;
1335 nstatics = 0;
1337 else if (amask == MIPS_SVRS_ALL_STATICS)
1339 nargs = 0;
1340 nstatics = 4;
1342 else
1344 nargs = amask >> 2;
1345 nstatics = amask & 3;
1348 sep = "";
1349 if (nargs > 0)
1351 infprintf (is, "%s", mips_gpr_names[4]);
1352 if (nargs > 1)
1353 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1354 sep = ",";
1357 infprintf (is, "%s%d", sep, frame_size);
1359 if (ra) /* $ra */
1360 infprintf (is, ",%s", mips_gpr_names[31]);
1362 smask = 0;
1363 if (s0) /* $s0 */
1364 smask |= 1 << 0;
1365 if (s1) /* $s1 */
1366 smask |= 1 << 1;
1367 if (nsreg > 0) /* $s2-$s8 */
1368 smask |= ((1 << nsreg) - 1) << 2;
1370 for (i = 0; i < 9; i++)
1371 if (smask & (1 << i))
1373 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1374 /* Skip over string of set bits. */
1375 for (j = i; smask & (2 << j); j++)
1376 continue;
1377 if (j > i)
1378 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1379 i = j + 1;
1381 /* Statics $ax - $a3. */
1382 if (nstatics == 1)
1383 infprintf (is, ",%s", mips_gpr_names[7]);
1384 else if (nstatics > 0)
1385 infprintf (is, ",%s-%s",
1386 mips_gpr_names[7 - nstatics + 1],
1387 mips_gpr_names[7]);
1391 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1392 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1393 the base address for OP_PCREL operands. */
1395 static void
1396 print_insn_arg (struct disassemble_info *info,
1397 struct mips_print_arg_state *state,
1398 const struct mips_opcode *opcode,
1399 const struct mips_operand *operand,
1400 bfd_vma base_pc,
1401 unsigned int uval)
1403 const fprintf_ftype infprintf = info->fprintf_func;
1404 void *is = info->stream;
1406 switch (operand->type)
1408 case OP_INT:
1410 const struct mips_int_operand *int_op;
1412 int_op = (const struct mips_int_operand *) operand;
1413 uval = mips_decode_int_operand (int_op, uval);
1414 state->last_int = uval;
1415 if (int_op->print_hex)
1416 infprintf (is, "0x%x", uval);
1417 else
1418 infprintf (is, "%d", uval);
1420 break;
1422 case OP_MAPPED_INT:
1424 const struct mips_mapped_int_operand *mint_op;
1426 mint_op = (const struct mips_mapped_int_operand *) operand;
1427 uval = mint_op->int_map[uval];
1428 state->last_int = uval;
1429 if (mint_op->print_hex)
1430 infprintf (is, "0x%x", uval);
1431 else
1432 infprintf (is, "%d", uval);
1434 break;
1436 case OP_MSB:
1438 const struct mips_msb_operand *msb_op;
1440 msb_op = (const struct mips_msb_operand *) operand;
1441 uval += msb_op->bias;
1442 if (msb_op->add_lsb)
1443 uval -= state->last_int;
1444 infprintf (is, "0x%x", uval);
1446 break;
1448 case OP_REG:
1449 case OP_OPTIONAL_REG:
1451 const struct mips_reg_operand *reg_op;
1453 reg_op = (const struct mips_reg_operand *) operand;
1454 uval = mips_decode_reg_operand (reg_op, uval);
1455 print_reg (info, opcode, reg_op->reg_type, uval);
1457 mips_seen_register (state, uval, reg_op->reg_type);
1459 break;
1461 case OP_REG_PAIR:
1463 const struct mips_reg_pair_operand *pair_op;
1465 pair_op = (const struct mips_reg_pair_operand *) operand;
1466 print_reg (info, opcode, pair_op->reg_type,
1467 pair_op->reg1_map[uval]);
1468 infprintf (is, ",");
1469 print_reg (info, opcode, pair_op->reg_type,
1470 pair_op->reg2_map[uval]);
1472 break;
1474 case OP_PCREL:
1476 const struct mips_pcrel_operand *pcrel_op;
1478 pcrel_op = (const struct mips_pcrel_operand *) operand;
1479 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1481 /* For jumps and branches clear the ISA bit except for
1482 the GDB disassembler. */
1483 if (pcrel_op->include_isa_bit
1484 && info->flavour != bfd_target_unknown_flavour)
1485 info->target &= -2;
1487 (*info->print_address_func) (info->target, info);
1489 break;
1491 case OP_PERF_REG:
1492 infprintf (is, "%d", uval);
1493 break;
1495 case OP_ADDIUSP_INT:
1497 int sval;
1499 sval = mips_signed_operand (operand, uval) * 4;
1500 if (sval >= -8 && sval < 8)
1501 sval ^= 0x400;
1502 infprintf (is, "%d", sval);
1503 break;
1506 case OP_CLO_CLZ_DEST:
1508 unsigned int reg1, reg2;
1510 reg1 = uval & 31;
1511 reg2 = uval >> 5;
1512 /* If one is zero use the other. */
1513 if (reg1 == reg2 || reg2 == 0)
1514 infprintf (is, "%s", mips_gpr_names[reg1]);
1515 else if (reg1 == 0)
1516 infprintf (is, "%s", mips_gpr_names[reg2]);
1517 else
1518 /* Bogus, result depends on processor. */
1519 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1520 mips_gpr_names[reg2]);
1522 break;
1524 case OP_SAME_RS_RT:
1525 case OP_CHECK_PREV:
1526 case OP_NON_ZERO_REG:
1528 print_reg (info, opcode, OP_REG_GP, uval & 31);
1529 mips_seen_register (state, uval, OP_REG_GP);
1531 break;
1533 case OP_LWM_SWM_LIST:
1534 if (operand->size == 2)
1536 if (uval == 0)
1537 infprintf (is, "%s,%s",
1538 mips_gpr_names[16],
1539 mips_gpr_names[31]);
1540 else
1541 infprintf (is, "%s-%s,%s",
1542 mips_gpr_names[16],
1543 mips_gpr_names[16 + uval],
1544 mips_gpr_names[31]);
1546 else
1548 int s_reg_encode;
1550 s_reg_encode = uval & 0xf;
1551 if (s_reg_encode != 0)
1553 if (s_reg_encode == 1)
1554 infprintf (is, "%s", mips_gpr_names[16]);
1555 else if (s_reg_encode < 9)
1556 infprintf (is, "%s-%s",
1557 mips_gpr_names[16],
1558 mips_gpr_names[15 + s_reg_encode]);
1559 else if (s_reg_encode == 9)
1560 infprintf (is, "%s-%s,%s",
1561 mips_gpr_names[16],
1562 mips_gpr_names[23],
1563 mips_gpr_names[30]);
1564 else
1565 infprintf (is, "UNKNOWN");
1568 if (uval & 0x10) /* For ra. */
1570 if (s_reg_encode == 0)
1571 infprintf (is, "%s", mips_gpr_names[31]);
1572 else
1573 infprintf (is, ",%s", mips_gpr_names[31]);
1576 break;
1578 case OP_ENTRY_EXIT_LIST:
1580 const char *sep;
1581 unsigned int amask, smask;
1583 sep = "";
1584 amask = (uval >> 3) & 7;
1585 if (amask > 0 && amask < 5)
1587 infprintf (is, "%s", mips_gpr_names[4]);
1588 if (amask > 1)
1589 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1590 sep = ",";
1593 smask = (uval >> 1) & 3;
1594 if (smask == 3)
1596 infprintf (is, "%s??", sep);
1597 sep = ",";
1599 else if (smask > 0)
1601 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1602 if (smask > 1)
1603 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1604 sep = ",";
1607 if (uval & 1)
1609 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1610 sep = ",";
1613 if (amask == 5 || amask == 6)
1615 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1616 if (amask == 6)
1617 infprintf (is, "-%s", mips_fpr_names[1]);
1620 break;
1622 case OP_SAVE_RESTORE_LIST:
1623 /* Should be handled by the caller due to complex behavior. */
1624 abort ();
1626 case OP_MDMX_IMM_REG:
1628 unsigned int vsel;
1630 vsel = uval >> 5;
1631 uval &= 31;
1632 if ((vsel & 0x10) == 0)
1634 int fmt;
1636 vsel &= 0x0f;
1637 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1638 if ((vsel & 1) == 0)
1639 break;
1640 print_reg (info, opcode, OP_REG_VEC, uval);
1641 infprintf (is, "[%d]", vsel >> 1);
1643 else if ((vsel & 0x08) == 0)
1644 print_reg (info, opcode, OP_REG_VEC, uval);
1645 else
1646 infprintf (is, "0x%x", uval);
1648 break;
1650 case OP_REPEAT_PREV_REG:
1651 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1652 break;
1654 case OP_REPEAT_DEST_REG:
1655 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1656 break;
1658 case OP_PC:
1659 infprintf (is, "$pc");
1660 break;
1662 case OP_REG28:
1663 print_reg (info, opcode, OP_REG_GP, 28);
1664 break;
1666 case OP_VU0_SUFFIX:
1667 case OP_VU0_MATCH_SUFFIX:
1668 print_vu0_channel (info, operand, uval);
1669 break;
1671 case OP_IMM_INDEX:
1672 infprintf (is, "[%d]", uval);
1673 break;
1675 case OP_REG_INDEX:
1676 infprintf (is, "[");
1677 print_reg (info, opcode, OP_REG_GP, uval);
1678 infprintf (is, "]");
1679 break;
1683 /* Validate the arguments for INSN, which is described by OPCODE.
1684 Use DECODE_OPERAND to get the encoding of each operand. */
1686 static bool
1687 validate_insn_args (const struct mips_opcode *opcode,
1688 const struct mips_operand *(*decode_operand) (const char *),
1689 unsigned int insn)
1691 struct mips_print_arg_state state;
1692 const struct mips_operand *operand;
1693 const char *s;
1694 unsigned int uval;
1696 init_print_arg_state (&state);
1697 for (s = opcode->args; *s; ++s)
1699 switch (*s)
1701 case ',':
1702 case '(':
1703 case ')':
1704 break;
1706 case '#':
1707 ++s;
1708 break;
1710 default:
1711 operand = decode_operand (s);
1713 if (operand)
1715 uval = mips_extract_operand (operand, insn);
1716 switch (operand->type)
1718 case OP_REG:
1719 case OP_OPTIONAL_REG:
1721 const struct mips_reg_operand *reg_op;
1723 reg_op = (const struct mips_reg_operand *) operand;
1724 uval = mips_decode_reg_operand (reg_op, uval);
1725 mips_seen_register (&state, uval, reg_op->reg_type);
1727 break;
1729 case OP_SAME_RS_RT:
1731 unsigned int reg1, reg2;
1733 reg1 = uval & 31;
1734 reg2 = uval >> 5;
1736 if (reg1 != reg2 || reg1 == 0)
1737 return false;
1739 break;
1741 case OP_CHECK_PREV:
1743 const struct mips_check_prev_operand *prev_op;
1745 prev_op = (const struct mips_check_prev_operand *) operand;
1747 if (!prev_op->zero_ok && uval == 0)
1748 return false;
1750 if (((prev_op->less_than_ok && uval < state.last_regno)
1751 || (prev_op->greater_than_ok && uval > state.last_regno)
1752 || (prev_op->equal_ok && uval == state.last_regno)))
1753 break;
1755 return false;
1758 case OP_NON_ZERO_REG:
1760 if (uval == 0)
1761 return false;
1763 break;
1765 case OP_INT:
1766 case OP_MAPPED_INT:
1767 case OP_MSB:
1768 case OP_REG_PAIR:
1769 case OP_PCREL:
1770 case OP_PERF_REG:
1771 case OP_ADDIUSP_INT:
1772 case OP_CLO_CLZ_DEST:
1773 case OP_LWM_SWM_LIST:
1774 case OP_ENTRY_EXIT_LIST:
1775 case OP_MDMX_IMM_REG:
1776 case OP_REPEAT_PREV_REG:
1777 case OP_REPEAT_DEST_REG:
1778 case OP_PC:
1779 case OP_REG28:
1780 case OP_VU0_SUFFIX:
1781 case OP_VU0_MATCH_SUFFIX:
1782 case OP_IMM_INDEX:
1783 case OP_REG_INDEX:
1784 case OP_SAVE_RESTORE_LIST:
1785 break;
1788 if (*s == 'm' || *s == '+' || *s == '-')
1789 ++s;
1792 return true;
1795 /* Print the arguments for INSN, which is described by OPCODE.
1796 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1797 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1798 operand is for a branch or jump. */
1800 static void
1801 print_insn_args (struct disassemble_info *info,
1802 const struct mips_opcode *opcode,
1803 const struct mips_operand *(*decode_operand) (const char *),
1804 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1806 const fprintf_ftype infprintf = info->fprintf_func;
1807 void *is = info->stream;
1808 struct mips_print_arg_state state;
1809 const struct mips_operand *operand;
1810 const char *s;
1812 init_print_arg_state (&state);
1813 for (s = opcode->args; *s; ++s)
1815 switch (*s)
1817 case ',':
1818 case '(':
1819 case ')':
1820 infprintf (is, "%c", *s);
1821 break;
1823 case '#':
1824 ++s;
1825 infprintf (is, "%c%c", *s, *s);
1826 break;
1828 default:
1829 operand = decode_operand (s);
1830 if (!operand)
1832 /* xgettext:c-format */
1833 infprintf (is,
1834 _("# internal error, undefined operand in `%s %s'"),
1835 opcode->name, opcode->args);
1836 return;
1839 if (operand->type == OP_SAVE_RESTORE_LIST)
1841 /* Handle this case here because of the complex behavior. */
1842 unsigned int amask = (insn >> 15) & 0xf;
1843 unsigned int nsreg = (insn >> 23) & 0x7;
1844 unsigned int ra = insn & 0x1000; /* $ra */
1845 unsigned int s0 = insn & 0x800; /* $s0 */
1846 unsigned int s1 = insn & 0x400; /* $s1 */
1847 unsigned int frame_size = (((insn >> 15) & 0xf0)
1848 | ((insn >> 6) & 0x0f)) * 8;
1849 mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1850 frame_size);
1852 else if (operand->type == OP_REG
1853 && s[1] == ','
1854 && s[2] == 'H'
1855 && opcode->name[strlen (opcode->name) - 1] == '0')
1857 /* Coprocessor register 0 with sel field. */
1858 const struct mips_cp0sel_name *n;
1859 unsigned int reg, sel;
1861 reg = mips_extract_operand (operand, insn);
1862 s += 2;
1863 operand = decode_operand (s);
1864 sel = mips_extract_operand (operand, insn);
1866 /* CP0 register including 'sel' code for mftc0, to be
1867 printed textually if known. If not known, print both
1868 CP0 register name and sel numerically since CP0 register
1869 with sel 0 may have a name unrelated to register being
1870 printed. */
1871 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1872 mips_cp0sel_names_len,
1873 reg, sel);
1874 if (n != NULL)
1875 infprintf (is, "%s", n->name);
1876 else
1877 infprintf (is, "$%d,%d", reg, sel);
1879 else
1881 bfd_vma base_pc = insn_pc;
1883 /* Adjust the PC relative base so that branch/jump insns use
1884 the following PC as the base but genuinely PC relative
1885 operands use the current PC. */
1886 if (operand->type == OP_PCREL)
1888 const struct mips_pcrel_operand *pcrel_op;
1890 pcrel_op = (const struct mips_pcrel_operand *) operand;
1891 /* The include_isa_bit flag is sufficient to distinguish
1892 branch/jump from other PC relative operands. */
1893 if (pcrel_op->include_isa_bit)
1894 base_pc += length;
1897 print_insn_arg (info, &state, opcode, operand, base_pc,
1898 mips_extract_operand (operand, insn));
1900 if (*s == 'm' || *s == '+' || *s == '-')
1901 ++s;
1902 break;
1907 /* Print the mips instruction at address MEMADDR in debugged memory,
1908 on using INFO. Returns length of the instruction, in bytes, which is
1909 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1910 this is little-endian code. */
1912 static int
1913 print_insn_mips (bfd_vma memaddr,
1914 int word,
1915 struct disassemble_info *info)
1917 #define GET_OP(insn, field) \
1918 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1919 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1920 const fprintf_ftype infprintf = info->fprintf_func;
1921 const struct mips_opcode *op;
1922 static bool init = 0;
1923 void *is = info->stream;
1925 /* Build a hash table to shorten the search time. */
1926 if (! init)
1928 unsigned int i;
1930 for (i = 0; i <= OP_MASK_OP; i++)
1932 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1934 if (op->pinfo == INSN_MACRO
1935 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1936 continue;
1937 if (i == GET_OP (op->match, OP))
1939 mips_hash[i] = op;
1940 break;
1945 init = 1;
1948 info->bytes_per_chunk = INSNLEN;
1949 info->display_endian = info->endian;
1950 info->insn_info_valid = 1;
1951 info->branch_delay_insns = 0;
1952 info->data_size = 0;
1953 info->insn_type = dis_nonbranch;
1954 info->target = 0;
1955 info->target2 = 0;
1957 op = mips_hash[GET_OP (word, OP)];
1958 if (op != NULL)
1960 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1962 if (op->pinfo != INSN_MACRO
1963 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1964 && (word & op->mask) == op->match)
1966 /* We always disassemble the jalx instruction, except for MIPS r6. */
1967 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1968 && (strcmp (op->name, "jalx")
1969 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1970 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
1971 continue;
1973 /* Figure out instruction type and branch delay information. */
1974 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1976 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
1977 info->insn_type = dis_jsr;
1978 else
1979 info->insn_type = dis_branch;
1980 info->branch_delay_insns = 1;
1982 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1983 | INSN_COND_BRANCH_LIKELY)) != 0)
1985 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1986 info->insn_type = dis_condjsr;
1987 else
1988 info->insn_type = dis_condbranch;
1989 info->branch_delay_insns = 1;
1991 else if ((op->pinfo & (INSN_STORE_MEMORY
1992 | INSN_LOAD_MEMORY)) != 0)
1993 info->insn_type = dis_dref;
1995 if (!validate_insn_args (op, decode_mips_operand, word))
1996 continue;
1998 infprintf (is, "%s", op->name);
1999 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
2001 unsigned int uval;
2003 infprintf (is, ".");
2004 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
2005 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
2008 if (op->args[0])
2010 infprintf (is, "\t");
2011 print_insn_args (info, op, decode_mips_operand, word,
2012 memaddr, 4);
2015 return INSNLEN;
2019 #undef GET_OP
2021 /* Handle undefined instructions. */
2022 info->insn_type = dis_noninsn;
2023 infprintf (is, "0x%x", word);
2024 return INSNLEN;
2027 /* Disassemble an operand for a mips16 instruction. */
2029 static void
2030 print_mips16_insn_arg (struct disassemble_info *info,
2031 struct mips_print_arg_state *state,
2032 const struct mips_opcode *opcode,
2033 char type, bfd_vma memaddr,
2034 unsigned insn, bool use_extend,
2035 unsigned extend, bool is_offset)
2037 const fprintf_ftype infprintf = info->fprintf_func;
2038 void *is = info->stream;
2039 const struct mips_operand *operand, *ext_operand;
2040 unsigned short ext_size;
2041 unsigned int uval;
2042 bfd_vma baseaddr;
2044 if (!use_extend)
2045 extend = 0;
2047 switch (type)
2049 case ',':
2050 case '(':
2051 case ')':
2052 infprintf (is, "%c", type);
2053 break;
2055 default:
2056 operand = decode_mips16_operand (type, false);
2057 if (!operand)
2059 /* xgettext:c-format */
2060 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
2061 opcode->name, opcode->args);
2062 return;
2065 if (operand->type == OP_SAVE_RESTORE_LIST)
2067 /* Handle this case here because of the complex interaction
2068 with the EXTEND opcode. */
2069 unsigned int amask = extend & 0xf;
2070 unsigned int nsreg = (extend >> 8) & 0x7;
2071 unsigned int ra = insn & 0x40; /* $ra */
2072 unsigned int s0 = insn & 0x20; /* $s0 */
2073 unsigned int s1 = insn & 0x10; /* $s1 */
2074 unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
2075 if (frame_size == 0 && !use_extend)
2076 frame_size = 128;
2077 mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
2078 break;
2081 if (is_offset && operand->type == OP_INT)
2083 const struct mips_int_operand *int_op;
2085 int_op = (const struct mips_int_operand *) operand;
2086 info->insn_type = dis_dref;
2087 info->data_size = 1 << int_op->shift;
2090 ext_size = 0;
2091 if (use_extend)
2093 ext_operand = decode_mips16_operand (type, true);
2094 if (ext_operand != operand
2095 || (operand->type == OP_INT && operand->lsb == 0
2096 && mips_opcode_32bit_p (opcode)))
2098 ext_size = ext_operand->size;
2099 operand = ext_operand;
2102 if (operand->size == 26)
2103 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
2104 else if (ext_size == 16 || ext_size == 9)
2105 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2106 else if (ext_size == 15)
2107 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2108 else if (ext_size == 6)
2109 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2110 else
2111 uval = mips_extract_operand (operand, (extend << 16) | insn);
2112 if (ext_size == 9)
2113 uval &= (1U << ext_size) - 1;
2115 baseaddr = memaddr + 2;
2116 if (operand->type == OP_PCREL)
2118 const struct mips_pcrel_operand *pcrel_op;
2120 pcrel_op = (const struct mips_pcrel_operand *) operand;
2121 if (!pcrel_op->include_isa_bit && use_extend)
2122 baseaddr = memaddr - 2;
2123 else if (!pcrel_op->include_isa_bit)
2125 bfd_byte buffer[2];
2127 /* If this instruction is in the delay slot of a JAL/JALX
2128 instruction, the base address is the address of the
2129 JAL/JALX instruction. If it is in the delay slot of
2130 a JR/JALR instruction, the base address is the address
2131 of the JR/JALR instruction. This test is unreliable:
2132 we have no way of knowing whether the previous word is
2133 instruction or data. */
2134 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2135 && (((info->endian == BFD_ENDIAN_BIG
2136 ? bfd_getb16 (buffer)
2137 : bfd_getl16 (buffer))
2138 & 0xf800) == 0x1800))
2139 baseaddr = memaddr - 4;
2140 else if (info->read_memory_func (memaddr - 2, buffer, 2,
2141 info) == 0
2142 && (((info->endian == BFD_ENDIAN_BIG
2143 ? bfd_getb16 (buffer)
2144 : bfd_getl16 (buffer))
2145 & 0xf89f) == 0xe800)
2146 && (((info->endian == BFD_ENDIAN_BIG
2147 ? bfd_getb16 (buffer)
2148 : bfd_getl16 (buffer))
2149 & 0x0060) != 0x0060))
2150 baseaddr = memaddr - 2;
2151 else
2152 baseaddr = memaddr;
2156 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
2157 break;
2162 /* Check if the given address is the last word of a MIPS16 PLT entry.
2163 This word is data and depending on the value it may interfere with
2164 disassembly of further PLT entries. We make use of the fact PLT
2165 symbols are marked BSF_SYNTHETIC. */
2166 static bool
2167 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2169 if (info->symbols
2170 && info->symbols[0]
2171 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2172 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2173 return true;
2175 return false;
2178 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2180 enum match_kind
2182 MATCH_NONE,
2183 MATCH_FULL,
2184 MATCH_SHORT
2187 /* Disassemble mips16 instructions. */
2189 static int
2190 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2192 const fprintf_ftype infprintf = info->fprintf_func;
2193 int status;
2194 bfd_byte buffer[4];
2195 const struct mips_opcode *op, *opend;
2196 struct mips_print_arg_state state;
2197 void *is = info->stream;
2198 bool have_second;
2199 bool extend_only;
2200 unsigned int second;
2201 unsigned int first;
2202 unsigned int full;
2204 info->bytes_per_chunk = 2;
2205 info->display_endian = info->endian;
2206 info->insn_info_valid = 1;
2207 info->branch_delay_insns = 0;
2208 info->data_size = 0;
2209 info->target = 0;
2210 info->target2 = 0;
2212 #define GET_OP(insn, field) \
2213 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2214 /* Decode PLT entry's GOT slot address word. */
2215 if (is_mips16_plt_tail (info, memaddr))
2217 info->insn_type = dis_noninsn;
2218 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2219 if (status == 0)
2221 unsigned int gotslot;
2223 if (info->endian == BFD_ENDIAN_BIG)
2224 gotslot = bfd_getb32 (buffer);
2225 else
2226 gotslot = bfd_getl32 (buffer);
2227 infprintf (is, ".word\t0x%x", gotslot);
2229 return 4;
2232 else
2234 info->insn_type = dis_nonbranch;
2235 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2237 if (status != 0)
2239 (*info->memory_error_func) (status, memaddr, info);
2240 return -1;
2243 extend_only = false;
2245 if (info->endian == BFD_ENDIAN_BIG)
2246 first = bfd_getb16 (buffer);
2247 else
2248 first = bfd_getl16 (buffer);
2250 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2251 if (status == 0)
2253 have_second = true;
2254 if (info->endian == BFD_ENDIAN_BIG)
2255 second = bfd_getb16 (buffer);
2256 else
2257 second = bfd_getl16 (buffer);
2258 full = (first << 16) | second;
2260 else
2262 have_second = false;
2263 second = 0;
2264 full = first;
2267 /* FIXME: Should probably use a hash table on the major opcode here. */
2269 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2270 for (op = mips16_opcodes; op < opend; op++)
2272 enum match_kind match;
2274 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2275 continue;
2277 if (op->pinfo == INSN_MACRO
2278 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2279 match = MATCH_NONE;
2280 else if (mips_opcode_32bit_p (op))
2282 if (have_second
2283 && (full & op->mask) == op->match)
2284 match = MATCH_FULL;
2285 else
2286 match = MATCH_NONE;
2288 else if ((first & op->mask) == op->match)
2290 match = MATCH_SHORT;
2291 second = 0;
2292 full = first;
2294 else if ((first & 0xf800) == 0xf000
2295 && have_second
2296 && !extend_only
2297 && (second & op->mask) == op->match)
2299 if (op->pinfo2 & INSN2_SHORT_ONLY)
2301 match = MATCH_NONE;
2302 extend_only = true;
2304 else
2305 match = MATCH_FULL;
2307 else
2308 match = MATCH_NONE;
2310 if (match != MATCH_NONE)
2312 const char *s;
2314 infprintf (is, "%s", op->name);
2315 if (op->args[0] != '\0')
2316 infprintf (is, "\t");
2318 init_print_arg_state (&state);
2319 for (s = op->args; *s != '\0'; s++)
2321 if (*s == ','
2322 && s[1] == 'w'
2323 && GET_OP (full, RX) == GET_OP (full, RY))
2325 /* Skip the register and the comma. */
2326 ++s;
2327 continue;
2329 if (*s == ','
2330 && s[1] == 'v'
2331 && GET_OP (full, RZ) == GET_OP (full, RX))
2333 /* Skip the register and the comma. */
2334 ++s;
2335 continue;
2337 if (s[0] == 'N'
2338 && s[1] == ','
2339 && s[2] == 'O'
2340 && op->name[strlen (op->name) - 1] == '0')
2342 /* Coprocessor register 0 with sel field. */
2343 const struct mips_cp0sel_name *n;
2344 const struct mips_operand *operand;
2345 unsigned int reg, sel;
2347 operand = decode_mips16_operand (*s, true);
2348 reg = mips_extract_operand (operand, (first << 16) | second);
2349 s += 2;
2350 operand = decode_mips16_operand (*s, true);
2351 sel = mips_extract_operand (operand, (first << 16) | second);
2353 /* CP0 register including 'sel' code for mftc0, to be
2354 printed textually if known. If not known, print both
2355 CP0 register name and sel numerically since CP0 register
2356 with sel 0 may have a name unrelated to register being
2357 printed. */
2358 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2359 mips_cp0sel_names_len,
2360 reg, sel);
2361 if (n != NULL)
2362 infprintf (is, "%s", n->name);
2363 else
2364 infprintf (is, "$%d,%d", reg, sel);
2366 else
2367 switch (match)
2369 case MATCH_FULL:
2370 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2371 second, true, first, s[1] == '(');
2372 break;
2373 case MATCH_SHORT:
2374 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2375 first, false, 0, s[1] == '(');
2376 break;
2377 case MATCH_NONE: /* Stop the compiler complaining. */
2378 break;
2382 /* Figure out branch instruction type and delay slot information. */
2383 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2384 info->branch_delay_insns = 1;
2385 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2386 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2388 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2389 info->insn_type = dis_jsr;
2390 else
2391 info->insn_type = dis_branch;
2393 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2394 info->insn_type = dis_condbranch;
2396 return match == MATCH_FULL ? 4 : 2;
2399 #undef GET_OP
2401 infprintf (is, "0x%x", first);
2402 info->insn_type = dis_noninsn;
2404 return 2;
2407 /* Disassemble microMIPS instructions. */
2409 static int
2410 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2412 const fprintf_ftype infprintf = info->fprintf_func;
2413 const struct mips_opcode *op, *opend;
2414 void *is = info->stream;
2415 bfd_byte buffer[2];
2416 unsigned int higher;
2417 unsigned int length;
2418 int status;
2419 unsigned int insn;
2421 info->bytes_per_chunk = 2;
2422 info->display_endian = info->endian;
2423 info->insn_info_valid = 1;
2424 info->branch_delay_insns = 0;
2425 info->data_size = 0;
2426 info->insn_type = dis_nonbranch;
2427 info->target = 0;
2428 info->target2 = 0;
2430 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2431 if (status != 0)
2433 (*info->memory_error_func) (status, memaddr, info);
2434 return -1;
2437 length = 2;
2439 if (info->endian == BFD_ENDIAN_BIG)
2440 insn = bfd_getb16 (buffer);
2441 else
2442 insn = bfd_getl16 (buffer);
2444 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2446 /* This is a 32-bit microMIPS instruction. */
2447 higher = insn;
2449 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2450 if (status != 0)
2452 infprintf (is, "micromips 0x%x", higher);
2453 (*info->memory_error_func) (status, memaddr + 2, info);
2454 return -1;
2457 if (info->endian == BFD_ENDIAN_BIG)
2458 insn = bfd_getb16 (buffer);
2459 else
2460 insn = bfd_getl16 (buffer);
2462 insn = insn | (higher << 16);
2464 length += 2;
2467 /* FIXME: Should probably use a hash table on the major opcode here. */
2469 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2470 for (op = micromips_opcodes; op < opend; op++)
2472 if (op->pinfo != INSN_MACRO
2473 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2474 && (insn & op->mask) == op->match
2475 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2476 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2478 if (!validate_insn_args (op, decode_micromips_operand, insn))
2479 continue;
2481 infprintf (is, "%s", op->name);
2483 if (op->args[0])
2485 infprintf (is, "\t");
2486 print_insn_args (info, op, decode_micromips_operand, insn,
2487 memaddr + 1, length);
2490 /* Figure out instruction type and branch delay information. */
2491 if ((op->pinfo
2492 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2493 info->branch_delay_insns = 1;
2494 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2495 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2497 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2498 info->insn_type = dis_jsr;
2499 else
2500 info->insn_type = dis_branch;
2502 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2503 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2505 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2506 info->insn_type = dis_condjsr;
2507 else
2508 info->insn_type = dis_condbranch;
2510 else if ((op->pinfo
2511 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2512 info->insn_type = dis_dref;
2514 return length;
2518 infprintf (is, "0x%x", insn);
2519 info->insn_type = dis_noninsn;
2521 return length;
2524 /* Return 1 if a symbol associated with the location being disassembled
2525 indicates a compressed mode, either MIPS16 or microMIPS, according to
2526 MICROMIPS_P. We iterate over all the symbols at the address being
2527 considered assuming if at least one of them indicates code compression,
2528 then such code has been genuinely produced here (other symbols could
2529 have been derived from function symbols defined elsewhere or could
2530 define data). Otherwise, return 0. */
2532 static bool
2533 is_compressed_mode_p (struct disassemble_info *info, bool micromips_p)
2535 int i;
2536 int l;
2538 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2539 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2540 && ((!micromips_p
2541 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2542 || (micromips_p
2543 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2544 return 1;
2545 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2546 && info->symtab[i]->section == info->section)
2548 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2549 if ((!micromips_p
2550 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2551 || (micromips_p
2552 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2553 return 1;
2556 return 0;
2559 /* In an environment where we do not know the symbol type of the
2560 instruction we are forced to assume that the low order bit of the
2561 instructions' address may mark it as a mips16 instruction. If we
2562 are single stepping, or the pc is within the disassembled function,
2563 this works. Otherwise, we need a clue. Sometimes. */
2565 static int
2566 _print_insn_mips (bfd_vma memaddr,
2567 struct disassemble_info *info,
2568 enum bfd_endian endianness)
2570 bfd_byte buffer[INSNLEN];
2571 int status;
2573 set_default_mips_dis_options (info);
2574 parse_mips_dis_options (info->disassembler_options);
2576 if (info->mach == bfd_mach_mips16)
2577 return print_insn_mips16 (memaddr, info);
2578 if (info->mach == bfd_mach_mips_micromips)
2579 return print_insn_micromips (memaddr, info);
2581 #if 1
2582 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2583 /* Only a few tools will work this way. */
2584 if (memaddr & 0x01)
2586 if (micromips_ase)
2587 return print_insn_micromips (memaddr, info);
2588 else
2589 return print_insn_mips16 (memaddr, info);
2591 #endif
2593 #if SYMTAB_AVAILABLE
2594 if (is_compressed_mode_p (info, true))
2595 return print_insn_micromips (memaddr, info);
2596 if (is_compressed_mode_p (info, false))
2597 return print_insn_mips16 (memaddr, info);
2598 #endif
2600 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2601 if (status == 0)
2603 int insn;
2605 if (endianness == BFD_ENDIAN_BIG)
2606 insn = bfd_getb32 (buffer);
2607 else
2608 insn = bfd_getl32 (buffer);
2610 return print_insn_mips (memaddr, insn, info);
2612 else
2614 (*info->memory_error_func) (status, memaddr, info);
2615 return -1;
2620 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2622 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2626 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2628 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2631 /* Indices into option argument vector for options accepting an argument.
2632 Use MIPS_OPTION_ARG_NONE for options accepting no argument. */
2633 typedef enum
2635 MIPS_OPTION_ARG_NONE = -1,
2636 MIPS_OPTION_ARG_ABI,
2637 MIPS_OPTION_ARG_ARCH,
2638 MIPS_OPTION_ARG_SIZE
2639 } mips_option_arg_t;
2641 /* Valid MIPS disassembler options. */
2642 static struct
2644 const char *name;
2645 const char *description;
2646 mips_option_arg_t arg;
2647 } mips_options[] =
2649 { "no-aliases", N_("Use canonical instruction forms.\n"),
2650 MIPS_OPTION_ARG_NONE },
2651 { "msa", N_("Recognize MSA instructions.\n"),
2652 MIPS_OPTION_ARG_NONE },
2653 { "virt", N_("Recognize the virtualization ASE instructions.\n"),
2654 MIPS_OPTION_ARG_NONE },
2655 { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\
2656 instructions.\n"),
2657 MIPS_OPTION_ARG_NONE },
2658 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2659 "instructions.\n"),
2660 MIPS_OPTION_ARG_NONE },
2661 { "loongson-mmi",
2662 N_("Recognize the Loongson MultiMedia extensions "
2663 "Instructions (MMI) ASE instructions.\n"),
2664 MIPS_OPTION_ARG_NONE },
2665 { "loongson-cam",
2666 N_("Recognize the Loongson Content Address Memory (CAM) "
2667 " instructions.\n"),
2668 MIPS_OPTION_ARG_NONE },
2669 { "loongson-ext",
2670 N_("Recognize the Loongson EXTensions (EXT) "
2671 " instructions.\n"),
2672 MIPS_OPTION_ARG_NONE },
2673 { "loongson-ext2",
2674 N_("Recognize the Loongson EXTensions R2 (EXT2) "
2675 " instructions.\n"),
2676 MIPS_OPTION_ARG_NONE },
2677 { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
2678 Default: based on binary being disassembled.\n"),
2679 MIPS_OPTION_ARG_ABI },
2680 { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
2681 Default: numeric.\n"),
2682 MIPS_OPTION_ARG_ABI },
2683 { "cp0-names=", N_("Print CP0 register names according to specified "
2684 "architecture.\n\
2685 Default: based on binary being disassembled.\n"),
2686 MIPS_OPTION_ARG_ARCH },
2687 { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
2688 Default: based on binary being disassembled.\n"),
2689 MIPS_OPTION_ARG_ARCH },
2690 { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
2691 MIPS_OPTION_ARG_ABI },
2692 { "reg-names=", N_("Print CP0 register and HWR names according to "
2693 "specified\n\
2694 architecture."),
2695 MIPS_OPTION_ARG_ARCH }
2698 /* Build the structure representing valid MIPS disassembler options.
2699 This is done dynamically for maintenance ease purpose; a static
2700 initializer would be unreadable. */
2702 const disasm_options_and_args_t *
2703 disassembler_options_mips (void)
2705 static disasm_options_and_args_t *opts_and_args;
2707 if (opts_and_args == NULL)
2709 size_t num_options = ARRAY_SIZE (mips_options);
2710 size_t num_args = MIPS_OPTION_ARG_SIZE;
2711 disasm_option_arg_t *args;
2712 disasm_options_t *opts;
2713 size_t i;
2714 size_t j;
2716 args = XNEWVEC (disasm_option_arg_t, num_args + 1);
2718 args[MIPS_OPTION_ARG_ABI].name = "ABI";
2719 args[MIPS_OPTION_ARG_ABI].values
2720 = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1);
2721 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2722 args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name;
2723 /* The array we return must be NULL terminated. */
2724 args[MIPS_OPTION_ARG_ABI].values[i] = NULL;
2726 args[MIPS_OPTION_ARG_ARCH].name = "ARCH";
2727 args[MIPS_OPTION_ARG_ARCH].values
2728 = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1);
2729 for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2730 if (*mips_arch_choices[i].name != '\0')
2731 args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name;
2732 /* The array we return must be NULL terminated. */
2733 args[MIPS_OPTION_ARG_ARCH].values[j] = NULL;
2735 /* The array we return must be NULL terminated. */
2736 args[MIPS_OPTION_ARG_SIZE].name = NULL;
2737 args[MIPS_OPTION_ARG_SIZE].values = NULL;
2739 opts_and_args = XNEW (disasm_options_and_args_t);
2740 opts_and_args->args = args;
2742 opts = &opts_and_args->options;
2743 opts->name = XNEWVEC (const char *, num_options + 1);
2744 opts->description = XNEWVEC (const char *, num_options + 1);
2745 opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
2746 for (i = 0; i < num_options; i++)
2748 opts->name[i] = mips_options[i].name;
2749 opts->description[i] = _(mips_options[i].description);
2750 if (mips_options[i].arg != MIPS_OPTION_ARG_NONE)
2751 opts->arg[i] = &args[mips_options[i].arg];
2752 else
2753 opts->arg[i] = NULL;
2755 /* The array we return must be NULL terminated. */
2756 opts->name[i] = NULL;
2757 opts->description[i] = NULL;
2758 opts->arg[i] = NULL;
2761 return opts_and_args;
2764 void
2765 print_mips_disassembler_options (FILE *stream)
2767 const disasm_options_and_args_t *opts_and_args;
2768 const disasm_option_arg_t *args;
2769 const disasm_options_t *opts;
2770 size_t max_len = 0;
2771 size_t i;
2772 size_t j;
2774 opts_and_args = disassembler_options_mips ();
2775 opts = &opts_and_args->options;
2776 args = opts_and_args->args;
2778 fprintf (stream, _("\n\
2779 The following MIPS specific disassembler options are supported for use\n\
2780 with the -M switch (multiple options should be separated by commas):\n\n"));
2782 /* Compute the length of the longest option name. */
2783 for (i = 0; opts->name[i] != NULL; i++)
2785 size_t len = strlen (opts->name[i]);
2787 if (opts->arg[i] != NULL)
2788 len += strlen (opts->arg[i]->name);
2789 if (max_len < len)
2790 max_len = len;
2793 for (i = 0, max_len++; opts->name[i] != NULL; i++)
2795 fprintf (stream, " %s", opts->name[i]);
2796 if (opts->arg[i] != NULL)
2797 fprintf (stream, "%s", opts->arg[i]->name);
2798 if (opts->description[i] != NULL)
2800 size_t len = strlen (opts->name[i]);
2802 if (opts->arg[i] != NULL)
2803 len += strlen (opts->arg[i]->name);
2804 fprintf (stream,
2805 "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
2807 fprintf (stream, _("\n"));
2810 for (i = 0; args[i].name != NULL; i++)
2812 fprintf (stream, _("\n\
2813 For the options above, the following values are supported for \"%s\":\n "),
2814 args[i].name);
2815 for (j = 0; args[i].values[j] != NULL; j++)
2816 fprintf (stream, " %s", args[i].values[j]);
2817 fprintf (stream, _("\n"));
2820 fprintf (stream, _("\n"));