1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2019 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"
28 /* FIXME: These are needed to figure out if the code is mips16 or
29 not. The low bit of the address is often a good indicator. No
30 symbol table is available when this code runs out in an embedded
31 system as when it is used for disassembler support in a monitor. */
33 #if !defined(EMBEDDED_ENV)
34 #define SYMTAB_AVAILABLE 1
39 /* Mips instructions are at maximum this many bytes long. */
43 /* FIXME: These should be shared with gdb somehow. */
45 struct mips_cp0sel_name
49 const char * const name;
52 static const char * const mips_gpr_names_numeric[32] =
54 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
55 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
56 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
57 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
60 static const char * const mips_gpr_names_oldabi[32] =
62 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
63 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
64 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
65 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
68 static const char * const mips_gpr_names_newabi[32] =
70 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
71 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
72 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
73 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
76 static const char * const mips_fpr_names_numeric[32] =
78 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
79 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
80 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
81 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
84 static const char * const mips_fpr_names_32[32] =
86 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
87 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
88 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
89 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
92 static const char * const mips_fpr_names_n32[32] =
94 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
95 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
96 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
97 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
100 static const char * const mips_fpr_names_64[32] =
102 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
103 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
104 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
105 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
108 static const char * const mips_cp0_names_numeric[32] =
110 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
111 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
112 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
113 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
116 static const char * const mips_cp1_names_numeric[32] =
118 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
119 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
120 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
121 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
124 static const char * const mips_cp0_names_r3000[32] =
126 "c0_index", "c0_random", "c0_entrylo", "$3",
127 "c0_context", "$5", "$6", "$7",
128 "c0_badvaddr", "$9", "c0_entryhi", "$11",
129 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
130 "$16", "$17", "$18", "$19",
131 "$20", "$21", "$22", "$23",
132 "$24", "$25", "$26", "$27",
133 "$28", "$29", "$30", "$31",
136 static const char * const mips_cp0_names_r4000[32] =
138 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
139 "c0_context", "c0_pagemask", "c0_wired", "$7",
140 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
141 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
142 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
143 "c0_xcontext", "$21", "$22", "$23",
144 "$24", "$25", "c0_ecc", "c0_cacheerr",
145 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
148 static const char * const mips_cp0_names_r5900[32] =
150 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
151 "c0_context", "c0_pagemask", "c0_wired", "$7",
152 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
153 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
154 "c0_config", "$17", "$18", "$19",
155 "$20", "$21", "$22", "c0_badpaddr",
156 "c0_depc", "c0_perfcnt", "$26", "$27",
157 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
160 static const char * const mips_cp0_names_mips3264[32] =
162 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
163 "c0_context", "c0_pagemask", "c0_wired", "$7",
164 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
165 "c0_status", "c0_cause", "c0_epc", "c0_prid",
166 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
167 "c0_xcontext", "$21", "$22", "c0_debug",
168 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
169 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
172 static const char * const mips_cp1_names_mips3264[32] =
174 "c1_fir", "c1_ufr", "$2", "$3",
175 "c1_unfr", "$5", "$6", "$7",
176 "$8", "$9", "$10", "$11",
177 "$12", "$13", "$14", "$15",
178 "$16", "$17", "$18", "$19",
179 "$20", "$21", "$22", "$23",
180 "$24", "c1_fccr", "c1_fexr", "$27",
181 "c1_fenr", "$29", "$30", "c1_fcsr"
184 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
186 { 16, 1, "c0_config1" },
187 { 16, 2, "c0_config2" },
188 { 16, 3, "c0_config3" },
189 { 18, 1, "c0_watchlo,1" },
190 { 18, 2, "c0_watchlo,2" },
191 { 18, 3, "c0_watchlo,3" },
192 { 18, 4, "c0_watchlo,4" },
193 { 18, 5, "c0_watchlo,5" },
194 { 18, 6, "c0_watchlo,6" },
195 { 18, 7, "c0_watchlo,7" },
196 { 19, 1, "c0_watchhi,1" },
197 { 19, 2, "c0_watchhi,2" },
198 { 19, 3, "c0_watchhi,3" },
199 { 19, 4, "c0_watchhi,4" },
200 { 19, 5, "c0_watchhi,5" },
201 { 19, 6, "c0_watchhi,6" },
202 { 19, 7, "c0_watchhi,7" },
203 { 25, 1, "c0_perfcnt,1" },
204 { 25, 2, "c0_perfcnt,2" },
205 { 25, 3, "c0_perfcnt,3" },
206 { 25, 4, "c0_perfcnt,4" },
207 { 25, 5, "c0_perfcnt,5" },
208 { 25, 6, "c0_perfcnt,6" },
209 { 25, 7, "c0_perfcnt,7" },
210 { 27, 1, "c0_cacheerr,1" },
211 { 27, 2, "c0_cacheerr,2" },
212 { 27, 3, "c0_cacheerr,3" },
213 { 28, 1, "c0_datalo" },
214 { 29, 1, "c0_datahi" }
217 static const char * const mips_cp0_names_mips3264r2[32] =
219 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
220 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
221 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
222 "c0_status", "c0_cause", "c0_epc", "c0_prid",
223 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
224 "c0_xcontext", "$21", "$22", "c0_debug",
225 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
226 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
229 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
231 { 4, 1, "c0_contextconfig" },
232 { 0, 1, "c0_mvpcontrol" },
233 { 0, 2, "c0_mvpconf0" },
234 { 0, 3, "c0_mvpconf1" },
235 { 1, 1, "c0_vpecontrol" },
236 { 1, 2, "c0_vpeconf0" },
237 { 1, 3, "c0_vpeconf1" },
238 { 1, 4, "c0_yqmask" },
239 { 1, 5, "c0_vpeschedule" },
240 { 1, 6, "c0_vpeschefback" },
241 { 2, 1, "c0_tcstatus" },
242 { 2, 2, "c0_tcbind" },
243 { 2, 3, "c0_tcrestart" },
244 { 2, 4, "c0_tchalt" },
245 { 2, 5, "c0_tccontext" },
246 { 2, 6, "c0_tcschedule" },
247 { 2, 7, "c0_tcschefback" },
248 { 5, 1, "c0_pagegrain" },
249 { 6, 1, "c0_srsconf0" },
250 { 6, 2, "c0_srsconf1" },
251 { 6, 3, "c0_srsconf2" },
252 { 6, 4, "c0_srsconf3" },
253 { 6, 5, "c0_srsconf4" },
254 { 12, 1, "c0_intctl" },
255 { 12, 2, "c0_srsctl" },
256 { 12, 3, "c0_srsmap" },
257 { 15, 1, "c0_ebase" },
258 { 16, 1, "c0_config1" },
259 { 16, 2, "c0_config2" },
260 { 16, 3, "c0_config3" },
261 { 18, 1, "c0_watchlo,1" },
262 { 18, 2, "c0_watchlo,2" },
263 { 18, 3, "c0_watchlo,3" },
264 { 18, 4, "c0_watchlo,4" },
265 { 18, 5, "c0_watchlo,5" },
266 { 18, 6, "c0_watchlo,6" },
267 { 18, 7, "c0_watchlo,7" },
268 { 19, 1, "c0_watchhi,1" },
269 { 19, 2, "c0_watchhi,2" },
270 { 19, 3, "c0_watchhi,3" },
271 { 19, 4, "c0_watchhi,4" },
272 { 19, 5, "c0_watchhi,5" },
273 { 19, 6, "c0_watchhi,6" },
274 { 19, 7, "c0_watchhi,7" },
275 { 23, 1, "c0_tracecontrol" },
276 { 23, 2, "c0_tracecontrol2" },
277 { 23, 3, "c0_usertracedata" },
278 { 23, 4, "c0_tracebpc" },
279 { 25, 1, "c0_perfcnt,1" },
280 { 25, 2, "c0_perfcnt,2" },
281 { 25, 3, "c0_perfcnt,3" },
282 { 25, 4, "c0_perfcnt,4" },
283 { 25, 5, "c0_perfcnt,5" },
284 { 25, 6, "c0_perfcnt,6" },
285 { 25, 7, "c0_perfcnt,7" },
286 { 27, 1, "c0_cacheerr,1" },
287 { 27, 2, "c0_cacheerr,2" },
288 { 27, 3, "c0_cacheerr,3" },
289 { 28, 1, "c0_datalo" },
290 { 28, 2, "c0_taglo1" },
291 { 28, 3, "c0_datalo1" },
292 { 28, 4, "c0_taglo2" },
293 { 28, 5, "c0_datalo2" },
294 { 28, 6, "c0_taglo3" },
295 { 28, 7, "c0_datalo3" },
296 { 29, 1, "c0_datahi" },
297 { 29, 2, "c0_taghi1" },
298 { 29, 3, "c0_datahi1" },
299 { 29, 4, "c0_taghi2" },
300 { 29, 5, "c0_datahi2" },
301 { 29, 6, "c0_taghi3" },
302 { 29, 7, "c0_datahi3" },
305 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
306 static const char * const mips_cp0_names_sb1[32] =
308 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
309 "c0_context", "c0_pagemask", "c0_wired", "$7",
310 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
311 "c0_status", "c0_cause", "c0_epc", "c0_prid",
312 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
313 "c0_xcontext", "$21", "$22", "c0_debug",
314 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
315 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
318 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
320 { 16, 1, "c0_config1" },
321 { 18, 1, "c0_watchlo,1" },
322 { 19, 1, "c0_watchhi,1" },
323 { 22, 0, "c0_perftrace" },
324 { 23, 3, "c0_edebug" },
325 { 25, 1, "c0_perfcnt,1" },
326 { 25, 2, "c0_perfcnt,2" },
327 { 25, 3, "c0_perfcnt,3" },
328 { 25, 4, "c0_perfcnt,4" },
329 { 25, 5, "c0_perfcnt,5" },
330 { 25, 6, "c0_perfcnt,6" },
331 { 25, 7, "c0_perfcnt,7" },
332 { 26, 1, "c0_buserr_pa" },
333 { 27, 1, "c0_cacheerr_d" },
334 { 27, 3, "c0_cacheerr_d_pa" },
335 { 28, 1, "c0_datalo_i" },
336 { 28, 2, "c0_taglo_d" },
337 { 28, 3, "c0_datalo_d" },
338 { 29, 1, "c0_datahi_i" },
339 { 29, 2, "c0_taghi_d" },
340 { 29, 3, "c0_datahi_d" },
343 /* Xlr cop0 register names. */
344 static const char * const mips_cp0_names_xlr[32] = {
345 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
346 "c0_context", "c0_pagemask", "c0_wired", "$7",
347 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
348 "c0_status", "c0_cause", "c0_epc", "c0_prid",
349 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
350 "c0_xcontext", "$21", "$22", "c0_debug",
351 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
352 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
355 /* XLR's CP0 Select Registers. */
357 static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
358 { 9, 6, "c0_extintreq" },
359 { 9, 7, "c0_extintmask" },
360 { 15, 1, "c0_ebase" },
361 { 16, 1, "c0_config1" },
362 { 16, 2, "c0_config2" },
363 { 16, 3, "c0_config3" },
364 { 16, 7, "c0_procid2" },
365 { 18, 1, "c0_watchlo,1" },
366 { 18, 2, "c0_watchlo,2" },
367 { 18, 3, "c0_watchlo,3" },
368 { 18, 4, "c0_watchlo,4" },
369 { 18, 5, "c0_watchlo,5" },
370 { 18, 6, "c0_watchlo,6" },
371 { 18, 7, "c0_watchlo,7" },
372 { 19, 1, "c0_watchhi,1" },
373 { 19, 2, "c0_watchhi,2" },
374 { 19, 3, "c0_watchhi,3" },
375 { 19, 4, "c0_watchhi,4" },
376 { 19, 5, "c0_watchhi,5" },
377 { 19, 6, "c0_watchhi,6" },
378 { 19, 7, "c0_watchhi,7" },
379 { 25, 1, "c0_perfcnt,1" },
380 { 25, 2, "c0_perfcnt,2" },
381 { 25, 3, "c0_perfcnt,3" },
382 { 25, 4, "c0_perfcnt,4" },
383 { 25, 5, "c0_perfcnt,5" },
384 { 25, 6, "c0_perfcnt,6" },
385 { 25, 7, "c0_perfcnt,7" },
386 { 27, 1, "c0_cacheerr,1" },
387 { 27, 2, "c0_cacheerr,2" },
388 { 27, 3, "c0_cacheerr,3" },
389 { 28, 1, "c0_datalo" },
390 { 29, 1, "c0_datahi" }
393 static const char * const mips_hwr_names_numeric[32] =
395 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
396 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
397 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
398 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
401 static const char * const mips_hwr_names_mips3264r2[32] =
403 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
404 "$4", "$5", "$6", "$7",
405 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
406 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
407 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
410 static const char * const msa_control_names[32] =
412 "msa_ir", "msa_csr", "msa_access", "msa_save",
413 "msa_modify", "msa_request", "msa_map", "msa_unmap",
414 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
415 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
416 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
419 struct mips_abi_choice
422 const char * const *gpr_names;
423 const char * const *fpr_names;
426 struct mips_abi_choice mips_abi_choices[] =
428 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
429 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
430 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
431 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
434 struct mips_arch_choice
438 unsigned long bfd_mach;
442 const char * const *cp0_names;
443 const struct mips_cp0sel_name *cp0sel_names;
444 unsigned int cp0sel_names_len;
445 const char * const *cp1_names;
446 const char * const *hwr_names;
449 const struct mips_arch_choice mips_arch_choices[] =
451 { "numeric", 0, 0, 0, 0, 0,
452 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
453 mips_hwr_names_numeric },
455 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
456 mips_cp0_names_r3000, NULL, 0, mips_cp1_names_numeric,
457 mips_hwr_names_numeric },
458 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
459 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
460 mips_hwr_names_numeric },
461 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
462 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
463 mips_hwr_names_numeric },
464 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
465 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
466 mips_hwr_names_numeric },
467 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
468 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
469 mips_hwr_names_numeric },
470 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
471 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
472 mips_hwr_names_numeric },
473 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
474 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
475 mips_hwr_names_numeric },
476 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
477 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
478 mips_hwr_names_numeric },
479 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
480 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
481 mips_hwr_names_numeric },
482 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
483 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
484 mips_hwr_names_numeric },
485 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
486 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
487 mips_hwr_names_numeric },
488 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
489 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
490 mips_hwr_names_numeric },
491 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
492 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
493 mips_hwr_names_numeric },
494 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
495 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
496 mips_hwr_names_numeric },
497 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
498 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_numeric,
499 mips_hwr_names_numeric },
500 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
501 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
502 mips_hwr_names_numeric },
503 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
504 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
505 mips_hwr_names_numeric },
506 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
507 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
508 mips_hwr_names_numeric },
509 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
510 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
511 mips_hwr_names_numeric },
512 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
513 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
514 mips_hwr_names_numeric },
515 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
516 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
517 mips_hwr_names_numeric },
518 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
519 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
520 mips_hwr_names_numeric },
521 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
522 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
523 mips_hwr_names_numeric },
524 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
525 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
526 mips_hwr_names_numeric },
528 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
529 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
530 _MIPS32 Architecture For Programmers Volume I: Introduction to the
531 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
533 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
534 ISA_MIPS32, ASE_SMARTMIPS,
535 mips_cp0_names_mips3264,
536 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
537 mips_cp1_names_mips3264, mips_hwr_names_numeric },
539 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
541 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
542 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
543 mips_cp0_names_mips3264r2,
544 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
545 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
547 { "mips32r3", 1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
549 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
550 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
551 mips_cp0_names_mips3264r2,
552 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
553 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
555 { "mips32r5", 1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
557 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
558 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
559 mips_cp0_names_mips3264r2,
560 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
561 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
563 { "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
565 (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
566 | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC | ASE_GINV),
567 mips_cp0_names_mips3264r2,
568 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
569 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
571 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
572 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
573 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
574 mips_cp0_names_mips3264,
575 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
576 mips_cp1_names_mips3264, mips_hwr_names_numeric },
578 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
580 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
581 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
582 mips_cp0_names_mips3264r2,
583 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
584 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
586 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
588 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
589 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
590 mips_cp0_names_mips3264r2,
591 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
592 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
594 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
596 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
597 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
598 mips_cp0_names_mips3264r2,
599 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
600 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
602 { "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
604 (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
605 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC
606 | ASE_CRC64 | ASE_GINV),
607 mips_cp0_names_mips3264r2,
608 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
609 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
611 { "interaptiv-mr2", 1, bfd_mach_mips_interaptiv_mr2, CPU_INTERAPTIV_MR2,
613 ASE_MT | ASE_EVA | ASE_DSP | ASE_DSPR2 | ASE_MIPS16E2 | ASE_MIPS16E2_MT,
614 mips_cp0_names_mips3264r2,
615 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
616 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
618 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
619 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
621 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
622 mips_cp1_names_mips3264, mips_hwr_names_numeric },
624 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
625 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
626 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
628 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
629 ISA_MIPS3 | INSN_LOONGSON_2F, ASE_LOONGSON_MMI, mips_cp0_names_numeric,
630 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
632 /* The loongson3a is an alias of gs464 for compatibility */
633 { "loongson3a", 1, bfd_mach_mips_gs464, CPU_GS464,
634 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
635 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
636 mips_hwr_names_numeric },
638 { "g464", 1, bfd_mach_mips_gs464, CPU_GS464,
639 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
640 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
641 mips_hwr_names_numeric },
643 { "g464e", 1, bfd_mach_mips_gs464e, CPU_GS464E,
644 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
645 | ASE_LOONGSON_EXT2, mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
646 mips_hwr_names_numeric },
648 { "g264e", 1, bfd_mach_mips_gs464e, CPU_GS264E,
649 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
650 | ASE_LOONGSON_EXT2 | ASE_MSA | ASE_MSA64, mips_cp0_names_numeric, NULL,
651 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
653 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
654 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
655 mips_cp1_names_mips3264, mips_hwr_names_numeric },
657 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
658 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
659 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
661 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
662 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
663 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
665 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
666 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
667 mips_cp0_names_numeric,
668 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
670 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
671 ISA_MIPS64 | INSN_XLR, 0,
673 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
674 mips_cp1_names_mips3264, mips_hwr_names_numeric },
676 /* XLP is mostly like XLR, with the prominent exception it is being
678 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
679 ISA_MIPS64R2 | INSN_XLR, 0,
681 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
682 mips_cp1_names_mips3264, mips_hwr_names_numeric },
684 /* This entry, mips16, is here only for ISA/processor selection; do
685 not print its name. */
686 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
687 ASE_MIPS16E2 | ASE_MIPS16E2_MT,
688 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
689 mips_hwr_names_numeric },
692 /* ISA and processor type to disassemble for, and register names to use.
693 set_default_mips_dis_options and parse_mips_dis_options fill in these
695 static int mips_processor;
698 static int micromips_ase;
699 static const char * const *mips_gpr_names;
700 static const char * const *mips_fpr_names;
701 static const char * const *mips_cp0_names;
702 static const struct mips_cp0sel_name *mips_cp0sel_names;
703 static int mips_cp0sel_names_len;
704 static const char * const *mips_cp1_names;
705 static const char * const *mips_hwr_names;
708 static int no_aliases; /* If set disassemble as most general inst. */
710 static const struct mips_abi_choice *
711 choose_abi_by_name (const char *name, unsigned int namelen)
713 const struct mips_abi_choice *c;
716 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
717 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
718 && strlen (mips_abi_choices[i].name) == namelen)
719 c = &mips_abi_choices[i];
724 static const struct mips_arch_choice *
725 choose_arch_by_name (const char *name, unsigned int namelen)
727 const struct mips_arch_choice *c = NULL;
730 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
731 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
732 && strlen (mips_arch_choices[i].name) == namelen)
733 c = &mips_arch_choices[i];
738 static const struct mips_arch_choice *
739 choose_arch_by_number (unsigned long mach)
741 static unsigned long hint_bfd_mach;
742 static const struct mips_arch_choice *hint_arch_choice;
743 const struct mips_arch_choice *c;
746 /* We optimize this because even if the user specifies no
747 flags, this will be done for every instruction! */
748 if (hint_bfd_mach == mach
749 && hint_arch_choice != NULL
750 && hint_arch_choice->bfd_mach == hint_bfd_mach)
751 return hint_arch_choice;
753 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
755 if (mips_arch_choices[i].bfd_mach_valid
756 && mips_arch_choices[i].bfd_mach == mach)
758 c = &mips_arch_choices[i];
759 hint_bfd_mach = mach;
760 hint_arch_choice = c;
766 /* Check if the object uses NewABI conventions. */
769 is_newabi (Elf_Internal_Ehdr *header)
771 /* There are no old-style ABIs which use 64-bit ELF. */
772 if (header->e_ident[EI_CLASS] == ELFCLASS64)
775 /* If a 32-bit ELF file, n32 is a new-style ABI. */
776 if ((header->e_flags & EF_MIPS_ABI2) != 0)
782 /* Check if the object has microMIPS ASE code. */
785 is_micromips (Elf_Internal_Ehdr *header)
787 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
793 /* Convert ASE flags from .MIPS.abiflags to internal values. */
796 mips_convert_abiflags_ases (unsigned long afl_ases)
798 unsigned long opcode_ases = 0;
800 if (afl_ases & AFL_ASE_DSP)
801 opcode_ases |= ASE_DSP;
802 if (afl_ases & AFL_ASE_DSPR2)
803 opcode_ases |= ASE_DSPR2;
804 if (afl_ases & AFL_ASE_EVA)
805 opcode_ases |= ASE_EVA;
806 if (afl_ases & AFL_ASE_MCU)
807 opcode_ases |= ASE_MCU;
808 if (afl_ases & AFL_ASE_MDMX)
809 opcode_ases |= ASE_MDMX;
810 if (afl_ases & AFL_ASE_MIPS3D)
811 opcode_ases |= ASE_MIPS3D;
812 if (afl_ases & AFL_ASE_MT)
813 opcode_ases |= ASE_MT;
814 if (afl_ases & AFL_ASE_SMARTMIPS)
815 opcode_ases |= ASE_SMARTMIPS;
816 if (afl_ases & AFL_ASE_VIRT)
817 opcode_ases |= ASE_VIRT;
818 if (afl_ases & AFL_ASE_MSA)
819 opcode_ases |= ASE_MSA;
820 if (afl_ases & AFL_ASE_XPA)
821 opcode_ases |= ASE_XPA;
822 if (afl_ases & AFL_ASE_DSPR3)
823 opcode_ases |= ASE_DSPR3;
824 if (afl_ases & AFL_ASE_MIPS16E2)
825 opcode_ases |= ASE_MIPS16E2;
829 /* Calculate combination ASE flags from regular ASE flags. */
832 mips_calculate_combination_ases (unsigned long opcode_ases)
834 unsigned long combination_ases = 0;
836 if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
837 combination_ases |= ASE_XPA_VIRT;
838 if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
839 combination_ases |= ASE_MIPS16E2_MT;
840 return combination_ases;
844 set_default_mips_dis_options (struct disassemble_info *info)
846 const struct mips_arch_choice *chosen_arch;
848 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
849 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
850 CP0 register, and HWR names. */
851 mips_isa = ISA_MIPS3;
852 mips_processor = CPU_R3000;
855 mips_gpr_names = mips_gpr_names_oldabi;
856 mips_fpr_names = mips_fpr_names_numeric;
857 mips_cp0_names = mips_cp0_names_numeric;
858 mips_cp0sel_names = NULL;
859 mips_cp0sel_names_len = 0;
860 mips_cp1_names = mips_cp1_names_numeric;
861 mips_hwr_names = mips_hwr_names_numeric;
864 /* Set ISA, architecture, and cp0 register names as best we can. */
865 #if ! SYMTAB_AVAILABLE
866 /* This is running out on a target machine, not in a host tool.
867 FIXME: Where does mips_target_info come from? */
868 target_processor = mips_target_info.processor;
869 mips_isa = mips_target_info.isa;
870 mips_ase = mips_target_info.ase;
872 chosen_arch = choose_arch_by_number (info->mach);
873 if (chosen_arch != NULL)
875 mips_processor = chosen_arch->processor;
876 mips_isa = chosen_arch->isa;
877 mips_ase = chosen_arch->ase;
878 mips_cp0_names = chosen_arch->cp0_names;
879 mips_cp0sel_names = chosen_arch->cp0sel_names;
880 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
881 mips_cp1_names = chosen_arch->cp1_names;
882 mips_hwr_names = chosen_arch->hwr_names;
885 /* Update settings according to the ELF file header flags. */
886 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
888 struct bfd *abfd = info->section->owner;
889 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
890 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
892 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
893 because we won't then have a MIPS/ELF BFD, however we need
894 to guard against a link error in a `--enable-targets=...'
895 configuration with a 32-bit host where the MIPS target is
896 a secondary, or with MIPS/ECOFF configurations. */
897 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
898 abiflags = bfd_mips_elf_get_abiflags (abfd);
900 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
901 if (is_newabi (header))
902 mips_gpr_names = mips_gpr_names_newabi;
903 /* If a microMIPS binary, then don't use MIPS16 bindings. */
904 micromips_ase = is_micromips (header);
905 /* OR in any extra ASE flags set in ELF file structures. */
907 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
908 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
909 mips_ase |= ASE_MDMX;
912 mips_ase |= mips_calculate_combination_ases (mips_ase);
915 /* Parse an ASE disassembler option and set the corresponding global
916 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
919 parse_mips_ase_option (const char *option)
921 if (CONST_STRNEQ (option, "msa"))
924 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
925 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
926 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
927 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
928 mips_ase |= ASE_MSA64;
932 if (CONST_STRNEQ (option, "virt"))
934 mips_ase |= ASE_VIRT;
935 if (mips_isa & ISA_MIPS64R2
936 || mips_isa & ISA_MIPS64R3
937 || mips_isa & ISA_MIPS64R5
938 || mips_isa & ISA_MIPS64R6)
939 mips_ase |= ASE_VIRT64;
943 if (CONST_STRNEQ (option, "xpa"))
949 if (CONST_STRNEQ (option, "ginv"))
951 mips_ase |= ASE_GINV;
955 if (CONST_STRNEQ (option, "loongson-mmi"))
957 mips_ase |= ASE_LOONGSON_MMI;
961 if (CONST_STRNEQ (option, "loongson-cam"))
963 mips_ase |= ASE_LOONGSON_CAM;
967 /* Put here for match ext2 frist */
968 if (CONST_STRNEQ (option, "loongson-ext2"))
970 mips_ase |= ASE_LOONGSON_EXT2;
974 if (CONST_STRNEQ (option, "loongson-ext"))
976 mips_ase |= ASE_LOONGSON_EXT;
984 parse_mips_dis_option (const char *option, unsigned int len)
986 unsigned int i, optionlen, vallen;
988 const struct mips_abi_choice *chosen_abi;
989 const struct mips_arch_choice *chosen_arch;
991 /* Try to match options that are simple flags */
992 if (CONST_STRNEQ (option, "no-aliases"))
998 if (parse_mips_ase_option (option))
1000 mips_ase |= mips_calculate_combination_ases (mips_ase);
1004 /* Look for the = that delimits the end of the option name. */
1005 for (i = 0; i < len; i++)
1006 if (option[i] == '=')
1009 if (i == 0) /* Invalid option: no name before '='. */
1011 if (i == len) /* Invalid option: no '='. */
1013 if (i == (len - 1)) /* Invalid option: no value after '='. */
1017 val = option + (optionlen + 1);
1018 vallen = len - (optionlen + 1);
1020 if (strncmp ("gpr-names", option, optionlen) == 0
1021 && strlen ("gpr-names") == optionlen)
1023 chosen_abi = choose_abi_by_name (val, vallen);
1024 if (chosen_abi != NULL)
1025 mips_gpr_names = chosen_abi->gpr_names;
1029 if (strncmp ("fpr-names", option, optionlen) == 0
1030 && strlen ("fpr-names") == optionlen)
1032 chosen_abi = choose_abi_by_name (val, vallen);
1033 if (chosen_abi != NULL)
1034 mips_fpr_names = chosen_abi->fpr_names;
1038 if (strncmp ("cp0-names", option, optionlen) == 0
1039 && strlen ("cp0-names") == optionlen)
1041 chosen_arch = choose_arch_by_name (val, vallen);
1042 if (chosen_arch != NULL)
1044 mips_cp0_names = chosen_arch->cp0_names;
1045 mips_cp0sel_names = chosen_arch->cp0sel_names;
1046 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1051 if (strncmp ("cp1-names", option, optionlen) == 0
1052 && strlen ("cp1-names") == optionlen)
1054 chosen_arch = choose_arch_by_name (val, vallen);
1055 if (chosen_arch != NULL)
1056 mips_cp1_names = chosen_arch->cp1_names;
1060 if (strncmp ("hwr-names", option, optionlen) == 0
1061 && strlen ("hwr-names") == optionlen)
1063 chosen_arch = choose_arch_by_name (val, vallen);
1064 if (chosen_arch != NULL)
1065 mips_hwr_names = chosen_arch->hwr_names;
1069 if (strncmp ("reg-names", option, optionlen) == 0
1070 && strlen ("reg-names") == optionlen)
1072 /* We check both ABI and ARCH here unconditionally, so
1073 that "numeric" will do the desirable thing: select
1074 numeric register names for all registers. Other than
1075 that, a given name probably won't match both. */
1076 chosen_abi = choose_abi_by_name (val, vallen);
1077 if (chosen_abi != NULL)
1079 mips_gpr_names = chosen_abi->gpr_names;
1080 mips_fpr_names = chosen_abi->fpr_names;
1082 chosen_arch = choose_arch_by_name (val, vallen);
1083 if (chosen_arch != NULL)
1085 mips_cp0_names = chosen_arch->cp0_names;
1086 mips_cp0sel_names = chosen_arch->cp0sel_names;
1087 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1088 mips_cp1_names = chosen_arch->cp1_names;
1089 mips_hwr_names = chosen_arch->hwr_names;
1094 /* Invalid option. */
1098 parse_mips_dis_options (const char *options)
1100 const char *option_end;
1102 if (options == NULL)
1105 while (*options != '\0')
1107 /* Skip empty options. */
1108 if (*options == ',')
1114 /* We know that *options is neither NUL or a comma. */
1115 option_end = options + 1;
1116 while (*option_end != ',' && *option_end != '\0')
1119 parse_mips_dis_option (options, option_end - options);
1121 /* Go on to the next one. If option_end points to a comma, it
1122 will be skipped above. */
1123 options = option_end;
1127 static const struct mips_cp0sel_name *
1128 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1130 unsigned int cp0reg,
1135 for (i = 0; i < len; i++)
1136 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1141 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1144 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1145 enum mips_reg_operand_type type, int regno)
1150 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1154 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1158 if (opcode->pinfo & (FP_D | FP_S))
1159 info->fprintf_func (info->stream, "$fcc%d", regno);
1161 info->fprintf_func (info->stream, "$cc%d", regno);
1165 if (opcode->membership & INSN_5400)
1166 info->fprintf_func (info->stream, "$f%d", regno);
1168 info->fprintf_func (info->stream, "$v%d", regno);
1172 info->fprintf_func (info->stream, "$ac%d", regno);
1176 if (opcode->name[strlen (opcode->name) - 1] == '0')
1177 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
1178 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1179 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
1181 info->fprintf_func (info->stream, "$%d", regno);
1185 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1189 info->fprintf_func (info->stream, "$vf%d", regno);
1193 info->fprintf_func (info->stream, "$vi%d", regno);
1196 case OP_REG_R5900_I:
1197 info->fprintf_func (info->stream, "$I");
1200 case OP_REG_R5900_Q:
1201 info->fprintf_func (info->stream, "$Q");
1204 case OP_REG_R5900_R:
1205 info->fprintf_func (info->stream, "$R");
1208 case OP_REG_R5900_ACC:
1209 info->fprintf_func (info->stream, "$ACC");
1213 info->fprintf_func (info->stream, "$w%d", regno);
1216 case OP_REG_MSA_CTRL:
1217 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1223 /* Used to track the state carried over from previous operands in
1225 struct mips_print_arg_state {
1226 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1227 where the value is known to be unsigned and small. */
1228 unsigned int last_int;
1230 /* The type and number of the last OP_REG seen. We only use this for
1231 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1232 enum mips_reg_operand_type last_reg_type;
1233 unsigned int last_regno;
1234 unsigned int dest_regno;
1235 unsigned int seen_dest;
1238 /* Initialize STATE for the start of an instruction. */
1241 init_print_arg_state (struct mips_print_arg_state *state)
1243 memset (state, 0, sizeof (*state));
1246 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1247 whose value is given by UVAL. */
1250 print_vu0_channel (struct disassemble_info *info,
1251 const struct mips_operand *operand, unsigned int uval)
1253 if (operand->size == 4)
1254 info->fprintf_func (info->stream, "%s%s%s%s",
1255 uval & 8 ? "x" : "",
1256 uval & 4 ? "y" : "",
1257 uval & 2 ? "z" : "",
1258 uval & 1 ? "w" : "");
1259 else if (operand->size == 2)
1260 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1265 /* Record information about a register operand. */
1268 mips_seen_register (struct mips_print_arg_state *state,
1270 enum mips_reg_operand_type reg_type)
1272 state->last_reg_type = reg_type;
1273 state->last_regno = regno;
1275 if (!state->seen_dest)
1277 state->seen_dest = 1;
1278 state->dest_regno = regno;
1282 /* Print SAVE/RESTORE instruction operands according to the argument
1283 register mask AMASK, the number of static registers saved NSREG,
1284 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1285 and the frame size FRAME_SIZE. */
1288 mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
1289 unsigned int nsreg, unsigned int ra,
1290 unsigned int s0, unsigned int s1,
1291 unsigned int frame_size)
1293 const fprintf_ftype infprintf = info->fprintf_func;
1294 unsigned int nargs, nstatics, smask, i, j;
1295 void *is = info->stream;
1298 if (amask == MIPS_SVRS_ALL_ARGS)
1303 else if (amask == MIPS_SVRS_ALL_STATICS)
1311 nstatics = amask & 3;
1317 infprintf (is, "%s", mips_gpr_names[4]);
1319 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1323 infprintf (is, "%s%d", sep, frame_size);
1326 infprintf (is, ",%s", mips_gpr_names[31]);
1333 if (nsreg > 0) /* $s2-$s8 */
1334 smask |= ((1 << nsreg) - 1) << 2;
1336 for (i = 0; i < 9; i++)
1337 if (smask & (1 << i))
1339 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1340 /* Skip over string of set bits. */
1341 for (j = i; smask & (2 << j); j++)
1344 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1347 /* Statics $ax - $a3. */
1349 infprintf (is, ",%s", mips_gpr_names[7]);
1350 else if (nstatics > 0)
1351 infprintf (is, ",%s-%s",
1352 mips_gpr_names[7 - nstatics + 1],
1357 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1358 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1359 the base address for OP_PCREL operands. */
1362 print_insn_arg (struct disassemble_info *info,
1363 struct mips_print_arg_state *state,
1364 const struct mips_opcode *opcode,
1365 const struct mips_operand *operand,
1369 const fprintf_ftype infprintf = info->fprintf_func;
1370 void *is = info->stream;
1372 switch (operand->type)
1376 const struct mips_int_operand *int_op;
1378 int_op = (const struct mips_int_operand *) operand;
1379 uval = mips_decode_int_operand (int_op, uval);
1380 state->last_int = uval;
1381 if (int_op->print_hex)
1382 infprintf (is, "0x%x", uval);
1384 infprintf (is, "%d", uval);
1390 const struct mips_mapped_int_operand *mint_op;
1392 mint_op = (const struct mips_mapped_int_operand *) operand;
1393 uval = mint_op->int_map[uval];
1394 state->last_int = uval;
1395 if (mint_op->print_hex)
1396 infprintf (is, "0x%x", uval);
1398 infprintf (is, "%d", uval);
1404 const struct mips_msb_operand *msb_op;
1406 msb_op = (const struct mips_msb_operand *) operand;
1407 uval += msb_op->bias;
1408 if (msb_op->add_lsb)
1409 uval -= state->last_int;
1410 infprintf (is, "0x%x", uval);
1415 case OP_OPTIONAL_REG:
1417 const struct mips_reg_operand *reg_op;
1419 reg_op = (const struct mips_reg_operand *) operand;
1420 uval = mips_decode_reg_operand (reg_op, uval);
1421 print_reg (info, opcode, reg_op->reg_type, uval);
1423 mips_seen_register (state, uval, reg_op->reg_type);
1429 const struct mips_reg_pair_operand *pair_op;
1431 pair_op = (const struct mips_reg_pair_operand *) operand;
1432 print_reg (info, opcode, pair_op->reg_type,
1433 pair_op->reg1_map[uval]);
1434 infprintf (is, ",");
1435 print_reg (info, opcode, pair_op->reg_type,
1436 pair_op->reg2_map[uval]);
1442 const struct mips_pcrel_operand *pcrel_op;
1444 pcrel_op = (const struct mips_pcrel_operand *) operand;
1445 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1447 /* For jumps and branches clear the ISA bit except for
1448 the GDB disassembler. */
1449 if (pcrel_op->include_isa_bit
1450 && info->flavour != bfd_target_unknown_flavour)
1453 (*info->print_address_func) (info->target, info);
1458 infprintf (is, "%d", uval);
1461 case OP_ADDIUSP_INT:
1465 sval = mips_signed_operand (operand, uval) * 4;
1466 if (sval >= -8 && sval < 8)
1468 infprintf (is, "%d", sval);
1472 case OP_CLO_CLZ_DEST:
1474 unsigned int reg1, reg2;
1478 /* If one is zero use the other. */
1479 if (reg1 == reg2 || reg2 == 0)
1480 infprintf (is, "%s", mips_gpr_names[reg1]);
1482 infprintf (is, "%s", mips_gpr_names[reg2]);
1484 /* Bogus, result depends on processor. */
1485 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1486 mips_gpr_names[reg2]);
1492 case OP_NON_ZERO_REG:
1494 print_reg (info, opcode, OP_REG_GP, uval & 31);
1495 mips_seen_register (state, uval, OP_REG_GP);
1499 case OP_LWM_SWM_LIST:
1500 if (operand->size == 2)
1503 infprintf (is, "%s,%s",
1505 mips_gpr_names[31]);
1507 infprintf (is, "%s-%s,%s",
1509 mips_gpr_names[16 + uval],
1510 mips_gpr_names[31]);
1516 s_reg_encode = uval & 0xf;
1517 if (s_reg_encode != 0)
1519 if (s_reg_encode == 1)
1520 infprintf (is, "%s", mips_gpr_names[16]);
1521 else if (s_reg_encode < 9)
1522 infprintf (is, "%s-%s",
1524 mips_gpr_names[15 + s_reg_encode]);
1525 else if (s_reg_encode == 9)
1526 infprintf (is, "%s-%s,%s",
1529 mips_gpr_names[30]);
1531 infprintf (is, "UNKNOWN");
1534 if (uval & 0x10) /* For ra. */
1536 if (s_reg_encode == 0)
1537 infprintf (is, "%s", mips_gpr_names[31]);
1539 infprintf (is, ",%s", mips_gpr_names[31]);
1544 case OP_ENTRY_EXIT_LIST:
1547 unsigned int amask, smask;
1550 amask = (uval >> 3) & 7;
1551 if (amask > 0 && amask < 5)
1553 infprintf (is, "%s", mips_gpr_names[4]);
1555 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1559 smask = (uval >> 1) & 3;
1562 infprintf (is, "%s??", sep);
1567 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1569 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1575 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1579 if (amask == 5 || amask == 6)
1581 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1583 infprintf (is, "-%s", mips_fpr_names[1]);
1588 case OP_SAVE_RESTORE_LIST:
1589 /* Should be handled by the caller due to complex behavior. */
1592 case OP_MDMX_IMM_REG:
1598 if ((vsel & 0x10) == 0)
1603 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1604 if ((vsel & 1) == 0)
1606 print_reg (info, opcode, OP_REG_VEC, uval);
1607 infprintf (is, "[%d]", vsel >> 1);
1609 else if ((vsel & 0x08) == 0)
1610 print_reg (info, opcode, OP_REG_VEC, uval);
1612 infprintf (is, "0x%x", uval);
1616 case OP_REPEAT_PREV_REG:
1617 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1620 case OP_REPEAT_DEST_REG:
1621 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1625 infprintf (is, "$pc");
1629 print_reg (info, opcode, OP_REG_GP, 28);
1633 case OP_VU0_MATCH_SUFFIX:
1634 print_vu0_channel (info, operand, uval);
1638 infprintf (is, "[%d]", uval);
1642 infprintf (is, "[");
1643 print_reg (info, opcode, OP_REG_GP, uval);
1644 infprintf (is, "]");
1649 /* Validate the arguments for INSN, which is described by OPCODE.
1650 Use DECODE_OPERAND to get the encoding of each operand. */
1653 validate_insn_args (const struct mips_opcode *opcode,
1654 const struct mips_operand *(*decode_operand) (const char *),
1657 struct mips_print_arg_state state;
1658 const struct mips_operand *operand;
1662 init_print_arg_state (&state);
1663 for (s = opcode->args; *s; ++s)
1677 operand = decode_operand (s);
1681 uval = mips_extract_operand (operand, insn);
1682 switch (operand->type)
1685 case OP_OPTIONAL_REG:
1687 const struct mips_reg_operand *reg_op;
1689 reg_op = (const struct mips_reg_operand *) operand;
1690 uval = mips_decode_reg_operand (reg_op, uval);
1691 mips_seen_register (&state, uval, reg_op->reg_type);
1697 unsigned int reg1, reg2;
1702 if (reg1 != reg2 || reg1 == 0)
1709 const struct mips_check_prev_operand *prev_op;
1711 prev_op = (const struct mips_check_prev_operand *) operand;
1713 if (!prev_op->zero_ok && uval == 0)
1716 if (((prev_op->less_than_ok && uval < state.last_regno)
1717 || (prev_op->greater_than_ok && uval > state.last_regno)
1718 || (prev_op->equal_ok && uval == state.last_regno)))
1724 case OP_NON_ZERO_REG:
1737 case OP_ADDIUSP_INT:
1738 case OP_CLO_CLZ_DEST:
1739 case OP_LWM_SWM_LIST:
1740 case OP_ENTRY_EXIT_LIST:
1741 case OP_MDMX_IMM_REG:
1742 case OP_REPEAT_PREV_REG:
1743 case OP_REPEAT_DEST_REG:
1747 case OP_VU0_MATCH_SUFFIX:
1750 case OP_SAVE_RESTORE_LIST:
1754 if (*s == 'm' || *s == '+' || *s == '-')
1761 /* Print the arguments for INSN, which is described by OPCODE.
1762 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1763 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1764 operand is for a branch or jump. */
1767 print_insn_args (struct disassemble_info *info,
1768 const struct mips_opcode *opcode,
1769 const struct mips_operand *(*decode_operand) (const char *),
1770 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1772 const fprintf_ftype infprintf = info->fprintf_func;
1773 void *is = info->stream;
1774 struct mips_print_arg_state state;
1775 const struct mips_operand *operand;
1778 init_print_arg_state (&state);
1779 for (s = opcode->args; *s; ++s)
1786 infprintf (is, "%c", *s);
1791 infprintf (is, "%c%c", *s, *s);
1795 operand = decode_operand (s);
1798 /* xgettext:c-format */
1800 _("# internal error, undefined operand in `%s %s'"),
1801 opcode->name, opcode->args);
1805 if (operand->type == OP_SAVE_RESTORE_LIST)
1807 /* Handle this case here because of the complex behavior. */
1808 unsigned int amask = (insn >> 15) & 0xf;
1809 unsigned int nsreg = (insn >> 23) & 0x7;
1810 unsigned int ra = insn & 0x1000; /* $ra */
1811 unsigned int s0 = insn & 0x800; /* $s0 */
1812 unsigned int s1 = insn & 0x400; /* $s1 */
1813 unsigned int frame_size = (((insn >> 15) & 0xf0)
1814 | ((insn >> 6) & 0x0f)) * 8;
1815 mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1818 else if (operand->type == OP_REG
1821 && opcode->name[strlen (opcode->name) - 1] == '0')
1823 /* Coprocessor register 0 with sel field. */
1824 const struct mips_cp0sel_name *n;
1825 unsigned int reg, sel;
1827 reg = mips_extract_operand (operand, insn);
1829 operand = decode_operand (s);
1830 sel = mips_extract_operand (operand, insn);
1832 /* CP0 register including 'sel' code for mftc0, to be
1833 printed textually if known. If not known, print both
1834 CP0 register name and sel numerically since CP0 register
1835 with sel 0 may have a name unrelated to register being
1837 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1838 mips_cp0sel_names_len,
1841 infprintf (is, "%s", n->name);
1843 infprintf (is, "$%d,%d", reg, sel);
1847 bfd_vma base_pc = insn_pc;
1849 /* Adjust the PC relative base so that branch/jump insns use
1850 the following PC as the base but genuinely PC relative
1851 operands use the current PC. */
1852 if (operand->type == OP_PCREL)
1854 const struct mips_pcrel_operand *pcrel_op;
1856 pcrel_op = (const struct mips_pcrel_operand *) operand;
1857 /* The include_isa_bit flag is sufficient to distinguish
1858 branch/jump from other PC relative operands. */
1859 if (pcrel_op->include_isa_bit)
1863 print_insn_arg (info, &state, opcode, operand, base_pc,
1864 mips_extract_operand (operand, insn));
1866 if (*s == 'm' || *s == '+' || *s == '-')
1873 /* Print the mips instruction at address MEMADDR in debugged memory,
1874 on using INFO. Returns length of the instruction, in bytes, which is
1875 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1876 this is little-endian code. */
1879 print_insn_mips (bfd_vma memaddr,
1881 struct disassemble_info *info)
1883 #define GET_OP(insn, field) \
1884 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1885 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1886 const fprintf_ftype infprintf = info->fprintf_func;
1887 const struct mips_opcode *op;
1888 static bfd_boolean init = 0;
1889 void *is = info->stream;
1891 /* Build a hash table to shorten the search time. */
1896 for (i = 0; i <= OP_MASK_OP; i++)
1898 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1900 if (op->pinfo == INSN_MACRO
1901 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1903 if (i == GET_OP (op->match, OP))
1914 info->bytes_per_chunk = INSNLEN;
1915 info->display_endian = info->endian;
1916 info->insn_info_valid = 1;
1917 info->branch_delay_insns = 0;
1918 info->data_size = 0;
1919 info->insn_type = dis_nonbranch;
1923 op = mips_hash[GET_OP (word, OP)];
1926 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1928 if (op->pinfo != INSN_MACRO
1929 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1930 && (word & op->mask) == op->match)
1932 /* We always disassemble the jalx instruction, except for MIPS r6. */
1933 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1934 && (strcmp (op->name, "jalx")
1935 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1936 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
1939 /* Figure out instruction type and branch delay information. */
1940 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1942 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
1943 info->insn_type = dis_jsr;
1945 info->insn_type = dis_branch;
1946 info->branch_delay_insns = 1;
1948 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1949 | INSN_COND_BRANCH_LIKELY)) != 0)
1951 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1952 info->insn_type = dis_condjsr;
1954 info->insn_type = dis_condbranch;
1955 info->branch_delay_insns = 1;
1957 else if ((op->pinfo & (INSN_STORE_MEMORY
1958 | INSN_LOAD_MEMORY)) != 0)
1959 info->insn_type = dis_dref;
1961 if (!validate_insn_args (op, decode_mips_operand, word))
1964 infprintf (is, "%s", op->name);
1965 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1969 infprintf (is, ".");
1970 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1971 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1976 infprintf (is, "\t");
1977 print_insn_args (info, op, decode_mips_operand, word,
1987 /* Handle undefined instructions. */
1988 info->insn_type = dis_noninsn;
1989 infprintf (is, "0x%x", word);
1993 /* Disassemble an operand for a mips16 instruction. */
1996 print_mips16_insn_arg (struct disassemble_info *info,
1997 struct mips_print_arg_state *state,
1998 const struct mips_opcode *opcode,
1999 char type, bfd_vma memaddr,
2000 unsigned insn, bfd_boolean use_extend,
2001 unsigned extend, bfd_boolean is_offset)
2003 const fprintf_ftype infprintf = info->fprintf_func;
2004 void *is = info->stream;
2005 const struct mips_operand *operand, *ext_operand;
2006 unsigned short ext_size;
2018 infprintf (is, "%c", type);
2022 operand = decode_mips16_operand (type, FALSE);
2025 /* xgettext:c-format */
2026 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
2027 opcode->name, opcode->args);
2031 if (operand->type == OP_SAVE_RESTORE_LIST)
2033 /* Handle this case here because of the complex interaction
2034 with the EXTEND opcode. */
2035 unsigned int amask = extend & 0xf;
2036 unsigned int nsreg = (extend >> 8) & 0x7;
2037 unsigned int ra = insn & 0x40; /* $ra */
2038 unsigned int s0 = insn & 0x20; /* $s0 */
2039 unsigned int s1 = insn & 0x10; /* $s1 */
2040 unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
2041 if (frame_size == 0 && !use_extend)
2043 mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
2047 if (is_offset && operand->type == OP_INT)
2049 const struct mips_int_operand *int_op;
2051 int_op = (const struct mips_int_operand *) operand;
2052 info->insn_type = dis_dref;
2053 info->data_size = 1 << int_op->shift;
2059 ext_operand = decode_mips16_operand (type, TRUE);
2060 if (ext_operand != operand
2061 || (operand->type == OP_INT && operand->lsb == 0
2062 && mips_opcode_32bit_p (opcode)))
2064 ext_size = ext_operand->size;
2065 operand = ext_operand;
2068 if (operand->size == 26)
2069 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
2070 else if (ext_size == 16 || ext_size == 9)
2071 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2072 else if (ext_size == 15)
2073 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2074 else if (ext_size == 6)
2075 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2077 uval = mips_extract_operand (operand, (extend << 16) | insn);
2079 uval &= (1U << ext_size) - 1;
2081 baseaddr = memaddr + 2;
2082 if (operand->type == OP_PCREL)
2084 const struct mips_pcrel_operand *pcrel_op;
2086 pcrel_op = (const struct mips_pcrel_operand *) operand;
2087 if (!pcrel_op->include_isa_bit && use_extend)
2088 baseaddr = memaddr - 2;
2089 else if (!pcrel_op->include_isa_bit)
2093 /* If this instruction is in the delay slot of a JAL/JALX
2094 instruction, the base address is the address of the
2095 JAL/JALX instruction. If it is in the delay slot of
2096 a JR/JALR instruction, the base address is the address
2097 of the JR/JALR instruction. This test is unreliable:
2098 we have no way of knowing whether the previous word is
2099 instruction or data. */
2100 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2101 && (((info->endian == BFD_ENDIAN_BIG
2102 ? bfd_getb16 (buffer)
2103 : bfd_getl16 (buffer))
2104 & 0xf800) == 0x1800))
2105 baseaddr = memaddr - 4;
2106 else if (info->read_memory_func (memaddr - 2, buffer, 2,
2108 && (((info->endian == BFD_ENDIAN_BIG
2109 ? bfd_getb16 (buffer)
2110 : bfd_getl16 (buffer))
2111 & 0xf89f) == 0xe800)
2112 && (((info->endian == BFD_ENDIAN_BIG
2113 ? bfd_getb16 (buffer)
2114 : bfd_getl16 (buffer))
2115 & 0x0060) != 0x0060))
2116 baseaddr = memaddr - 2;
2122 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
2128 /* Check if the given address is the last word of a MIPS16 PLT entry.
2129 This word is data and depending on the value it may interfere with
2130 disassembly of further PLT entries. We make use of the fact PLT
2131 symbols are marked BSF_SYNTHETIC. */
2133 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2137 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2138 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2144 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2153 /* Disassemble mips16 instructions. */
2156 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2158 const fprintf_ftype infprintf = info->fprintf_func;
2161 const struct mips_opcode *op, *opend;
2162 struct mips_print_arg_state state;
2163 void *is = info->stream;
2164 bfd_boolean have_second;
2165 bfd_boolean extend_only;
2166 unsigned int second;
2170 info->bytes_per_chunk = 2;
2171 info->display_endian = info->endian;
2172 info->insn_info_valid = 1;
2173 info->branch_delay_insns = 0;
2174 info->data_size = 0;
2178 #define GET_OP(insn, field) \
2179 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2180 /* Decode PLT entry's GOT slot address word. */
2181 if (is_mips16_plt_tail (info, memaddr))
2183 info->insn_type = dis_noninsn;
2184 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2187 unsigned int gotslot;
2189 if (info->endian == BFD_ENDIAN_BIG)
2190 gotslot = bfd_getb32 (buffer);
2192 gotslot = bfd_getl32 (buffer);
2193 infprintf (is, ".word\t0x%x", gotslot);
2200 info->insn_type = dis_nonbranch;
2201 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2205 (*info->memory_error_func) (status, memaddr, info);
2209 extend_only = FALSE;
2211 if (info->endian == BFD_ENDIAN_BIG)
2212 first = bfd_getb16 (buffer);
2214 first = bfd_getl16 (buffer);
2216 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2220 if (info->endian == BFD_ENDIAN_BIG)
2221 second = bfd_getb16 (buffer);
2223 second = bfd_getl16 (buffer);
2224 full = (first << 16) | second;
2228 have_second = FALSE;
2233 /* FIXME: Should probably use a hash table on the major opcode here. */
2235 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2236 for (op = mips16_opcodes; op < opend; op++)
2238 enum match_kind match;
2240 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2243 if (op->pinfo == INSN_MACRO
2244 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2246 else if (mips_opcode_32bit_p (op))
2249 && (full & op->mask) == op->match)
2254 else if ((first & op->mask) == op->match)
2256 match = MATCH_SHORT;
2260 else if ((first & 0xf800) == 0xf000
2263 && (second & op->mask) == op->match)
2265 if (op->pinfo2 & INSN2_SHORT_ONLY)
2276 if (match != MATCH_NONE)
2280 infprintf (is, "%s", op->name);
2281 if (op->args[0] != '\0')
2282 infprintf (is, "\t");
2284 init_print_arg_state (&state);
2285 for (s = op->args; *s != '\0'; s++)
2289 && GET_OP (full, RX) == GET_OP (full, RY))
2291 /* Skip the register and the comma. */
2297 && GET_OP (full, RZ) == GET_OP (full, RX))
2299 /* Skip the register and the comma. */
2306 && op->name[strlen (op->name) - 1] == '0')
2308 /* Coprocessor register 0 with sel field. */
2309 const struct mips_cp0sel_name *n;
2310 const struct mips_operand *operand;
2311 unsigned int reg, sel;
2313 operand = decode_mips16_operand (*s, TRUE);
2314 reg = mips_extract_operand (operand, (first << 16) | second);
2316 operand = decode_mips16_operand (*s, TRUE);
2317 sel = mips_extract_operand (operand, (first << 16) | second);
2319 /* CP0 register including 'sel' code for mftc0, to be
2320 printed textually if known. If not known, print both
2321 CP0 register name and sel numerically since CP0 register
2322 with sel 0 may have a name unrelated to register being
2324 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2325 mips_cp0sel_names_len,
2328 infprintf (is, "%s", n->name);
2330 infprintf (is, "$%d,%d", reg, sel);
2336 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2337 second, TRUE, first, s[1] == '(');
2340 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2341 first, FALSE, 0, s[1] == '(');
2343 case MATCH_NONE: /* Stop the compiler complaining. */
2348 /* Figure out branch instruction type and delay slot information. */
2349 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2350 info->branch_delay_insns = 1;
2351 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2352 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2354 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2355 info->insn_type = dis_jsr;
2357 info->insn_type = dis_branch;
2359 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2360 info->insn_type = dis_condbranch;
2362 return match == MATCH_FULL ? 4 : 2;
2367 infprintf (is, "0x%x", first);
2368 info->insn_type = dis_noninsn;
2373 /* Disassemble microMIPS instructions. */
2376 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2378 const fprintf_ftype infprintf = info->fprintf_func;
2379 const struct mips_opcode *op, *opend;
2380 void *is = info->stream;
2382 unsigned int higher;
2383 unsigned int length;
2387 info->bytes_per_chunk = 2;
2388 info->display_endian = info->endian;
2389 info->insn_info_valid = 1;
2390 info->branch_delay_insns = 0;
2391 info->data_size = 0;
2392 info->insn_type = dis_nonbranch;
2396 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2399 (*info->memory_error_func) (status, memaddr, info);
2405 if (info->endian == BFD_ENDIAN_BIG)
2406 insn = bfd_getb16 (buffer);
2408 insn = bfd_getl16 (buffer);
2410 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2412 /* This is a 32-bit microMIPS instruction. */
2415 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2418 infprintf (is, "micromips 0x%x", higher);
2419 (*info->memory_error_func) (status, memaddr + 2, info);
2423 if (info->endian == BFD_ENDIAN_BIG)
2424 insn = bfd_getb16 (buffer);
2426 insn = bfd_getl16 (buffer);
2428 insn = insn | (higher << 16);
2433 /* FIXME: Should probably use a hash table on the major opcode here. */
2435 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2436 for (op = micromips_opcodes; op < opend; op++)
2438 if (op->pinfo != INSN_MACRO
2439 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2440 && (insn & op->mask) == op->match
2441 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2442 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2444 if (!validate_insn_args (op, decode_micromips_operand, insn))
2447 infprintf (is, "%s", op->name);
2451 infprintf (is, "\t");
2452 print_insn_args (info, op, decode_micromips_operand, insn,
2453 memaddr + 1, length);
2456 /* Figure out instruction type and branch delay information. */
2458 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2459 info->branch_delay_insns = 1;
2460 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2461 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2463 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2464 info->insn_type = dis_jsr;
2466 info->insn_type = dis_branch;
2468 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2469 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2471 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2472 info->insn_type = dis_condjsr;
2474 info->insn_type = dis_condbranch;
2477 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2478 info->insn_type = dis_dref;
2484 infprintf (is, "0x%x", insn);
2485 info->insn_type = dis_noninsn;
2490 /* Return 1 if a symbol associated with the location being disassembled
2491 indicates a compressed mode, either MIPS16 or microMIPS, according to
2492 MICROMIPS_P. We iterate over all the symbols at the address being
2493 considered assuming if at least one of them indicates code compression,
2494 then such code has been genuinely produced here (other symbols could
2495 have been derived from function symbols defined elsewhere or could
2496 define data). Otherwise, return 0. */
2499 is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
2504 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2505 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2507 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2509 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2511 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2512 && info->symtab[i]->section == info->section)
2514 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2516 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2518 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2525 /* In an environment where we do not know the symbol type of the
2526 instruction we are forced to assume that the low order bit of the
2527 instructions' address may mark it as a mips16 instruction. If we
2528 are single stepping, or the pc is within the disassembled function,
2529 this works. Otherwise, we need a clue. Sometimes. */
2532 _print_insn_mips (bfd_vma memaddr,
2533 struct disassemble_info *info,
2534 enum bfd_endian endianness)
2536 bfd_byte buffer[INSNLEN];
2539 set_default_mips_dis_options (info);
2540 parse_mips_dis_options (info->disassembler_options);
2542 if (info->mach == bfd_mach_mips16)
2543 return print_insn_mips16 (memaddr, info);
2544 if (info->mach == bfd_mach_mips_micromips)
2545 return print_insn_micromips (memaddr, info);
2548 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2549 /* Only a few tools will work this way. */
2553 return print_insn_micromips (memaddr, info);
2555 return print_insn_mips16 (memaddr, info);
2559 #if SYMTAB_AVAILABLE
2560 if (is_compressed_mode_p (info, TRUE))
2561 return print_insn_micromips (memaddr, info);
2562 if (is_compressed_mode_p (info, FALSE))
2563 return print_insn_mips16 (memaddr, info);
2566 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2571 if (endianness == BFD_ENDIAN_BIG)
2572 insn = bfd_getb32 (buffer);
2574 insn = bfd_getl32 (buffer);
2576 return print_insn_mips (memaddr, insn, info);
2580 (*info->memory_error_func) (status, memaddr, info);
2586 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2588 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2592 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2594 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2597 /* Indices into option argument vector for options accepting an argument.
2598 Use MIPS_OPTION_ARG_NONE for options accepting no argument. */
2601 MIPS_OPTION_ARG_NONE = -1,
2602 MIPS_OPTION_ARG_ABI,
2603 MIPS_OPTION_ARG_ARCH,
2604 MIPS_OPTION_ARG_SIZE
2605 } mips_option_arg_t;
2607 /* Valid MIPS disassembler options. */
2611 const char *description;
2612 mips_option_arg_t arg;
2615 { "no-aliases", N_("Use canonical instruction forms.\n"),
2616 MIPS_OPTION_ARG_NONE },
2617 { "msa", N_("Recognize MSA instructions.\n"),
2618 MIPS_OPTION_ARG_NONE },
2619 { "virt", N_("Recognize the virtualization ASE instructions.\n"),
2620 MIPS_OPTION_ARG_NONE },
2621 { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\
2623 MIPS_OPTION_ARG_NONE },
2624 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2626 MIPS_OPTION_ARG_NONE },
2628 N_("Recognize the Loongson MultiMedia extensions "
2629 "Instructions (MMI) ASE instructions.\n"),
2630 MIPS_OPTION_ARG_NONE },
2632 N_("Recognize the Loongson Content Address Memory (CAM) "
2633 " instructions.\n"),
2634 MIPS_OPTION_ARG_NONE },
2636 N_("Recognize the Loongson EXTensions (EXT) "
2637 " instructions.\n"),
2638 MIPS_OPTION_ARG_NONE },
2640 N_("Recognize the Loongson EXTensions R2 (EXT2) "
2641 " instructions.\n"),
2642 MIPS_OPTION_ARG_NONE },
2643 { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
2644 Default: based on binary being disassembled.\n"),
2645 MIPS_OPTION_ARG_ABI },
2646 { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
2647 Default: numeric.\n"),
2648 MIPS_OPTION_ARG_ABI },
2649 { "cp0-names=", N_("Print CP0 register names according to specified "
2651 Default: based on binary being disassembled.\n"),
2652 MIPS_OPTION_ARG_ARCH },
2653 { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
2654 Default: based on binary being disassembled.\n"),
2655 MIPS_OPTION_ARG_ARCH },
2656 { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
2657 MIPS_OPTION_ARG_ABI },
2658 { "reg-names=", N_("Print CP0 register and HWR names according to "
2661 MIPS_OPTION_ARG_ARCH }
2664 /* Build the structure representing valid MIPS disassembler options.
2665 This is done dynamically for maintenance ease purpose; a static
2666 initializer would be unreadable. */
2668 const disasm_options_and_args_t *
2669 disassembler_options_mips (void)
2671 static disasm_options_and_args_t *opts_and_args;
2673 if (opts_and_args == NULL)
2675 size_t num_options = ARRAY_SIZE (mips_options);
2676 size_t num_args = MIPS_OPTION_ARG_SIZE;
2677 disasm_option_arg_t *args;
2678 disasm_options_t *opts;
2682 args = XNEWVEC (disasm_option_arg_t, num_args + 1);
2684 args[MIPS_OPTION_ARG_ABI].name = "ABI";
2685 args[MIPS_OPTION_ARG_ABI].values
2686 = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1);
2687 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2688 args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name;
2689 /* The array we return must be NULL terminated. */
2690 args[MIPS_OPTION_ARG_ABI].values[i] = NULL;
2692 args[MIPS_OPTION_ARG_ARCH].name = "ARCH";
2693 args[MIPS_OPTION_ARG_ARCH].values
2694 = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1);
2695 for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2696 if (*mips_arch_choices[i].name != '\0')
2697 args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name;
2698 /* The array we return must be NULL terminated. */
2699 args[MIPS_OPTION_ARG_ARCH].values[j] = NULL;
2701 /* The array we return must be NULL terminated. */
2702 args[MIPS_OPTION_ARG_SIZE].name = NULL;
2703 args[MIPS_OPTION_ARG_SIZE].values = NULL;
2705 opts_and_args = XNEW (disasm_options_and_args_t);
2706 opts_and_args->args = args;
2708 opts = &opts_and_args->options;
2709 opts->name = XNEWVEC (const char *, num_options + 1);
2710 opts->description = XNEWVEC (const char *, num_options + 1);
2711 opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
2712 for (i = 0; i < num_options; i++)
2714 opts->name[i] = mips_options[i].name;
2715 opts->description[i] = _(mips_options[i].description);
2716 if (mips_options[i].arg != MIPS_OPTION_ARG_NONE)
2717 opts->arg[i] = &args[mips_options[i].arg];
2719 opts->arg[i] = NULL;
2721 /* The array we return must be NULL terminated. */
2722 opts->name[i] = NULL;
2723 opts->description[i] = NULL;
2724 opts->arg[i] = NULL;
2727 return opts_and_args;
2731 print_mips_disassembler_options (FILE *stream)
2733 const disasm_options_and_args_t *opts_and_args;
2734 const disasm_option_arg_t *args;
2735 const disasm_options_t *opts;
2740 opts_and_args = disassembler_options_mips ();
2741 opts = &opts_and_args->options;
2742 args = opts_and_args->args;
2744 fprintf (stream, _("\n\
2745 The following MIPS specific disassembler options are supported for use\n\
2746 with the -M switch (multiple options should be separated by commas):\n\n"));
2748 /* Compute the length of the longest option name. */
2749 for (i = 0; opts->name[i] != NULL; i++)
2751 size_t len = strlen (opts->name[i]);
2753 if (opts->arg[i] != NULL)
2754 len += strlen (opts->arg[i]->name);
2759 for (i = 0, max_len++; opts->name[i] != NULL; i++)
2761 fprintf (stream, " %s", opts->name[i]);
2762 if (opts->arg[i] != NULL)
2763 fprintf (stream, "%s", opts->arg[i]->name);
2764 if (opts->description[i] != NULL)
2766 size_t len = strlen (opts->name[i]);
2768 if (opts->arg[i] != NULL)
2769 len += strlen (opts->arg[i]->name);
2771 "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
2773 fprintf (stream, _("\n"));
2776 for (i = 0; args[i].name != NULL; i++)
2778 fprintf (stream, _("\n\
2779 For the options above, the following values are supported for \"%s\":\n "),
2781 for (j = 0; args[i].values[j] != NULL; j++)
2782 fprintf (stream, " %s", args[i].values[j]);
2783 fprintf (stream, _("\n"));
2786 fprintf (stream, _("\n"));