1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2021 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_mips3264
[32] =
187 "c1_fir", "c1_ufr", "$2", "$3",
188 "c1_unfr", "$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", "c1_fccr", "c1_fexr", "$27",
194 "c1_fenr", "$29", "$30", "c1_fcsr"
197 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] =
199 { 16, 1, "c0_config1" },
200 { 16, 2, "c0_config2" },
201 { 16, 3, "c0_config3" },
202 { 18, 1, "c0_watchlo,1" },
203 { 18, 2, "c0_watchlo,2" },
204 { 18, 3, "c0_watchlo,3" },
205 { 18, 4, "c0_watchlo,4" },
206 { 18, 5, "c0_watchlo,5" },
207 { 18, 6, "c0_watchlo,6" },
208 { 18, 7, "c0_watchlo,7" },
209 { 19, 1, "c0_watchhi,1" },
210 { 19, 2, "c0_watchhi,2" },
211 { 19, 3, "c0_watchhi,3" },
212 { 19, 4, "c0_watchhi,4" },
213 { 19, 5, "c0_watchhi,5" },
214 { 19, 6, "c0_watchhi,6" },
215 { 19, 7, "c0_watchhi,7" },
216 { 25, 1, "c0_perfcnt,1" },
217 { 25, 2, "c0_perfcnt,2" },
218 { 25, 3, "c0_perfcnt,3" },
219 { 25, 4, "c0_perfcnt,4" },
220 { 25, 5, "c0_perfcnt,5" },
221 { 25, 6, "c0_perfcnt,6" },
222 { 25, 7, "c0_perfcnt,7" },
223 { 27, 1, "c0_cacheerr,1" },
224 { 27, 2, "c0_cacheerr,2" },
225 { 27, 3, "c0_cacheerr,3" },
226 { 28, 1, "c0_datalo" },
227 { 29, 1, "c0_datahi" }
230 static const char * const mips_cp0_names_mips3264r2
[32] =
232 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
233 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
234 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
235 "c0_status", "c0_cause", "c0_epc", "c0_prid",
236 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
237 "c0_xcontext", "$21", "$22", "c0_debug",
238 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
239 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
242 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] =
244 { 4, 1, "c0_contextconfig" },
245 { 0, 1, "c0_mvpcontrol" },
246 { 0, 2, "c0_mvpconf0" },
247 { 0, 3, "c0_mvpconf1" },
248 { 1, 1, "c0_vpecontrol" },
249 { 1, 2, "c0_vpeconf0" },
250 { 1, 3, "c0_vpeconf1" },
251 { 1, 4, "c0_yqmask" },
252 { 1, 5, "c0_vpeschedule" },
253 { 1, 6, "c0_vpeschefback" },
254 { 2, 1, "c0_tcstatus" },
255 { 2, 2, "c0_tcbind" },
256 { 2, 3, "c0_tcrestart" },
257 { 2, 4, "c0_tchalt" },
258 { 2, 5, "c0_tccontext" },
259 { 2, 6, "c0_tcschedule" },
260 { 2, 7, "c0_tcschefback" },
261 { 5, 1, "c0_pagegrain" },
262 { 6, 1, "c0_srsconf0" },
263 { 6, 2, "c0_srsconf1" },
264 { 6, 3, "c0_srsconf2" },
265 { 6, 4, "c0_srsconf3" },
266 { 6, 5, "c0_srsconf4" },
267 { 12, 1, "c0_intctl" },
268 { 12, 2, "c0_srsctl" },
269 { 12, 3, "c0_srsmap" },
270 { 15, 1, "c0_ebase" },
271 { 16, 1, "c0_config1" },
272 { 16, 2, "c0_config2" },
273 { 16, 3, "c0_config3" },
274 { 18, 1, "c0_watchlo,1" },
275 { 18, 2, "c0_watchlo,2" },
276 { 18, 3, "c0_watchlo,3" },
277 { 18, 4, "c0_watchlo,4" },
278 { 18, 5, "c0_watchlo,5" },
279 { 18, 6, "c0_watchlo,6" },
280 { 18, 7, "c0_watchlo,7" },
281 { 19, 1, "c0_watchhi,1" },
282 { 19, 2, "c0_watchhi,2" },
283 { 19, 3, "c0_watchhi,3" },
284 { 19, 4, "c0_watchhi,4" },
285 { 19, 5, "c0_watchhi,5" },
286 { 19, 6, "c0_watchhi,6" },
287 { 19, 7, "c0_watchhi,7" },
288 { 23, 1, "c0_tracecontrol" },
289 { 23, 2, "c0_tracecontrol2" },
290 { 23, 3, "c0_usertracedata" },
291 { 23, 4, "c0_tracebpc" },
292 { 25, 1, "c0_perfcnt,1" },
293 { 25, 2, "c0_perfcnt,2" },
294 { 25, 3, "c0_perfcnt,3" },
295 { 25, 4, "c0_perfcnt,4" },
296 { 25, 5, "c0_perfcnt,5" },
297 { 25, 6, "c0_perfcnt,6" },
298 { 25, 7, "c0_perfcnt,7" },
299 { 27, 1, "c0_cacheerr,1" },
300 { 27, 2, "c0_cacheerr,2" },
301 { 27, 3, "c0_cacheerr,3" },
302 { 28, 1, "c0_datalo" },
303 { 28, 2, "c0_taglo1" },
304 { 28, 3, "c0_datalo1" },
305 { 28, 4, "c0_taglo2" },
306 { 28, 5, "c0_datalo2" },
307 { 28, 6, "c0_taglo3" },
308 { 28, 7, "c0_datalo3" },
309 { 29, 1, "c0_datahi" },
310 { 29, 2, "c0_taghi1" },
311 { 29, 3, "c0_datahi1" },
312 { 29, 4, "c0_taghi2" },
313 { 29, 5, "c0_datahi2" },
314 { 29, 6, "c0_taghi3" },
315 { 29, 7, "c0_datahi3" },
318 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
319 static const char * const mips_cp0_names_sb1
[32] =
321 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
322 "c0_context", "c0_pagemask", "c0_wired", "$7",
323 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
324 "c0_status", "c0_cause", "c0_epc", "c0_prid",
325 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
326 "c0_xcontext", "$21", "$22", "c0_debug",
327 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
328 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
331 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] =
333 { 16, 1, "c0_config1" },
334 { 18, 1, "c0_watchlo,1" },
335 { 19, 1, "c0_watchhi,1" },
336 { 22, 0, "c0_perftrace" },
337 { 23, 3, "c0_edebug" },
338 { 25, 1, "c0_perfcnt,1" },
339 { 25, 2, "c0_perfcnt,2" },
340 { 25, 3, "c0_perfcnt,3" },
341 { 25, 4, "c0_perfcnt,4" },
342 { 25, 5, "c0_perfcnt,5" },
343 { 25, 6, "c0_perfcnt,6" },
344 { 25, 7, "c0_perfcnt,7" },
345 { 26, 1, "c0_buserr_pa" },
346 { 27, 1, "c0_cacheerr_d" },
347 { 27, 3, "c0_cacheerr_d_pa" },
348 { 28, 1, "c0_datalo_i" },
349 { 28, 2, "c0_taglo_d" },
350 { 28, 3, "c0_datalo_d" },
351 { 29, 1, "c0_datahi_i" },
352 { 29, 2, "c0_taghi_d" },
353 { 29, 3, "c0_datahi_d" },
356 /* Xlr cop0 register names. */
357 static const char * const mips_cp0_names_xlr
[32] = {
358 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
359 "c0_context", "c0_pagemask", "c0_wired", "$7",
360 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
361 "c0_status", "c0_cause", "c0_epc", "c0_prid",
362 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
363 "c0_xcontext", "$21", "$22", "c0_debug",
364 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
365 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
368 /* XLR's CP0 Select Registers. */
370 static const struct mips_cp0sel_name mips_cp0sel_names_xlr
[] = {
371 { 9, 6, "c0_extintreq" },
372 { 9, 7, "c0_extintmask" },
373 { 15, 1, "c0_ebase" },
374 { 16, 1, "c0_config1" },
375 { 16, 2, "c0_config2" },
376 { 16, 3, "c0_config3" },
377 { 16, 7, "c0_procid2" },
378 { 18, 1, "c0_watchlo,1" },
379 { 18, 2, "c0_watchlo,2" },
380 { 18, 3, "c0_watchlo,3" },
381 { 18, 4, "c0_watchlo,4" },
382 { 18, 5, "c0_watchlo,5" },
383 { 18, 6, "c0_watchlo,6" },
384 { 18, 7, "c0_watchlo,7" },
385 { 19, 1, "c0_watchhi,1" },
386 { 19, 2, "c0_watchhi,2" },
387 { 19, 3, "c0_watchhi,3" },
388 { 19, 4, "c0_watchhi,4" },
389 { 19, 5, "c0_watchhi,5" },
390 { 19, 6, "c0_watchhi,6" },
391 { 19, 7, "c0_watchhi,7" },
392 { 25, 1, "c0_perfcnt,1" },
393 { 25, 2, "c0_perfcnt,2" },
394 { 25, 3, "c0_perfcnt,3" },
395 { 25, 4, "c0_perfcnt,4" },
396 { 25, 5, "c0_perfcnt,5" },
397 { 25, 6, "c0_perfcnt,6" },
398 { 25, 7, "c0_perfcnt,7" },
399 { 27, 1, "c0_cacheerr,1" },
400 { 27, 2, "c0_cacheerr,2" },
401 { 27, 3, "c0_cacheerr,3" },
402 { 28, 1, "c0_datalo" },
403 { 29, 1, "c0_datahi" }
406 static const char * const mips_hwr_names_numeric
[32] =
408 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
409 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
410 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
411 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
414 static const char * const mips_hwr_names_mips3264r2
[32] =
416 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
417 "$4", "$5", "$6", "$7",
418 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
419 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
420 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
423 static const char * const msa_control_names
[32] =
425 "msa_ir", "msa_csr", "msa_access", "msa_save",
426 "msa_modify", "msa_request", "msa_map", "msa_unmap",
427 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
428 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
429 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
432 struct mips_abi_choice
435 const char * const *gpr_names
;
436 const char * const *fpr_names
;
439 struct mips_abi_choice mips_abi_choices
[] =
441 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
442 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
443 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
444 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
447 struct mips_arch_choice
451 unsigned long bfd_mach
;
455 const char * const *cp0_names
;
456 const struct mips_cp0sel_name
*cp0sel_names
;
457 unsigned int cp0sel_names_len
;
458 const char * const *cp1_names
;
459 const char * const *hwr_names
;
462 const struct mips_arch_choice mips_arch_choices
[] =
464 { "numeric", 0, 0, 0, 0, 0,
465 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
466 mips_hwr_names_numeric
},
468 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
, 0,
469 mips_cp0_names_r3000
, NULL
, 0, mips_cp1_names_numeric
,
470 mips_hwr_names_numeric
},
471 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
, 0,
472 mips_cp0_names_r3900
, NULL
, 0, mips_cp1_names_numeric
,
473 mips_hwr_names_numeric
},
474 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
, 0,
475 mips_cp0_names_r4000
, NULL
, 0, mips_cp1_names_numeric
,
476 mips_hwr_names_numeric
},
477 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
, 0,
478 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
479 mips_hwr_names_numeric
},
480 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
, 0,
481 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
482 mips_hwr_names_numeric
},
483 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
, 0,
484 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
485 mips_hwr_names_numeric
},
486 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
, 0,
487 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
488 mips_hwr_names_numeric
},
489 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
, 0,
490 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
491 mips_hwr_names_numeric
},
492 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
, 0,
493 mips_cp0_names_r4000
, NULL
, 0, mips_cp1_names_numeric
,
494 mips_hwr_names_numeric
},
495 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
, 0,
496 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
497 mips_hwr_names_numeric
},
498 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
, 0,
499 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
500 mips_hwr_names_numeric
},
501 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
, 0,
502 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
503 mips_hwr_names_numeric
},
504 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
, 0,
505 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
506 mips_hwr_names_numeric
},
507 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
, 0,
508 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
509 mips_hwr_names_numeric
},
510 { "r5900", 1, bfd_mach_mips5900
, CPU_R5900
, ISA_MIPS3
, 0,
511 mips_cp0_names_r5900
, NULL
, 0, mips_cp1_names_numeric
,
512 mips_hwr_names_numeric
},
513 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
, 0,
514 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
515 mips_hwr_names_numeric
},
516 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
517 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
518 mips_hwr_names_numeric
},
519 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
520 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
521 mips_hwr_names_numeric
},
522 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
, 0,
523 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
524 mips_hwr_names_numeric
},
525 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
, 0,
526 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
527 mips_hwr_names_numeric
},
528 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
, 0,
529 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
530 mips_hwr_names_numeric
},
531 { "r14000", 1, bfd_mach_mips14000
, CPU_R14000
, ISA_MIPS4
, 0,
532 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
533 mips_hwr_names_numeric
},
534 { "r16000", 1, bfd_mach_mips16000
, CPU_R16000
, ISA_MIPS4
, 0,
535 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
536 mips_hwr_names_numeric
},
537 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
, 0,
538 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
539 mips_hwr_names_numeric
},
541 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
542 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
543 _MIPS32 Architecture For Programmers Volume I: Introduction to the
544 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
546 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
547 ISA_MIPS32
, ASE_SMARTMIPS
,
548 mips_cp0_names_mips3264
,
549 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
550 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
552 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
554 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
555 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
| ASE_XPA
),
556 mips_cp0_names_mips3264r2
,
557 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
558 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
560 { "mips32r3", 1, bfd_mach_mipsisa32r3
, CPU_MIPS32R3
,
562 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
563 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
| ASE_XPA
),
564 mips_cp0_names_mips3264r2
,
565 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
566 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
568 { "mips32r5", 1, bfd_mach_mipsisa32r5
, CPU_MIPS32R5
,
570 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
571 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
| ASE_XPA
),
572 mips_cp0_names_mips3264r2
,
573 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
574 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
576 { "mips32r6", 1, bfd_mach_mipsisa32r6
, CPU_MIPS32R6
,
578 (ASE_EVA
| ASE_MSA
| ASE_VIRT
| ASE_XPA
| ASE_MCU
| ASE_MT
| ASE_DSP
579 | ASE_DSPR2
| ASE_DSPR3
| ASE_CRC
| ASE_GINV
),
580 mips_cp0_names_mips3264r2
,
581 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
582 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
584 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
585 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
586 ISA_MIPS64
, ASE_MIPS3D
| ASE_MDMX
,
587 mips_cp0_names_mips3264
,
588 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
589 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
591 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
593 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
594 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
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 { "mips64r3", 1, bfd_mach_mipsisa64r3
, CPU_MIPS64R3
,
601 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
602 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
603 mips_cp0_names_mips3264r2
,
604 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
605 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
607 { "mips64r5", 1, bfd_mach_mipsisa64r5
, CPU_MIPS64R5
,
609 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
610 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
611 mips_cp0_names_mips3264r2
,
612 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
613 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
615 { "mips64r6", 1, bfd_mach_mipsisa64r6
, CPU_MIPS64R6
,
617 (ASE_EVA
| ASE_MSA
| ASE_MSA64
| ASE_XPA
| ASE_VIRT
| ASE_VIRT64
618 | ASE_MCU
| ASE_MT
| ASE_DSP
| ASE_DSPR2
| ASE_DSPR3
| ASE_CRC
619 | ASE_CRC64
| ASE_GINV
),
620 mips_cp0_names_mips3264r2
,
621 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
622 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
624 { "interaptiv-mr2", 1, bfd_mach_mips_interaptiv_mr2
, CPU_INTERAPTIV_MR2
,
626 ASE_MT
| ASE_EVA
| ASE_DSP
| ASE_DSPR2
| ASE_MIPS16E2
| ASE_MIPS16E2_MT
,
627 mips_cp0_names_mips3264r2
,
628 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
629 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
631 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
632 ISA_MIPS64
| INSN_SB1
, ASE_MIPS3D
,
634 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
635 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
637 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
638 ISA_MIPS3
| INSN_LOONGSON_2E
, 0, mips_cp0_names_numeric
,
639 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
641 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
642 ISA_MIPS3
| INSN_LOONGSON_2F
, ASE_LOONGSON_MMI
, mips_cp0_names_numeric
,
643 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
645 /* The loongson3a is an alias of gs464 for compatibility */
646 { "loongson3a", 1, bfd_mach_mips_gs464
, CPU_GS464
,
647 ISA_MIPS64R2
, ASE_LOONGSON_MMI
| ASE_LOONGSON_CAM
| ASE_LOONGSON_EXT
,
648 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_mips3264
,
649 mips_hwr_names_numeric
},
651 { "gs464", 1, bfd_mach_mips_gs464
, CPU_GS464
,
652 ISA_MIPS64R2
, ASE_LOONGSON_MMI
| ASE_LOONGSON_CAM
| ASE_LOONGSON_EXT
,
653 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_mips3264
,
654 mips_hwr_names_numeric
},
656 { "gs464e", 1, bfd_mach_mips_gs464e
, CPU_GS464E
,
657 ISA_MIPS64R2
, ASE_LOONGSON_MMI
| ASE_LOONGSON_CAM
| ASE_LOONGSON_EXT
658 | ASE_LOONGSON_EXT2
, mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_mips3264
,
659 mips_hwr_names_numeric
},
661 { "gs264e", 1, bfd_mach_mips_gs464e
, CPU_GS264E
,
662 ISA_MIPS64R2
, ASE_LOONGSON_MMI
| ASE_LOONGSON_CAM
| ASE_LOONGSON_EXT
663 | ASE_LOONGSON_EXT2
| ASE_MSA
| ASE_MSA64
, mips_cp0_names_numeric
, NULL
,
664 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
666 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
667 ISA_MIPS64R2
| INSN_OCTEON
, 0, mips_cp0_names_numeric
, NULL
, 0,
668 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
670 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
671 ISA_MIPS64R2
| INSN_OCTEONP
, 0, mips_cp0_names_numeric
,
672 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
674 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
675 ISA_MIPS64R2
| INSN_OCTEON2
, 0, mips_cp0_names_numeric
,
676 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
678 { "octeon3", 1, bfd_mach_mips_octeon3
, CPU_OCTEON3
,
679 ISA_MIPS64R5
| INSN_OCTEON3
, ASE_VIRT
| ASE_VIRT64
,
680 mips_cp0_names_numeric
,
681 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
683 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
684 ISA_MIPS64
| INSN_XLR
, 0,
686 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
687 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
689 /* XLP is mostly like XLR, with the prominent exception it is being
691 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
692 ISA_MIPS64R2
| INSN_XLR
, 0,
694 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
695 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
697 /* This entry, mips16, is here only for ISA/processor selection; do
698 not print its name. */
699 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS64
,
700 ASE_MIPS16E2
| ASE_MIPS16E2_MT
,
701 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
702 mips_hwr_names_numeric
},
705 /* ISA and processor type to disassemble for, and register names to use.
706 set_default_mips_dis_options and parse_mips_dis_options fill in these
708 static int mips_processor
;
711 static int micromips_ase
;
712 static const char * const *mips_gpr_names
;
713 static const char * const *mips_fpr_names
;
714 static const char * const *mips_cp0_names
;
715 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
716 static int mips_cp0sel_names_len
;
717 static const char * const *mips_cp1_names
;
718 static const char * const *mips_hwr_names
;
721 static int no_aliases
; /* If set disassemble as most general inst. */
723 static const struct mips_abi_choice
*
724 choose_abi_by_name (const char *name
, unsigned int namelen
)
726 const struct mips_abi_choice
*c
;
729 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
730 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
731 && strlen (mips_abi_choices
[i
].name
) == namelen
)
732 c
= &mips_abi_choices
[i
];
737 static const struct mips_arch_choice
*
738 choose_arch_by_name (const char *name
, unsigned int namelen
)
740 const struct mips_arch_choice
*c
= NULL
;
743 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
744 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
745 && strlen (mips_arch_choices
[i
].name
) == namelen
)
746 c
= &mips_arch_choices
[i
];
751 static const struct mips_arch_choice
*
752 choose_arch_by_number (unsigned long mach
)
754 static unsigned long hint_bfd_mach
;
755 static const struct mips_arch_choice
*hint_arch_choice
;
756 const struct mips_arch_choice
*c
;
759 /* We optimize this because even if the user specifies no
760 flags, this will be done for every instruction! */
761 if (hint_bfd_mach
== mach
762 && hint_arch_choice
!= NULL
763 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
764 return hint_arch_choice
;
766 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
768 if (mips_arch_choices
[i
].bfd_mach_valid
769 && mips_arch_choices
[i
].bfd_mach
== mach
)
771 c
= &mips_arch_choices
[i
];
772 hint_bfd_mach
= mach
;
773 hint_arch_choice
= c
;
779 /* Check if the object uses NewABI conventions. */
782 is_newabi (Elf_Internal_Ehdr
*header
)
784 /* There are no old-style ABIs which use 64-bit ELF. */
785 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
788 /* If a 32-bit ELF file, n32 is a new-style ABI. */
789 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
795 /* Check if the object has microMIPS ASE code. */
798 is_micromips (Elf_Internal_Ehdr
*header
)
800 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
806 /* Convert ASE flags from .MIPS.abiflags to internal values. */
809 mips_convert_abiflags_ases (unsigned long afl_ases
)
811 unsigned long opcode_ases
= 0;
813 if (afl_ases
& AFL_ASE_DSP
)
814 opcode_ases
|= ASE_DSP
;
815 if (afl_ases
& AFL_ASE_DSPR2
)
816 opcode_ases
|= ASE_DSPR2
;
817 if (afl_ases
& AFL_ASE_EVA
)
818 opcode_ases
|= ASE_EVA
;
819 if (afl_ases
& AFL_ASE_MCU
)
820 opcode_ases
|= ASE_MCU
;
821 if (afl_ases
& AFL_ASE_MDMX
)
822 opcode_ases
|= ASE_MDMX
;
823 if (afl_ases
& AFL_ASE_MIPS3D
)
824 opcode_ases
|= ASE_MIPS3D
;
825 if (afl_ases
& AFL_ASE_MT
)
826 opcode_ases
|= ASE_MT
;
827 if (afl_ases
& AFL_ASE_SMARTMIPS
)
828 opcode_ases
|= ASE_SMARTMIPS
;
829 if (afl_ases
& AFL_ASE_VIRT
)
830 opcode_ases
|= ASE_VIRT
;
831 if (afl_ases
& AFL_ASE_MSA
)
832 opcode_ases
|= ASE_MSA
;
833 if (afl_ases
& AFL_ASE_XPA
)
834 opcode_ases
|= ASE_XPA
;
835 if (afl_ases
& AFL_ASE_DSPR3
)
836 opcode_ases
|= ASE_DSPR3
;
837 if (afl_ases
& AFL_ASE_MIPS16E2
)
838 opcode_ases
|= ASE_MIPS16E2
;
842 /* Calculate combination ASE flags from regular ASE flags. */
845 mips_calculate_combination_ases (int opcode_isa
, unsigned long opcode_ases
)
847 unsigned long combination_ases
= 0;
849 if ((opcode_ases
& (ASE_XPA
| ASE_VIRT
)) == (ASE_XPA
| ASE_VIRT
))
850 combination_ases
|= ASE_XPA_VIRT
;
851 if ((opcode_ases
& (ASE_MIPS16E2
| ASE_MT
)) == (ASE_MIPS16E2
| ASE_MT
))
852 combination_ases
|= ASE_MIPS16E2_MT
;
853 if ((opcode_ases
& ASE_EVA
)
854 && ((opcode_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
855 || (opcode_isa
& INSN_ISA_MASK
) == ISA_MIPS32R6
))
856 combination_ases
|= ASE_EVA_R6
;
857 return combination_ases
;
861 set_default_mips_dis_options (struct disassemble_info
*info
)
863 const struct mips_arch_choice
*chosen_arch
;
865 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
866 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
867 CP0 register, and HWR names. */
868 mips_isa
= ISA_MIPS3
;
869 mips_processor
= CPU_R3000
;
872 mips_gpr_names
= mips_gpr_names_oldabi
;
873 mips_fpr_names
= mips_fpr_names_numeric
;
874 mips_cp0_names
= mips_cp0_names_numeric
;
875 mips_cp0sel_names
= NULL
;
876 mips_cp0sel_names_len
= 0;
877 mips_cp1_names
= mips_cp1_names_numeric
;
878 mips_hwr_names
= mips_hwr_names_numeric
;
881 /* Set ISA, architecture, and cp0 register names as best we can. */
882 #if ! SYMTAB_AVAILABLE
883 /* This is running out on a target machine, not in a host tool.
884 FIXME: Where does mips_target_info come from? */
885 target_processor
= mips_target_info
.processor
;
886 mips_isa
= mips_target_info
.isa
;
887 mips_ase
= mips_target_info
.ase
;
889 chosen_arch
= choose_arch_by_number (info
->mach
);
890 if (chosen_arch
!= NULL
)
892 mips_processor
= chosen_arch
->processor
;
893 mips_isa
= chosen_arch
->isa
;
894 mips_ase
= chosen_arch
->ase
;
895 mips_cp0_names
= chosen_arch
->cp0_names
;
896 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
897 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
898 mips_cp1_names
= chosen_arch
->cp1_names
;
899 mips_hwr_names
= chosen_arch
->hwr_names
;
902 /* Update settings according to the ELF file header flags. */
903 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
905 struct bfd
*abfd
= info
->section
->owner
;
906 Elf_Internal_Ehdr
*header
= elf_elfheader (abfd
);
907 Elf_Internal_ABIFlags_v0
*abiflags
= NULL
;
909 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
910 because we won't then have a MIPS/ELF BFD, however we need
911 to guard against a link error in a `--enable-targets=...'
912 configuration with a 32-bit host where the MIPS target is
913 a secondary, or with MIPS/ECOFF configurations. */
914 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
915 abiflags
= bfd_mips_elf_get_abiflags (abfd
);
917 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
918 if (is_newabi (header
))
919 mips_gpr_names
= mips_gpr_names_newabi
;
920 /* If a microMIPS binary, then don't use MIPS16 bindings. */
921 micromips_ase
= is_micromips (header
);
922 /* OR in any extra ASE flags set in ELF file structures. */
924 mips_ase
|= mips_convert_abiflags_ases (abiflags
->ases
);
925 else if (header
->e_flags
& EF_MIPS_ARCH_ASE_MDMX
)
926 mips_ase
|= ASE_MDMX
;
929 mips_ase
|= mips_calculate_combination_ases (mips_isa
, mips_ase
);
932 /* Parse an ASE disassembler option and set the corresponding global
933 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
936 parse_mips_ase_option (const char *option
)
938 if (startswith (option
, "msa"))
941 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
942 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R3
943 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R5
944 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
)
945 mips_ase
|= ASE_MSA64
;
949 if (startswith (option
, "virt"))
951 mips_ase
|= ASE_VIRT
;
952 if (mips_isa
& ISA_MIPS64R2
953 || mips_isa
& ISA_MIPS64R3
954 || mips_isa
& ISA_MIPS64R5
955 || mips_isa
& ISA_MIPS64R6
)
956 mips_ase
|= ASE_VIRT64
;
960 if (startswith (option
, "xpa"))
966 if (startswith (option
, "ginv"))
968 mips_ase
|= ASE_GINV
;
972 if (startswith (option
, "loongson-mmi"))
974 mips_ase
|= ASE_LOONGSON_MMI
;
978 if (startswith (option
, "loongson-cam"))
980 mips_ase
|= ASE_LOONGSON_CAM
;
984 /* Put here for match ext2 frist */
985 if (startswith (option
, "loongson-ext2"))
987 mips_ase
|= ASE_LOONGSON_EXT2
;
991 if (startswith (option
, "loongson-ext"))
993 mips_ase
|= ASE_LOONGSON_EXT
;
1001 parse_mips_dis_option (const char *option
, unsigned int len
)
1003 unsigned int i
, optionlen
, vallen
;
1005 const struct mips_abi_choice
*chosen_abi
;
1006 const struct mips_arch_choice
*chosen_arch
;
1008 /* Try to match options that are simple flags */
1009 if (startswith (option
, "no-aliases"))
1015 if (parse_mips_ase_option (option
))
1017 mips_ase
|= mips_calculate_combination_ases (mips_isa
, mips_ase
);
1021 /* Look for the = that delimits the end of the option name. */
1022 for (i
= 0; i
< len
; i
++)
1023 if (option
[i
] == '=')
1026 if (i
== 0) /* Invalid option: no name before '='. */
1028 if (i
== len
) /* Invalid option: no '='. */
1030 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
1034 val
= option
+ (optionlen
+ 1);
1035 vallen
= len
- (optionlen
+ 1);
1037 if (strncmp ("gpr-names", option
, optionlen
) == 0
1038 && strlen ("gpr-names") == optionlen
)
1040 chosen_abi
= choose_abi_by_name (val
, vallen
);
1041 if (chosen_abi
!= NULL
)
1042 mips_gpr_names
= chosen_abi
->gpr_names
;
1046 if (strncmp ("fpr-names", option
, optionlen
) == 0
1047 && strlen ("fpr-names") == optionlen
)
1049 chosen_abi
= choose_abi_by_name (val
, vallen
);
1050 if (chosen_abi
!= NULL
)
1051 mips_fpr_names
= chosen_abi
->fpr_names
;
1055 if (strncmp ("cp0-names", option
, optionlen
) == 0
1056 && strlen ("cp0-names") == optionlen
)
1058 chosen_arch
= choose_arch_by_name (val
, vallen
);
1059 if (chosen_arch
!= NULL
)
1061 mips_cp0_names
= chosen_arch
->cp0_names
;
1062 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
1063 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
1068 if (strncmp ("cp1-names", option
, optionlen
) == 0
1069 && strlen ("cp1-names") == optionlen
)
1071 chosen_arch
= choose_arch_by_name (val
, vallen
);
1072 if (chosen_arch
!= NULL
)
1073 mips_cp1_names
= chosen_arch
->cp1_names
;
1077 if (strncmp ("hwr-names", option
, optionlen
) == 0
1078 && strlen ("hwr-names") == optionlen
)
1080 chosen_arch
= choose_arch_by_name (val
, vallen
);
1081 if (chosen_arch
!= NULL
)
1082 mips_hwr_names
= chosen_arch
->hwr_names
;
1086 if (strncmp ("reg-names", option
, optionlen
) == 0
1087 && strlen ("reg-names") == optionlen
)
1089 /* We check both ABI and ARCH here unconditionally, so
1090 that "numeric" will do the desirable thing: select
1091 numeric register names for all registers. Other than
1092 that, a given name probably won't match both. */
1093 chosen_abi
= choose_abi_by_name (val
, vallen
);
1094 if (chosen_abi
!= NULL
)
1096 mips_gpr_names
= chosen_abi
->gpr_names
;
1097 mips_fpr_names
= chosen_abi
->fpr_names
;
1099 chosen_arch
= choose_arch_by_name (val
, vallen
);
1100 if (chosen_arch
!= NULL
)
1102 mips_cp0_names
= chosen_arch
->cp0_names
;
1103 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
1104 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
1105 mips_cp1_names
= chosen_arch
->cp1_names
;
1106 mips_hwr_names
= chosen_arch
->hwr_names
;
1111 /* Invalid option. */
1115 parse_mips_dis_options (const char *options
)
1117 const char *option_end
;
1119 if (options
== NULL
)
1122 while (*options
!= '\0')
1124 /* Skip empty options. */
1125 if (*options
== ',')
1131 /* We know that *options is neither NUL or a comma. */
1132 option_end
= options
+ 1;
1133 while (*option_end
!= ',' && *option_end
!= '\0')
1136 parse_mips_dis_option (options
, option_end
- options
);
1138 /* Go on to the next one. If option_end points to a comma, it
1139 will be skipped above. */
1140 options
= option_end
;
1144 static const struct mips_cp0sel_name
*
1145 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
1147 unsigned int cp0reg
,
1152 for (i
= 0; i
< len
; i
++)
1153 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
1158 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1161 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
1162 enum mips_reg_operand_type type
, int regno
)
1167 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
1171 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
1175 if (opcode
->pinfo
& (FP_D
| FP_S
))
1176 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
1178 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
1182 if (opcode
->membership
& INSN_5400
)
1183 info
->fprintf_func (info
->stream
, "$f%d", regno
);
1185 info
->fprintf_func (info
->stream
, "$v%d", regno
);
1189 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
1193 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1194 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
1195 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
1196 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
1198 info
->fprintf_func (info
->stream
, "$%d", regno
);
1202 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1206 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1210 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1213 case OP_REG_R5900_I
:
1214 info
->fprintf_func (info
->stream
, "$I");
1217 case OP_REG_R5900_Q
:
1218 info
->fprintf_func (info
->stream
, "$Q");
1221 case OP_REG_R5900_R
:
1222 info
->fprintf_func (info
->stream
, "$R");
1225 case OP_REG_R5900_ACC
:
1226 info
->fprintf_func (info
->stream
, "$ACC");
1230 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1233 case OP_REG_MSA_CTRL
:
1234 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1240 /* Used to track the state carried over from previous operands in
1242 struct mips_print_arg_state
{
1243 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1244 where the value is known to be unsigned and small. */
1245 unsigned int last_int
;
1247 /* The type and number of the last OP_REG seen. We only use this for
1248 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1249 enum mips_reg_operand_type last_reg_type
;
1250 unsigned int last_regno
;
1251 unsigned int dest_regno
;
1252 unsigned int seen_dest
;
1255 /* Initialize STATE for the start of an instruction. */
1258 init_print_arg_state (struct mips_print_arg_state
*state
)
1260 memset (state
, 0, sizeof (*state
));
1263 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1264 whose value is given by UVAL. */
1267 print_vu0_channel (struct disassemble_info
*info
,
1268 const struct mips_operand
*operand
, unsigned int uval
)
1270 if (operand
->size
== 4)
1271 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1272 uval
& 8 ? "x" : "",
1273 uval
& 4 ? "y" : "",
1274 uval
& 2 ? "z" : "",
1275 uval
& 1 ? "w" : "");
1276 else if (operand
->size
== 2)
1277 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1282 /* Record information about a register operand. */
1285 mips_seen_register (struct mips_print_arg_state
*state
,
1287 enum mips_reg_operand_type reg_type
)
1289 state
->last_reg_type
= reg_type
;
1290 state
->last_regno
= regno
;
1292 if (!state
->seen_dest
)
1294 state
->seen_dest
= 1;
1295 state
->dest_regno
= regno
;
1299 /* Print SAVE/RESTORE instruction operands according to the argument
1300 register mask AMASK, the number of static registers saved NSREG,
1301 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1302 and the frame size FRAME_SIZE. */
1305 mips_print_save_restore (struct disassemble_info
*info
, unsigned int amask
,
1306 unsigned int nsreg
, unsigned int ra
,
1307 unsigned int s0
, unsigned int s1
,
1308 unsigned int frame_size
)
1310 const fprintf_ftype infprintf
= info
->fprintf_func
;
1311 unsigned int nargs
, nstatics
, smask
, i
, j
;
1312 void *is
= info
->stream
;
1315 if (amask
== MIPS_SVRS_ALL_ARGS
)
1320 else if (amask
== MIPS_SVRS_ALL_STATICS
)
1328 nstatics
= amask
& 3;
1334 infprintf (is
, "%s", mips_gpr_names
[4]);
1336 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1340 infprintf (is
, "%s%d", sep
, frame_size
);
1343 infprintf (is
, ",%s", mips_gpr_names
[31]);
1350 if (nsreg
> 0) /* $s2-$s8 */
1351 smask
|= ((1 << nsreg
) - 1) << 2;
1353 for (i
= 0; i
< 9; i
++)
1354 if (smask
& (1 << i
))
1356 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1357 /* Skip over string of set bits. */
1358 for (j
= i
; smask
& (2 << j
); j
++)
1361 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1364 /* Statics $ax - $a3. */
1366 infprintf (is
, ",%s", mips_gpr_names
[7]);
1367 else if (nstatics
> 0)
1368 infprintf (is
, ",%s-%s",
1369 mips_gpr_names
[7 - nstatics
+ 1],
1374 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1375 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1376 the base address for OP_PCREL operands. */
1379 print_insn_arg (struct disassemble_info
*info
,
1380 struct mips_print_arg_state
*state
,
1381 const struct mips_opcode
*opcode
,
1382 const struct mips_operand
*operand
,
1386 const fprintf_ftype infprintf
= info
->fprintf_func
;
1387 void *is
= info
->stream
;
1389 switch (operand
->type
)
1393 const struct mips_int_operand
*int_op
;
1395 int_op
= (const struct mips_int_operand
*) operand
;
1396 uval
= mips_decode_int_operand (int_op
, uval
);
1397 state
->last_int
= uval
;
1398 if (int_op
->print_hex
)
1399 infprintf (is
, "0x%x", uval
);
1401 infprintf (is
, "%d", uval
);
1407 const struct mips_mapped_int_operand
*mint_op
;
1409 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1410 uval
= mint_op
->int_map
[uval
];
1411 state
->last_int
= uval
;
1412 if (mint_op
->print_hex
)
1413 infprintf (is
, "0x%x", uval
);
1415 infprintf (is
, "%d", uval
);
1421 const struct mips_msb_operand
*msb_op
;
1423 msb_op
= (const struct mips_msb_operand
*) operand
;
1424 uval
+= msb_op
->bias
;
1425 if (msb_op
->add_lsb
)
1426 uval
-= state
->last_int
;
1427 infprintf (is
, "0x%x", uval
);
1432 case OP_OPTIONAL_REG
:
1434 const struct mips_reg_operand
*reg_op
;
1436 reg_op
= (const struct mips_reg_operand
*) operand
;
1437 uval
= mips_decode_reg_operand (reg_op
, uval
);
1438 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1440 mips_seen_register (state
, uval
, reg_op
->reg_type
);
1446 const struct mips_reg_pair_operand
*pair_op
;
1448 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1449 print_reg (info
, opcode
, pair_op
->reg_type
,
1450 pair_op
->reg1_map
[uval
]);
1451 infprintf (is
, ",");
1452 print_reg (info
, opcode
, pair_op
->reg_type
,
1453 pair_op
->reg2_map
[uval
]);
1459 const struct mips_pcrel_operand
*pcrel_op
;
1461 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1462 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1464 /* For jumps and branches clear the ISA bit except for
1465 the GDB disassembler. */
1466 if (pcrel_op
->include_isa_bit
1467 && info
->flavour
!= bfd_target_unknown_flavour
)
1470 (*info
->print_address_func
) (info
->target
, info
);
1475 infprintf (is
, "%d", uval
);
1478 case OP_ADDIUSP_INT
:
1482 sval
= mips_signed_operand (operand
, uval
) * 4;
1483 if (sval
>= -8 && sval
< 8)
1485 infprintf (is
, "%d", sval
);
1489 case OP_CLO_CLZ_DEST
:
1491 unsigned int reg1
, reg2
;
1495 /* If one is zero use the other. */
1496 if (reg1
== reg2
|| reg2
== 0)
1497 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1499 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1501 /* Bogus, result depends on processor. */
1502 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1503 mips_gpr_names
[reg2
]);
1509 case OP_NON_ZERO_REG
:
1511 print_reg (info
, opcode
, OP_REG_GP
, uval
& 31);
1512 mips_seen_register (state
, uval
, OP_REG_GP
);
1516 case OP_LWM_SWM_LIST
:
1517 if (operand
->size
== 2)
1520 infprintf (is
, "%s,%s",
1522 mips_gpr_names
[31]);
1524 infprintf (is
, "%s-%s,%s",
1526 mips_gpr_names
[16 + uval
],
1527 mips_gpr_names
[31]);
1533 s_reg_encode
= uval
& 0xf;
1534 if (s_reg_encode
!= 0)
1536 if (s_reg_encode
== 1)
1537 infprintf (is
, "%s", mips_gpr_names
[16]);
1538 else if (s_reg_encode
< 9)
1539 infprintf (is
, "%s-%s",
1541 mips_gpr_names
[15 + s_reg_encode
]);
1542 else if (s_reg_encode
== 9)
1543 infprintf (is
, "%s-%s,%s",
1546 mips_gpr_names
[30]);
1548 infprintf (is
, "UNKNOWN");
1551 if (uval
& 0x10) /* For ra. */
1553 if (s_reg_encode
== 0)
1554 infprintf (is
, "%s", mips_gpr_names
[31]);
1556 infprintf (is
, ",%s", mips_gpr_names
[31]);
1561 case OP_ENTRY_EXIT_LIST
:
1564 unsigned int amask
, smask
;
1567 amask
= (uval
>> 3) & 7;
1568 if (amask
> 0 && amask
< 5)
1570 infprintf (is
, "%s", mips_gpr_names
[4]);
1572 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1576 smask
= (uval
>> 1) & 3;
1579 infprintf (is
, "%s??", sep
);
1584 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1586 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1592 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1596 if (amask
== 5 || amask
== 6)
1598 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1600 infprintf (is
, "-%s", mips_fpr_names
[1]);
1605 case OP_SAVE_RESTORE_LIST
:
1606 /* Should be handled by the caller due to complex behavior. */
1609 case OP_MDMX_IMM_REG
:
1615 if ((vsel
& 0x10) == 0)
1620 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1621 if ((vsel
& 1) == 0)
1623 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1624 infprintf (is
, "[%d]", vsel
>> 1);
1626 else if ((vsel
& 0x08) == 0)
1627 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1629 infprintf (is
, "0x%x", uval
);
1633 case OP_REPEAT_PREV_REG
:
1634 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1637 case OP_REPEAT_DEST_REG
:
1638 print_reg (info
, opcode
, state
->last_reg_type
, state
->dest_regno
);
1642 infprintf (is
, "$pc");
1646 print_reg (info
, opcode
, OP_REG_GP
, 28);
1650 case OP_VU0_MATCH_SUFFIX
:
1651 print_vu0_channel (info
, operand
, uval
);
1655 infprintf (is
, "[%d]", uval
);
1659 infprintf (is
, "[");
1660 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1661 infprintf (is
, "]");
1666 /* Validate the arguments for INSN, which is described by OPCODE.
1667 Use DECODE_OPERAND to get the encoding of each operand. */
1670 validate_insn_args (const struct mips_opcode
*opcode
,
1671 const struct mips_operand
*(*decode_operand
) (const char *),
1674 struct mips_print_arg_state state
;
1675 const struct mips_operand
*operand
;
1679 init_print_arg_state (&state
);
1680 for (s
= opcode
->args
; *s
; ++s
)
1694 operand
= decode_operand (s
);
1698 uval
= mips_extract_operand (operand
, insn
);
1699 switch (operand
->type
)
1702 case OP_OPTIONAL_REG
:
1704 const struct mips_reg_operand
*reg_op
;
1706 reg_op
= (const struct mips_reg_operand
*) operand
;
1707 uval
= mips_decode_reg_operand (reg_op
, uval
);
1708 mips_seen_register (&state
, uval
, reg_op
->reg_type
);
1714 unsigned int reg1
, reg2
;
1719 if (reg1
!= reg2
|| reg1
== 0)
1726 const struct mips_check_prev_operand
*prev_op
;
1728 prev_op
= (const struct mips_check_prev_operand
*) operand
;
1730 if (!prev_op
->zero_ok
&& uval
== 0)
1733 if (((prev_op
->less_than_ok
&& uval
< state
.last_regno
)
1734 || (prev_op
->greater_than_ok
&& uval
> state
.last_regno
)
1735 || (prev_op
->equal_ok
&& uval
== state
.last_regno
)))
1741 case OP_NON_ZERO_REG
:
1754 case OP_ADDIUSP_INT
:
1755 case OP_CLO_CLZ_DEST
:
1756 case OP_LWM_SWM_LIST
:
1757 case OP_ENTRY_EXIT_LIST
:
1758 case OP_MDMX_IMM_REG
:
1759 case OP_REPEAT_PREV_REG
:
1760 case OP_REPEAT_DEST_REG
:
1764 case OP_VU0_MATCH_SUFFIX
:
1767 case OP_SAVE_RESTORE_LIST
:
1771 if (*s
== 'm' || *s
== '+' || *s
== '-')
1778 /* Print the arguments for INSN, which is described by OPCODE.
1779 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1780 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1781 operand is for a branch or jump. */
1784 print_insn_args (struct disassemble_info
*info
,
1785 const struct mips_opcode
*opcode
,
1786 const struct mips_operand
*(*decode_operand
) (const char *),
1787 unsigned int insn
, bfd_vma insn_pc
, unsigned int length
)
1789 const fprintf_ftype infprintf
= info
->fprintf_func
;
1790 void *is
= info
->stream
;
1791 struct mips_print_arg_state state
;
1792 const struct mips_operand
*operand
;
1795 init_print_arg_state (&state
);
1796 for (s
= opcode
->args
; *s
; ++s
)
1803 infprintf (is
, "%c", *s
);
1808 infprintf (is
, "%c%c", *s
, *s
);
1812 operand
= decode_operand (s
);
1815 /* xgettext:c-format */
1817 _("# internal error, undefined operand in `%s %s'"),
1818 opcode
->name
, opcode
->args
);
1822 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1824 /* Handle this case here because of the complex behavior. */
1825 unsigned int amask
= (insn
>> 15) & 0xf;
1826 unsigned int nsreg
= (insn
>> 23) & 0x7;
1827 unsigned int ra
= insn
& 0x1000; /* $ra */
1828 unsigned int s0
= insn
& 0x800; /* $s0 */
1829 unsigned int s1
= insn
& 0x400; /* $s1 */
1830 unsigned int frame_size
= (((insn
>> 15) & 0xf0)
1831 | ((insn
>> 6) & 0x0f)) * 8;
1832 mips_print_save_restore (info
, amask
, nsreg
, ra
, s0
, s1
,
1835 else if (operand
->type
== OP_REG
1838 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1840 /* Coprocessor register 0 with sel field. */
1841 const struct mips_cp0sel_name
*n
;
1842 unsigned int reg
, sel
;
1844 reg
= mips_extract_operand (operand
, insn
);
1846 operand
= decode_operand (s
);
1847 sel
= mips_extract_operand (operand
, insn
);
1849 /* CP0 register including 'sel' code for mftc0, to be
1850 printed textually if known. If not known, print both
1851 CP0 register name and sel numerically since CP0 register
1852 with sel 0 may have a name unrelated to register being
1854 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1855 mips_cp0sel_names_len
,
1858 infprintf (is
, "%s", n
->name
);
1860 infprintf (is
, "$%d,%d", reg
, sel
);
1864 bfd_vma base_pc
= insn_pc
;
1866 /* Adjust the PC relative base so that branch/jump insns use
1867 the following PC as the base but genuinely PC relative
1868 operands use the current PC. */
1869 if (operand
->type
== OP_PCREL
)
1871 const struct mips_pcrel_operand
*pcrel_op
;
1873 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1874 /* The include_isa_bit flag is sufficient to distinguish
1875 branch/jump from other PC relative operands. */
1876 if (pcrel_op
->include_isa_bit
)
1880 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1881 mips_extract_operand (operand
, insn
));
1883 if (*s
== 'm' || *s
== '+' || *s
== '-')
1890 /* Print the mips instruction at address MEMADDR in debugged memory,
1891 on using INFO. Returns length of the instruction, in bytes, which is
1892 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1893 this is little-endian code. */
1896 print_insn_mips (bfd_vma memaddr
,
1898 struct disassemble_info
*info
)
1900 #define GET_OP(insn, field) \
1901 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1902 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1903 const fprintf_ftype infprintf
= info
->fprintf_func
;
1904 const struct mips_opcode
*op
;
1905 static bool init
= 0;
1906 void *is
= info
->stream
;
1908 /* Build a hash table to shorten the search time. */
1913 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1915 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1917 if (op
->pinfo
== INSN_MACRO
1918 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1920 if (i
== GET_OP (op
->match
, OP
))
1931 info
->bytes_per_chunk
= INSNLEN
;
1932 info
->display_endian
= info
->endian
;
1933 info
->insn_info_valid
= 1;
1934 info
->branch_delay_insns
= 0;
1935 info
->data_size
= 0;
1936 info
->insn_type
= dis_nonbranch
;
1940 op
= mips_hash
[GET_OP (word
, OP
)];
1943 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1945 if (op
->pinfo
!= INSN_MACRO
1946 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1947 && (word
& op
->mask
) == op
->match
)
1949 /* We always disassemble the jalx instruction, except for MIPS r6. */
1950 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1951 && (strcmp (op
->name
, "jalx")
1952 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS32R6
1953 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
))
1956 /* Figure out instruction type and branch delay information. */
1957 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1959 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1960 info
->insn_type
= dis_jsr
;
1962 info
->insn_type
= dis_branch
;
1963 info
->branch_delay_insns
= 1;
1965 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1966 | INSN_COND_BRANCH_LIKELY
)) != 0)
1968 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1969 info
->insn_type
= dis_condjsr
;
1971 info
->insn_type
= dis_condbranch
;
1972 info
->branch_delay_insns
= 1;
1974 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1975 | INSN_LOAD_MEMORY
)) != 0)
1976 info
->insn_type
= dis_dref
;
1978 if (!validate_insn_args (op
, decode_mips_operand
, word
))
1981 infprintf (is
, "%s", op
->name
);
1982 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1986 infprintf (is
, ".");
1987 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1988 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1993 infprintf (is
, "\t");
1994 print_insn_args (info
, op
, decode_mips_operand
, word
,
2004 /* Handle undefined instructions. */
2005 info
->insn_type
= dis_noninsn
;
2006 infprintf (is
, "0x%x", word
);
2010 /* Disassemble an operand for a mips16 instruction. */
2013 print_mips16_insn_arg (struct disassemble_info
*info
,
2014 struct mips_print_arg_state
*state
,
2015 const struct mips_opcode
*opcode
,
2016 char type
, bfd_vma memaddr
,
2017 unsigned insn
, bool use_extend
,
2018 unsigned extend
, bool is_offset
)
2020 const fprintf_ftype infprintf
= info
->fprintf_func
;
2021 void *is
= info
->stream
;
2022 const struct mips_operand
*operand
, *ext_operand
;
2023 unsigned short ext_size
;
2035 infprintf (is
, "%c", type
);
2039 operand
= decode_mips16_operand (type
, false);
2042 /* xgettext:c-format */
2043 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
2044 opcode
->name
, opcode
->args
);
2048 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
2050 /* Handle this case here because of the complex interaction
2051 with the EXTEND opcode. */
2052 unsigned int amask
= extend
& 0xf;
2053 unsigned int nsreg
= (extend
>> 8) & 0x7;
2054 unsigned int ra
= insn
& 0x40; /* $ra */
2055 unsigned int s0
= insn
& 0x20; /* $s0 */
2056 unsigned int s1
= insn
& 0x10; /* $s1 */
2057 unsigned int frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
2058 if (frame_size
== 0 && !use_extend
)
2060 mips_print_save_restore (info
, amask
, nsreg
, ra
, s0
, s1
, frame_size
);
2064 if (is_offset
&& operand
->type
== OP_INT
)
2066 const struct mips_int_operand
*int_op
;
2068 int_op
= (const struct mips_int_operand
*) operand
;
2069 info
->insn_type
= dis_dref
;
2070 info
->data_size
= 1 << int_op
->shift
;
2076 ext_operand
= decode_mips16_operand (type
, true);
2077 if (ext_operand
!= operand
2078 || (operand
->type
== OP_INT
&& operand
->lsb
== 0
2079 && mips_opcode_32bit_p (opcode
)))
2081 ext_size
= ext_operand
->size
;
2082 operand
= ext_operand
;
2085 if (operand
->size
== 26)
2086 uval
= ((extend
& 0x1f) << 21) | ((extend
& 0x3e0) << 11) | insn
;
2087 else if (ext_size
== 16 || ext_size
== 9)
2088 uval
= ((extend
& 0x1f) << 11) | (extend
& 0x7e0) | (insn
& 0x1f);
2089 else if (ext_size
== 15)
2090 uval
= ((extend
& 0xf) << 11) | (extend
& 0x7f0) | (insn
& 0xf);
2091 else if (ext_size
== 6)
2092 uval
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
2094 uval
= mips_extract_operand (operand
, (extend
<< 16) | insn
);
2096 uval
&= (1U << ext_size
) - 1;
2098 baseaddr
= memaddr
+ 2;
2099 if (operand
->type
== OP_PCREL
)
2101 const struct mips_pcrel_operand
*pcrel_op
;
2103 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
2104 if (!pcrel_op
->include_isa_bit
&& use_extend
)
2105 baseaddr
= memaddr
- 2;
2106 else if (!pcrel_op
->include_isa_bit
)
2110 /* If this instruction is in the delay slot of a JAL/JALX
2111 instruction, the base address is the address of the
2112 JAL/JALX instruction. If it is in the delay slot of
2113 a JR/JALR instruction, the base address is the address
2114 of the JR/JALR instruction. This test is unreliable:
2115 we have no way of knowing whether the previous word is
2116 instruction or data. */
2117 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
2118 && (((info
->endian
== BFD_ENDIAN_BIG
2119 ? bfd_getb16 (buffer
)
2120 : bfd_getl16 (buffer
))
2121 & 0xf800) == 0x1800))
2122 baseaddr
= memaddr
- 4;
2123 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
2125 && (((info
->endian
== BFD_ENDIAN_BIG
2126 ? bfd_getb16 (buffer
)
2127 : bfd_getl16 (buffer
))
2128 & 0xf89f) == 0xe800)
2129 && (((info
->endian
== BFD_ENDIAN_BIG
2130 ? bfd_getb16 (buffer
)
2131 : bfd_getl16 (buffer
))
2132 & 0x0060) != 0x0060))
2133 baseaddr
= memaddr
- 2;
2139 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
2145 /* Check if the given address is the last word of a MIPS16 PLT entry.
2146 This word is data and depending on the value it may interfere with
2147 disassembly of further PLT entries. We make use of the fact PLT
2148 symbols are marked BSF_SYNTHETIC. */
2150 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2154 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2155 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2161 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2170 /* Disassemble mips16 instructions. */
2173 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2175 const fprintf_ftype infprintf
= info
->fprintf_func
;
2178 const struct mips_opcode
*op
, *opend
;
2179 struct mips_print_arg_state state
;
2180 void *is
= info
->stream
;
2183 unsigned int second
;
2187 info
->bytes_per_chunk
= 2;
2188 info
->display_endian
= info
->endian
;
2189 info
->insn_info_valid
= 1;
2190 info
->branch_delay_insns
= 0;
2191 info
->data_size
= 0;
2195 #define GET_OP(insn, field) \
2196 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2197 /* Decode PLT entry's GOT slot address word. */
2198 if (is_mips16_plt_tail (info
, memaddr
))
2200 info
->insn_type
= dis_noninsn
;
2201 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2204 unsigned int gotslot
;
2206 if (info
->endian
== BFD_ENDIAN_BIG
)
2207 gotslot
= bfd_getb32 (buffer
);
2209 gotslot
= bfd_getl32 (buffer
);
2210 infprintf (is
, ".word\t0x%x", gotslot
);
2217 info
->insn_type
= dis_nonbranch
;
2218 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2222 (*info
->memory_error_func
) (status
, memaddr
, info
);
2226 extend_only
= false;
2228 if (info
->endian
== BFD_ENDIAN_BIG
)
2229 first
= bfd_getb16 (buffer
);
2231 first
= bfd_getl16 (buffer
);
2233 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2237 if (info
->endian
== BFD_ENDIAN_BIG
)
2238 second
= bfd_getb16 (buffer
);
2240 second
= bfd_getl16 (buffer
);
2241 full
= (first
<< 16) | second
;
2245 have_second
= false;
2250 /* FIXME: Should probably use a hash table on the major opcode here. */
2252 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2253 for (op
= mips16_opcodes
; op
< opend
; op
++)
2255 enum match_kind match
;
2257 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
))
2260 if (op
->pinfo
== INSN_MACRO
2261 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
2263 else if (mips_opcode_32bit_p (op
))
2266 && (full
& op
->mask
) == op
->match
)
2271 else if ((first
& op
->mask
) == op
->match
)
2273 match
= MATCH_SHORT
;
2277 else if ((first
& 0xf800) == 0xf000
2280 && (second
& op
->mask
) == op
->match
)
2282 if (op
->pinfo2
& INSN2_SHORT_ONLY
)
2293 if (match
!= MATCH_NONE
)
2297 infprintf (is
, "%s", op
->name
);
2298 if (op
->args
[0] != '\0')
2299 infprintf (is
, "\t");
2301 init_print_arg_state (&state
);
2302 for (s
= op
->args
; *s
!= '\0'; s
++)
2306 && GET_OP (full
, RX
) == GET_OP (full
, RY
))
2308 /* Skip the register and the comma. */
2314 && GET_OP (full
, RZ
) == GET_OP (full
, RX
))
2316 /* Skip the register and the comma. */
2323 && op
->name
[strlen (op
->name
) - 1] == '0')
2325 /* Coprocessor register 0 with sel field. */
2326 const struct mips_cp0sel_name
*n
;
2327 const struct mips_operand
*operand
;
2328 unsigned int reg
, sel
;
2330 operand
= decode_mips16_operand (*s
, true);
2331 reg
= mips_extract_operand (operand
, (first
<< 16) | second
);
2333 operand
= decode_mips16_operand (*s
, true);
2334 sel
= mips_extract_operand (operand
, (first
<< 16) | second
);
2336 /* CP0 register including 'sel' code for mftc0, to be
2337 printed textually if known. If not known, print both
2338 CP0 register name and sel numerically since CP0 register
2339 with sel 0 may have a name unrelated to register being
2341 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2342 mips_cp0sel_names_len
,
2345 infprintf (is
, "%s", n
->name
);
2347 infprintf (is
, "$%d,%d", reg
, sel
);
2353 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
+ 2,
2354 second
, true, first
, s
[1] == '(');
2357 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
,
2358 first
, false, 0, s
[1] == '(');
2360 case MATCH_NONE
: /* Stop the compiler complaining. */
2365 /* Figure out branch instruction type and delay slot information. */
2366 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2367 info
->branch_delay_insns
= 1;
2368 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
2369 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
2371 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2372 info
->insn_type
= dis_jsr
;
2374 info
->insn_type
= dis_branch
;
2376 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
2377 info
->insn_type
= dis_condbranch
;
2379 return match
== MATCH_FULL
? 4 : 2;
2384 infprintf (is
, "0x%x", first
);
2385 info
->insn_type
= dis_noninsn
;
2390 /* Disassemble microMIPS instructions. */
2393 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2395 const fprintf_ftype infprintf
= info
->fprintf_func
;
2396 const struct mips_opcode
*op
, *opend
;
2397 void *is
= info
->stream
;
2399 unsigned int higher
;
2400 unsigned int length
;
2404 info
->bytes_per_chunk
= 2;
2405 info
->display_endian
= info
->endian
;
2406 info
->insn_info_valid
= 1;
2407 info
->branch_delay_insns
= 0;
2408 info
->data_size
= 0;
2409 info
->insn_type
= dis_nonbranch
;
2413 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2416 (*info
->memory_error_func
) (status
, memaddr
, info
);
2422 if (info
->endian
== BFD_ENDIAN_BIG
)
2423 insn
= bfd_getb16 (buffer
);
2425 insn
= bfd_getl16 (buffer
);
2427 if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2429 /* This is a 32-bit microMIPS instruction. */
2432 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2435 infprintf (is
, "micromips 0x%x", higher
);
2436 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2440 if (info
->endian
== BFD_ENDIAN_BIG
)
2441 insn
= bfd_getb16 (buffer
);
2443 insn
= bfd_getl16 (buffer
);
2445 insn
= insn
| (higher
<< 16);
2450 /* FIXME: Should probably use a hash table on the major opcode here. */
2452 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2453 for (op
= micromips_opcodes
; op
< opend
; op
++)
2455 if (op
->pinfo
!= INSN_MACRO
2456 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2457 && (insn
& op
->mask
) == op
->match
2458 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2459 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2461 if (!validate_insn_args (op
, decode_micromips_operand
, insn
))
2464 infprintf (is
, "%s", op
->name
);
2468 infprintf (is
, "\t");
2469 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2470 memaddr
+ 1, length
);
2473 /* Figure out instruction type and branch delay information. */
2475 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2476 info
->branch_delay_insns
= 1;
2477 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2478 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2480 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2481 info
->insn_type
= dis_jsr
;
2483 info
->insn_type
= dis_branch
;
2485 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2486 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2488 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2489 info
->insn_type
= dis_condjsr
;
2491 info
->insn_type
= dis_condbranch
;
2494 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2495 info
->insn_type
= dis_dref
;
2501 infprintf (is
, "0x%x", insn
);
2502 info
->insn_type
= dis_noninsn
;
2507 /* Return 1 if a symbol associated with the location being disassembled
2508 indicates a compressed mode, either MIPS16 or microMIPS, according to
2509 MICROMIPS_P. We iterate over all the symbols at the address being
2510 considered assuming if at least one of them indicates code compression,
2511 then such code has been genuinely produced here (other symbols could
2512 have been derived from function symbols defined elsewhere or could
2513 define data). Otherwise, return 0. */
2516 is_compressed_mode_p (struct disassemble_info
*info
, bool micromips_p
)
2521 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2522 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2524 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2526 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2528 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2529 && info
->symtab
[i
]->section
== info
->section
)
2531 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2533 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2535 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2542 /* In an environment where we do not know the symbol type of the
2543 instruction we are forced to assume that the low order bit of the
2544 instructions' address may mark it as a mips16 instruction. If we
2545 are single stepping, or the pc is within the disassembled function,
2546 this works. Otherwise, we need a clue. Sometimes. */
2549 _print_insn_mips (bfd_vma memaddr
,
2550 struct disassemble_info
*info
,
2551 enum bfd_endian endianness
)
2553 bfd_byte buffer
[INSNLEN
];
2556 set_default_mips_dis_options (info
);
2557 parse_mips_dis_options (info
->disassembler_options
);
2559 if (info
->mach
== bfd_mach_mips16
)
2560 return print_insn_mips16 (memaddr
, info
);
2561 if (info
->mach
== bfd_mach_mips_micromips
)
2562 return print_insn_micromips (memaddr
, info
);
2565 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2566 /* Only a few tools will work this way. */
2570 return print_insn_micromips (memaddr
, info
);
2572 return print_insn_mips16 (memaddr
, info
);
2576 #if SYMTAB_AVAILABLE
2577 if (is_compressed_mode_p (info
, true))
2578 return print_insn_micromips (memaddr
, info
);
2579 if (is_compressed_mode_p (info
, false))
2580 return print_insn_mips16 (memaddr
, info
);
2583 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2588 if (endianness
== BFD_ENDIAN_BIG
)
2589 insn
= bfd_getb32 (buffer
);
2591 insn
= bfd_getl32 (buffer
);
2593 return print_insn_mips (memaddr
, insn
, info
);
2597 (*info
->memory_error_func
) (status
, memaddr
, info
);
2603 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2605 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2609 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2611 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2614 /* Indices into option argument vector for options accepting an argument.
2615 Use MIPS_OPTION_ARG_NONE for options accepting no argument. */
2618 MIPS_OPTION_ARG_NONE
= -1,
2619 MIPS_OPTION_ARG_ABI
,
2620 MIPS_OPTION_ARG_ARCH
,
2621 MIPS_OPTION_ARG_SIZE
2622 } mips_option_arg_t
;
2624 /* Valid MIPS disassembler options. */
2628 const char *description
;
2629 mips_option_arg_t arg
;
2632 { "no-aliases", N_("Use canonical instruction forms.\n"),
2633 MIPS_OPTION_ARG_NONE
},
2634 { "msa", N_("Recognize MSA instructions.\n"),
2635 MIPS_OPTION_ARG_NONE
},
2636 { "virt", N_("Recognize the virtualization ASE instructions.\n"),
2637 MIPS_OPTION_ARG_NONE
},
2638 { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\
2640 MIPS_OPTION_ARG_NONE
},
2641 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2643 MIPS_OPTION_ARG_NONE
},
2645 N_("Recognize the Loongson MultiMedia extensions "
2646 "Instructions (MMI) ASE instructions.\n"),
2647 MIPS_OPTION_ARG_NONE
},
2649 N_("Recognize the Loongson Content Address Memory (CAM) "
2650 " instructions.\n"),
2651 MIPS_OPTION_ARG_NONE
},
2653 N_("Recognize the Loongson EXTensions (EXT) "
2654 " instructions.\n"),
2655 MIPS_OPTION_ARG_NONE
},
2657 N_("Recognize the Loongson EXTensions R2 (EXT2) "
2658 " instructions.\n"),
2659 MIPS_OPTION_ARG_NONE
},
2660 { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
2661 Default: based on binary being disassembled.\n"),
2662 MIPS_OPTION_ARG_ABI
},
2663 { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
2664 Default: numeric.\n"),
2665 MIPS_OPTION_ARG_ABI
},
2666 { "cp0-names=", N_("Print CP0 register names according to specified "
2668 Default: based on binary being disassembled.\n"),
2669 MIPS_OPTION_ARG_ARCH
},
2670 { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
2671 Default: based on binary being disassembled.\n"),
2672 MIPS_OPTION_ARG_ARCH
},
2673 { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
2674 MIPS_OPTION_ARG_ABI
},
2675 { "reg-names=", N_("Print CP0 register and HWR names according to "
2678 MIPS_OPTION_ARG_ARCH
}
2681 /* Build the structure representing valid MIPS disassembler options.
2682 This is done dynamically for maintenance ease purpose; a static
2683 initializer would be unreadable. */
2685 const disasm_options_and_args_t
*
2686 disassembler_options_mips (void)
2688 static disasm_options_and_args_t
*opts_and_args
;
2690 if (opts_and_args
== NULL
)
2692 size_t num_options
= ARRAY_SIZE (mips_options
);
2693 size_t num_args
= MIPS_OPTION_ARG_SIZE
;
2694 disasm_option_arg_t
*args
;
2695 disasm_options_t
*opts
;
2699 args
= XNEWVEC (disasm_option_arg_t
, num_args
+ 1);
2701 args
[MIPS_OPTION_ARG_ABI
].name
= "ABI";
2702 args
[MIPS_OPTION_ARG_ABI
].values
2703 = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices
) + 1);
2704 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2705 args
[MIPS_OPTION_ARG_ABI
].values
[i
] = mips_abi_choices
[i
].name
;
2706 /* The array we return must be NULL terminated. */
2707 args
[MIPS_OPTION_ARG_ABI
].values
[i
] = NULL
;
2709 args
[MIPS_OPTION_ARG_ARCH
].name
= "ARCH";
2710 args
[MIPS_OPTION_ARG_ARCH
].values
2711 = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices
) + 1);
2712 for (i
= 0, j
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2713 if (*mips_arch_choices
[i
].name
!= '\0')
2714 args
[MIPS_OPTION_ARG_ARCH
].values
[j
++] = mips_arch_choices
[i
].name
;
2715 /* The array we return must be NULL terminated. */
2716 args
[MIPS_OPTION_ARG_ARCH
].values
[j
] = NULL
;
2718 /* The array we return must be NULL terminated. */
2719 args
[MIPS_OPTION_ARG_SIZE
].name
= NULL
;
2720 args
[MIPS_OPTION_ARG_SIZE
].values
= NULL
;
2722 opts_and_args
= XNEW (disasm_options_and_args_t
);
2723 opts_and_args
->args
= args
;
2725 opts
= &opts_and_args
->options
;
2726 opts
->name
= XNEWVEC (const char *, num_options
+ 1);
2727 opts
->description
= XNEWVEC (const char *, num_options
+ 1);
2728 opts
->arg
= XNEWVEC (const disasm_option_arg_t
*, num_options
+ 1);
2729 for (i
= 0; i
< num_options
; i
++)
2731 opts
->name
[i
] = mips_options
[i
].name
;
2732 opts
->description
[i
] = _(mips_options
[i
].description
);
2733 if (mips_options
[i
].arg
!= MIPS_OPTION_ARG_NONE
)
2734 opts
->arg
[i
] = &args
[mips_options
[i
].arg
];
2736 opts
->arg
[i
] = NULL
;
2738 /* The array we return must be NULL terminated. */
2739 opts
->name
[i
] = NULL
;
2740 opts
->description
[i
] = NULL
;
2741 opts
->arg
[i
] = NULL
;
2744 return opts_and_args
;
2748 print_mips_disassembler_options (FILE *stream
)
2750 const disasm_options_and_args_t
*opts_and_args
;
2751 const disasm_option_arg_t
*args
;
2752 const disasm_options_t
*opts
;
2757 opts_and_args
= disassembler_options_mips ();
2758 opts
= &opts_and_args
->options
;
2759 args
= opts_and_args
->args
;
2761 fprintf (stream
, _("\n\
2762 The following MIPS specific disassembler options are supported for use\n\
2763 with the -M switch (multiple options should be separated by commas):\n\n"));
2765 /* Compute the length of the longest option name. */
2766 for (i
= 0; opts
->name
[i
] != NULL
; i
++)
2768 size_t len
= strlen (opts
->name
[i
]);
2770 if (opts
->arg
[i
] != NULL
)
2771 len
+= strlen (opts
->arg
[i
]->name
);
2776 for (i
= 0, max_len
++; opts
->name
[i
] != NULL
; i
++)
2778 fprintf (stream
, " %s", opts
->name
[i
]);
2779 if (opts
->arg
[i
] != NULL
)
2780 fprintf (stream
, "%s", opts
->arg
[i
]->name
);
2781 if (opts
->description
[i
] != NULL
)
2783 size_t len
= strlen (opts
->name
[i
]);
2785 if (opts
->arg
[i
] != NULL
)
2786 len
+= strlen (opts
->arg
[i
]->name
);
2788 "%*c %s", (int) (max_len
- len
), ' ', opts
->description
[i
]);
2790 fprintf (stream
, _("\n"));
2793 for (i
= 0; args
[i
].name
!= NULL
; i
++)
2795 fprintf (stream
, _("\n\
2796 For the options above, the following values are supported for \"%s\":\n "),
2798 for (j
= 0; args
[i
].values
[j
] != NULL
; j
++)
2799 fprintf (stream
, " %s", args
[i
].values
[j
]);
2800 fprintf (stream
, _("\n"));
2803 fprintf (stream
, _("\n"));