Add support for the .gnu.sgstubs section to the linker for ARM/ELF based targets.
[binutils-gdb.git] / opcodes / mips-dis.c
blob859d4e3806fa506468d5074645ef777a4d5b4550
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2023 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 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1178 switch (type)
1180 case OP_REG_GP:
1181 infprintf (info->stream, dis_style_register, "%s",
1182 mips_gpr_names[regno]);
1183 break;
1185 case OP_REG_FP:
1186 infprintf (info->stream, dis_style_register, "%s",
1187 mips_fpr_names[regno]);
1188 break;
1190 case OP_REG_CCC:
1191 if (opcode->pinfo & (FP_D | FP_S))
1192 infprintf (info->stream, dis_style_register, "$fcc%d", regno);
1193 else
1194 infprintf (info->stream, dis_style_register, "$cc%d", regno);
1195 break;
1197 case OP_REG_VEC:
1198 if (opcode->membership & INSN_5400)
1199 infprintf (info->stream, dis_style_register, "$f%d", regno);
1200 else
1201 infprintf (info->stream, dis_style_register, "$v%d", regno);
1202 break;
1204 case OP_REG_ACC:
1205 infprintf (info->stream, dis_style_register, "$ac%d", regno);
1206 break;
1208 case OP_REG_COPRO:
1209 if (opcode->name[strlen (opcode->name) - 1] == '0')
1210 infprintf (info->stream, dis_style_register, "%s", mips_cp0_names[regno]);
1211 else
1212 infprintf (info->stream, dis_style_register, "$%d", regno);
1213 break;
1215 case OP_REG_CONTROL:
1216 if (opcode->name[strlen (opcode->name) - 1] == '1')
1217 infprintf (info->stream, dis_style_register, "%s", mips_cp1_names[regno]);
1218 else
1219 infprintf (info->stream, dis_style_register, "$%d", regno);
1220 break;
1222 case OP_REG_HW:
1223 infprintf (info->stream, dis_style_register, "%s", mips_hwr_names[regno]);
1224 break;
1226 case OP_REG_VF:
1227 infprintf (info->stream, dis_style_register, "$vf%d", regno);
1228 break;
1230 case OP_REG_VI:
1231 infprintf (info->stream, dis_style_register, "$vi%d", regno);
1232 break;
1234 case OP_REG_R5900_I:
1235 infprintf (info->stream, dis_style_register, "$I");
1236 break;
1238 case OP_REG_R5900_Q:
1239 infprintf (info->stream, dis_style_register, "$Q");
1240 break;
1242 case OP_REG_R5900_R:
1243 infprintf (info->stream, dis_style_register, "$R");
1244 break;
1246 case OP_REG_R5900_ACC:
1247 infprintf (info->stream, dis_style_register, "$ACC");
1248 break;
1250 case OP_REG_MSA:
1251 infprintf (info->stream, dis_style_register, "$w%d", regno);
1252 break;
1254 case OP_REG_MSA_CTRL:
1255 infprintf (info->stream, dis_style_register, "%s",
1256 msa_control_names[regno]);
1257 break;
1262 /* Used to track the state carried over from previous operands in
1263 an instruction. */
1264 struct mips_print_arg_state {
1265 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1266 where the value is known to be unsigned and small. */
1267 unsigned int last_int;
1269 /* The type and number of the last OP_REG seen. We only use this for
1270 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1271 enum mips_reg_operand_type last_reg_type;
1272 unsigned int last_regno;
1273 unsigned int dest_regno;
1274 unsigned int seen_dest;
1277 /* Initialize STATE for the start of an instruction. */
1279 static inline void
1280 init_print_arg_state (struct mips_print_arg_state *state)
1282 memset (state, 0, sizeof (*state));
1285 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1286 whose value is given by UVAL. */
1288 static void
1289 print_vu0_channel (struct disassemble_info *info,
1290 const struct mips_operand *operand, unsigned int uval,
1291 enum disassembler_style style)
1293 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1295 if (operand->size == 4)
1296 infprintf (info->stream, style, "%s%s%s%s",
1297 uval & 8 ? "x" : "",
1298 uval & 4 ? "y" : "",
1299 uval & 2 ? "z" : "",
1300 uval & 1 ? "w" : "");
1301 else if (operand->size == 2)
1302 infprintf (info->stream, style, "%c", "xyzw"[uval]);
1303 else
1304 abort ();
1307 /* Record information about a register operand. */
1309 static void
1310 mips_seen_register (struct mips_print_arg_state *state,
1311 unsigned int regno,
1312 enum mips_reg_operand_type reg_type)
1314 state->last_reg_type = reg_type;
1315 state->last_regno = regno;
1317 if (!state->seen_dest)
1319 state->seen_dest = 1;
1320 state->dest_regno = regno;
1324 /* Print SAVE/RESTORE instruction operands according to the argument
1325 register mask AMASK, the number of static registers saved NSREG,
1326 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1327 and the frame size FRAME_SIZE. */
1329 static void
1330 mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
1331 unsigned int nsreg, unsigned int ra,
1332 unsigned int s0, unsigned int s1,
1333 unsigned int frame_size)
1335 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1336 unsigned int nargs, nstatics, smask, i, j;
1337 void *is = info->stream;
1338 const char *sep;
1340 if (amask == MIPS_SVRS_ALL_ARGS)
1342 nargs = 4;
1343 nstatics = 0;
1345 else if (amask == MIPS_SVRS_ALL_STATICS)
1347 nargs = 0;
1348 nstatics = 4;
1350 else
1352 nargs = amask >> 2;
1353 nstatics = amask & 3;
1356 sep = "";
1357 if (nargs > 0)
1359 infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1360 if (nargs > 1)
1361 infprintf (is, dis_style_register, "-%s", mips_gpr_names[4 + nargs - 1]);
1362 sep = ",";
1365 infprintf (is, dis_style_text, "%s", sep);
1366 infprintf (is, dis_style_immediate, "%d", frame_size);
1368 if (ra) /* $ra */
1370 infprintf (is, dis_style_text, ",");
1371 infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1374 smask = 0;
1375 if (s0) /* $s0 */
1376 smask |= 1 << 0;
1377 if (s1) /* $s1 */
1378 smask |= 1 << 1;
1379 if (nsreg > 0) /* $s2-$s8 */
1380 smask |= ((1 << nsreg) - 1) << 2;
1382 for (i = 0; i < 9; i++)
1383 if (smask & (1 << i))
1385 infprintf (is, dis_style_text, ",");
1386 infprintf (is, dis_style_register, "%s",
1387 mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1388 /* Skip over string of set bits. */
1389 for (j = i; smask & (2 << j); j++)
1390 continue;
1391 if (j > i)
1393 infprintf (is, dis_style_text, "-");
1394 infprintf (is, dis_style_register, "%s",
1395 mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1397 i = j + 1;
1399 /* Statics $ax - $a3. */
1400 if (nstatics == 1)
1402 infprintf (is, dis_style_text, ",");
1403 infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1405 else if (nstatics > 0)
1407 infprintf (is, dis_style_text, ",");
1408 infprintf (is, dis_style_register, "%s",
1409 mips_gpr_names[7 - nstatics + 1]);
1410 infprintf (is, dis_style_text, "-");
1411 infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1416 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1417 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1418 the base address for OP_PCREL operands. */
1420 static void
1421 print_insn_arg (struct disassemble_info *info,
1422 struct mips_print_arg_state *state,
1423 const struct mips_opcode *opcode,
1424 const struct mips_operand *operand,
1425 bfd_vma base_pc,
1426 unsigned int uval)
1428 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1429 void *is = info->stream;
1431 switch (operand->type)
1433 case OP_INT:
1435 const struct mips_int_operand *int_op;
1437 int_op = (const struct mips_int_operand *) operand;
1438 uval = mips_decode_int_operand (int_op, uval);
1439 state->last_int = uval;
1440 if (int_op->print_hex)
1441 infprintf (is, dis_style_immediate, "0x%x", uval);
1442 else
1443 infprintf (is, dis_style_immediate, "%d", uval);
1445 break;
1447 case OP_MAPPED_INT:
1449 const struct mips_mapped_int_operand *mint_op;
1451 mint_op = (const struct mips_mapped_int_operand *) operand;
1452 uval = mint_op->int_map[uval];
1453 state->last_int = uval;
1454 if (mint_op->print_hex)
1455 infprintf (is, dis_style_immediate, "0x%x", uval);
1456 else
1457 infprintf (is, dis_style_immediate, "%d", uval);
1459 break;
1461 case OP_MSB:
1463 const struct mips_msb_operand *msb_op;
1465 msb_op = (const struct mips_msb_operand *) operand;
1466 uval += msb_op->bias;
1467 if (msb_op->add_lsb)
1468 uval -= state->last_int;
1469 infprintf (is, dis_style_immediate, "0x%x", uval);
1471 break;
1473 case OP_REG:
1474 case OP_OPTIONAL_REG:
1476 const struct mips_reg_operand *reg_op;
1478 reg_op = (const struct mips_reg_operand *) operand;
1479 uval = mips_decode_reg_operand (reg_op, uval);
1480 print_reg (info, opcode, reg_op->reg_type, uval);
1482 mips_seen_register (state, uval, reg_op->reg_type);
1484 break;
1486 case OP_REG_PAIR:
1488 const struct mips_reg_pair_operand *pair_op;
1490 pair_op = (const struct mips_reg_pair_operand *) operand;
1491 print_reg (info, opcode, pair_op->reg_type,
1492 pair_op->reg1_map[uval]);
1493 infprintf (is, dis_style_text, ",");
1494 print_reg (info, opcode, pair_op->reg_type,
1495 pair_op->reg2_map[uval]);
1497 break;
1499 case OP_PCREL:
1501 const struct mips_pcrel_operand *pcrel_op;
1503 pcrel_op = (const struct mips_pcrel_operand *) operand;
1504 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1506 /* For jumps and branches clear the ISA bit except for
1507 the GDB disassembler. */
1508 if (pcrel_op->include_isa_bit
1509 && info->flavour != bfd_target_unknown_flavour)
1510 info->target &= -2;
1512 (*info->print_address_func) (info->target, info);
1514 break;
1516 case OP_PERF_REG:
1517 infprintf (is, dis_style_register, "%d", uval);
1518 break;
1520 case OP_ADDIUSP_INT:
1522 int sval;
1524 sval = mips_signed_operand (operand, uval) * 4;
1525 if (sval >= -8 && sval < 8)
1526 sval ^= 0x400;
1527 infprintf (is, dis_style_immediate, "%d", sval);
1528 break;
1531 case OP_CLO_CLZ_DEST:
1533 unsigned int reg1, reg2;
1535 reg1 = uval & 31;
1536 reg2 = uval >> 5;
1537 /* If one is zero use the other. */
1538 if (reg1 == reg2 || reg2 == 0)
1539 infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1540 else if (reg1 == 0)
1541 infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1542 else
1544 /* Bogus, result depends on processor. */
1545 infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1546 infprintf (is, dis_style_text, " or ");
1547 infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1550 break;
1552 case OP_SAME_RS_RT:
1553 case OP_CHECK_PREV:
1554 case OP_NON_ZERO_REG:
1556 print_reg (info, opcode, OP_REG_GP, uval & 31);
1557 mips_seen_register (state, uval, OP_REG_GP);
1559 break;
1561 case OP_LWM_SWM_LIST:
1562 if (operand->size == 2)
1564 if (uval == 0)
1566 infprintf (is, dis_style_register, "%s",
1567 mips_gpr_names[16]);
1568 infprintf (is, dis_style_text, ",");
1569 infprintf (is, dis_style_register, "%s",
1570 mips_gpr_names[31]);
1572 else
1574 infprintf (is, dis_style_register, "%s",
1575 mips_gpr_names[16]);
1576 infprintf (is, dis_style_text, "-");
1577 infprintf (is, dis_style_register, "%s",
1578 mips_gpr_names[16 + uval]);
1579 infprintf (is, dis_style_text, ",");
1580 infprintf (is, dis_style_register, "%s",
1581 mips_gpr_names[31]);
1584 else
1586 int s_reg_encode;
1588 s_reg_encode = uval & 0xf;
1589 if (s_reg_encode != 0)
1591 if (s_reg_encode == 1)
1592 infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1593 else if (s_reg_encode < 9)
1595 infprintf (is, dis_style_register, "%s",
1596 mips_gpr_names[16]);
1597 infprintf (is, dis_style_text, "-");
1598 infprintf (is, dis_style_register, "%s",
1599 mips_gpr_names[15 + s_reg_encode]);
1601 else if (s_reg_encode == 9)
1603 infprintf (is, dis_style_register, "%s",
1604 mips_gpr_names[16]);
1605 infprintf (is, dis_style_text, "-");
1606 infprintf (is, dis_style_register, "%s",
1607 mips_gpr_names[23]);
1608 infprintf (is, dis_style_text, ",");
1609 infprintf (is, dis_style_register, "%s",
1610 mips_gpr_names[30]);
1612 else
1613 infprintf (is, dis_style_text, "UNKNOWN");
1616 if (uval & 0x10) /* For ra. */
1618 if (s_reg_encode == 0)
1619 infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1620 else
1622 infprintf (is, dis_style_text, ",");
1623 infprintf (is, dis_style_register, "%s",
1624 mips_gpr_names[31]);
1628 break;
1630 case OP_ENTRY_EXIT_LIST:
1632 const char *sep;
1633 unsigned int amask, smask;
1635 sep = "";
1636 amask = (uval >> 3) & 7;
1637 if (amask > 0 && amask < 5)
1639 infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1640 if (amask > 1)
1642 infprintf (is, dis_style_text, "-");
1643 infprintf (is, dis_style_register, "%s",
1644 mips_gpr_names[amask + 3]);
1646 sep = ",";
1649 smask = (uval >> 1) & 3;
1650 if (smask == 3)
1652 infprintf (is, dis_style_text, "%s??", sep);
1653 sep = ",";
1655 else if (smask > 0)
1657 infprintf (is, dis_style_text, "%s", sep);
1658 infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1659 if (smask > 1)
1661 infprintf (is, dis_style_text, "-");
1662 infprintf (is, dis_style_register, "%s",
1663 mips_gpr_names[smask + 15]);
1665 sep = ",";
1668 if (uval & 1)
1670 infprintf (is, dis_style_text, "%s", sep);
1671 infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1672 sep = ",";
1675 if (amask == 5 || amask == 6)
1677 infprintf (is, dis_style_text, "%s", sep);
1678 infprintf (is, dis_style_register, "%s", mips_fpr_names[0]);
1679 if (amask == 6)
1681 infprintf (is, dis_style_text, "-");
1682 infprintf (is, dis_style_register, "%s", mips_fpr_names[1]);
1686 break;
1688 case OP_SAVE_RESTORE_LIST:
1689 /* Should be handled by the caller due to complex behavior. */
1690 abort ();
1692 case OP_MDMX_IMM_REG:
1694 unsigned int vsel;
1696 vsel = uval >> 5;
1697 uval &= 31;
1698 if ((vsel & 0x10) == 0)
1700 int fmt;
1702 vsel &= 0x0f;
1703 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1704 if ((vsel & 1) == 0)
1705 break;
1706 print_reg (info, opcode, OP_REG_VEC, uval);
1707 infprintf (is, dis_style_text, "[");
1708 infprintf (is, dis_style_immediate, "%d", vsel >> 1);
1709 infprintf (is, dis_style_text, "]");
1711 else if ((vsel & 0x08) == 0)
1712 print_reg (info, opcode, OP_REG_VEC, uval);
1713 else
1714 infprintf (is, dis_style_immediate, "0x%x", uval);
1716 break;
1718 case OP_REPEAT_PREV_REG:
1719 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1720 break;
1722 case OP_REPEAT_DEST_REG:
1723 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1724 break;
1726 case OP_PC:
1727 infprintf (is, dis_style_register, "$pc");
1728 break;
1730 case OP_REG28:
1731 print_reg (info, opcode, OP_REG_GP, 28);
1732 break;
1734 case OP_VU0_SUFFIX:
1735 case OP_VU0_MATCH_SUFFIX:
1736 print_vu0_channel (info, operand, uval, dis_style_register);
1737 break;
1739 case OP_IMM_INDEX:
1740 infprintf (is, dis_style_text, "[");
1741 infprintf (is, dis_style_immediate, "%d", uval);
1742 infprintf (is, dis_style_text, "]");
1743 break;
1745 case OP_REG_INDEX:
1746 infprintf (is, dis_style_text, "[");
1747 print_reg (info, opcode, OP_REG_GP, uval);
1748 infprintf (is, dis_style_text, "]");
1749 break;
1753 /* Validate the arguments for INSN, which is described by OPCODE.
1754 Use DECODE_OPERAND to get the encoding of each operand. */
1756 static bool
1757 validate_insn_args (const struct mips_opcode *opcode,
1758 const struct mips_operand *(*decode_operand) (const char *),
1759 unsigned int insn)
1761 struct mips_print_arg_state state;
1762 const struct mips_operand *operand;
1763 const char *s;
1764 unsigned int uval;
1766 init_print_arg_state (&state);
1767 for (s = opcode->args; *s; ++s)
1769 switch (*s)
1771 case ',':
1772 case '(':
1773 case ')':
1774 break;
1776 case '#':
1777 ++s;
1778 break;
1780 default:
1781 operand = decode_operand (s);
1783 if (operand)
1785 uval = mips_extract_operand (operand, insn);
1786 switch (operand->type)
1788 case OP_REG:
1789 case OP_OPTIONAL_REG:
1791 const struct mips_reg_operand *reg_op;
1793 reg_op = (const struct mips_reg_operand *) operand;
1794 uval = mips_decode_reg_operand (reg_op, uval);
1795 mips_seen_register (&state, uval, reg_op->reg_type);
1797 break;
1799 case OP_SAME_RS_RT:
1801 unsigned int reg1, reg2;
1803 reg1 = uval & 31;
1804 reg2 = uval >> 5;
1806 if (reg1 != reg2 || reg1 == 0)
1807 return false;
1809 break;
1811 case OP_CHECK_PREV:
1813 const struct mips_check_prev_operand *prev_op;
1815 prev_op = (const struct mips_check_prev_operand *) operand;
1817 if (!prev_op->zero_ok && uval == 0)
1818 return false;
1820 if (((prev_op->less_than_ok && uval < state.last_regno)
1821 || (prev_op->greater_than_ok && uval > state.last_regno)
1822 || (prev_op->equal_ok && uval == state.last_regno)))
1823 break;
1825 return false;
1828 case OP_NON_ZERO_REG:
1830 if (uval == 0)
1831 return false;
1833 break;
1835 case OP_INT:
1836 case OP_MAPPED_INT:
1837 case OP_MSB:
1838 case OP_REG_PAIR:
1839 case OP_PCREL:
1840 case OP_PERF_REG:
1841 case OP_ADDIUSP_INT:
1842 case OP_CLO_CLZ_DEST:
1843 case OP_LWM_SWM_LIST:
1844 case OP_ENTRY_EXIT_LIST:
1845 case OP_MDMX_IMM_REG:
1846 case OP_REPEAT_PREV_REG:
1847 case OP_REPEAT_DEST_REG:
1848 case OP_PC:
1849 case OP_REG28:
1850 case OP_VU0_SUFFIX:
1851 case OP_VU0_MATCH_SUFFIX:
1852 case OP_IMM_INDEX:
1853 case OP_REG_INDEX:
1854 case OP_SAVE_RESTORE_LIST:
1855 break;
1858 if (*s == 'm' || *s == '+' || *s == '-')
1859 ++s;
1862 return true;
1865 /* Print the arguments for INSN, which is described by OPCODE.
1866 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1867 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1868 operand is for a branch or jump. */
1870 static void
1871 print_insn_args (struct disassemble_info *info,
1872 const struct mips_opcode *opcode,
1873 const struct mips_operand *(*decode_operand) (const char *),
1874 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1876 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1877 void *is = info->stream;
1878 struct mips_print_arg_state state;
1879 const struct mips_operand *operand;
1880 const char *s;
1882 init_print_arg_state (&state);
1883 for (s = opcode->args; *s; ++s)
1885 switch (*s)
1887 case ',':
1888 case '(':
1889 case ')':
1890 infprintf (is, dis_style_text, "%c", *s);
1891 break;
1893 case '#':
1894 ++s;
1895 infprintf (is, dis_style_text, "%c%c", *s, *s);
1896 break;
1898 default:
1899 operand = decode_operand (s);
1900 if (!operand)
1902 /* xgettext:c-format */
1903 infprintf (is, dis_style_text,
1904 _("# internal error, undefined operand in `%s %s'"),
1905 opcode->name, opcode->args);
1906 return;
1909 if (operand->type == OP_SAVE_RESTORE_LIST)
1911 /* Handle this case here because of the complex behavior. */
1912 unsigned int amask = (insn >> 15) & 0xf;
1913 unsigned int nsreg = (insn >> 23) & 0x7;
1914 unsigned int ra = insn & 0x1000; /* $ra */
1915 unsigned int s0 = insn & 0x800; /* $s0 */
1916 unsigned int s1 = insn & 0x400; /* $s1 */
1917 unsigned int frame_size = (((insn >> 15) & 0xf0)
1918 | ((insn >> 6) & 0x0f)) * 8;
1919 mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1920 frame_size);
1922 else if (operand->type == OP_REG
1923 && s[1] == ','
1924 && s[2] == 'H'
1925 && opcode->name[strlen (opcode->name) - 1] == '0')
1927 /* Coprocessor register 0 with sel field. */
1928 const struct mips_cp0sel_name *n;
1929 unsigned int reg, sel;
1931 reg = mips_extract_operand (operand, insn);
1932 s += 2;
1933 operand = decode_operand (s);
1934 sel = mips_extract_operand (operand, insn);
1936 /* CP0 register including 'sel' code for mftc0, to be
1937 printed textually if known. If not known, print both
1938 CP0 register name and sel numerically since CP0 register
1939 with sel 0 may have a name unrelated to register being
1940 printed. */
1941 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1942 mips_cp0sel_names_len,
1943 reg, sel);
1944 if (n != NULL)
1945 infprintf (is, dis_style_register, "%s", n->name);
1946 else
1948 infprintf (is, dis_style_register, "$%d", reg);
1949 infprintf (is, dis_style_text, ",");
1950 infprintf (is, dis_style_immediate, "%d", sel);
1953 else
1955 bfd_vma base_pc = insn_pc;
1957 /* Adjust the PC relative base so that branch/jump insns use
1958 the following PC as the base but genuinely PC relative
1959 operands use the current PC. */
1960 if (operand->type == OP_PCREL)
1962 const struct mips_pcrel_operand *pcrel_op;
1964 pcrel_op = (const struct mips_pcrel_operand *) operand;
1965 /* The include_isa_bit flag is sufficient to distinguish
1966 branch/jump from other PC relative operands. */
1967 if (pcrel_op->include_isa_bit)
1968 base_pc += length;
1971 print_insn_arg (info, &state, opcode, operand, base_pc,
1972 mips_extract_operand (operand, insn));
1974 if (*s == 'm' || *s == '+' || *s == '-')
1975 ++s;
1976 break;
1981 /* Print the mips instruction at address MEMADDR in debugged memory,
1982 on using INFO. Returns length of the instruction, in bytes, which is
1983 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1984 this is little-endian code. */
1986 static int
1987 print_insn_mips (bfd_vma memaddr,
1988 int word,
1989 struct disassemble_info *info)
1991 #define GET_OP(insn, field) \
1992 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1993 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1994 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1995 const struct mips_opcode *op;
1996 static bool init = 0;
1997 void *is = info->stream;
1999 /* Build a hash table to shorten the search time. */
2000 if (! init)
2002 unsigned int i;
2004 for (i = 0; i <= OP_MASK_OP; i++)
2006 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
2008 if (op->pinfo == INSN_MACRO
2009 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2010 continue;
2011 if (i == GET_OP (op->match, OP))
2013 mips_hash[i] = op;
2014 break;
2019 init = 1;
2022 info->bytes_per_chunk = INSNLEN;
2023 info->display_endian = info->endian;
2024 info->insn_info_valid = 1;
2025 info->branch_delay_insns = 0;
2026 info->data_size = 0;
2027 info->insn_type = dis_nonbranch;
2028 info->target = 0;
2029 info->target2 = 0;
2031 op = mips_hash[GET_OP (word, OP)];
2032 if (op != NULL)
2034 for (; op < &mips_opcodes[NUMOPCODES]; op++)
2036 if (op->pinfo != INSN_MACRO
2037 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2038 && (word & op->mask) == op->match)
2040 /* We always disassemble the jalx instruction, except for MIPS r6. */
2041 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
2042 && (strcmp (op->name, "jalx")
2043 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
2044 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
2045 continue;
2047 /* Figure out instruction type and branch delay information. */
2048 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2050 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2051 info->insn_type = dis_jsr;
2052 else
2053 info->insn_type = dis_branch;
2054 info->branch_delay_insns = 1;
2056 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
2057 | INSN_COND_BRANCH_LIKELY)) != 0)
2059 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2060 info->insn_type = dis_condjsr;
2061 else
2062 info->insn_type = dis_condbranch;
2063 info->branch_delay_insns = 1;
2065 else if ((op->pinfo & (INSN_STORE_MEMORY
2066 | INSN_LOAD_MEMORY)) != 0)
2067 info->insn_type = dis_dref;
2069 if (!validate_insn_args (op, decode_mips_operand, word))
2070 continue;
2072 infprintf (is, dis_style_mnemonic, "%s", op->name);
2073 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
2075 unsigned int uval;
2077 infprintf (is, dis_style_mnemonic, ".");
2078 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
2079 print_vu0_channel (info, &mips_vu0_channel_mask, uval,
2080 dis_style_mnemonic);
2083 if (op->args[0])
2085 infprintf (is, dis_style_text, "\t");
2086 print_insn_args (info, op, decode_mips_operand, word,
2087 memaddr, 4);
2090 return INSNLEN;
2094 #undef GET_OP
2096 /* Handle undefined instructions. */
2097 info->insn_type = dis_noninsn;
2098 infprintf (is, dis_style_assembler_directive, ".word");
2099 infprintf (is, dis_style_text, "\t");
2100 infprintf (is, dis_style_immediate, "0x%x", word);
2101 return INSNLEN;
2104 /* Disassemble an operand for a mips16 instruction. */
2106 static void
2107 print_mips16_insn_arg (struct disassemble_info *info,
2108 struct mips_print_arg_state *state,
2109 const struct mips_opcode *opcode,
2110 char type, bfd_vma memaddr,
2111 unsigned insn, bool use_extend,
2112 unsigned extend, bool is_offset)
2114 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2115 void *is = info->stream;
2116 const struct mips_operand *operand, *ext_operand;
2117 unsigned short ext_size;
2118 unsigned int uval;
2119 bfd_vma baseaddr;
2121 if (!use_extend)
2122 extend = 0;
2124 switch (type)
2126 case ',':
2127 case '(':
2128 case ')':
2129 infprintf (is, dis_style_text, "%c", type);
2130 break;
2132 default:
2133 operand = decode_mips16_operand (type, false);
2134 if (!operand)
2136 /* xgettext:c-format */
2137 infprintf (is, dis_style_text, _("# internal error, undefined operand in `%s %s'"),
2138 opcode->name, opcode->args);
2139 return;
2142 if (operand->type == OP_SAVE_RESTORE_LIST)
2144 /* Handle this case here because of the complex interaction
2145 with the EXTEND opcode. */
2146 unsigned int amask = extend & 0xf;
2147 unsigned int nsreg = (extend >> 8) & 0x7;
2148 unsigned int ra = insn & 0x40; /* $ra */
2149 unsigned int s0 = insn & 0x20; /* $s0 */
2150 unsigned int s1 = insn & 0x10; /* $s1 */
2151 unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
2152 if (frame_size == 0 && !use_extend)
2153 frame_size = 128;
2154 mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
2155 break;
2158 if (is_offset && operand->type == OP_INT)
2160 const struct mips_int_operand *int_op;
2162 int_op = (const struct mips_int_operand *) operand;
2163 info->insn_type = dis_dref;
2164 info->data_size = 1 << int_op->shift;
2167 ext_size = 0;
2168 if (use_extend)
2170 ext_operand = decode_mips16_operand (type, true);
2171 if (ext_operand != operand
2172 || (operand->type == OP_INT && operand->lsb == 0
2173 && mips_opcode_32bit_p (opcode)))
2175 ext_size = ext_operand->size;
2176 operand = ext_operand;
2179 if (operand->size == 26)
2180 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
2181 else if (ext_size == 16 || ext_size == 9)
2182 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2183 else if (ext_size == 15)
2184 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2185 else if (ext_size == 6)
2186 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2187 else
2188 uval = mips_extract_operand (operand, (extend << 16) | insn);
2189 if (ext_size == 9)
2190 uval &= (1U << ext_size) - 1;
2192 baseaddr = memaddr + 2;
2193 if (operand->type == OP_PCREL)
2195 const struct mips_pcrel_operand *pcrel_op;
2197 pcrel_op = (const struct mips_pcrel_operand *) operand;
2198 if (!pcrel_op->include_isa_bit && use_extend)
2199 baseaddr = memaddr - 2;
2200 else if (!pcrel_op->include_isa_bit)
2202 bfd_byte buffer[2];
2204 /* If this instruction is in the delay slot of a JAL/JALX
2205 instruction, the base address is the address of the
2206 JAL/JALX instruction. If it is in the delay slot of
2207 a JR/JALR instruction, the base address is the address
2208 of the JR/JALR instruction. This test is unreliable:
2209 we have no way of knowing whether the previous word is
2210 instruction or data. */
2211 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2212 && (((info->endian == BFD_ENDIAN_BIG
2213 ? bfd_getb16 (buffer)
2214 : bfd_getl16 (buffer))
2215 & 0xf800) == 0x1800))
2216 baseaddr = memaddr - 4;
2217 else if (info->read_memory_func (memaddr - 2, buffer, 2,
2218 info) == 0
2219 && (((info->endian == BFD_ENDIAN_BIG
2220 ? bfd_getb16 (buffer)
2221 : bfd_getl16 (buffer))
2222 & 0xf89f) == 0xe800)
2223 && (((info->endian == BFD_ENDIAN_BIG
2224 ? bfd_getb16 (buffer)
2225 : bfd_getl16 (buffer))
2226 & 0x0060) != 0x0060))
2227 baseaddr = memaddr - 2;
2228 else
2229 baseaddr = memaddr;
2233 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
2234 break;
2239 /* Check if the given address is the last word of a MIPS16 PLT entry.
2240 This word is data and depending on the value it may interfere with
2241 disassembly of further PLT entries. We make use of the fact PLT
2242 symbols are marked BSF_SYNTHETIC. */
2243 static bool
2244 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2246 if (info->symbols
2247 && info->symbols[0]
2248 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2249 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2250 return true;
2252 return false;
2255 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2257 enum match_kind
2259 MATCH_NONE,
2260 MATCH_FULL,
2261 MATCH_SHORT
2264 /* Disassemble mips16 instructions. */
2266 static int
2267 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2269 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2270 int status;
2271 bfd_byte buffer[4];
2272 const struct mips_opcode *op, *opend;
2273 struct mips_print_arg_state state;
2274 void *is = info->stream;
2275 bool have_second;
2276 bool extend_only;
2277 unsigned int second;
2278 unsigned int first;
2279 unsigned int full;
2281 info->bytes_per_chunk = 2;
2282 info->display_endian = info->endian;
2283 info->insn_info_valid = 1;
2284 info->branch_delay_insns = 0;
2285 info->data_size = 0;
2286 info->target = 0;
2287 info->target2 = 0;
2289 #define GET_OP(insn, field) \
2290 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2291 /* Decode PLT entry's GOT slot address word. */
2292 if (is_mips16_plt_tail (info, memaddr))
2294 info->insn_type = dis_noninsn;
2295 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2296 if (status == 0)
2298 unsigned int gotslot;
2300 if (info->endian == BFD_ENDIAN_BIG)
2301 gotslot = bfd_getb32 (buffer);
2302 else
2303 gotslot = bfd_getl32 (buffer);
2304 infprintf (is, dis_style_assembler_directive, ".word");
2305 infprintf (is, dis_style_text, "\t");
2306 infprintf (is, dis_style_immediate, "0x%x", gotslot);
2308 return 4;
2311 else
2313 info->insn_type = dis_nonbranch;
2314 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2316 if (status != 0)
2318 (*info->memory_error_func) (status, memaddr, info);
2319 return -1;
2322 extend_only = false;
2324 if (info->endian == BFD_ENDIAN_BIG)
2325 first = bfd_getb16 (buffer);
2326 else
2327 first = bfd_getl16 (buffer);
2329 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2330 if (status == 0)
2332 have_second = true;
2333 if (info->endian == BFD_ENDIAN_BIG)
2334 second = bfd_getb16 (buffer);
2335 else
2336 second = bfd_getl16 (buffer);
2337 full = (first << 16) | second;
2339 else
2341 have_second = false;
2342 second = 0;
2343 full = first;
2346 /* FIXME: Should probably use a hash table on the major opcode here. */
2348 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2349 for (op = mips16_opcodes; op < opend; op++)
2351 enum match_kind match;
2353 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2354 continue;
2356 if (op->pinfo == INSN_MACRO
2357 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2358 match = MATCH_NONE;
2359 else if (mips_opcode_32bit_p (op))
2361 if (have_second
2362 && (full & op->mask) == op->match)
2363 match = MATCH_FULL;
2364 else
2365 match = MATCH_NONE;
2367 else if ((first & op->mask) == op->match)
2369 match = MATCH_SHORT;
2370 second = 0;
2371 full = first;
2373 else if ((first & 0xf800) == 0xf000
2374 && have_second
2375 && !extend_only
2376 && (second & op->mask) == op->match)
2378 if (op->pinfo2 & INSN2_SHORT_ONLY)
2380 match = MATCH_NONE;
2381 extend_only = true;
2383 else
2384 match = MATCH_FULL;
2386 else
2387 match = MATCH_NONE;
2389 if (match != MATCH_NONE)
2391 const char *s;
2393 infprintf (is, dis_style_mnemonic, "%s", op->name);
2394 if (op->args[0] != '\0')
2395 infprintf (is, dis_style_text, "\t");
2397 init_print_arg_state (&state);
2398 for (s = op->args; *s != '\0'; s++)
2400 if (*s == ','
2401 && s[1] == 'w'
2402 && GET_OP (full, RX) == GET_OP (full, RY))
2404 /* Skip the register and the comma. */
2405 ++s;
2406 continue;
2408 if (*s == ','
2409 && s[1] == 'v'
2410 && GET_OP (full, RZ) == GET_OP (full, RX))
2412 /* Skip the register and the comma. */
2413 ++s;
2414 continue;
2416 if (s[0] == 'N'
2417 && s[1] == ','
2418 && s[2] == 'O'
2419 && op->name[strlen (op->name) - 1] == '0')
2421 /* Coprocessor register 0 with sel field. */
2422 const struct mips_cp0sel_name *n;
2423 const struct mips_operand *operand;
2424 unsigned int reg, sel;
2426 operand = decode_mips16_operand (*s, true);
2427 reg = mips_extract_operand (operand, (first << 16) | second);
2428 s += 2;
2429 operand = decode_mips16_operand (*s, true);
2430 sel = mips_extract_operand (operand, (first << 16) | second);
2432 /* CP0 register including 'sel' code for mftc0, to be
2433 printed textually if known. If not known, print both
2434 CP0 register name and sel numerically since CP0 register
2435 with sel 0 may have a name unrelated to register being
2436 printed. */
2437 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2438 mips_cp0sel_names_len,
2439 reg, sel);
2440 if (n != NULL)
2441 infprintf (is, dis_style_register, "%s", n->name);
2442 else
2444 infprintf (is, dis_style_register, "$%d", reg);
2445 infprintf (is, dis_style_text, ",");
2446 infprintf (is, dis_style_immediate, "%d", sel);
2449 else
2450 switch (match)
2452 case MATCH_FULL:
2453 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2454 second, true, first, s[1] == '(');
2455 break;
2456 case MATCH_SHORT:
2457 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2458 first, false, 0, s[1] == '(');
2459 break;
2460 case MATCH_NONE: /* Stop the compiler complaining. */
2461 break;
2465 /* Figure out branch instruction type and delay slot information. */
2466 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2467 info->branch_delay_insns = 1;
2468 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2469 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2471 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2472 info->insn_type = dis_jsr;
2473 else
2474 info->insn_type = dis_branch;
2476 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2477 info->insn_type = dis_condbranch;
2479 return match == MATCH_FULL ? 4 : 2;
2482 #undef GET_OP
2484 infprintf (is, dis_style_assembler_directive, ".short");
2485 infprintf (is, dis_style_text, "\t");
2486 infprintf (is, dis_style_immediate, "0x%x", first);
2487 info->insn_type = dis_noninsn;
2489 return 2;
2492 /* Disassemble microMIPS instructions. */
2494 static int
2495 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2497 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2498 const struct mips_opcode *op, *opend;
2499 void *is = info->stream;
2500 bfd_byte buffer[2];
2501 unsigned int higher;
2502 unsigned int length;
2503 int status;
2504 unsigned int insn;
2506 info->bytes_per_chunk = 2;
2507 info->display_endian = info->endian;
2508 info->insn_info_valid = 1;
2509 info->branch_delay_insns = 0;
2510 info->data_size = 0;
2511 info->insn_type = dis_nonbranch;
2512 info->target = 0;
2513 info->target2 = 0;
2515 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2516 if (status != 0)
2518 (*info->memory_error_func) (status, memaddr, info);
2519 return -1;
2522 length = 2;
2524 if (info->endian == BFD_ENDIAN_BIG)
2525 insn = bfd_getb16 (buffer);
2526 else
2527 insn = bfd_getl16 (buffer);
2529 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2531 /* This is a 32-bit microMIPS instruction. */
2532 higher = insn;
2534 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2535 if (status != 0)
2537 infprintf (is, dis_style_text, "micromips 0x%x", higher);
2538 (*info->memory_error_func) (status, memaddr + 2, info);
2539 return -1;
2542 if (info->endian == BFD_ENDIAN_BIG)
2543 insn = bfd_getb16 (buffer);
2544 else
2545 insn = bfd_getl16 (buffer);
2547 insn = insn | (higher << 16);
2549 length += 2;
2552 /* FIXME: Should probably use a hash table on the major opcode here. */
2554 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2555 for (op = micromips_opcodes; op < opend; op++)
2557 if (op->pinfo != INSN_MACRO
2558 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2559 && (insn & op->mask) == op->match
2560 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2561 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2563 if (!validate_insn_args (op, decode_micromips_operand, insn))
2564 continue;
2566 infprintf (is, dis_style_mnemonic, "%s", op->name);
2568 if (op->args[0])
2570 infprintf (is, dis_style_text, "\t");
2571 print_insn_args (info, op, decode_micromips_operand, insn,
2572 memaddr + 1, length);
2575 /* Figure out instruction type and branch delay information. */
2576 if ((op->pinfo
2577 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2578 info->branch_delay_insns = 1;
2579 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2580 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2582 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2583 info->insn_type = dis_jsr;
2584 else
2585 info->insn_type = dis_branch;
2587 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2588 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2590 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2591 info->insn_type = dis_condjsr;
2592 else
2593 info->insn_type = dis_condbranch;
2595 else if ((op->pinfo
2596 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2597 info->insn_type = dis_dref;
2599 return length;
2603 infprintf (is, dis_style_assembler_directive, ".short");
2604 infprintf (is, dis_style_text, "\t");
2605 if (length != 2)
2607 infprintf (is, dis_style_immediate, "0x%x", (insn >> 16) & 0xffff);
2608 infprintf (is, dis_style_text, ", ");
2610 infprintf (is, dis_style_immediate, "0x%x", (insn & 0xffff));
2612 info->insn_type = dis_noninsn;
2614 return length;
2617 /* Return 1 if a symbol associated with the location being disassembled
2618 indicates a compressed mode, either MIPS16 or microMIPS, according to
2619 MICROMIPS_P. We iterate over all the symbols at the address being
2620 considered assuming if at least one of them indicates code compression,
2621 then such code has been genuinely produced here (other symbols could
2622 have been derived from function symbols defined elsewhere or could
2623 define data). Otherwise, return 0. */
2625 static bool
2626 is_compressed_mode_p (struct disassemble_info *info, bool micromips_p)
2628 int i;
2629 int l;
2631 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2632 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2633 && ((!micromips_p
2634 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2635 || (micromips_p
2636 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2637 return 1;
2638 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2639 && info->symtab[i]->section == info->section)
2641 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2642 if ((!micromips_p
2643 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2644 || (micromips_p
2645 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2646 return 1;
2649 return 0;
2652 /* In an environment where we do not know the symbol type of the
2653 instruction we are forced to assume that the low order bit of the
2654 instructions' address may mark it as a mips16 instruction. If we
2655 are single stepping, or the pc is within the disassembled function,
2656 this works. Otherwise, we need a clue. Sometimes. */
2658 static int
2659 _print_insn_mips (bfd_vma memaddr,
2660 struct disassemble_info *info,
2661 enum bfd_endian endianness)
2663 bfd_byte buffer[INSNLEN];
2664 int status;
2666 set_default_mips_dis_options (info);
2667 parse_mips_dis_options (info->disassembler_options);
2669 if (info->mach == bfd_mach_mips16)
2670 return print_insn_mips16 (memaddr, info);
2671 if (info->mach == bfd_mach_mips_micromips)
2672 return print_insn_micromips (memaddr, info);
2674 #if 1
2675 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2676 /* Only a few tools will work this way. */
2677 if (memaddr & 0x01)
2679 if (micromips_ase)
2680 return print_insn_micromips (memaddr, info);
2681 else
2682 return print_insn_mips16 (memaddr, info);
2684 #endif
2686 #if SYMTAB_AVAILABLE
2687 if (is_compressed_mode_p (info, true))
2688 return print_insn_micromips (memaddr, info);
2689 if (is_compressed_mode_p (info, false))
2690 return print_insn_mips16 (memaddr, info);
2691 #endif
2693 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2694 if (status == 0)
2696 int insn;
2698 if (endianness == BFD_ENDIAN_BIG)
2699 insn = bfd_getb32 (buffer);
2700 else
2701 insn = bfd_getl32 (buffer);
2703 return print_insn_mips (memaddr, insn, info);
2705 else
2707 (*info->memory_error_func) (status, memaddr, info);
2708 return -1;
2713 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2715 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2719 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2721 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2724 /* Indices into option argument vector for options accepting an argument.
2725 Use MIPS_OPTION_ARG_NONE for options accepting no argument. */
2726 typedef enum
2728 MIPS_OPTION_ARG_NONE = -1,
2729 MIPS_OPTION_ARG_ABI,
2730 MIPS_OPTION_ARG_ARCH,
2731 MIPS_OPTION_ARG_SIZE
2732 } mips_option_arg_t;
2734 /* Valid MIPS disassembler options. */
2735 static struct
2737 const char *name;
2738 const char *description;
2739 mips_option_arg_t arg;
2740 } mips_options[] =
2742 { "no-aliases", N_("Use canonical instruction forms.\n"),
2743 MIPS_OPTION_ARG_NONE },
2744 { "msa", N_("Recognize MSA instructions.\n"),
2745 MIPS_OPTION_ARG_NONE },
2746 { "virt", N_("Recognize the virtualization ASE instructions.\n"),
2747 MIPS_OPTION_ARG_NONE },
2748 { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\
2749 instructions.\n"),
2750 MIPS_OPTION_ARG_NONE },
2751 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2752 "instructions.\n"),
2753 MIPS_OPTION_ARG_NONE },
2754 { "loongson-mmi",
2755 N_("Recognize the Loongson MultiMedia extensions "
2756 "Instructions (MMI) ASE instructions.\n"),
2757 MIPS_OPTION_ARG_NONE },
2758 { "loongson-cam",
2759 N_("Recognize the Loongson Content Address Memory (CAM) "
2760 " instructions.\n"),
2761 MIPS_OPTION_ARG_NONE },
2762 { "loongson-ext",
2763 N_("Recognize the Loongson EXTensions (EXT) "
2764 " instructions.\n"),
2765 MIPS_OPTION_ARG_NONE },
2766 { "loongson-ext2",
2767 N_("Recognize the Loongson EXTensions R2 (EXT2) "
2768 " instructions.\n"),
2769 MIPS_OPTION_ARG_NONE },
2770 { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
2771 Default: based on binary being disassembled.\n"),
2772 MIPS_OPTION_ARG_ABI },
2773 { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
2774 Default: numeric.\n"),
2775 MIPS_OPTION_ARG_ABI },
2776 { "cp0-names=", N_("Print CP0 register names according to specified "
2777 "architecture.\n\
2778 Default: based on binary being disassembled.\n"),
2779 MIPS_OPTION_ARG_ARCH },
2780 { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
2781 Default: based on binary being disassembled.\n"),
2782 MIPS_OPTION_ARG_ARCH },
2783 { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
2784 MIPS_OPTION_ARG_ABI },
2785 { "reg-names=", N_("Print CP0 register and HWR names according to "
2786 "specified\n\
2787 architecture."),
2788 MIPS_OPTION_ARG_ARCH }
2791 /* Build the structure representing valid MIPS disassembler options.
2792 This is done dynamically for maintenance ease purpose; a static
2793 initializer would be unreadable. */
2795 const disasm_options_and_args_t *
2796 disassembler_options_mips (void)
2798 static disasm_options_and_args_t *opts_and_args;
2800 if (opts_and_args == NULL)
2802 size_t num_options = ARRAY_SIZE (mips_options);
2803 size_t num_args = MIPS_OPTION_ARG_SIZE;
2804 disasm_option_arg_t *args;
2805 disasm_options_t *opts;
2806 size_t i;
2807 size_t j;
2809 args = XNEWVEC (disasm_option_arg_t, num_args + 1);
2811 args[MIPS_OPTION_ARG_ABI].name = "ABI";
2812 args[MIPS_OPTION_ARG_ABI].values
2813 = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1);
2814 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2815 args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name;
2816 /* The array we return must be NULL terminated. */
2817 args[MIPS_OPTION_ARG_ABI].values[i] = NULL;
2819 args[MIPS_OPTION_ARG_ARCH].name = "ARCH";
2820 args[MIPS_OPTION_ARG_ARCH].values
2821 = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1);
2822 for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2823 if (*mips_arch_choices[i].name != '\0')
2824 args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name;
2825 /* The array we return must be NULL terminated. */
2826 args[MIPS_OPTION_ARG_ARCH].values[j] = NULL;
2828 /* The array we return must be NULL terminated. */
2829 args[MIPS_OPTION_ARG_SIZE].name = NULL;
2830 args[MIPS_OPTION_ARG_SIZE].values = NULL;
2832 opts_and_args = XNEW (disasm_options_and_args_t);
2833 opts_and_args->args = args;
2835 opts = &opts_and_args->options;
2836 opts->name = XNEWVEC (const char *, num_options + 1);
2837 opts->description = XNEWVEC (const char *, num_options + 1);
2838 opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
2839 for (i = 0; i < num_options; i++)
2841 opts->name[i] = mips_options[i].name;
2842 opts->description[i] = _(mips_options[i].description);
2843 if (mips_options[i].arg != MIPS_OPTION_ARG_NONE)
2844 opts->arg[i] = &args[mips_options[i].arg];
2845 else
2846 opts->arg[i] = NULL;
2848 /* The array we return must be NULL terminated. */
2849 opts->name[i] = NULL;
2850 opts->description[i] = NULL;
2851 opts->arg[i] = NULL;
2854 return opts_and_args;
2857 void
2858 print_mips_disassembler_options (FILE *stream)
2860 const disasm_options_and_args_t *opts_and_args;
2861 const disasm_option_arg_t *args;
2862 const disasm_options_t *opts;
2863 size_t max_len = 0;
2864 size_t i;
2865 size_t j;
2867 opts_and_args = disassembler_options_mips ();
2868 opts = &opts_and_args->options;
2869 args = opts_and_args->args;
2871 fprintf (stream, _("\n\
2872 The following MIPS specific disassembler options are supported for use\n\
2873 with the -M switch (multiple options should be separated by commas):\n\n"));
2875 /* Compute the length of the longest option name. */
2876 for (i = 0; opts->name[i] != NULL; i++)
2878 size_t len = strlen (opts->name[i]);
2880 if (opts->arg[i] != NULL)
2881 len += strlen (opts->arg[i]->name);
2882 if (max_len < len)
2883 max_len = len;
2886 for (i = 0, max_len++; opts->name[i] != NULL; i++)
2888 fprintf (stream, " %s", opts->name[i]);
2889 if (opts->arg[i] != NULL)
2890 fprintf (stream, "%s", opts->arg[i]->name);
2891 if (opts->description[i] != NULL)
2893 size_t len = strlen (opts->name[i]);
2895 if (opts->arg[i] != NULL)
2896 len += strlen (opts->arg[i]->name);
2897 fprintf (stream,
2898 "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
2900 fprintf (stream, _("\n"));
2903 for (i = 0; args[i].name != NULL; i++)
2905 if (args[i].values == NULL)
2906 continue;
2907 fprintf (stream, _("\n\
2908 For the options above, the following values are supported for \"%s\":\n "),
2909 args[i].name);
2910 for (j = 0; args[i].values[j] != NULL; j++)
2911 fprintf (stream, " %s", args[i].values[j]);
2912 fprintf (stream, _("\n"));
2915 fprintf (stream, _("\n"));