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)
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. */
23 #include "disassemble.h"
24 #include "libiberty.h"
25 #include "opcode/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
40 /* Mips instructions are at maximum this many bytes long. */
44 /* FIXME: These should be shared with gdb somehow. */
46 struct mips_cp0sel_name
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
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
463 unsigned long bfd_mach
;
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),
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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,
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
706 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
707 ISA_MIPS64R2
| INSN_XLR
, 0,
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
723 static int mips_processor
;
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
;
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
;
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
];
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
;
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
];
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
;
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
;
794 /* Check if the object uses NewABI conventions. */
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
)
803 /* If a 32-bit ELF file, n32 is a new-style ABI. */
804 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
810 /* Check if the object has microMIPS ASE code. */
813 is_micromips (Elf_Internal_Ehdr
*header
)
815 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
821 /* Convert ASE flags from .MIPS.abiflags to internal values. */
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
;
857 /* Calculate combination ASE flags from regular ASE flags. */
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
;
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
;
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
;
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
;
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
);
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. */
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
;
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. */
951 parse_mips_ase_option (const char *option
)
953 if (startswith (option
, "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
;
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
;
975 if (startswith (option
, "xpa"))
981 if (startswith (option
, "ginv"))
983 mips_ase
|= ASE_GINV
;
987 if (startswith (option
, "loongson-mmi"))
989 mips_ase
|= ASE_LOONGSON_MMI
;
993 if (startswith (option
, "loongson-cam"))
995 mips_ase
|= ASE_LOONGSON_CAM
;
999 /* Put here for match ext2 frist */
1000 if (startswith (option
, "loongson-ext2"))
1002 mips_ase
|= ASE_LOONGSON_EXT2
;
1006 if (startswith (option
, "loongson-ext"))
1008 mips_ase
|= ASE_LOONGSON_EXT
;
1016 parse_mips_dis_option (const char *option
, unsigned int len
)
1018 unsigned int i
, optionlen
, vallen
;
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"))
1030 if (parse_mips_ase_option (option
))
1032 mips_ase
|= mips_calculate_combination_ases (mips_isa
, mips_ase
);
1036 /* Look for the = that delimits the end of the option name. */
1037 for (i
= 0; i
< len
; i
++)
1038 if (option
[i
] == '=')
1041 if (i
== 0) /* Invalid option: no name before '='. */
1043 if (i
== len
) /* Invalid option: no '='. */
1045 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
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
;
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
;
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
;
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
;
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
;
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
;
1126 /* Invalid option. */
1130 parse_mips_dis_options (const char *options
)
1132 const char *option_end
;
1134 if (options
== NULL
)
1137 while (*options
!= '\0')
1139 /* Skip empty options. */
1140 if (*options
== ',')
1146 /* We know that *options is neither NUL or a comma. */
1147 option_end
= options
+ 1;
1148 while (*option_end
!= ',' && *option_end
!= '\0')
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
,
1162 unsigned int cp0reg
,
1167 for (i
= 0; i
< len
; i
++)
1168 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
1173 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
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
;
1184 infprintf (info
->stream
, dis_style_register
, "%s",
1185 mips_gpr_names
[regno
]);
1189 infprintf (info
->stream
, dis_style_register
, "%s",
1190 mips_fpr_names
[regno
]);
1194 if (opcode
->pinfo
& (FP_D
| FP_S
))
1195 infprintf (info
->stream
, dis_style_register
, "$fcc%d", regno
);
1197 infprintf (info
->stream
, dis_style_register
, "$cc%d", regno
);
1201 if (opcode
->membership
& INSN_5400
)
1202 infprintf (info
->stream
, dis_style_register
, "$f%d", regno
);
1204 infprintf (info
->stream
, dis_style_register
, "$v%d", regno
);
1208 infprintf (info
->stream
, dis_style_register
, "$ac%d", regno
);
1212 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1213 infprintf (info
->stream
, dis_style_register
, "%s", mips_cp0_names
[regno
]);
1215 infprintf (info
->stream
, dis_style_register
, "$%d", regno
);
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
]);
1222 infprintf (info
->stream
, dis_style_register
, "$%d", regno
);
1226 infprintf (info
->stream
, dis_style_register
, "%s", mips_hwr_names
[regno
]);
1230 infprintf (info
->stream
, dis_style_register
, "$vf%d", regno
);
1234 infprintf (info
->stream
, dis_style_register
, "$vi%d", regno
);
1237 case OP_REG_R5900_I
:
1238 infprintf (info
->stream
, dis_style_register
, "$I");
1241 case OP_REG_R5900_Q
:
1242 infprintf (info
->stream
, dis_style_register
, "$Q");
1245 case OP_REG_R5900_R
:
1246 infprintf (info
->stream
, dis_style_register
, "$R");
1249 case OP_REG_R5900_ACC
:
1250 infprintf (info
->stream
, dis_style_register
, "$ACC");
1254 infprintf (info
->stream
, dis_style_register
, "$w%d", regno
);
1257 case OP_REG_MSA_CTRL
:
1258 infprintf (info
->stream
, dis_style_register
, "%s",
1259 msa_control_names
[regno
]);
1265 /* Used to track the state carried over from previous operands in
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. */
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. */
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
]);
1310 /* Record information about a register operand. */
1313 mips_seen_register (struct mips_print_arg_state
*state
,
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. */
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
;
1343 if (amask
== MIPS_SVRS_ALL_ARGS
)
1348 else if (amask
== MIPS_SVRS_ALL_STATICS
)
1356 nstatics
= amask
& 3;
1362 infprintf (is
, dis_style_register
, "%s", mips_gpr_names
[4]);
1364 infprintf (is
, dis_style_register
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1368 infprintf (is
, dis_style_text
, "%s", sep
);
1369 infprintf (is
, dis_style_immediate
, "%d", frame_size
);
1373 infprintf (is
, dis_style_text
, ",");
1374 infprintf (is
, dis_style_register
, "%s", mips_gpr_names
[31]);
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
++)
1396 infprintf (is
, dis_style_text
, "-");
1397 infprintf (is
, dis_style_register
, "%s",
1398 mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1402 /* Statics $ax - $a3. */
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. */
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
,
1431 const fprintf_styled_ftype infprintf
= info
->fprintf_styled_func
;
1432 void *is
= info
->stream
;
1434 switch (operand
->type
)
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
);
1446 infprintf (is
, dis_style_immediate
, "%d", uval
);
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
);
1460 infprintf (is
, dis_style_immediate
, "%d", uval
);
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
);
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
);
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
]);
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
)
1515 (*info
->print_address_func
) (info
->target
, info
);
1520 infprintf (is
, dis_style_register
, "%d", uval
);
1523 case OP_ADDIUSP_INT
:
1527 sval
= mips_signed_operand (operand
, uval
) * 4;
1528 if (sval
>= -8 && sval
< 8)
1530 infprintf (is
, dis_style_immediate
, "%d", sval
);
1534 case OP_CLO_CLZ_DEST
:
1536 unsigned int reg1
, reg2
;
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
]);
1544 infprintf (is
, dis_style_register
, "%s", mips_gpr_names
[reg2
]);
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
]);
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
);
1564 case OP_LWM_SWM_LIST
:
1565 if (operand
->size
== 2)
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]);
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]);
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]);
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]);
1625 infprintf (is
, dis_style_text
, ",");
1626 infprintf (is
, dis_style_register
, "%s",
1627 mips_gpr_names
[31]);
1633 case OP_ENTRY_EXIT_LIST
:
1636 unsigned int amask
, smask
;
1639 amask
= (uval
>> 3) & 7;
1640 if (amask
> 0 && amask
< 5)
1642 infprintf (is
, dis_style_register
, "%s", mips_gpr_names
[4]);
1645 infprintf (is
, dis_style_text
, "-");
1646 infprintf (is
, dis_style_register
, "%s",
1647 mips_gpr_names
[amask
+ 3]);
1652 smask
= (uval
>> 1) & 3;
1655 infprintf (is
, dis_style_text
, "%s??", sep
);
1660 infprintf (is
, dis_style_text
, "%s", sep
);
1661 infprintf (is
, dis_style_register
, "%s", mips_gpr_names
[16]);
1664 infprintf (is
, dis_style_text
, "-");
1665 infprintf (is
, dis_style_register
, "%s",
1666 mips_gpr_names
[smask
+ 15]);
1673 infprintf (is
, dis_style_text
, "%s", sep
);
1674 infprintf (is
, dis_style_register
, "%s", mips_gpr_names
[31]);
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]);
1684 infprintf (is
, dis_style_text
, "-");
1685 infprintf (is
, dis_style_register
, "%s", mips_fpr_names
[1]);
1691 case OP_SAVE_RESTORE_LIST
:
1692 /* Should be handled by the caller due to complex behavior. */
1695 case OP_MDMX_IMM_REG
:
1701 if ((vsel
& 0x10) == 0)
1706 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1707 if ((vsel
& 1) == 0)
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
);
1717 infprintf (is
, dis_style_immediate
, "0x%x", uval
);
1721 case OP_REPEAT_PREV_REG
:
1722 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1725 case OP_REPEAT_DEST_REG
:
1726 print_reg (info
, opcode
, state
->last_reg_type
, state
->dest_regno
);
1730 infprintf (is
, dis_style_register
, "$pc");
1734 print_reg (info
, opcode
, OP_REG_GP
, 28);
1738 case OP_VU0_MATCH_SUFFIX
:
1739 print_vu0_channel (info
, operand
, uval
, dis_style_register
);
1743 infprintf (is
, dis_style_text
, "[");
1744 infprintf (is
, dis_style_immediate
, "%d", uval
);
1745 infprintf (is
, dis_style_text
, "]");
1749 infprintf (is
, dis_style_text
, "[");
1750 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1751 infprintf (is
, dis_style_text
, "]");
1756 /* Validate the arguments for INSN, which is described by OPCODE.
1757 Use DECODE_OPERAND to get the encoding of each operand. */
1760 validate_insn_args (const struct mips_opcode
*opcode
,
1761 const struct mips_operand
*(*decode_operand
) (const char *),
1764 struct mips_print_arg_state state
;
1765 const struct mips_operand
*operand
;
1769 init_print_arg_state (&state
);
1770 for (s
= opcode
->args
; *s
; ++s
)
1784 operand
= decode_operand (s
);
1788 uval
= mips_extract_operand (operand
, insn
);
1789 switch (operand
->type
)
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
);
1804 unsigned int reg1
, reg2
;
1809 if (reg1
!= reg2
|| reg1
== 0)
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)
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
)))
1831 case OP_NON_ZERO_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
:
1854 case OP_VU0_MATCH_SUFFIX
:
1857 case OP_SAVE_RESTORE_LIST
:
1861 if (*s
== 'm' || *s
== '+' || *s
== '-')
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. */
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
;
1885 init_print_arg_state (&state
);
1886 for (s
= opcode
->args
; *s
; ++s
)
1893 infprintf (is
, dis_style_text
, "%c", *s
);
1898 infprintf (is
, dis_style_text
, "%c%c", *s
, *s
);
1902 operand
= decode_operand (s
);
1905 /* xgettext:c-format */
1906 infprintf (is
, dis_style_text
,
1907 _("# internal error, undefined operand in `%s %s'"),
1908 opcode
->name
, opcode
->args
);
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
,
1925 else if (operand
->type
== OP_REG
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
);
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
1944 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1945 mips_cp0sel_names_len
,
1948 infprintf (is
, dis_style_register
, "%s", n
->name
);
1951 infprintf (is
, dis_style_register
, "$%d", reg
);
1952 infprintf (is
, dis_style_text
, ",");
1953 infprintf (is
, dis_style_immediate
, "%d", sel
);
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
)
1974 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1975 mips_extract_operand (operand
, insn
));
1977 if (*s
== 'm' || *s
== '+' || *s
== '-')
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. */
1990 print_insn_mips (bfd_vma memaddr
,
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. */
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
)))
2014 if (i
== GET_OP (op
->match
, OP
))
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
;
2034 op
= mips_hash
[GET_OP (word
, OP
)];
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
))
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
;
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
;
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
))
2075 infprintf (is
, dis_style_mnemonic
, "%s", op
->name
);
2076 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
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
);
2088 infprintf (is
, dis_style_text
, "\t");
2089 print_insn_args (info
, op
, decode_mips_operand
, word
,
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
);
2107 /* Disassemble an operand for a mips16 instruction. */
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
;
2132 infprintf (is
, dis_style_text
, "%c", type
);
2136 operand
= decode_mips16_operand (type
, false);
2139 /* xgettext:c-format */
2140 infprintf (is
, dis_style_text
, _("# internal error, undefined operand in `%s %s'"),
2141 opcode
->name
, opcode
->args
);
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
)
2157 mips_print_save_restore (info
, amask
, nsreg
, ra
, s0
, s1
, frame_size
);
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
;
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);
2191 uval
= mips_extract_operand (operand
, (extend
<< 16) | insn
);
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
)
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,
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;
2236 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
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. */
2247 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2251 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2252 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2258 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2267 /* Disassemble mips16 instructions. */
2270 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2272 const fprintf_styled_ftype infprintf
= info
->fprintf_styled_func
;
2275 const struct mips_opcode
*op
, *opend
;
2276 struct mips_print_arg_state state
;
2277 void *is
= info
->stream
;
2280 unsigned int second
;
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;
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
);
2301 unsigned int gotslot
;
2303 if (info
->endian
== BFD_ENDIAN_BIG
)
2304 gotslot
= bfd_getb32 (buffer
);
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
);
2316 info
->insn_type
= dis_nonbranch
;
2317 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2321 (*info
->memory_error_func
) (status
, memaddr
, info
);
2325 extend_only
= false;
2327 if (info
->endian
== BFD_ENDIAN_BIG
)
2328 first
= bfd_getb16 (buffer
);
2330 first
= bfd_getl16 (buffer
);
2332 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2336 if (info
->endian
== BFD_ENDIAN_BIG
)
2337 second
= bfd_getb16 (buffer
);
2339 second
= bfd_getl16 (buffer
);
2340 full
= (first
<< 16) | second
;
2344 have_second
= false;
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
))
2359 if (op
->pinfo
== INSN_MACRO
2360 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
2362 else if (mips_opcode_32bit_p (op
))
2365 && (full
& op
->mask
) == op
->match
)
2370 else if ((first
& op
->mask
) == op
->match
)
2372 match
= MATCH_SHORT
;
2376 else if ((first
& 0xf800) == 0xf000
2379 && (second
& op
->mask
) == op
->match
)
2381 if (op
->pinfo2
& INSN2_SHORT_ONLY
)
2392 if (match
!= MATCH_NONE
)
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
++)
2405 && GET_OP (full
, RX
) == GET_OP (full
, RY
))
2407 /* Skip the register and the comma. */
2413 && GET_OP (full
, RZ
) == GET_OP (full
, RX
))
2415 /* Skip the register and the comma. */
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
);
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
2440 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2441 mips_cp0sel_names_len
,
2444 infprintf (is
, dis_style_register
, "%s", n
->name
);
2447 infprintf (is
, dis_style_register
, "$%d", reg
);
2448 infprintf (is
, dis_style_text
, ",");
2449 infprintf (is
, dis_style_immediate
, "%d", sel
);
2456 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
+ 2,
2457 second
, true, first
, s
[1] == '(');
2460 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
,
2461 first
, false, 0, s
[1] == '(');
2463 case MATCH_NONE
: /* Stop the compiler complaining. */
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
;
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;
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
;
2495 /* Disassemble microMIPS instructions. */
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
;
2504 unsigned int higher
;
2505 unsigned int length
;
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
;
2518 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2521 (*info
->memory_error_func
) (status
, memaddr
, info
);
2527 if (info
->endian
== BFD_ENDIAN_BIG
)
2528 insn
= bfd_getb16 (buffer
);
2530 insn
= bfd_getl16 (buffer
);
2532 if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2534 /* This is a 32-bit microMIPS instruction. */
2537 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2540 infprintf (is
, dis_style_text
, "micromips 0x%x", higher
);
2541 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2545 if (info
->endian
== BFD_ENDIAN_BIG
)
2546 insn
= bfd_getb16 (buffer
);
2548 insn
= bfd_getl16 (buffer
);
2550 insn
= insn
| (higher
<< 16);
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
))
2569 infprintf (is
, dis_style_mnemonic
, "%s", op
->name
);
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. */
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
;
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
;
2596 info
->insn_type
= dis_condbranch
;
2599 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2600 info
->insn_type
= dis_dref
;
2606 infprintf (is
, dis_style_assembler_directive
, ".short");
2607 infprintf (is
, dis_style_text
, "\t");
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
;
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. */
2629 is_compressed_mode_p (struct disassemble_info
*info
, bool micromips_p
)
2634 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2635 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2637 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2639 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
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
];
2646 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2648 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
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. */
2662 _print_insn_mips (bfd_vma memaddr
,
2663 struct disassemble_info
*info
,
2664 enum bfd_endian endianness
)
2666 bfd_byte buffer
[INSNLEN
];
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
);
2678 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2679 /* Only a few tools will work this way. */
2683 return print_insn_micromips (memaddr
, info
);
2685 return print_insn_mips16 (memaddr
, info
);
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
);
2696 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2701 if (endianness
== BFD_ENDIAN_BIG
)
2702 insn
= bfd_getb32 (buffer
);
2704 insn
= bfd_getl32 (buffer
);
2706 return print_insn_mips (memaddr
, insn
, info
);
2710 (*info
->memory_error_func
) (status
, memaddr
, info
);
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. */
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. */
2741 const char *description
;
2742 mips_option_arg_t arg
;
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\
2753 MIPS_OPTION_ARG_NONE
},
2754 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2756 MIPS_OPTION_ARG_NONE
},
2758 N_("Recognize the Loongson MultiMedia extensions "
2759 "Instructions (MMI) ASE instructions.\n"),
2760 MIPS_OPTION_ARG_NONE
},
2762 N_("Recognize the Loongson Content Address Memory (CAM) "
2763 " instructions.\n"),
2764 MIPS_OPTION_ARG_NONE
},
2766 N_("Recognize the Loongson EXTensions (EXT) "
2767 " instructions.\n"),
2768 MIPS_OPTION_ARG_NONE
},
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 "
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 "
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
;
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
];
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
;
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
;
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
);
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
);
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
)
2910 fprintf (stream
, _("\n\
2911 For the options above, the following values are supported for \"%s\":\n "),
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"));