1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2018 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 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
649 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
650 mips_cp1_names_mips3264, mips_hwr_names_numeric },
652 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
653 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
654 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
656 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
657 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
658 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
660 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
661 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
662 mips_cp0_names_numeric,
663 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
665 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
666 ISA_MIPS64 | INSN_XLR, 0,
668 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
669 mips_cp1_names_mips3264, mips_hwr_names_numeric },
671 /* XLP is mostly like XLR, with the prominent exception it is being
673 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
674 ISA_MIPS64R2 | INSN_XLR, 0,
676 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
677 mips_cp1_names_mips3264, mips_hwr_names_numeric },
679 /* This entry, mips16, is here only for ISA/processor selection; do
680 not print its name. */
681 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
682 ASE_MIPS16E2 | ASE_MIPS16E2_MT,
683 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
684 mips_hwr_names_numeric },
687 /* ISA and processor type to disassemble for, and register names to use.
688 set_default_mips_dis_options and parse_mips_dis_options fill in these
690 static int mips_processor;
693 static int micromips_ase;
694 static const char * const *mips_gpr_names;
695 static const char * const *mips_fpr_names;
696 static const char * const *mips_cp0_names;
697 static const struct mips_cp0sel_name *mips_cp0sel_names;
698 static int mips_cp0sel_names_len;
699 static const char * const *mips_cp1_names;
700 static const char * const *mips_hwr_names;
703 static int no_aliases; /* If set disassemble as most general inst. */
705 static const struct mips_abi_choice *
706 choose_abi_by_name (const char *name, unsigned int namelen)
708 const struct mips_abi_choice *c;
711 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
712 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
713 && strlen (mips_abi_choices[i].name) == namelen)
714 c = &mips_abi_choices[i];
719 static const struct mips_arch_choice *
720 choose_arch_by_name (const char *name, unsigned int namelen)
722 const struct mips_arch_choice *c = NULL;
725 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
726 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
727 && strlen (mips_arch_choices[i].name) == namelen)
728 c = &mips_arch_choices[i];
733 static const struct mips_arch_choice *
734 choose_arch_by_number (unsigned long mach)
736 static unsigned long hint_bfd_mach;
737 static const struct mips_arch_choice *hint_arch_choice;
738 const struct mips_arch_choice *c;
741 /* We optimize this because even if the user specifies no
742 flags, this will be done for every instruction! */
743 if (hint_bfd_mach == mach
744 && hint_arch_choice != NULL
745 && hint_arch_choice->bfd_mach == hint_bfd_mach)
746 return hint_arch_choice;
748 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
750 if (mips_arch_choices[i].bfd_mach_valid
751 && mips_arch_choices[i].bfd_mach == mach)
753 c = &mips_arch_choices[i];
754 hint_bfd_mach = mach;
755 hint_arch_choice = c;
761 /* Check if the object uses NewABI conventions. */
764 is_newabi (Elf_Internal_Ehdr *header)
766 /* There are no old-style ABIs which use 64-bit ELF. */
767 if (header->e_ident[EI_CLASS] == ELFCLASS64)
770 /* If a 32-bit ELF file, n32 is a new-style ABI. */
771 if ((header->e_flags & EF_MIPS_ABI2) != 0)
777 /* Check if the object has microMIPS ASE code. */
780 is_micromips (Elf_Internal_Ehdr *header)
782 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
788 /* Convert ASE flags from .MIPS.abiflags to internal values. */
791 mips_convert_abiflags_ases (unsigned long afl_ases)
793 unsigned long opcode_ases = 0;
795 if (afl_ases & AFL_ASE_DSP)
796 opcode_ases |= ASE_DSP;
797 if (afl_ases & AFL_ASE_DSPR2)
798 opcode_ases |= ASE_DSPR2;
799 if (afl_ases & AFL_ASE_EVA)
800 opcode_ases |= ASE_EVA;
801 if (afl_ases & AFL_ASE_MCU)
802 opcode_ases |= ASE_MCU;
803 if (afl_ases & AFL_ASE_MDMX)
804 opcode_ases |= ASE_MDMX;
805 if (afl_ases & AFL_ASE_MIPS3D)
806 opcode_ases |= ASE_MIPS3D;
807 if (afl_ases & AFL_ASE_MT)
808 opcode_ases |= ASE_MT;
809 if (afl_ases & AFL_ASE_SMARTMIPS)
810 opcode_ases |= ASE_SMARTMIPS;
811 if (afl_ases & AFL_ASE_VIRT)
812 opcode_ases |= ASE_VIRT;
813 if (afl_ases & AFL_ASE_MSA)
814 opcode_ases |= ASE_MSA;
815 if (afl_ases & AFL_ASE_XPA)
816 opcode_ases |= ASE_XPA;
817 if (afl_ases & AFL_ASE_DSPR3)
818 opcode_ases |= ASE_DSPR3;
819 if (afl_ases & AFL_ASE_MIPS16E2)
820 opcode_ases |= ASE_MIPS16E2;
824 /* Calculate combination ASE flags from regular ASE flags. */
827 mips_calculate_combination_ases (unsigned long opcode_ases)
829 unsigned long combination_ases = 0;
831 if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
832 combination_ases |= ASE_XPA_VIRT;
833 if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
834 combination_ases |= ASE_MIPS16E2_MT;
835 return combination_ases;
839 set_default_mips_dis_options (struct disassemble_info *info)
841 const struct mips_arch_choice *chosen_arch;
843 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
844 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
845 CP0 register, and HWR names. */
846 mips_isa = ISA_MIPS3;
847 mips_processor = CPU_R3000;
850 mips_gpr_names = mips_gpr_names_oldabi;
851 mips_fpr_names = mips_fpr_names_numeric;
852 mips_cp0_names = mips_cp0_names_numeric;
853 mips_cp0sel_names = NULL;
854 mips_cp0sel_names_len = 0;
855 mips_cp1_names = mips_cp1_names_numeric;
856 mips_hwr_names = mips_hwr_names_numeric;
859 /* Set ISA, architecture, and cp0 register names as best we can. */
860 #if ! SYMTAB_AVAILABLE
861 /* This is running out on a target machine, not in a host tool.
862 FIXME: Where does mips_target_info come from? */
863 target_processor = mips_target_info.processor;
864 mips_isa = mips_target_info.isa;
865 mips_ase = mips_target_info.ase;
867 chosen_arch = choose_arch_by_number (info->mach);
868 if (chosen_arch != NULL)
870 mips_processor = chosen_arch->processor;
871 mips_isa = chosen_arch->isa;
872 mips_ase = chosen_arch->ase;
873 mips_cp0_names = chosen_arch->cp0_names;
874 mips_cp0sel_names = chosen_arch->cp0sel_names;
875 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
876 mips_cp1_names = chosen_arch->cp1_names;
877 mips_hwr_names = chosen_arch->hwr_names;
880 /* Update settings according to the ELF file header flags. */
881 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
883 struct bfd *abfd = info->section->owner;
884 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
885 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
887 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
888 because we won't then have a MIPS/ELF BFD, however we need
889 to guard against a link error in a `--enable-targets=...'
890 configuration with a 32-bit host where the MIPS target is
891 a secondary, or with MIPS/ECOFF configurations. */
892 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
893 abiflags = bfd_mips_elf_get_abiflags (abfd);
895 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
896 if (is_newabi (header))
897 mips_gpr_names = mips_gpr_names_newabi;
898 /* If a microMIPS binary, then don't use MIPS16 bindings. */
899 micromips_ase = is_micromips (header);
900 /* OR in any extra ASE flags set in ELF file structures. */
902 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
903 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
904 mips_ase |= ASE_MDMX;
907 mips_ase |= mips_calculate_combination_ases (mips_ase);
910 /* Parse an ASE disassembler option and set the corresponding global
911 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
914 parse_mips_ase_option (const char *option)
916 if (CONST_STRNEQ (option, "msa"))
919 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
920 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
921 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
922 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
923 mips_ase |= ASE_MSA64;
927 if (CONST_STRNEQ (option, "virt"))
929 mips_ase |= ASE_VIRT;
930 if (mips_isa & ISA_MIPS64R2
931 || mips_isa & ISA_MIPS64R3
932 || mips_isa & ISA_MIPS64R5
933 || mips_isa & ISA_MIPS64R6)
934 mips_ase |= ASE_VIRT64;
938 if (CONST_STRNEQ (option, "xpa"))
944 if (CONST_STRNEQ (option, "ginv"))
946 mips_ase |= ASE_GINV;
950 if (CONST_STRNEQ (option, "loongson-mmi"))
952 mips_ase |= ASE_LOONGSON_MMI;
956 if (CONST_STRNEQ (option, "loongson-cam"))
958 mips_ase |= ASE_LOONGSON_CAM;
962 /* Put here for match ext2 frist */
963 if (CONST_STRNEQ (option, "loongson-ext2"))
965 mips_ase |= ASE_LOONGSON_EXT2;
969 if (CONST_STRNEQ (option, "loongson-ext"))
971 mips_ase |= ASE_LOONGSON_EXT;
979 parse_mips_dis_option (const char *option, unsigned int len)
981 unsigned int i, optionlen, vallen;
983 const struct mips_abi_choice *chosen_abi;
984 const struct mips_arch_choice *chosen_arch;
986 /* Try to match options that are simple flags */
987 if (CONST_STRNEQ (option, "no-aliases"))
993 if (parse_mips_ase_option (option))
995 mips_ase |= mips_calculate_combination_ases (mips_ase);
999 /* Look for the = that delimits the end of the option name. */
1000 for (i = 0; i < len; i++)
1001 if (option[i] == '=')
1004 if (i == 0) /* Invalid option: no name before '='. */
1006 if (i == len) /* Invalid option: no '='. */
1008 if (i == (len - 1)) /* Invalid option: no value after '='. */
1012 val = option + (optionlen + 1);
1013 vallen = len - (optionlen + 1);
1015 if (strncmp ("gpr-names", option, optionlen) == 0
1016 && strlen ("gpr-names") == optionlen)
1018 chosen_abi = choose_abi_by_name (val, vallen);
1019 if (chosen_abi != NULL)
1020 mips_gpr_names = chosen_abi->gpr_names;
1024 if (strncmp ("fpr-names", option, optionlen) == 0
1025 && strlen ("fpr-names") == optionlen)
1027 chosen_abi = choose_abi_by_name (val, vallen);
1028 if (chosen_abi != NULL)
1029 mips_fpr_names = chosen_abi->fpr_names;
1033 if (strncmp ("cp0-names", option, optionlen) == 0
1034 && strlen ("cp0-names") == optionlen)
1036 chosen_arch = choose_arch_by_name (val, vallen);
1037 if (chosen_arch != NULL)
1039 mips_cp0_names = chosen_arch->cp0_names;
1040 mips_cp0sel_names = chosen_arch->cp0sel_names;
1041 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1046 if (strncmp ("cp1-names", option, optionlen) == 0
1047 && strlen ("cp1-names") == optionlen)
1049 chosen_arch = choose_arch_by_name (val, vallen);
1050 if (chosen_arch != NULL)
1051 mips_cp1_names = chosen_arch->cp1_names;
1055 if (strncmp ("hwr-names", option, optionlen) == 0
1056 && strlen ("hwr-names") == optionlen)
1058 chosen_arch = choose_arch_by_name (val, vallen);
1059 if (chosen_arch != NULL)
1060 mips_hwr_names = chosen_arch->hwr_names;
1064 if (strncmp ("reg-names", option, optionlen) == 0
1065 && strlen ("reg-names") == optionlen)
1067 /* We check both ABI and ARCH here unconditionally, so
1068 that "numeric" will do the desirable thing: select
1069 numeric register names for all registers. Other than
1070 that, a given name probably won't match both. */
1071 chosen_abi = choose_abi_by_name (val, vallen);
1072 if (chosen_abi != NULL)
1074 mips_gpr_names = chosen_abi->gpr_names;
1075 mips_fpr_names = chosen_abi->fpr_names;
1077 chosen_arch = choose_arch_by_name (val, vallen);
1078 if (chosen_arch != NULL)
1080 mips_cp0_names = chosen_arch->cp0_names;
1081 mips_cp0sel_names = chosen_arch->cp0sel_names;
1082 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1083 mips_cp1_names = chosen_arch->cp1_names;
1084 mips_hwr_names = chosen_arch->hwr_names;
1089 /* Invalid option. */
1093 parse_mips_dis_options (const char *options)
1095 const char *option_end;
1097 if (options == NULL)
1100 while (*options != '\0')
1102 /* Skip empty options. */
1103 if (*options == ',')
1109 /* We know that *options is neither NUL or a comma. */
1110 option_end = options + 1;
1111 while (*option_end != ',' && *option_end != '\0')
1114 parse_mips_dis_option (options, option_end - options);
1116 /* Go on to the next one. If option_end points to a comma, it
1117 will be skipped above. */
1118 options = option_end;
1122 static const struct mips_cp0sel_name *
1123 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1125 unsigned int cp0reg,
1130 for (i = 0; i < len; i++)
1131 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1136 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1139 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1140 enum mips_reg_operand_type type, int regno)
1145 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1149 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1153 if (opcode->pinfo & (FP_D | FP_S))
1154 info->fprintf_func (info->stream, "$fcc%d", regno);
1156 info->fprintf_func (info->stream, "$cc%d", regno);
1160 if (opcode->membership & INSN_5400)
1161 info->fprintf_func (info->stream, "$f%d", regno);
1163 info->fprintf_func (info->stream, "$v%d", regno);
1167 info->fprintf_func (info->stream, "$ac%d", regno);
1171 if (opcode->name[strlen (opcode->name) - 1] == '0')
1172 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
1173 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1174 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
1176 info->fprintf_func (info->stream, "$%d", regno);
1180 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1184 info->fprintf_func (info->stream, "$vf%d", regno);
1188 info->fprintf_func (info->stream, "$vi%d", regno);
1191 case OP_REG_R5900_I:
1192 info->fprintf_func (info->stream, "$I");
1195 case OP_REG_R5900_Q:
1196 info->fprintf_func (info->stream, "$Q");
1199 case OP_REG_R5900_R:
1200 info->fprintf_func (info->stream, "$R");
1203 case OP_REG_R5900_ACC:
1204 info->fprintf_func (info->stream, "$ACC");
1208 info->fprintf_func (info->stream, "$w%d", regno);
1211 case OP_REG_MSA_CTRL:
1212 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1218 /* Used to track the state carried over from previous operands in
1220 struct mips_print_arg_state {
1221 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1222 where the value is known to be unsigned and small. */
1223 unsigned int last_int;
1225 /* The type and number of the last OP_REG seen. We only use this for
1226 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1227 enum mips_reg_operand_type last_reg_type;
1228 unsigned int last_regno;
1229 unsigned int dest_regno;
1230 unsigned int seen_dest;
1233 /* Initialize STATE for the start of an instruction. */
1236 init_print_arg_state (struct mips_print_arg_state *state)
1238 memset (state, 0, sizeof (*state));
1241 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1242 whose value is given by UVAL. */
1245 print_vu0_channel (struct disassemble_info *info,
1246 const struct mips_operand *operand, unsigned int uval)
1248 if (operand->size == 4)
1249 info->fprintf_func (info->stream, "%s%s%s%s",
1250 uval & 8 ? "x" : "",
1251 uval & 4 ? "y" : "",
1252 uval & 2 ? "z" : "",
1253 uval & 1 ? "w" : "");
1254 else if (operand->size == 2)
1255 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1260 /* Record information about a register operand. */
1263 mips_seen_register (struct mips_print_arg_state *state,
1265 enum mips_reg_operand_type reg_type)
1267 state->last_reg_type = reg_type;
1268 state->last_regno = regno;
1270 if (!state->seen_dest)
1272 state->seen_dest = 1;
1273 state->dest_regno = regno;
1277 /* Print SAVE/RESTORE instruction operands according to the argument
1278 register mask AMASK, the number of static registers saved NSREG,
1279 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1280 and the frame size FRAME_SIZE. */
1283 mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
1284 unsigned int nsreg, unsigned int ra,
1285 unsigned int s0, unsigned int s1,
1286 unsigned int frame_size)
1288 const fprintf_ftype infprintf = info->fprintf_func;
1289 unsigned int nargs, nstatics, smask, i, j;
1290 void *is = info->stream;
1293 if (amask == MIPS_SVRS_ALL_ARGS)
1298 else if (amask == MIPS_SVRS_ALL_STATICS)
1306 nstatics = amask & 3;
1312 infprintf (is, "%s", mips_gpr_names[4]);
1314 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1318 infprintf (is, "%s%d", sep, frame_size);
1321 infprintf (is, ",%s", mips_gpr_names[31]);
1328 if (nsreg > 0) /* $s2-$s8 */
1329 smask |= ((1 << nsreg) - 1) << 2;
1331 for (i = 0; i < 9; i++)
1332 if (smask & (1 << i))
1334 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1335 /* Skip over string of set bits. */
1336 for (j = i; smask & (2 << j); j++)
1339 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1342 /* Statics $ax - $a3. */
1344 infprintf (is, ",%s", mips_gpr_names[7]);
1345 else if (nstatics > 0)
1346 infprintf (is, ",%s-%s",
1347 mips_gpr_names[7 - nstatics + 1],
1352 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1353 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1354 the base address for OP_PCREL operands. */
1357 print_insn_arg (struct disassemble_info *info,
1358 struct mips_print_arg_state *state,
1359 const struct mips_opcode *opcode,
1360 const struct mips_operand *operand,
1364 const fprintf_ftype infprintf = info->fprintf_func;
1365 void *is = info->stream;
1367 switch (operand->type)
1371 const struct mips_int_operand *int_op;
1373 int_op = (const struct mips_int_operand *) operand;
1374 uval = mips_decode_int_operand (int_op, uval);
1375 state->last_int = uval;
1376 if (int_op->print_hex)
1377 infprintf (is, "0x%x", uval);
1379 infprintf (is, "%d", uval);
1385 const struct mips_mapped_int_operand *mint_op;
1387 mint_op = (const struct mips_mapped_int_operand *) operand;
1388 uval = mint_op->int_map[uval];
1389 state->last_int = uval;
1390 if (mint_op->print_hex)
1391 infprintf (is, "0x%x", uval);
1393 infprintf (is, "%d", uval);
1399 const struct mips_msb_operand *msb_op;
1401 msb_op = (const struct mips_msb_operand *) operand;
1402 uval += msb_op->bias;
1403 if (msb_op->add_lsb)
1404 uval -= state->last_int;
1405 infprintf (is, "0x%x", uval);
1410 case OP_OPTIONAL_REG:
1412 const struct mips_reg_operand *reg_op;
1414 reg_op = (const struct mips_reg_operand *) operand;
1415 uval = mips_decode_reg_operand (reg_op, uval);
1416 print_reg (info, opcode, reg_op->reg_type, uval);
1418 mips_seen_register (state, uval, reg_op->reg_type);
1424 const struct mips_reg_pair_operand *pair_op;
1426 pair_op = (const struct mips_reg_pair_operand *) operand;
1427 print_reg (info, opcode, pair_op->reg_type,
1428 pair_op->reg1_map[uval]);
1429 infprintf (is, ",");
1430 print_reg (info, opcode, pair_op->reg_type,
1431 pair_op->reg2_map[uval]);
1437 const struct mips_pcrel_operand *pcrel_op;
1439 pcrel_op = (const struct mips_pcrel_operand *) operand;
1440 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1442 /* For jumps and branches clear the ISA bit except for
1443 the GDB disassembler. */
1444 if (pcrel_op->include_isa_bit
1445 && info->flavour != bfd_target_unknown_flavour)
1448 (*info->print_address_func) (info->target, info);
1453 infprintf (is, "%d", uval);
1456 case OP_ADDIUSP_INT:
1460 sval = mips_signed_operand (operand, uval) * 4;
1461 if (sval >= -8 && sval < 8)
1463 infprintf (is, "%d", sval);
1467 case OP_CLO_CLZ_DEST:
1469 unsigned int reg1, reg2;
1473 /* If one is zero use the other. */
1474 if (reg1 == reg2 || reg2 == 0)
1475 infprintf (is, "%s", mips_gpr_names[reg1]);
1477 infprintf (is, "%s", mips_gpr_names[reg2]);
1479 /* Bogus, result depends on processor. */
1480 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1481 mips_gpr_names[reg2]);
1487 case OP_NON_ZERO_REG:
1489 print_reg (info, opcode, OP_REG_GP, uval & 31);
1490 mips_seen_register (state, uval, OP_REG_GP);
1494 case OP_LWM_SWM_LIST:
1495 if (operand->size == 2)
1498 infprintf (is, "%s,%s",
1500 mips_gpr_names[31]);
1502 infprintf (is, "%s-%s,%s",
1504 mips_gpr_names[16 + uval],
1505 mips_gpr_names[31]);
1511 s_reg_encode = uval & 0xf;
1512 if (s_reg_encode != 0)
1514 if (s_reg_encode == 1)
1515 infprintf (is, "%s", mips_gpr_names[16]);
1516 else if (s_reg_encode < 9)
1517 infprintf (is, "%s-%s",
1519 mips_gpr_names[15 + s_reg_encode]);
1520 else if (s_reg_encode == 9)
1521 infprintf (is, "%s-%s,%s",
1524 mips_gpr_names[30]);
1526 infprintf (is, "UNKNOWN");
1529 if (uval & 0x10) /* For ra. */
1531 if (s_reg_encode == 0)
1532 infprintf (is, "%s", mips_gpr_names[31]);
1534 infprintf (is, ",%s", mips_gpr_names[31]);
1539 case OP_ENTRY_EXIT_LIST:
1542 unsigned int amask, smask;
1545 amask = (uval >> 3) & 7;
1546 if (amask > 0 && amask < 5)
1548 infprintf (is, "%s", mips_gpr_names[4]);
1550 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1554 smask = (uval >> 1) & 3;
1557 infprintf (is, "%s??", sep);
1562 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1564 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1570 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1574 if (amask == 5 || amask == 6)
1576 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1578 infprintf (is, "-%s", mips_fpr_names[1]);
1583 case OP_SAVE_RESTORE_LIST:
1584 /* Should be handled by the caller due to complex behavior. */
1587 case OP_MDMX_IMM_REG:
1593 if ((vsel & 0x10) == 0)
1598 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1599 if ((vsel & 1) == 0)
1601 print_reg (info, opcode, OP_REG_VEC, uval);
1602 infprintf (is, "[%d]", vsel >> 1);
1604 else if ((vsel & 0x08) == 0)
1605 print_reg (info, opcode, OP_REG_VEC, uval);
1607 infprintf (is, "0x%x", uval);
1611 case OP_REPEAT_PREV_REG:
1612 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1615 case OP_REPEAT_DEST_REG:
1616 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1620 infprintf (is, "$pc");
1624 print_reg (info, opcode, OP_REG_GP, 28);
1628 case OP_VU0_MATCH_SUFFIX:
1629 print_vu0_channel (info, operand, uval);
1633 infprintf (is, "[%d]", uval);
1637 infprintf (is, "[");
1638 print_reg (info, opcode, OP_REG_GP, uval);
1639 infprintf (is, "]");
1644 /* Validate the arguments for INSN, which is described by OPCODE.
1645 Use DECODE_OPERAND to get the encoding of each operand. */
1648 validate_insn_args (const struct mips_opcode *opcode,
1649 const struct mips_operand *(*decode_operand) (const char *),
1652 struct mips_print_arg_state state;
1653 const struct mips_operand *operand;
1657 init_print_arg_state (&state);
1658 for (s = opcode->args; *s; ++s)
1672 operand = decode_operand (s);
1676 uval = mips_extract_operand (operand, insn);
1677 switch (operand->type)
1680 case OP_OPTIONAL_REG:
1682 const struct mips_reg_operand *reg_op;
1684 reg_op = (const struct mips_reg_operand *) operand;
1685 uval = mips_decode_reg_operand (reg_op, uval);
1686 mips_seen_register (&state, uval, reg_op->reg_type);
1692 unsigned int reg1, reg2;
1697 if (reg1 != reg2 || reg1 == 0)
1704 const struct mips_check_prev_operand *prev_op;
1706 prev_op = (const struct mips_check_prev_operand *) operand;
1708 if (!prev_op->zero_ok && uval == 0)
1711 if (((prev_op->less_than_ok && uval < state.last_regno)
1712 || (prev_op->greater_than_ok && uval > state.last_regno)
1713 || (prev_op->equal_ok && uval == state.last_regno)))
1719 case OP_NON_ZERO_REG:
1732 case OP_ADDIUSP_INT:
1733 case OP_CLO_CLZ_DEST:
1734 case OP_LWM_SWM_LIST:
1735 case OP_ENTRY_EXIT_LIST:
1736 case OP_MDMX_IMM_REG:
1737 case OP_REPEAT_PREV_REG:
1738 case OP_REPEAT_DEST_REG:
1742 case OP_VU0_MATCH_SUFFIX:
1745 case OP_SAVE_RESTORE_LIST:
1749 if (*s == 'm' || *s == '+' || *s == '-')
1756 /* Print the arguments for INSN, which is described by OPCODE.
1757 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1758 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1759 operand is for a branch or jump. */
1762 print_insn_args (struct disassemble_info *info,
1763 const struct mips_opcode *opcode,
1764 const struct mips_operand *(*decode_operand) (const char *),
1765 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1767 const fprintf_ftype infprintf = info->fprintf_func;
1768 void *is = info->stream;
1769 struct mips_print_arg_state state;
1770 const struct mips_operand *operand;
1773 init_print_arg_state (&state);
1774 for (s = opcode->args; *s; ++s)
1781 infprintf (is, "%c", *s);
1786 infprintf (is, "%c%c", *s, *s);
1790 operand = decode_operand (s);
1793 /* xgettext:c-format */
1795 _("# internal error, undefined operand in `%s %s'"),
1796 opcode->name, opcode->args);
1800 if (operand->type == OP_SAVE_RESTORE_LIST)
1802 /* Handle this case here because of the complex behavior. */
1803 unsigned int amask = (insn >> 15) & 0xf;
1804 unsigned int nsreg = (insn >> 23) & 0x7;
1805 unsigned int ra = insn & 0x1000; /* $ra */
1806 unsigned int s0 = insn & 0x800; /* $s0 */
1807 unsigned int s1 = insn & 0x400; /* $s1 */
1808 unsigned int frame_size = (((insn >> 15) & 0xf0)
1809 | ((insn >> 6) & 0x0f)) * 8;
1810 mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1813 else if (operand->type == OP_REG
1816 && opcode->name[strlen (opcode->name) - 1] == '0')
1818 /* Coprocessor register 0 with sel field. */
1819 const struct mips_cp0sel_name *n;
1820 unsigned int reg, sel;
1822 reg = mips_extract_operand (operand, insn);
1824 operand = decode_operand (s);
1825 sel = mips_extract_operand (operand, insn);
1827 /* CP0 register including 'sel' code for mftc0, to be
1828 printed textually if known. If not known, print both
1829 CP0 register name and sel numerically since CP0 register
1830 with sel 0 may have a name unrelated to register being
1832 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1833 mips_cp0sel_names_len,
1836 infprintf (is, "%s", n->name);
1838 infprintf (is, "$%d,%d", reg, sel);
1842 bfd_vma base_pc = insn_pc;
1844 /* Adjust the PC relative base so that branch/jump insns use
1845 the following PC as the base but genuinely PC relative
1846 operands use the current PC. */
1847 if (operand->type == OP_PCREL)
1849 const struct mips_pcrel_operand *pcrel_op;
1851 pcrel_op = (const struct mips_pcrel_operand *) operand;
1852 /* The include_isa_bit flag is sufficient to distinguish
1853 branch/jump from other PC relative operands. */
1854 if (pcrel_op->include_isa_bit)
1858 print_insn_arg (info, &state, opcode, operand, base_pc,
1859 mips_extract_operand (operand, insn));
1861 if (*s == 'm' || *s == '+' || *s == '-')
1868 /* Print the mips instruction at address MEMADDR in debugged memory,
1869 on using INFO. Returns length of the instruction, in bytes, which is
1870 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1871 this is little-endian code. */
1874 print_insn_mips (bfd_vma memaddr,
1876 struct disassemble_info *info)
1878 #define GET_OP(insn, field) \
1879 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1880 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1881 const fprintf_ftype infprintf = info->fprintf_func;
1882 const struct mips_opcode *op;
1883 static bfd_boolean init = 0;
1884 void *is = info->stream;
1886 /* Build a hash table to shorten the search time. */
1891 for (i = 0; i <= OP_MASK_OP; i++)
1893 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1895 if (op->pinfo == INSN_MACRO
1896 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1898 if (i == GET_OP (op->match, OP))
1909 info->bytes_per_chunk = INSNLEN;
1910 info->display_endian = info->endian;
1911 info->insn_info_valid = 1;
1912 info->branch_delay_insns = 0;
1913 info->data_size = 0;
1914 info->insn_type = dis_nonbranch;
1918 op = mips_hash[GET_OP (word, OP)];
1921 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1923 if (op->pinfo != INSN_MACRO
1924 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1925 && (word & op->mask) == op->match)
1927 /* We always disassemble the jalx instruction, except for MIPS r6. */
1928 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1929 && (strcmp (op->name, "jalx")
1930 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1931 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
1934 /* Figure out instruction type and branch delay information. */
1935 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1937 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
1938 info->insn_type = dis_jsr;
1940 info->insn_type = dis_branch;
1941 info->branch_delay_insns = 1;
1943 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1944 | INSN_COND_BRANCH_LIKELY)) != 0)
1946 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1947 info->insn_type = dis_condjsr;
1949 info->insn_type = dis_condbranch;
1950 info->branch_delay_insns = 1;
1952 else if ((op->pinfo & (INSN_STORE_MEMORY
1953 | INSN_LOAD_MEMORY)) != 0)
1954 info->insn_type = dis_dref;
1956 if (!validate_insn_args (op, decode_mips_operand, word))
1959 infprintf (is, "%s", op->name);
1960 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1964 infprintf (is, ".");
1965 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1966 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1971 infprintf (is, "\t");
1972 print_insn_args (info, op, decode_mips_operand, word,
1982 /* Handle undefined instructions. */
1983 info->insn_type = dis_noninsn;
1984 infprintf (is, "0x%x", word);
1988 /* Disassemble an operand for a mips16 instruction. */
1991 print_mips16_insn_arg (struct disassemble_info *info,
1992 struct mips_print_arg_state *state,
1993 const struct mips_opcode *opcode,
1994 char type, bfd_vma memaddr,
1995 unsigned insn, bfd_boolean use_extend,
1996 unsigned extend, bfd_boolean is_offset)
1998 const fprintf_ftype infprintf = info->fprintf_func;
1999 void *is = info->stream;
2000 const struct mips_operand *operand, *ext_operand;
2001 unsigned short ext_size;
2013 infprintf (is, "%c", type);
2017 operand = decode_mips16_operand (type, FALSE);
2020 /* xgettext:c-format */
2021 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
2022 opcode->name, opcode->args);
2026 if (operand->type == OP_SAVE_RESTORE_LIST)
2028 /* Handle this case here because of the complex interaction
2029 with the EXTEND opcode. */
2030 unsigned int amask = extend & 0xf;
2031 unsigned int nsreg = (extend >> 8) & 0x7;
2032 unsigned int ra = insn & 0x40; /* $ra */
2033 unsigned int s0 = insn & 0x20; /* $s0 */
2034 unsigned int s1 = insn & 0x10; /* $s1 */
2035 unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
2036 if (frame_size == 0 && !use_extend)
2038 mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
2042 if (is_offset && operand->type == OP_INT)
2044 const struct mips_int_operand *int_op;
2046 int_op = (const struct mips_int_operand *) operand;
2047 info->insn_type = dis_dref;
2048 info->data_size = 1 << int_op->shift;
2054 ext_operand = decode_mips16_operand (type, TRUE);
2055 if (ext_operand != operand
2056 || (operand->type == OP_INT && operand->lsb == 0
2057 && mips_opcode_32bit_p (opcode)))
2059 ext_size = ext_operand->size;
2060 operand = ext_operand;
2063 if (operand->size == 26)
2064 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
2065 else if (ext_size == 16 || ext_size == 9)
2066 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2067 else if (ext_size == 15)
2068 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2069 else if (ext_size == 6)
2070 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2072 uval = mips_extract_operand (operand, (extend << 16) | insn);
2074 uval &= (1U << ext_size) - 1;
2076 baseaddr = memaddr + 2;
2077 if (operand->type == OP_PCREL)
2079 const struct mips_pcrel_operand *pcrel_op;
2081 pcrel_op = (const struct mips_pcrel_operand *) operand;
2082 if (!pcrel_op->include_isa_bit && use_extend)
2083 baseaddr = memaddr - 2;
2084 else if (!pcrel_op->include_isa_bit)
2088 /* If this instruction is in the delay slot of a JAL/JALX
2089 instruction, the base address is the address of the
2090 JAL/JALX instruction. If it is in the delay slot of
2091 a JR/JALR instruction, the base address is the address
2092 of the JR/JALR instruction. This test is unreliable:
2093 we have no way of knowing whether the previous word is
2094 instruction or data. */
2095 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2096 && (((info->endian == BFD_ENDIAN_BIG
2097 ? bfd_getb16 (buffer)
2098 : bfd_getl16 (buffer))
2099 & 0xf800) == 0x1800))
2100 baseaddr = memaddr - 4;
2101 else if (info->read_memory_func (memaddr - 2, buffer, 2,
2103 && (((info->endian == BFD_ENDIAN_BIG
2104 ? bfd_getb16 (buffer)
2105 : bfd_getl16 (buffer))
2106 & 0xf89f) == 0xe800)
2107 && (((info->endian == BFD_ENDIAN_BIG
2108 ? bfd_getb16 (buffer)
2109 : bfd_getl16 (buffer))
2110 & 0x0060) != 0x0060))
2111 baseaddr = memaddr - 2;
2117 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
2123 /* Check if the given address is the last word of a MIPS16 PLT entry.
2124 This word is data and depending on the value it may interfere with
2125 disassembly of further PLT entries. We make use of the fact PLT
2126 symbols are marked BSF_SYNTHETIC. */
2128 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2132 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2133 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2139 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2148 /* Disassemble mips16 instructions. */
2151 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2153 const fprintf_ftype infprintf = info->fprintf_func;
2156 const struct mips_opcode *op, *opend;
2157 struct mips_print_arg_state state;
2158 void *is = info->stream;
2159 bfd_boolean have_second;
2160 bfd_boolean extend_only;
2161 unsigned int second;
2165 info->bytes_per_chunk = 2;
2166 info->display_endian = info->endian;
2167 info->insn_info_valid = 1;
2168 info->branch_delay_insns = 0;
2169 info->data_size = 0;
2173 #define GET_OP(insn, field) \
2174 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2175 /* Decode PLT entry's GOT slot address word. */
2176 if (is_mips16_plt_tail (info, memaddr))
2178 info->insn_type = dis_noninsn;
2179 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2182 unsigned int gotslot;
2184 if (info->endian == BFD_ENDIAN_BIG)
2185 gotslot = bfd_getb32 (buffer);
2187 gotslot = bfd_getl32 (buffer);
2188 infprintf (is, ".word\t0x%x", gotslot);
2195 info->insn_type = dis_nonbranch;
2196 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2200 (*info->memory_error_func) (status, memaddr, info);
2204 extend_only = FALSE;
2206 if (info->endian == BFD_ENDIAN_BIG)
2207 first = bfd_getb16 (buffer);
2209 first = bfd_getl16 (buffer);
2211 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2215 if (info->endian == BFD_ENDIAN_BIG)
2216 second = bfd_getb16 (buffer);
2218 second = bfd_getl16 (buffer);
2219 full = (first << 16) | second;
2223 have_second = FALSE;
2228 /* FIXME: Should probably use a hash table on the major opcode here. */
2230 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2231 for (op = mips16_opcodes; op < opend; op++)
2233 enum match_kind match;
2235 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2238 if (op->pinfo == INSN_MACRO
2239 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2241 else if (mips_opcode_32bit_p (op))
2244 && (full & op->mask) == op->match)
2249 else if ((first & op->mask) == op->match)
2251 match = MATCH_SHORT;
2255 else if ((first & 0xf800) == 0xf000
2258 && (second & op->mask) == op->match)
2260 if (op->pinfo2 & INSN2_SHORT_ONLY)
2271 if (match != MATCH_NONE)
2275 infprintf (is, "%s", op->name);
2276 if (op->args[0] != '\0')
2277 infprintf (is, "\t");
2279 init_print_arg_state (&state);
2280 for (s = op->args; *s != '\0'; s++)
2284 && GET_OP (full, RX) == GET_OP (full, RY))
2286 /* Skip the register and the comma. */
2292 && GET_OP (full, RZ) == GET_OP (full, RX))
2294 /* Skip the register and the comma. */
2301 && op->name[strlen (op->name) - 1] == '0')
2303 /* Coprocessor register 0 with sel field. */
2304 const struct mips_cp0sel_name *n;
2305 const struct mips_operand *operand;
2306 unsigned int reg, sel;
2308 operand = decode_mips16_operand (*s, TRUE);
2309 reg = mips_extract_operand (operand, (first << 16) | second);
2311 operand = decode_mips16_operand (*s, TRUE);
2312 sel = mips_extract_operand (operand, (first << 16) | second);
2314 /* CP0 register including 'sel' code for mftc0, to be
2315 printed textually if known. If not known, print both
2316 CP0 register name and sel numerically since CP0 register
2317 with sel 0 may have a name unrelated to register being
2319 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2320 mips_cp0sel_names_len,
2323 infprintf (is, "%s", n->name);
2325 infprintf (is, "$%d,%d", reg, sel);
2331 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2332 second, TRUE, first, s[1] == '(');
2335 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2336 first, FALSE, 0, s[1] == '(');
2338 case MATCH_NONE: /* Stop the compiler complaining. */
2343 /* Figure out branch instruction type and delay slot information. */
2344 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2345 info->branch_delay_insns = 1;
2346 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2347 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2349 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2350 info->insn_type = dis_jsr;
2352 info->insn_type = dis_branch;
2354 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2355 info->insn_type = dis_condbranch;
2357 return match == MATCH_FULL ? 4 : 2;
2362 infprintf (is, "0x%x", first);
2363 info->insn_type = dis_noninsn;
2368 /* Disassemble microMIPS instructions. */
2371 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2373 const fprintf_ftype infprintf = info->fprintf_func;
2374 const struct mips_opcode *op, *opend;
2375 void *is = info->stream;
2377 unsigned int higher;
2378 unsigned int length;
2382 info->bytes_per_chunk = 2;
2383 info->display_endian = info->endian;
2384 info->insn_info_valid = 1;
2385 info->branch_delay_insns = 0;
2386 info->data_size = 0;
2387 info->insn_type = dis_nonbranch;
2391 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2394 (*info->memory_error_func) (status, memaddr, info);
2400 if (info->endian == BFD_ENDIAN_BIG)
2401 insn = bfd_getb16 (buffer);
2403 insn = bfd_getl16 (buffer);
2405 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2407 /* This is a 32-bit microMIPS instruction. */
2410 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2413 infprintf (is, "micromips 0x%x", higher);
2414 (*info->memory_error_func) (status, memaddr + 2, info);
2418 if (info->endian == BFD_ENDIAN_BIG)
2419 insn = bfd_getb16 (buffer);
2421 insn = bfd_getl16 (buffer);
2423 insn = insn | (higher << 16);
2428 /* FIXME: Should probably use a hash table on the major opcode here. */
2430 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2431 for (op = micromips_opcodes; op < opend; op++)
2433 if (op->pinfo != INSN_MACRO
2434 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2435 && (insn & op->mask) == op->match
2436 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2437 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2439 if (!validate_insn_args (op, decode_micromips_operand, insn))
2442 infprintf (is, "%s", op->name);
2446 infprintf (is, "\t");
2447 print_insn_args (info, op, decode_micromips_operand, insn,
2448 memaddr + 1, length);
2451 /* Figure out instruction type and branch delay information. */
2453 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2454 info->branch_delay_insns = 1;
2455 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2456 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2458 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2459 info->insn_type = dis_jsr;
2461 info->insn_type = dis_branch;
2463 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2464 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2466 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2467 info->insn_type = dis_condjsr;
2469 info->insn_type = dis_condbranch;
2472 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2473 info->insn_type = dis_dref;
2479 infprintf (is, "0x%x", insn);
2480 info->insn_type = dis_noninsn;
2485 /* Return 1 if a symbol associated with the location being disassembled
2486 indicates a compressed mode, either MIPS16 or microMIPS, according to
2487 MICROMIPS_P. We iterate over all the symbols at the address being
2488 considered assuming if at least one of them indicates code compression,
2489 then such code has been genuinely produced here (other symbols could
2490 have been derived from function symbols defined elsewhere or could
2491 define data). Otherwise, return 0. */
2494 is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
2499 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2500 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2502 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2504 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2506 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2507 && info->symtab[i]->section == info->section)
2509 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2511 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2513 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2520 /* In an environment where we do not know the symbol type of the
2521 instruction we are forced to assume that the low order bit of the
2522 instructions' address may mark it as a mips16 instruction. If we
2523 are single stepping, or the pc is within the disassembled function,
2524 this works. Otherwise, we need a clue. Sometimes. */
2527 _print_insn_mips (bfd_vma memaddr,
2528 struct disassemble_info *info,
2529 enum bfd_endian endianness)
2531 bfd_byte buffer[INSNLEN];
2534 set_default_mips_dis_options (info);
2535 parse_mips_dis_options (info->disassembler_options);
2537 if (info->mach == bfd_mach_mips16)
2538 return print_insn_mips16 (memaddr, info);
2539 if (info->mach == bfd_mach_mips_micromips)
2540 return print_insn_micromips (memaddr, info);
2543 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2544 /* Only a few tools will work this way. */
2548 return print_insn_micromips (memaddr, info);
2550 return print_insn_mips16 (memaddr, info);
2554 #if SYMTAB_AVAILABLE
2555 if (is_compressed_mode_p (info, TRUE))
2556 return print_insn_micromips (memaddr, info);
2557 if (is_compressed_mode_p (info, FALSE))
2558 return print_insn_mips16 (memaddr, info);
2561 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2566 if (endianness == BFD_ENDIAN_BIG)
2567 insn = bfd_getb32 (buffer);
2569 insn = bfd_getl32 (buffer);
2571 return print_insn_mips (memaddr, insn, info);
2575 (*info->memory_error_func) (status, memaddr, info);
2581 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2583 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2587 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2589 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2592 /* Indices into option argument vector for options accepting an argument.
2593 Use MIPS_OPTION_ARG_NONE for options accepting no argument. */
2596 MIPS_OPTION_ARG_NONE = -1,
2597 MIPS_OPTION_ARG_ABI,
2598 MIPS_OPTION_ARG_ARCH,
2599 MIPS_OPTION_ARG_SIZE
2600 } mips_option_arg_t;
2602 /* Valid MIPS disassembler options. */
2606 const char *description;
2607 mips_option_arg_t arg;
2610 { "no-aliases", N_("Use canonical instruction forms.\n"),
2611 MIPS_OPTION_ARG_NONE },
2612 { "msa", N_("Recognize MSA instructions.\n"),
2613 MIPS_OPTION_ARG_NONE },
2614 { "virt", N_("Recognize the virtualization ASE instructions.\n"),
2615 MIPS_OPTION_ARG_NONE },
2616 { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\
2618 MIPS_OPTION_ARG_NONE },
2619 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2621 MIPS_OPTION_ARG_NONE },
2623 N_("Recognize the Loongson MultiMedia extensions "
2624 "Instructions (MMI) ASE instructions.\n"),
2625 MIPS_OPTION_ARG_NONE },
2627 N_("Recognize the Loongson Content Address Memory (CAM) "
2628 " instructions.\n"),
2629 MIPS_OPTION_ARG_NONE },
2631 N_("Recognize the Loongson EXTensions (EXT) "
2632 " instructions.\n"),
2633 MIPS_OPTION_ARG_NONE },
2635 N_("Recognize the Loongson EXTensions R2 (EXT2) "
2636 " instructions.\n"),
2637 MIPS_OPTION_ARG_NONE },
2638 { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
2639 Default: based on binary being disassembled.\n"),
2640 MIPS_OPTION_ARG_ABI },
2641 { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
2642 Default: numeric.\n"),
2643 MIPS_OPTION_ARG_ABI },
2644 { "cp0-names=", N_("Print CP0 register names according to specified "
2646 Default: based on binary being disassembled.\n"),
2647 MIPS_OPTION_ARG_ARCH },
2648 { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
2649 Default: based on binary being disassembled.\n"),
2650 MIPS_OPTION_ARG_ARCH },
2651 { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
2652 MIPS_OPTION_ARG_ABI },
2653 { "reg-names=", N_("Print CP0 register and HWR names according to "
2656 MIPS_OPTION_ARG_ARCH }
2659 /* Build the structure representing valid MIPS disassembler options.
2660 This is done dynamically for maintenance ease purpose; a static
2661 initializer would be unreadable. */
2663 const disasm_options_and_args_t *
2664 disassembler_options_mips (void)
2666 static disasm_options_and_args_t *opts_and_args;
2668 if (opts_and_args == NULL)
2670 size_t num_options = ARRAY_SIZE (mips_options);
2671 size_t num_args = MIPS_OPTION_ARG_SIZE;
2672 disasm_option_arg_t *args;
2673 disasm_options_t *opts;
2677 args = XNEWVEC (disasm_option_arg_t, num_args + 1);
2679 args[MIPS_OPTION_ARG_ABI].name = "ABI";
2680 args[MIPS_OPTION_ARG_ABI].values
2681 = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1);
2682 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2683 args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name;
2684 /* The array we return must be NULL terminated. */
2685 args[MIPS_OPTION_ARG_ABI].values[i] = NULL;
2687 args[MIPS_OPTION_ARG_ARCH].name = "ARCH";
2688 args[MIPS_OPTION_ARG_ARCH].values
2689 = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1);
2690 for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2691 if (*mips_arch_choices[i].name != '\0')
2692 args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name;
2693 /* The array we return must be NULL terminated. */
2694 args[MIPS_OPTION_ARG_ARCH].values[j] = NULL;
2696 /* The array we return must be NULL terminated. */
2697 args[MIPS_OPTION_ARG_SIZE].name = NULL;
2698 args[MIPS_OPTION_ARG_SIZE].values = NULL;
2700 opts_and_args = XNEW (disasm_options_and_args_t);
2701 opts_and_args->args = args;
2703 opts = &opts_and_args->options;
2704 opts->name = XNEWVEC (const char *, num_options + 1);
2705 opts->description = XNEWVEC (const char *, num_options + 1);
2706 opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
2707 for (i = 0; i < num_options; i++)
2709 opts->name[i] = mips_options[i].name;
2710 opts->description[i] = _(mips_options[i].description);
2711 if (mips_options[i].arg != MIPS_OPTION_ARG_NONE)
2712 opts->arg[i] = &args[mips_options[i].arg];
2714 opts->arg[i] = NULL;
2716 /* The array we return must be NULL terminated. */
2717 opts->name[i] = NULL;
2718 opts->description[i] = NULL;
2719 opts->arg[i] = NULL;
2722 return opts_and_args;
2726 print_mips_disassembler_options (FILE *stream)
2728 const disasm_options_and_args_t *opts_and_args;
2729 const disasm_option_arg_t *args;
2730 const disasm_options_t *opts;
2735 opts_and_args = disassembler_options_mips ();
2736 opts = &opts_and_args->options;
2737 args = opts_and_args->args;
2739 fprintf (stream, _("\n\
2740 The following MIPS specific disassembler options are supported for use\n\
2741 with the -M switch (multiple options should be separated by commas):\n\n"));
2743 /* Compute the length of the longest option name. */
2744 for (i = 0; opts->name[i] != NULL; i++)
2746 size_t len = strlen (opts->name[i]);
2748 if (opts->arg[i] != NULL)
2749 len += strlen (opts->arg[i]->name);
2754 for (i = 0, max_len++; opts->name[i] != NULL; i++)
2756 fprintf (stream, " %s", opts->name[i]);
2757 if (opts->arg[i] != NULL)
2758 fprintf (stream, "%s", opts->arg[i]->name);
2759 if (opts->description[i] != NULL)
2761 size_t len = strlen (opts->name[i]);
2763 if (opts->arg[i] != NULL)
2764 len += strlen (opts->arg[i]->name);
2766 "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
2768 fprintf (stream, _("\n"));
2771 for (i = 0; args[i].name != NULL; i++)
2773 fprintf (stream, _("\n\
2774 For the options above, the following values are supported for \"%s\":\n "),
2776 for (j = 0; args[i].values[j] != NULL; j++)
2777 fprintf (stream, " %s", args[i].values[j]);
2778 fprintf (stream, _("\n"));
2781 fprintf (stream, _("\n"));