testsuite: skip confirmation in 'gdb_reinitialize_dir'
[binutils-gdb.git] / opcodes / mips-dis.c
blobad5ec8ab9b29edb55b08160be279d931e6bd3412
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2024 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 { "allegrex", 1, bfd_mach_mips_allegrex, CPU_ALLEGREX, ISA_MIPS2, 0,
493 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
494 mips_hwr_names_numeric },
495 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
496 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
497 mips_hwr_names_numeric },
498 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
499 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
500 mips_hwr_names_numeric },
501 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
502 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
503 mips_hwr_names_numeric },
504 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
505 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
506 mips_hwr_names_numeric },
507 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
508 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_mips,
509 mips_hwr_names_numeric },
510 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
511 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
512 mips_hwr_names_numeric },
513 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
514 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
515 mips_hwr_names_numeric },
516 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
517 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
518 mips_hwr_names_numeric },
519 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
520 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
521 mips_hwr_names_numeric },
522 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
523 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
524 mips_hwr_names_numeric },
525 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
526 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_mips,
527 mips_hwr_names_numeric },
528 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
529 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
530 mips_hwr_names_numeric },
531 { "rm7000", 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 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
535 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
536 mips_hwr_names_numeric },
537 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
538 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
539 mips_hwr_names_numeric },
540 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
541 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
542 mips_hwr_names_numeric },
543 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
544 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
545 mips_hwr_names_numeric },
546 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
547 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
548 mips_hwr_names_numeric },
549 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
550 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
551 mips_hwr_names_numeric },
552 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
553 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips,
554 mips_hwr_names_numeric },
556 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
557 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
558 _MIPS32 Architecture For Programmers Volume I: Introduction to the
559 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
560 page 1. */
561 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
562 ISA_MIPS32, ASE_SMARTMIPS,
563 mips_cp0_names_mips3264,
564 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
565 mips_cp1_names_mips3264, mips_hwr_names_numeric },
567 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
568 ISA_MIPS32R2,
569 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
570 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
571 mips_cp0_names_mips3264r2,
572 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
573 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
575 { "mips32r3", 1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
576 ISA_MIPS32R3,
577 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
578 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
579 mips_cp0_names_mips3264r2,
580 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
581 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
583 { "mips32r5", 1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
584 ISA_MIPS32R5,
585 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
586 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
587 mips_cp0_names_mips3264r2,
588 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
589 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
591 { "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
592 ISA_MIPS32R6,
593 (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
594 | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC | ASE_GINV),
595 mips_cp0_names_mips3264r2,
596 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
597 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
599 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
600 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
601 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
602 mips_cp0_names_mips3264,
603 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
604 mips_cp1_names_mips3264, mips_hwr_names_numeric },
606 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
607 ISA_MIPS64R2,
608 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
609 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
610 mips_cp0_names_mips3264r2,
611 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
612 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
614 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
615 ISA_MIPS64R3,
616 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
617 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
618 mips_cp0_names_mips3264r2,
619 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
620 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
622 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
623 ISA_MIPS64R5,
624 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
625 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
626 mips_cp0_names_mips3264r2,
627 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
628 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
630 { "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
631 ISA_MIPS64R6,
632 (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
633 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC
634 | ASE_CRC64 | ASE_GINV),
635 mips_cp0_names_mips3264r2,
636 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
637 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
639 { "interaptiv-mr2", 1, bfd_mach_mips_interaptiv_mr2, CPU_INTERAPTIV_MR2,
640 ISA_MIPS32R3,
641 ASE_MT | ASE_EVA | ASE_DSP | ASE_DSPR2 | ASE_MIPS16E2 | ASE_MIPS16E2_MT,
642 mips_cp0_names_mips3264r2,
643 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
644 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
646 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
647 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
648 mips_cp0_names_sb1,
649 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
650 mips_cp1_names_mips3264, mips_hwr_names_numeric },
652 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
653 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
654 NULL, 0, mips_cp1_names_mips, mips_hwr_names_numeric },
656 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
657 ISA_MIPS3 | INSN_LOONGSON_2F, ASE_LOONGSON_MMI, mips_cp0_names_numeric,
658 NULL, 0, mips_cp1_names_mips, mips_hwr_names_numeric },
660 /* The loongson3a is an alias of gs464 for compatibility */
661 { "loongson3a", 1, bfd_mach_mips_gs464, CPU_GS464,
662 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
663 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
664 mips_hwr_names_numeric },
666 { "gs464", 1, bfd_mach_mips_gs464, CPU_GS464,
667 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
668 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
669 mips_hwr_names_numeric },
671 { "gs464e", 1, bfd_mach_mips_gs464e, CPU_GS464E,
672 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
673 | ASE_LOONGSON_EXT2, mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
674 mips_hwr_names_numeric },
676 { "gs264e", 1, bfd_mach_mips_gs264e, CPU_GS264E,
677 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
678 | ASE_LOONGSON_EXT2 | ASE_MSA | ASE_MSA64, mips_cp0_names_numeric, NULL,
679 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
681 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
682 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
683 mips_cp1_names_mips3264, mips_hwr_names_numeric },
685 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
686 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
687 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
689 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
690 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
691 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
693 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
694 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
695 mips_cp0_names_numeric,
696 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
698 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
699 ISA_MIPS64 | INSN_XLR, 0,
700 mips_cp0_names_xlr,
701 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
702 mips_cp1_names_mips3264, mips_hwr_names_numeric },
704 /* XLP is mostly like XLR, with the prominent exception it is being
705 MIPS64R2. */
706 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
707 ISA_MIPS64R2 | INSN_XLR, 0,
708 mips_cp0_names_xlr,
709 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
710 mips_cp1_names_mips3264, mips_hwr_names_numeric },
712 /* This entry, mips16, is here only for ISA/processor selection; do
713 not print its name. */
714 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
715 ASE_MIPS16E2 | ASE_MIPS16E2_MT,
716 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
717 mips_hwr_names_numeric },
720 /* ISA and processor type to disassemble for, and register names to use.
721 set_default_mips_dis_options and parse_mips_dis_options fill in these
722 values. */
723 static int mips_processor;
724 static int mips_isa;
725 static int mips_ase;
726 static int micromips_ase;
727 static const char * const *mips_gpr_names;
728 static const char * const *mips_fpr_names;
729 static const char * const *mips_cp0_names;
730 static const struct mips_cp0sel_name *mips_cp0sel_names;
731 static int mips_cp0sel_names_len;
732 static const char * const *mips_cp1_names;
733 static const char * const *mips_hwr_names;
735 /* Other options */
736 static int no_aliases; /* If set disassemble as most general inst. */
738 static const struct mips_abi_choice *
739 choose_abi_by_name (const char *name, unsigned int namelen)
741 const struct mips_abi_choice *c;
742 unsigned int i;
744 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
745 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
746 && strlen (mips_abi_choices[i].name) == namelen)
747 c = &mips_abi_choices[i];
749 return c;
752 static const struct mips_arch_choice *
753 choose_arch_by_name (const char *name, unsigned int namelen)
755 const struct mips_arch_choice *c = NULL;
756 unsigned int i;
758 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
759 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
760 && strlen (mips_arch_choices[i].name) == namelen)
761 c = &mips_arch_choices[i];
763 return c;
766 static const struct mips_arch_choice *
767 choose_arch_by_number (unsigned long mach)
769 static unsigned long hint_bfd_mach;
770 static const struct mips_arch_choice *hint_arch_choice;
771 const struct mips_arch_choice *c;
772 unsigned int i;
774 /* We optimize this because even if the user specifies no
775 flags, this will be done for every instruction! */
776 if (hint_bfd_mach == mach
777 && hint_arch_choice != NULL
778 && hint_arch_choice->bfd_mach == hint_bfd_mach)
779 return hint_arch_choice;
781 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
783 if (mips_arch_choices[i].bfd_mach_valid
784 && mips_arch_choices[i].bfd_mach == mach)
786 c = &mips_arch_choices[i];
787 hint_bfd_mach = mach;
788 hint_arch_choice = c;
791 return c;
794 /* Check if the object uses NewABI conventions. */
796 static int
797 is_newabi (Elf_Internal_Ehdr *header)
799 /* There are no old-style ABIs which use 64-bit ELF. */
800 if (header->e_ident[EI_CLASS] == ELFCLASS64)
801 return 1;
803 /* If a 32-bit ELF file, n32 is a new-style ABI. */
804 if ((header->e_flags & EF_MIPS_ABI2) != 0)
805 return 1;
807 return 0;
810 /* Check if the object has microMIPS ASE code. */
812 static int
813 is_micromips (Elf_Internal_Ehdr *header)
815 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
816 return 1;
818 return 0;
821 /* Convert ASE flags from .MIPS.abiflags to internal values. */
823 static unsigned long
824 mips_convert_abiflags_ases (unsigned long afl_ases)
826 unsigned long opcode_ases = 0;
828 if (afl_ases & AFL_ASE_DSP)
829 opcode_ases |= ASE_DSP;
830 if (afl_ases & AFL_ASE_DSPR2)
831 opcode_ases |= ASE_DSPR2;
832 if (afl_ases & AFL_ASE_EVA)
833 opcode_ases |= ASE_EVA;
834 if (afl_ases & AFL_ASE_MCU)
835 opcode_ases |= ASE_MCU;
836 if (afl_ases & AFL_ASE_MDMX)
837 opcode_ases |= ASE_MDMX;
838 if (afl_ases & AFL_ASE_MIPS3D)
839 opcode_ases |= ASE_MIPS3D;
840 if (afl_ases & AFL_ASE_MT)
841 opcode_ases |= ASE_MT;
842 if (afl_ases & AFL_ASE_SMARTMIPS)
843 opcode_ases |= ASE_SMARTMIPS;
844 if (afl_ases & AFL_ASE_VIRT)
845 opcode_ases |= ASE_VIRT;
846 if (afl_ases & AFL_ASE_MSA)
847 opcode_ases |= ASE_MSA;
848 if (afl_ases & AFL_ASE_XPA)
849 opcode_ases |= ASE_XPA;
850 if (afl_ases & AFL_ASE_DSPR3)
851 opcode_ases |= ASE_DSPR3;
852 if (afl_ases & AFL_ASE_MIPS16E2)
853 opcode_ases |= ASE_MIPS16E2;
854 return opcode_ases;
857 /* Calculate combination ASE flags from regular ASE flags. */
859 static unsigned long
860 mips_calculate_combination_ases (int opcode_isa, unsigned long opcode_ases)
862 unsigned long combination_ases = 0;
864 if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
865 combination_ases |= ASE_XPA_VIRT;
866 if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
867 combination_ases |= ASE_MIPS16E2_MT;
868 if ((opcode_ases & ASE_EVA)
869 && ((opcode_isa & INSN_ISA_MASK) == ISA_MIPS64R6
870 || (opcode_isa & INSN_ISA_MASK) == ISA_MIPS32R6))
871 combination_ases |= ASE_EVA_R6;
872 return combination_ases;
875 static void
876 set_default_mips_dis_options (struct disassemble_info *info)
878 const struct mips_arch_choice *chosen_arch;
880 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
881 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
882 CP0 register, and HWR names. */
883 mips_isa = ISA_MIPS3;
884 mips_processor = CPU_R3000;
885 micromips_ase = 0;
886 mips_ase = 0;
887 mips_gpr_names = mips_gpr_names_oldabi;
888 mips_fpr_names = mips_fpr_names_numeric;
889 mips_cp0_names = mips_cp0_names_numeric;
890 mips_cp0sel_names = NULL;
891 mips_cp0sel_names_len = 0;
892 mips_cp1_names = mips_cp1_names_numeric;
893 mips_hwr_names = mips_hwr_names_numeric;
894 no_aliases = 0;
896 /* Set ISA, architecture, and cp0 register names as best we can. */
897 #if ! SYMTAB_AVAILABLE
898 /* This is running out on a target machine, not in a host tool.
899 FIXME: Where does mips_target_info come from? */
900 target_processor = mips_target_info.processor;
901 mips_isa = mips_target_info.isa;
902 mips_ase = mips_target_info.ase;
903 #else
904 chosen_arch = choose_arch_by_number (info->mach);
905 if (chosen_arch != NULL)
907 mips_processor = chosen_arch->processor;
908 mips_isa = chosen_arch->isa;
909 mips_ase = chosen_arch->ase;
910 mips_cp0_names = chosen_arch->cp0_names;
911 mips_cp0sel_names = chosen_arch->cp0sel_names;
912 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
913 mips_cp1_names = chosen_arch->cp1_names;
914 mips_hwr_names = chosen_arch->hwr_names;
917 /* Update settings according to the ELF file header flags. */
918 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
920 struct bfd *abfd = info->section->owner;
921 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
922 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
924 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
925 because we won't then have a MIPS/ELF BFD, however we need
926 to guard against a link error in a `--enable-targets=...'
927 configuration with a 32-bit host where the MIPS target is
928 a secondary, or with MIPS/ECOFF configurations. */
929 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
930 abiflags = bfd_mips_elf_get_abiflags (abfd);
931 #endif
932 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
933 if (is_newabi (header))
934 mips_gpr_names = mips_gpr_names_newabi;
935 /* If a microMIPS binary, then don't use MIPS16 bindings. */
936 micromips_ase = is_micromips (header);
937 /* OR in any extra ASE flags set in ELF file structures. */
938 if (abiflags)
939 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
940 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
941 mips_ase |= ASE_MDMX;
943 #endif
944 mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
947 /* Parse an ASE disassembler option and set the corresponding global
948 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
950 static bool
951 parse_mips_ase_option (const char *option)
953 if (startswith (option, "msa"))
955 mips_ase |= ASE_MSA;
956 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
957 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
958 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
959 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
960 mips_ase |= ASE_MSA64;
961 return true;
964 if (startswith (option, "virt"))
966 mips_ase |= ASE_VIRT;
967 if (mips_isa & ISA_MIPS64R2
968 || mips_isa & ISA_MIPS64R3
969 || mips_isa & ISA_MIPS64R5
970 || mips_isa & ISA_MIPS64R6)
971 mips_ase |= ASE_VIRT64;
972 return true;
975 if (startswith (option, "xpa"))
977 mips_ase |= ASE_XPA;
978 return true;
981 if (startswith (option, "ginv"))
983 mips_ase |= ASE_GINV;
984 return true;
987 if (startswith (option, "loongson-mmi"))
989 mips_ase |= ASE_LOONGSON_MMI;
990 return true;
993 if (startswith (option, "loongson-cam"))
995 mips_ase |= ASE_LOONGSON_CAM;
996 return true;
999 /* Put here for match ext2 frist */
1000 if (startswith (option, "loongson-ext2"))
1002 mips_ase |= ASE_LOONGSON_EXT2;
1003 return true;
1006 if (startswith (option, "loongson-ext"))
1008 mips_ase |= ASE_LOONGSON_EXT;
1009 return true;
1012 return false;
1015 static void
1016 parse_mips_dis_option (const char *option, unsigned int len)
1018 unsigned int i, optionlen, vallen;
1019 const char *val;
1020 const struct mips_abi_choice *chosen_abi;
1021 const struct mips_arch_choice *chosen_arch;
1023 /* Try to match options that are simple flags */
1024 if (startswith (option, "no-aliases"))
1026 no_aliases = 1;
1027 return;
1030 if (parse_mips_ase_option (option))
1032 mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
1033 return;
1036 /* Look for the = that delimits the end of the option name. */
1037 for (i = 0; i < len; i++)
1038 if (option[i] == '=')
1039 break;
1041 if (i == 0) /* Invalid option: no name before '='. */
1042 return;
1043 if (i == len) /* Invalid option: no '='. */
1044 return;
1045 if (i == (len - 1)) /* Invalid option: no value after '='. */
1046 return;
1048 optionlen = i;
1049 val = option + (optionlen + 1);
1050 vallen = len - (optionlen + 1);
1052 if (strncmp ("gpr-names", option, optionlen) == 0
1053 && strlen ("gpr-names") == optionlen)
1055 chosen_abi = choose_abi_by_name (val, vallen);
1056 if (chosen_abi != NULL)
1057 mips_gpr_names = chosen_abi->gpr_names;
1058 return;
1061 if (strncmp ("fpr-names", option, optionlen) == 0
1062 && strlen ("fpr-names") == optionlen)
1064 chosen_abi = choose_abi_by_name (val, vallen);
1065 if (chosen_abi != NULL)
1066 mips_fpr_names = chosen_abi->fpr_names;
1067 return;
1070 if (strncmp ("cp0-names", option, optionlen) == 0
1071 && strlen ("cp0-names") == optionlen)
1073 chosen_arch = choose_arch_by_name (val, vallen);
1074 if (chosen_arch != NULL)
1076 mips_cp0_names = chosen_arch->cp0_names;
1077 mips_cp0sel_names = chosen_arch->cp0sel_names;
1078 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1080 return;
1083 if (strncmp ("cp1-names", option, optionlen) == 0
1084 && strlen ("cp1-names") == optionlen)
1086 chosen_arch = choose_arch_by_name (val, vallen);
1087 if (chosen_arch != NULL)
1088 mips_cp1_names = chosen_arch->cp1_names;
1089 return;
1092 if (strncmp ("hwr-names", option, optionlen) == 0
1093 && strlen ("hwr-names") == optionlen)
1095 chosen_arch = choose_arch_by_name (val, vallen);
1096 if (chosen_arch != NULL)
1097 mips_hwr_names = chosen_arch->hwr_names;
1098 return;
1101 if (strncmp ("reg-names", option, optionlen) == 0
1102 && strlen ("reg-names") == optionlen)
1104 /* We check both ABI and ARCH here unconditionally, so
1105 that "numeric" will do the desirable thing: select
1106 numeric register names for all registers. Other than
1107 that, a given name probably won't match both. */
1108 chosen_abi = choose_abi_by_name (val, vallen);
1109 if (chosen_abi != NULL)
1111 mips_gpr_names = chosen_abi->gpr_names;
1112 mips_fpr_names = chosen_abi->fpr_names;
1114 chosen_arch = choose_arch_by_name (val, vallen);
1115 if (chosen_arch != NULL)
1117 mips_cp0_names = chosen_arch->cp0_names;
1118 mips_cp0sel_names = chosen_arch->cp0sel_names;
1119 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1120 mips_cp1_names = chosen_arch->cp1_names;
1121 mips_hwr_names = chosen_arch->hwr_names;
1123 return;
1126 /* Invalid option. */
1129 static void
1130 parse_mips_dis_options (const char *options)
1132 const char *option_end;
1134 if (options == NULL)
1135 return;
1137 while (*options != '\0')
1139 /* Skip empty options. */
1140 if (*options == ',')
1142 options++;
1143 continue;
1146 /* We know that *options is neither NUL or a comma. */
1147 option_end = options + 1;
1148 while (*option_end != ',' && *option_end != '\0')
1149 option_end++;
1151 parse_mips_dis_option (options, option_end - options);
1153 /* Go on to the next one. If option_end points to a comma, it
1154 will be skipped above. */
1155 options = option_end;
1159 static const struct mips_cp0sel_name *
1160 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1161 unsigned int len,
1162 unsigned int cp0reg,
1163 unsigned int sel)
1165 unsigned int i;
1167 for (i = 0; i < len; i++)
1168 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1169 return &names[i];
1170 return NULL;
1173 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1175 static void
1176 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1177 enum mips_reg_operand_type type, int regno)
1179 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1181 switch (type)
1183 case OP_REG_GP:
1184 infprintf (info->stream, dis_style_register, "%s",
1185 mips_gpr_names[regno]);
1186 break;
1188 case OP_REG_FP:
1189 infprintf (info->stream, dis_style_register, "%s",
1190 mips_fpr_names[regno]);
1191 break;
1193 case OP_REG_CCC:
1194 if (opcode->pinfo & (FP_D | FP_S))
1195 infprintf (info->stream, dis_style_register, "$fcc%d", regno);
1196 else
1197 infprintf (info->stream, dis_style_register, "$cc%d", regno);
1198 break;
1200 case OP_REG_VEC:
1201 if (opcode->membership & INSN_5400)
1202 infprintf (info->stream, dis_style_register, "$f%d", regno);
1203 else
1204 infprintf (info->stream, dis_style_register, "$v%d", regno);
1205 break;
1207 case OP_REG_ACC:
1208 infprintf (info->stream, dis_style_register, "$ac%d", regno);
1209 break;
1211 case OP_REG_COPRO:
1212 if (opcode->name[strlen (opcode->name) - 1] == '0')
1213 infprintf (info->stream, dis_style_register, "%s", mips_cp0_names[regno]);
1214 else
1215 infprintf (info->stream, dis_style_register, "$%d", regno);
1216 break;
1218 case OP_REG_CONTROL:
1219 if (opcode->name[strlen (opcode->name) - 1] == '1')
1220 infprintf (info->stream, dis_style_register, "%s", mips_cp1_names[regno]);
1221 else
1222 infprintf (info->stream, dis_style_register, "$%d", regno);
1223 break;
1225 case OP_REG_HW:
1226 infprintf (info->stream, dis_style_register, "%s", mips_hwr_names[regno]);
1227 break;
1229 case OP_REG_VF:
1230 infprintf (info->stream, dis_style_register, "$vf%d", regno);
1231 break;
1233 case OP_REG_VI:
1234 infprintf (info->stream, dis_style_register, "$vi%d", regno);
1235 break;
1237 case OP_REG_R5900_I:
1238 infprintf (info->stream, dis_style_register, "$I");
1239 break;
1241 case OP_REG_R5900_Q:
1242 infprintf (info->stream, dis_style_register, "$Q");
1243 break;
1245 case OP_REG_R5900_R:
1246 infprintf (info->stream, dis_style_register, "$R");
1247 break;
1249 case OP_REG_R5900_ACC:
1250 infprintf (info->stream, dis_style_register, "$ACC");
1251 break;
1253 case OP_REG_MSA:
1254 infprintf (info->stream, dis_style_register, "$w%d", regno);
1255 break;
1257 case OP_REG_MSA_CTRL:
1258 infprintf (info->stream, dis_style_register, "%s",
1259 msa_control_names[regno]);
1260 break;
1265 /* Used to track the state carried over from previous operands in
1266 an instruction. */
1267 struct mips_print_arg_state {
1268 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1269 where the value is known to be unsigned and small. */
1270 unsigned int last_int;
1272 /* The type and number of the last OP_REG seen. We only use this for
1273 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1274 enum mips_reg_operand_type last_reg_type;
1275 unsigned int last_regno;
1276 unsigned int dest_regno;
1277 unsigned int seen_dest;
1280 /* Initialize STATE for the start of an instruction. */
1282 static inline void
1283 init_print_arg_state (struct mips_print_arg_state *state)
1285 memset (state, 0, sizeof (*state));
1288 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1289 whose value is given by UVAL. */
1291 static void
1292 print_vu0_channel (struct disassemble_info *info,
1293 const struct mips_operand *operand, unsigned int uval,
1294 enum disassembler_style style)
1296 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1298 if (operand->size == 4)
1299 infprintf (info->stream, style, "%s%s%s%s",
1300 uval & 8 ? "x" : "",
1301 uval & 4 ? "y" : "",
1302 uval & 2 ? "z" : "",
1303 uval & 1 ? "w" : "");
1304 else if (operand->size == 2)
1305 infprintf (info->stream, style, "%c", "xyzw"[uval]);
1306 else
1307 abort ();
1310 /* Record information about a register operand. */
1312 static void
1313 mips_seen_register (struct mips_print_arg_state *state,
1314 unsigned int regno,
1315 enum mips_reg_operand_type reg_type)
1317 state->last_reg_type = reg_type;
1318 state->last_regno = regno;
1320 if (!state->seen_dest)
1322 state->seen_dest = 1;
1323 state->dest_regno = regno;
1327 /* Print SAVE/RESTORE instruction operands according to the argument
1328 register mask AMASK, the number of static registers saved NSREG,
1329 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1330 and the frame size FRAME_SIZE. */
1332 static void
1333 mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
1334 unsigned int nsreg, unsigned int ra,
1335 unsigned int s0, unsigned int s1,
1336 unsigned int frame_size)
1338 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1339 unsigned int nargs, nstatics, smask, i, j;
1340 void *is = info->stream;
1341 const char *sep;
1343 if (amask == MIPS_SVRS_ALL_ARGS)
1345 nargs = 4;
1346 nstatics = 0;
1348 else if (amask == MIPS_SVRS_ALL_STATICS)
1350 nargs = 0;
1351 nstatics = 4;
1353 else
1355 nargs = amask >> 2;
1356 nstatics = amask & 3;
1359 sep = "";
1360 if (nargs > 0)
1362 infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1363 if (nargs > 1)
1364 infprintf (is, dis_style_register, "-%s", mips_gpr_names[4 + nargs - 1]);
1365 sep = ",";
1368 infprintf (is, dis_style_text, "%s", sep);
1369 infprintf (is, dis_style_immediate, "%d", frame_size);
1371 if (ra) /* $ra */
1373 infprintf (is, dis_style_text, ",");
1374 infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1377 smask = 0;
1378 if (s0) /* $s0 */
1379 smask |= 1 << 0;
1380 if (s1) /* $s1 */
1381 smask |= 1 << 1;
1382 if (nsreg > 0) /* $s2-$s8 */
1383 smask |= ((1 << nsreg) - 1) << 2;
1385 for (i = 0; i < 9; i++)
1386 if (smask & (1 << i))
1388 infprintf (is, dis_style_text, ",");
1389 infprintf (is, dis_style_register, "%s",
1390 mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1391 /* Skip over string of set bits. */
1392 for (j = i; smask & (2 << j); j++)
1393 continue;
1394 if (j > i)
1396 infprintf (is, dis_style_text, "-");
1397 infprintf (is, dis_style_register, "%s",
1398 mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1400 i = j + 1;
1402 /* Statics $ax - $a3. */
1403 if (nstatics == 1)
1405 infprintf (is, dis_style_text, ",");
1406 infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1408 else if (nstatics > 0)
1410 infprintf (is, dis_style_text, ",");
1411 infprintf (is, dis_style_register, "%s",
1412 mips_gpr_names[7 - nstatics + 1]);
1413 infprintf (is, dis_style_text, "-");
1414 infprintf (is, dis_style_register, "%s", mips_gpr_names[7]);
1419 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1420 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1421 the base address for OP_PCREL operands. */
1423 static void
1424 print_insn_arg (struct disassemble_info *info,
1425 struct mips_print_arg_state *state,
1426 const struct mips_opcode *opcode,
1427 const struct mips_operand *operand,
1428 bfd_vma base_pc,
1429 unsigned int uval)
1431 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1432 void *is = info->stream;
1434 switch (operand->type)
1436 case OP_INT:
1438 const struct mips_int_operand *int_op;
1440 int_op = (const struct mips_int_operand *) operand;
1441 uval = mips_decode_int_operand (int_op, uval);
1442 state->last_int = uval;
1443 if (int_op->print_hex)
1444 infprintf (is, dis_style_immediate, "0x%x", uval);
1445 else
1446 infprintf (is, dis_style_immediate, "%d", uval);
1448 break;
1450 case OP_MAPPED_INT:
1452 const struct mips_mapped_int_operand *mint_op;
1454 mint_op = (const struct mips_mapped_int_operand *) operand;
1455 uval = mint_op->int_map[uval];
1456 state->last_int = uval;
1457 if (mint_op->print_hex)
1458 infprintf (is, dis_style_immediate, "0x%x", uval);
1459 else
1460 infprintf (is, dis_style_immediate, "%d", uval);
1462 break;
1464 case OP_MSB:
1466 const struct mips_msb_operand *msb_op;
1468 msb_op = (const struct mips_msb_operand *) operand;
1469 uval += msb_op->bias;
1470 if (msb_op->add_lsb)
1471 uval -= state->last_int;
1472 infprintf (is, dis_style_immediate, "0x%x", uval);
1474 break;
1476 case OP_REG:
1477 case OP_OPTIONAL_REG:
1479 const struct mips_reg_operand *reg_op;
1481 reg_op = (const struct mips_reg_operand *) operand;
1482 uval = mips_decode_reg_operand (reg_op, uval);
1483 print_reg (info, opcode, reg_op->reg_type, uval);
1485 mips_seen_register (state, uval, reg_op->reg_type);
1487 break;
1489 case OP_REG_PAIR:
1491 const struct mips_reg_pair_operand *pair_op;
1493 pair_op = (const struct mips_reg_pair_operand *) operand;
1494 print_reg (info, opcode, pair_op->reg_type,
1495 pair_op->reg1_map[uval]);
1496 infprintf (is, dis_style_text, ",");
1497 print_reg (info, opcode, pair_op->reg_type,
1498 pair_op->reg2_map[uval]);
1500 break;
1502 case OP_PCREL:
1504 const struct mips_pcrel_operand *pcrel_op;
1506 pcrel_op = (const struct mips_pcrel_operand *) operand;
1507 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1509 /* For jumps and branches clear the ISA bit except for
1510 the GDB disassembler. */
1511 if (pcrel_op->include_isa_bit
1512 && info->flavour != bfd_target_unknown_flavour)
1513 info->target &= -2;
1515 (*info->print_address_func) (info->target, info);
1517 break;
1519 case OP_PERF_REG:
1520 infprintf (is, dis_style_register, "%d", uval);
1521 break;
1523 case OP_ADDIUSP_INT:
1525 int sval;
1527 sval = mips_signed_operand (operand, uval) * 4;
1528 if (sval >= -8 && sval < 8)
1529 sval ^= 0x400;
1530 infprintf (is, dis_style_immediate, "%d", sval);
1531 break;
1534 case OP_CLO_CLZ_DEST:
1536 unsigned int reg1, reg2;
1538 reg1 = uval & 31;
1539 reg2 = uval >> 5;
1540 /* If one is zero use the other. */
1541 if (reg1 == reg2 || reg2 == 0)
1542 infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1543 else if (reg1 == 0)
1544 infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1545 else
1547 /* Bogus, result depends on processor. */
1548 infprintf (is, dis_style_register, "%s", mips_gpr_names[reg1]);
1549 infprintf (is, dis_style_text, " or ");
1550 infprintf (is, dis_style_register, "%s", mips_gpr_names[reg2]);
1553 break;
1555 case OP_SAME_RS_RT:
1556 case OP_CHECK_PREV:
1557 case OP_NON_ZERO_REG:
1559 print_reg (info, opcode, OP_REG_GP, uval & 31);
1560 mips_seen_register (state, uval, OP_REG_GP);
1562 break;
1564 case OP_LWM_SWM_LIST:
1565 if (operand->size == 2)
1567 if (uval == 0)
1569 infprintf (is, dis_style_register, "%s",
1570 mips_gpr_names[16]);
1571 infprintf (is, dis_style_text, ",");
1572 infprintf (is, dis_style_register, "%s",
1573 mips_gpr_names[31]);
1575 else
1577 infprintf (is, dis_style_register, "%s",
1578 mips_gpr_names[16]);
1579 infprintf (is, dis_style_text, "-");
1580 infprintf (is, dis_style_register, "%s",
1581 mips_gpr_names[16 + uval]);
1582 infprintf (is, dis_style_text, ",");
1583 infprintf (is, dis_style_register, "%s",
1584 mips_gpr_names[31]);
1587 else
1589 int s_reg_encode;
1591 s_reg_encode = uval & 0xf;
1592 if (s_reg_encode != 0)
1594 if (s_reg_encode == 1)
1595 infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1596 else if (s_reg_encode < 9)
1598 infprintf (is, dis_style_register, "%s",
1599 mips_gpr_names[16]);
1600 infprintf (is, dis_style_text, "-");
1601 infprintf (is, dis_style_register, "%s",
1602 mips_gpr_names[15 + s_reg_encode]);
1604 else if (s_reg_encode == 9)
1606 infprintf (is, dis_style_register, "%s",
1607 mips_gpr_names[16]);
1608 infprintf (is, dis_style_text, "-");
1609 infprintf (is, dis_style_register, "%s",
1610 mips_gpr_names[23]);
1611 infprintf (is, dis_style_text, ",");
1612 infprintf (is, dis_style_register, "%s",
1613 mips_gpr_names[30]);
1615 else
1616 infprintf (is, dis_style_text, "UNKNOWN");
1619 if (uval & 0x10) /* For ra. */
1621 if (s_reg_encode == 0)
1622 infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1623 else
1625 infprintf (is, dis_style_text, ",");
1626 infprintf (is, dis_style_register, "%s",
1627 mips_gpr_names[31]);
1631 break;
1633 case OP_ENTRY_EXIT_LIST:
1635 const char *sep;
1636 unsigned int amask, smask;
1638 sep = "";
1639 amask = (uval >> 3) & 7;
1640 if (amask > 0 && amask < 5)
1642 infprintf (is, dis_style_register, "%s", mips_gpr_names[4]);
1643 if (amask > 1)
1645 infprintf (is, dis_style_text, "-");
1646 infprintf (is, dis_style_register, "%s",
1647 mips_gpr_names[amask + 3]);
1649 sep = ",";
1652 smask = (uval >> 1) & 3;
1653 if (smask == 3)
1655 infprintf (is, dis_style_text, "%s??", sep);
1656 sep = ",";
1658 else if (smask > 0)
1660 infprintf (is, dis_style_text, "%s", sep);
1661 infprintf (is, dis_style_register, "%s", mips_gpr_names[16]);
1662 if (smask > 1)
1664 infprintf (is, dis_style_text, "-");
1665 infprintf (is, dis_style_register, "%s",
1666 mips_gpr_names[smask + 15]);
1668 sep = ",";
1671 if (uval & 1)
1673 infprintf (is, dis_style_text, "%s", sep);
1674 infprintf (is, dis_style_register, "%s", mips_gpr_names[31]);
1675 sep = ",";
1678 if (amask == 5 || amask == 6)
1680 infprintf (is, dis_style_text, "%s", sep);
1681 infprintf (is, dis_style_register, "%s", mips_fpr_names[0]);
1682 if (amask == 6)
1684 infprintf (is, dis_style_text, "-");
1685 infprintf (is, dis_style_register, "%s", mips_fpr_names[1]);
1689 break;
1691 case OP_SAVE_RESTORE_LIST:
1692 /* Should be handled by the caller due to complex behavior. */
1693 abort ();
1695 case OP_MDMX_IMM_REG:
1697 unsigned int vsel;
1699 vsel = uval >> 5;
1700 uval &= 31;
1701 if ((vsel & 0x10) == 0)
1703 int fmt;
1705 vsel &= 0x0f;
1706 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1707 if ((vsel & 1) == 0)
1708 break;
1709 print_reg (info, opcode, OP_REG_VEC, uval);
1710 infprintf (is, dis_style_text, "[");
1711 infprintf (is, dis_style_immediate, "%d", vsel >> 1);
1712 infprintf (is, dis_style_text, "]");
1714 else if ((vsel & 0x08) == 0)
1715 print_reg (info, opcode, OP_REG_VEC, uval);
1716 else
1717 infprintf (is, dis_style_immediate, "0x%x", uval);
1719 break;
1721 case OP_REPEAT_PREV_REG:
1722 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1723 break;
1725 case OP_REPEAT_DEST_REG:
1726 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1727 break;
1729 case OP_PC:
1730 infprintf (is, dis_style_register, "$pc");
1731 break;
1733 case OP_REG28:
1734 print_reg (info, opcode, OP_REG_GP, 28);
1735 break;
1737 case OP_VU0_SUFFIX:
1738 case OP_VU0_MATCH_SUFFIX:
1739 print_vu0_channel (info, operand, uval, dis_style_register);
1740 break;
1742 case OP_IMM_INDEX:
1743 infprintf (is, dis_style_text, "[");
1744 infprintf (is, dis_style_immediate, "%d", uval);
1745 infprintf (is, dis_style_text, "]");
1746 break;
1748 case OP_REG_INDEX:
1749 infprintf (is, dis_style_text, "[");
1750 print_reg (info, opcode, OP_REG_GP, uval);
1751 infprintf (is, dis_style_text, "]");
1752 break;
1756 /* Validate the arguments for INSN, which is described by OPCODE.
1757 Use DECODE_OPERAND to get the encoding of each operand. */
1759 static bool
1760 validate_insn_args (const struct mips_opcode *opcode,
1761 const struct mips_operand *(*decode_operand) (const char *),
1762 unsigned int insn)
1764 struct mips_print_arg_state state;
1765 const struct mips_operand *operand;
1766 const char *s;
1767 unsigned int uval;
1769 init_print_arg_state (&state);
1770 for (s = opcode->args; *s; ++s)
1772 switch (*s)
1774 case ',':
1775 case '(':
1776 case ')':
1777 break;
1779 case '#':
1780 ++s;
1781 break;
1783 default:
1784 operand = decode_operand (s);
1786 if (operand)
1788 uval = mips_extract_operand (operand, insn);
1789 switch (operand->type)
1791 case OP_REG:
1792 case OP_OPTIONAL_REG:
1794 const struct mips_reg_operand *reg_op;
1796 reg_op = (const struct mips_reg_operand *) operand;
1797 uval = mips_decode_reg_operand (reg_op, uval);
1798 mips_seen_register (&state, uval, reg_op->reg_type);
1800 break;
1802 case OP_SAME_RS_RT:
1804 unsigned int reg1, reg2;
1806 reg1 = uval & 31;
1807 reg2 = uval >> 5;
1809 if (reg1 != reg2 || reg1 == 0)
1810 return false;
1812 break;
1814 case OP_CHECK_PREV:
1816 const struct mips_check_prev_operand *prev_op;
1818 prev_op = (const struct mips_check_prev_operand *) operand;
1820 if (!prev_op->zero_ok && uval == 0)
1821 return false;
1823 if (((prev_op->less_than_ok && uval < state.last_regno)
1824 || (prev_op->greater_than_ok && uval > state.last_regno)
1825 || (prev_op->equal_ok && uval == state.last_regno)))
1826 break;
1828 return false;
1831 case OP_NON_ZERO_REG:
1833 if (uval == 0)
1834 return false;
1836 break;
1838 case OP_INT:
1839 case OP_MAPPED_INT:
1840 case OP_MSB:
1841 case OP_REG_PAIR:
1842 case OP_PCREL:
1843 case OP_PERF_REG:
1844 case OP_ADDIUSP_INT:
1845 case OP_CLO_CLZ_DEST:
1846 case OP_LWM_SWM_LIST:
1847 case OP_ENTRY_EXIT_LIST:
1848 case OP_MDMX_IMM_REG:
1849 case OP_REPEAT_PREV_REG:
1850 case OP_REPEAT_DEST_REG:
1851 case OP_PC:
1852 case OP_REG28:
1853 case OP_VU0_SUFFIX:
1854 case OP_VU0_MATCH_SUFFIX:
1855 case OP_IMM_INDEX:
1856 case OP_REG_INDEX:
1857 case OP_SAVE_RESTORE_LIST:
1858 break;
1861 if (*s == 'm' || *s == '+' || *s == '-')
1862 ++s;
1865 return true;
1868 /* Print the arguments for INSN, which is described by OPCODE.
1869 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1870 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1871 operand is for a branch or jump. */
1873 static void
1874 print_insn_args (struct disassemble_info *info,
1875 const struct mips_opcode *opcode,
1876 const struct mips_operand *(*decode_operand) (const char *),
1877 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1879 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1880 void *is = info->stream;
1881 struct mips_print_arg_state state;
1882 const struct mips_operand *operand;
1883 const char *s;
1885 init_print_arg_state (&state);
1886 for (s = opcode->args; *s; ++s)
1888 switch (*s)
1890 case ',':
1891 case '(':
1892 case ')':
1893 infprintf (is, dis_style_text, "%c", *s);
1894 break;
1896 case '#':
1897 ++s;
1898 infprintf (is, dis_style_text, "%c%c", *s, *s);
1899 break;
1901 default:
1902 operand = decode_operand (s);
1903 if (!operand)
1905 /* xgettext:c-format */
1906 infprintf (is, dis_style_text,
1907 _("# internal error, undefined operand in `%s %s'"),
1908 opcode->name, opcode->args);
1909 return;
1912 if (operand->type == OP_SAVE_RESTORE_LIST)
1914 /* Handle this case here because of the complex behavior. */
1915 unsigned int amask = (insn >> 15) & 0xf;
1916 unsigned int nsreg = (insn >> 23) & 0x7;
1917 unsigned int ra = insn & 0x1000; /* $ra */
1918 unsigned int s0 = insn & 0x800; /* $s0 */
1919 unsigned int s1 = insn & 0x400; /* $s1 */
1920 unsigned int frame_size = (((insn >> 15) & 0xf0)
1921 | ((insn >> 6) & 0x0f)) * 8;
1922 mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1923 frame_size);
1925 else if (operand->type == OP_REG
1926 && s[1] == ','
1927 && (s[2] == 'H' || s[2] == 'J')
1928 && opcode->name[strlen (opcode->name) - 1] == '0')
1930 /* Coprocessor register 0 with sel field. */
1931 const struct mips_cp0sel_name *n;
1932 unsigned int reg, sel;
1934 reg = mips_extract_operand (operand, insn);
1935 s += 2;
1936 operand = decode_operand (s);
1937 sel = mips_extract_operand (operand, insn);
1939 /* CP0 register including 'sel' code for mftc0, to be
1940 printed textually if known. If not known, print both
1941 CP0 register name and sel numerically since CP0 register
1942 with sel 0 may have a name unrelated to register being
1943 printed. */
1944 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1945 mips_cp0sel_names_len,
1946 reg, sel);
1947 if (n != NULL)
1948 infprintf (is, dis_style_register, "%s", n->name);
1949 else
1951 infprintf (is, dis_style_register, "$%d", reg);
1952 infprintf (is, dis_style_text, ",");
1953 infprintf (is, dis_style_immediate, "%d", sel);
1956 else
1958 bfd_vma base_pc = insn_pc;
1960 /* Adjust the PC relative base so that branch/jump insns use
1961 the following PC as the base but genuinely PC relative
1962 operands use the current PC. */
1963 if (operand->type == OP_PCREL)
1965 const struct mips_pcrel_operand *pcrel_op;
1967 pcrel_op = (const struct mips_pcrel_operand *) operand;
1968 /* The include_isa_bit flag is sufficient to distinguish
1969 branch/jump from other PC relative operands. */
1970 if (pcrel_op->include_isa_bit)
1971 base_pc += length;
1974 print_insn_arg (info, &state, opcode, operand, base_pc,
1975 mips_extract_operand (operand, insn));
1977 if (*s == 'm' || *s == '+' || *s == '-')
1978 ++s;
1979 break;
1984 /* Print the mips instruction at address MEMADDR in debugged memory,
1985 on using INFO. Returns length of the instruction, in bytes, which is
1986 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1987 this is little-endian code. */
1989 static int
1990 print_insn_mips (bfd_vma memaddr,
1991 int word,
1992 struct disassemble_info *info)
1994 #define GET_OP(insn, field) \
1995 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1996 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1997 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
1998 const struct mips_opcode *op;
1999 static bool init = 0;
2000 void *is = info->stream;
2002 /* Build a hash table to shorten the search time. */
2003 if (! init)
2005 unsigned int i;
2007 for (i = 0; i <= OP_MASK_OP; i++)
2009 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
2011 if (op->pinfo == INSN_MACRO
2012 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2013 continue;
2014 if (i == GET_OP (op->match, OP))
2016 mips_hash[i] = op;
2017 break;
2022 init = 1;
2025 info->bytes_per_chunk = INSNLEN;
2026 info->display_endian = info->endian;
2027 info->insn_info_valid = 1;
2028 info->branch_delay_insns = 0;
2029 info->data_size = 0;
2030 info->insn_type = dis_nonbranch;
2031 info->target = 0;
2032 info->target2 = 0;
2034 op = mips_hash[GET_OP (word, OP)];
2035 if (op != NULL)
2037 for (; op < &mips_opcodes[NUMOPCODES]; op++)
2039 if (op->pinfo != INSN_MACRO
2040 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2041 && (word & op->mask) == op->match)
2043 /* We always disassemble the jalx instruction, except for MIPS r6. */
2044 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
2045 && (strcmp (op->name, "jalx")
2046 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
2047 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
2048 continue;
2050 /* Figure out instruction type and branch delay information. */
2051 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2053 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2054 info->insn_type = dis_jsr;
2055 else
2056 info->insn_type = dis_branch;
2057 info->branch_delay_insns = 1;
2059 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
2060 | INSN_COND_BRANCH_LIKELY)) != 0)
2062 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2063 info->insn_type = dis_condjsr;
2064 else
2065 info->insn_type = dis_condbranch;
2066 info->branch_delay_insns = 1;
2068 else if ((op->pinfo & (INSN_STORE_MEMORY
2069 | INSN_LOAD_MEMORY)) != 0)
2070 info->insn_type = dis_dref;
2072 if (!validate_insn_args (op, decode_mips_operand, word))
2073 continue;
2075 infprintf (is, dis_style_mnemonic, "%s", op->name);
2076 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
2078 unsigned int uval;
2080 infprintf (is, dis_style_mnemonic, ".");
2081 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
2082 print_vu0_channel (info, &mips_vu0_channel_mask, uval,
2083 dis_style_mnemonic);
2086 if (op->args[0])
2088 infprintf (is, dis_style_text, "\t");
2089 print_insn_args (info, op, decode_mips_operand, word,
2090 memaddr, 4);
2093 return INSNLEN;
2097 #undef GET_OP
2099 /* Handle undefined instructions. */
2100 info->insn_type = dis_noninsn;
2101 infprintf (is, dis_style_assembler_directive, ".word");
2102 infprintf (is, dis_style_text, "\t");
2103 infprintf (is, dis_style_immediate, "0x%x", word);
2104 return INSNLEN;
2107 /* Disassemble an operand for a mips16 instruction. */
2109 static void
2110 print_mips16_insn_arg (struct disassemble_info *info,
2111 struct mips_print_arg_state *state,
2112 const struct mips_opcode *opcode,
2113 char type, bfd_vma memaddr,
2114 unsigned insn, bool use_extend,
2115 unsigned extend, bool is_offset)
2117 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2118 void *is = info->stream;
2119 const struct mips_operand *operand, *ext_operand;
2120 unsigned short ext_size;
2121 unsigned int uval;
2122 bfd_vma baseaddr;
2124 if (!use_extend)
2125 extend = 0;
2127 switch (type)
2129 case ',':
2130 case '(':
2131 case ')':
2132 infprintf (is, dis_style_text, "%c", type);
2133 break;
2135 default:
2136 operand = decode_mips16_operand (type, false);
2137 if (!operand)
2139 /* xgettext:c-format */
2140 infprintf (is, dis_style_text, _("# internal error, undefined operand in `%s %s'"),
2141 opcode->name, opcode->args);
2142 return;
2145 if (operand->type == OP_SAVE_RESTORE_LIST)
2147 /* Handle this case here because of the complex interaction
2148 with the EXTEND opcode. */
2149 unsigned int amask = extend & 0xf;
2150 unsigned int nsreg = (extend >> 8) & 0x7;
2151 unsigned int ra = insn & 0x40; /* $ra */
2152 unsigned int s0 = insn & 0x20; /* $s0 */
2153 unsigned int s1 = insn & 0x10; /* $s1 */
2154 unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
2155 if (frame_size == 0 && !use_extend)
2156 frame_size = 128;
2157 mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
2158 break;
2161 if (is_offset && operand->type == OP_INT)
2163 const struct mips_int_operand *int_op;
2165 int_op = (const struct mips_int_operand *) operand;
2166 info->insn_type = dis_dref;
2167 info->data_size = 1 << int_op->shift;
2170 ext_size = 0;
2171 if (use_extend)
2173 ext_operand = decode_mips16_operand (type, true);
2174 if (ext_operand != operand
2175 || (operand->type == OP_INT && operand->lsb == 0
2176 && mips_opcode_32bit_p (opcode)))
2178 ext_size = ext_operand->size;
2179 operand = ext_operand;
2182 if (operand->size == 26)
2183 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
2184 else if (ext_size == 16 || ext_size == 9)
2185 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2186 else if (ext_size == 15)
2187 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2188 else if (ext_size == 6)
2189 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2190 else
2191 uval = mips_extract_operand (operand, (extend << 16) | insn);
2192 if (ext_size == 9)
2193 uval &= (1U << ext_size) - 1;
2195 baseaddr = memaddr + 2;
2196 if (operand->type == OP_PCREL)
2198 const struct mips_pcrel_operand *pcrel_op;
2200 pcrel_op = (const struct mips_pcrel_operand *) operand;
2201 if (!pcrel_op->include_isa_bit && use_extend)
2202 baseaddr = memaddr - 2;
2203 else if (!pcrel_op->include_isa_bit)
2205 bfd_byte buffer[2];
2207 /* If this instruction is in the delay slot of a JAL/JALX
2208 instruction, the base address is the address of the
2209 JAL/JALX instruction. If it is in the delay slot of
2210 a JR/JALR instruction, the base address is the address
2211 of the JR/JALR instruction. This test is unreliable:
2212 we have no way of knowing whether the previous word is
2213 instruction or data. */
2214 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2215 && (((info->endian == BFD_ENDIAN_BIG
2216 ? bfd_getb16 (buffer)
2217 : bfd_getl16 (buffer))
2218 & 0xf800) == 0x1800))
2219 baseaddr = memaddr - 4;
2220 else if (info->read_memory_func (memaddr - 2, buffer, 2,
2221 info) == 0
2222 && (((info->endian == BFD_ENDIAN_BIG
2223 ? bfd_getb16 (buffer)
2224 : bfd_getl16 (buffer))
2225 & 0xf89f) == 0xe800)
2226 && (((info->endian == BFD_ENDIAN_BIG
2227 ? bfd_getb16 (buffer)
2228 : bfd_getl16 (buffer))
2229 & 0x0060) != 0x0060))
2230 baseaddr = memaddr - 2;
2231 else
2232 baseaddr = memaddr;
2236 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
2237 break;
2242 /* Check if the given address is the last word of a MIPS16 PLT entry.
2243 This word is data and depending on the value it may interfere with
2244 disassembly of further PLT entries. We make use of the fact PLT
2245 symbols are marked BSF_SYNTHETIC. */
2246 static bool
2247 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2249 if (info->symbols
2250 && info->symbols[0]
2251 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2252 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2253 return true;
2255 return false;
2258 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2260 enum match_kind
2262 MATCH_NONE,
2263 MATCH_FULL,
2264 MATCH_SHORT
2267 /* Disassemble mips16 instructions. */
2269 static int
2270 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2272 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2273 int status;
2274 bfd_byte buffer[4];
2275 const struct mips_opcode *op, *opend;
2276 struct mips_print_arg_state state;
2277 void *is = info->stream;
2278 bool have_second;
2279 bool extend_only;
2280 unsigned int second;
2281 unsigned int first;
2282 unsigned int full;
2284 info->bytes_per_chunk = 2;
2285 info->display_endian = info->endian;
2286 info->insn_info_valid = 1;
2287 info->branch_delay_insns = 0;
2288 info->data_size = 0;
2289 info->target = 0;
2290 info->target2 = 0;
2292 #define GET_OP(insn, field) \
2293 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2294 /* Decode PLT entry's GOT slot address word. */
2295 if (is_mips16_plt_tail (info, memaddr))
2297 info->insn_type = dis_noninsn;
2298 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2299 if (status == 0)
2301 unsigned int gotslot;
2303 if (info->endian == BFD_ENDIAN_BIG)
2304 gotslot = bfd_getb32 (buffer);
2305 else
2306 gotslot = bfd_getl32 (buffer);
2307 infprintf (is, dis_style_assembler_directive, ".word");
2308 infprintf (is, dis_style_text, "\t");
2309 infprintf (is, dis_style_immediate, "0x%x", gotslot);
2311 return 4;
2314 else
2316 info->insn_type = dis_nonbranch;
2317 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2319 if (status != 0)
2321 (*info->memory_error_func) (status, memaddr, info);
2322 return -1;
2325 extend_only = false;
2327 if (info->endian == BFD_ENDIAN_BIG)
2328 first = bfd_getb16 (buffer);
2329 else
2330 first = bfd_getl16 (buffer);
2332 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2333 if (status == 0)
2335 have_second = true;
2336 if (info->endian == BFD_ENDIAN_BIG)
2337 second = bfd_getb16 (buffer);
2338 else
2339 second = bfd_getl16 (buffer);
2340 full = (first << 16) | second;
2342 else
2344 have_second = false;
2345 second = 0;
2346 full = first;
2349 /* FIXME: Should probably use a hash table on the major opcode here. */
2351 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2352 for (op = mips16_opcodes; op < opend; op++)
2354 enum match_kind match;
2356 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2357 continue;
2359 if (op->pinfo == INSN_MACRO
2360 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2361 match = MATCH_NONE;
2362 else if (mips_opcode_32bit_p (op))
2364 if (have_second
2365 && (full & op->mask) == op->match)
2366 match = MATCH_FULL;
2367 else
2368 match = MATCH_NONE;
2370 else if ((first & op->mask) == op->match)
2372 match = MATCH_SHORT;
2373 second = 0;
2374 full = first;
2376 else if ((first & 0xf800) == 0xf000
2377 && have_second
2378 && !extend_only
2379 && (second & op->mask) == op->match)
2381 if (op->pinfo2 & INSN2_SHORT_ONLY)
2383 match = MATCH_NONE;
2384 extend_only = true;
2386 else
2387 match = MATCH_FULL;
2389 else
2390 match = MATCH_NONE;
2392 if (match != MATCH_NONE)
2394 const char *s;
2396 infprintf (is, dis_style_mnemonic, "%s", op->name);
2397 if (op->args[0] != '\0')
2398 infprintf (is, dis_style_text, "\t");
2400 init_print_arg_state (&state);
2401 for (s = op->args; *s != '\0'; s++)
2403 if (*s == ','
2404 && s[1] == 'w'
2405 && GET_OP (full, RX) == GET_OP (full, RY))
2407 /* Skip the register and the comma. */
2408 ++s;
2409 continue;
2411 if (*s == ','
2412 && s[1] == 'v'
2413 && GET_OP (full, RZ) == GET_OP (full, RX))
2415 /* Skip the register and the comma. */
2416 ++s;
2417 continue;
2419 if (s[0] == 'N'
2420 && s[1] == ','
2421 && s[2] == 'O'
2422 && op->name[strlen (op->name) - 1] == '0')
2424 /* Coprocessor register 0 with sel field. */
2425 const struct mips_cp0sel_name *n;
2426 const struct mips_operand *operand;
2427 unsigned int reg, sel;
2429 operand = decode_mips16_operand (*s, true);
2430 reg = mips_extract_operand (operand, (first << 16) | second);
2431 s += 2;
2432 operand = decode_mips16_operand (*s, true);
2433 sel = mips_extract_operand (operand, (first << 16) | second);
2435 /* CP0 register including 'sel' code for mftc0, to be
2436 printed textually if known. If not known, print both
2437 CP0 register name and sel numerically since CP0 register
2438 with sel 0 may have a name unrelated to register being
2439 printed. */
2440 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2441 mips_cp0sel_names_len,
2442 reg, sel);
2443 if (n != NULL)
2444 infprintf (is, dis_style_register, "%s", n->name);
2445 else
2447 infprintf (is, dis_style_register, "$%d", reg);
2448 infprintf (is, dis_style_text, ",");
2449 infprintf (is, dis_style_immediate, "%d", sel);
2452 else
2453 switch (match)
2455 case MATCH_FULL:
2456 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2457 second, true, first, s[1] == '(');
2458 break;
2459 case MATCH_SHORT:
2460 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2461 first, false, 0, s[1] == '(');
2462 break;
2463 case MATCH_NONE: /* Stop the compiler complaining. */
2464 break;
2468 /* Figure out branch instruction type and delay slot information. */
2469 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2470 info->branch_delay_insns = 1;
2471 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2472 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2474 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2475 info->insn_type = dis_jsr;
2476 else
2477 info->insn_type = dis_branch;
2479 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2480 info->insn_type = dis_condbranch;
2482 return match == MATCH_FULL ? 4 : 2;
2485 #undef GET_OP
2487 infprintf (is, dis_style_assembler_directive, ".short");
2488 infprintf (is, dis_style_text, "\t");
2489 infprintf (is, dis_style_immediate, "0x%x", first);
2490 info->insn_type = dis_noninsn;
2492 return 2;
2495 /* Disassemble microMIPS instructions. */
2497 static int
2498 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2500 const fprintf_styled_ftype infprintf = info->fprintf_styled_func;
2501 const struct mips_opcode *op, *opend;
2502 void *is = info->stream;
2503 bfd_byte buffer[2];
2504 unsigned int higher;
2505 unsigned int length;
2506 int status;
2507 unsigned int insn;
2509 info->bytes_per_chunk = 2;
2510 info->display_endian = info->endian;
2511 info->insn_info_valid = 1;
2512 info->branch_delay_insns = 0;
2513 info->data_size = 0;
2514 info->insn_type = dis_nonbranch;
2515 info->target = 0;
2516 info->target2 = 0;
2518 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2519 if (status != 0)
2521 (*info->memory_error_func) (status, memaddr, info);
2522 return -1;
2525 length = 2;
2527 if (info->endian == BFD_ENDIAN_BIG)
2528 insn = bfd_getb16 (buffer);
2529 else
2530 insn = bfd_getl16 (buffer);
2532 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2534 /* This is a 32-bit microMIPS instruction. */
2535 higher = insn;
2537 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2538 if (status != 0)
2540 infprintf (is, dis_style_text, "micromips 0x%x", higher);
2541 (*info->memory_error_func) (status, memaddr + 2, info);
2542 return -1;
2545 if (info->endian == BFD_ENDIAN_BIG)
2546 insn = bfd_getb16 (buffer);
2547 else
2548 insn = bfd_getl16 (buffer);
2550 insn = insn | (higher << 16);
2552 length += 2;
2555 /* FIXME: Should probably use a hash table on the major opcode here. */
2557 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2558 for (op = micromips_opcodes; op < opend; op++)
2560 if (op->pinfo != INSN_MACRO
2561 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2562 && (insn & op->mask) == op->match
2563 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2564 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2566 if (!validate_insn_args (op, decode_micromips_operand, insn))
2567 continue;
2569 infprintf (is, dis_style_mnemonic, "%s", op->name);
2571 if (op->args[0])
2573 infprintf (is, dis_style_text, "\t");
2574 print_insn_args (info, op, decode_micromips_operand, insn,
2575 memaddr + 1, length);
2578 /* Figure out instruction type and branch delay information. */
2579 if ((op->pinfo
2580 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2581 info->branch_delay_insns = 1;
2582 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2583 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2585 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2586 info->insn_type = dis_jsr;
2587 else
2588 info->insn_type = dis_branch;
2590 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2591 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2593 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2594 info->insn_type = dis_condjsr;
2595 else
2596 info->insn_type = dis_condbranch;
2598 else if ((op->pinfo
2599 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2600 info->insn_type = dis_dref;
2602 return length;
2606 infprintf (is, dis_style_assembler_directive, ".short");
2607 infprintf (is, dis_style_text, "\t");
2608 if (length != 2)
2610 infprintf (is, dis_style_immediate, "0x%x", (insn >> 16) & 0xffff);
2611 infprintf (is, dis_style_text, ", ");
2613 infprintf (is, dis_style_immediate, "0x%x", (insn & 0xffff));
2615 info->insn_type = dis_noninsn;
2617 return length;
2620 /* Return 1 if a symbol associated with the location being disassembled
2621 indicates a compressed mode, either MIPS16 or microMIPS, according to
2622 MICROMIPS_P. We iterate over all the symbols at the address being
2623 considered assuming if at least one of them indicates code compression,
2624 then such code has been genuinely produced here (other symbols could
2625 have been derived from function symbols defined elsewhere or could
2626 define data). Otherwise, return 0. */
2628 static bool
2629 is_compressed_mode_p (struct disassemble_info *info, bool micromips_p)
2631 int i;
2632 int l;
2634 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2635 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2636 && ((!micromips_p
2637 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2638 || (micromips_p
2639 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2640 return 1;
2641 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2642 && info->symtab[i]->section == info->section)
2644 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2645 if ((!micromips_p
2646 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2647 || (micromips_p
2648 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2649 return 1;
2652 return 0;
2655 /* In an environment where we do not know the symbol type of the
2656 instruction we are forced to assume that the low order bit of the
2657 instructions' address may mark it as a mips16 instruction. If we
2658 are single stepping, or the pc is within the disassembled function,
2659 this works. Otherwise, we need a clue. Sometimes. */
2661 static int
2662 _print_insn_mips (bfd_vma memaddr,
2663 struct disassemble_info *info,
2664 enum bfd_endian endianness)
2666 bfd_byte buffer[INSNLEN];
2667 int status;
2669 set_default_mips_dis_options (info);
2670 parse_mips_dis_options (info->disassembler_options);
2672 if (info->mach == bfd_mach_mips16)
2673 return print_insn_mips16 (memaddr, info);
2674 if (info->mach == bfd_mach_mips_micromips)
2675 return print_insn_micromips (memaddr, info);
2677 #if 1
2678 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2679 /* Only a few tools will work this way. */
2680 if (memaddr & 0x01)
2682 if (micromips_ase)
2683 return print_insn_micromips (memaddr, info);
2684 else
2685 return print_insn_mips16 (memaddr, info);
2687 #endif
2689 #if SYMTAB_AVAILABLE
2690 if (is_compressed_mode_p (info, true))
2691 return print_insn_micromips (memaddr, info);
2692 if (is_compressed_mode_p (info, false))
2693 return print_insn_mips16 (memaddr, info);
2694 #endif
2696 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2697 if (status == 0)
2699 int insn;
2701 if (endianness == BFD_ENDIAN_BIG)
2702 insn = bfd_getb32 (buffer);
2703 else
2704 insn = bfd_getl32 (buffer);
2706 return print_insn_mips (memaddr, insn, info);
2708 else
2710 (*info->memory_error_func) (status, memaddr, info);
2711 return -1;
2716 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2718 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2722 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2724 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2727 /* Indices into option argument vector for options accepting an argument.
2728 Use MIPS_OPTION_ARG_NONE for options accepting no argument. */
2729 typedef enum
2731 MIPS_OPTION_ARG_NONE = -1,
2732 MIPS_OPTION_ARG_ABI,
2733 MIPS_OPTION_ARG_ARCH,
2734 MIPS_OPTION_ARG_SIZE
2735 } mips_option_arg_t;
2737 /* Valid MIPS disassembler options. */
2738 static struct
2740 const char *name;
2741 const char *description;
2742 mips_option_arg_t arg;
2743 } mips_options[] =
2745 { "no-aliases", N_("Use canonical instruction forms.\n"),
2746 MIPS_OPTION_ARG_NONE },
2747 { "msa", N_("Recognize MSA instructions.\n"),
2748 MIPS_OPTION_ARG_NONE },
2749 { "virt", N_("Recognize the virtualization ASE instructions.\n"),
2750 MIPS_OPTION_ARG_NONE },
2751 { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\
2752 instructions.\n"),
2753 MIPS_OPTION_ARG_NONE },
2754 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2755 "instructions.\n"),
2756 MIPS_OPTION_ARG_NONE },
2757 { "loongson-mmi",
2758 N_("Recognize the Loongson MultiMedia extensions "
2759 "Instructions (MMI) ASE instructions.\n"),
2760 MIPS_OPTION_ARG_NONE },
2761 { "loongson-cam",
2762 N_("Recognize the Loongson Content Address Memory (CAM) "
2763 " instructions.\n"),
2764 MIPS_OPTION_ARG_NONE },
2765 { "loongson-ext",
2766 N_("Recognize the Loongson EXTensions (EXT) "
2767 " instructions.\n"),
2768 MIPS_OPTION_ARG_NONE },
2769 { "loongson-ext2",
2770 N_("Recognize the Loongson EXTensions R2 (EXT2) "
2771 " instructions.\n"),
2772 MIPS_OPTION_ARG_NONE },
2773 { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
2774 Default: based on binary being disassembled.\n"),
2775 MIPS_OPTION_ARG_ABI },
2776 { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
2777 Default: numeric.\n"),
2778 MIPS_OPTION_ARG_ABI },
2779 { "cp0-names=", N_("Print CP0 register names according to specified "
2780 "architecture.\n\
2781 Default: based on binary being disassembled.\n"),
2782 MIPS_OPTION_ARG_ARCH },
2783 { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
2784 Default: based on binary being disassembled.\n"),
2785 MIPS_OPTION_ARG_ARCH },
2786 { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
2787 MIPS_OPTION_ARG_ABI },
2788 { "reg-names=", N_("Print CP0 register and HWR names according to "
2789 "specified\n\
2790 architecture."),
2791 MIPS_OPTION_ARG_ARCH }
2794 /* Build the structure representing valid MIPS disassembler options.
2795 This is done dynamically for maintenance ease purpose; a static
2796 initializer would be unreadable. */
2798 const disasm_options_and_args_t *
2799 disassembler_options_mips (void)
2801 static disasm_options_and_args_t *opts_and_args;
2803 if (opts_and_args == NULL)
2805 size_t num_options = ARRAY_SIZE (mips_options);
2806 size_t num_args = MIPS_OPTION_ARG_SIZE;
2807 disasm_option_arg_t *args;
2808 disasm_options_t *opts;
2809 size_t i;
2810 size_t j;
2812 args = XNEWVEC (disasm_option_arg_t, num_args + 1);
2814 args[MIPS_OPTION_ARG_ABI].name = "ABI";
2815 args[MIPS_OPTION_ARG_ABI].values
2816 = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1);
2817 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2818 args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name;
2819 /* The array we return must be NULL terminated. */
2820 args[MIPS_OPTION_ARG_ABI].values[i] = NULL;
2822 args[MIPS_OPTION_ARG_ARCH].name = "ARCH";
2823 args[MIPS_OPTION_ARG_ARCH].values
2824 = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1);
2825 for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2826 if (*mips_arch_choices[i].name != '\0')
2827 args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name;
2828 /* The array we return must be NULL terminated. */
2829 args[MIPS_OPTION_ARG_ARCH].values[j] = NULL;
2831 /* The array we return must be NULL terminated. */
2832 args[MIPS_OPTION_ARG_SIZE].name = NULL;
2833 args[MIPS_OPTION_ARG_SIZE].values = NULL;
2835 opts_and_args = XNEW (disasm_options_and_args_t);
2836 opts_and_args->args = args;
2838 opts = &opts_and_args->options;
2839 opts->name = XNEWVEC (const char *, num_options + 1);
2840 opts->description = XNEWVEC (const char *, num_options + 1);
2841 opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
2842 for (i = 0; i < num_options; i++)
2844 opts->name[i] = mips_options[i].name;
2845 opts->description[i] = _(mips_options[i].description);
2846 if (mips_options[i].arg != MIPS_OPTION_ARG_NONE)
2847 opts->arg[i] = &args[mips_options[i].arg];
2848 else
2849 opts->arg[i] = NULL;
2851 /* The array we return must be NULL terminated. */
2852 opts->name[i] = NULL;
2853 opts->description[i] = NULL;
2854 opts->arg[i] = NULL;
2857 return opts_and_args;
2860 void
2861 print_mips_disassembler_options (FILE *stream)
2863 const disasm_options_and_args_t *opts_and_args;
2864 const disasm_option_arg_t *args;
2865 const disasm_options_t *opts;
2866 size_t max_len = 0;
2867 size_t i;
2868 size_t j;
2870 opts_and_args = disassembler_options_mips ();
2871 opts = &opts_and_args->options;
2872 args = opts_and_args->args;
2874 fprintf (stream, _("\n\
2875 The following MIPS specific disassembler options are supported for use\n\
2876 with the -M switch (multiple options should be separated by commas):\n\n"));
2878 /* Compute the length of the longest option name. */
2879 for (i = 0; opts->name[i] != NULL; i++)
2881 size_t len = strlen (opts->name[i]);
2883 if (opts->arg[i] != NULL)
2884 len += strlen (opts->arg[i]->name);
2885 if (max_len < len)
2886 max_len = len;
2889 for (i = 0, max_len++; opts->name[i] != NULL; i++)
2891 fprintf (stream, " %s", opts->name[i]);
2892 if (opts->arg[i] != NULL)
2893 fprintf (stream, "%s", opts->arg[i]->name);
2894 if (opts->description[i] != NULL)
2896 size_t len = strlen (opts->name[i]);
2898 if (opts->arg[i] != NULL)
2899 len += strlen (opts->arg[i]->name);
2900 fprintf (stream,
2901 "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
2903 fprintf (stream, _("\n"));
2906 for (i = 0; args[i].name != NULL; i++)
2908 if (args[i].values == NULL)
2909 continue;
2910 fprintf (stream, _("\n\
2911 For the options above, the following values are supported for \"%s\":\n "),
2912 args[i].name);
2913 for (j = 0; args[i].values[j] != NULL; j++)
2914 fprintf (stream, " %s", args[i].values[j]);
2915 fprintf (stream, _("\n"));
2918 fprintf (stream, _("\n"));