1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2015 Free Software Foundation, Inc.
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. */
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 struct mips_cp0sel_name mips_cp0sel_names_mipsr5900[] =
163 { 24, 3, "c0_iabm" },
165 { 24, 5, "c0_dabm" },
167 { 24, 7, "c0_dvbm" },
168 { 25, 1, "c0_perfcnt,1" },
169 { 25, 2, "c0_perfcnt,2" }
172 static const char * const mips_cp0_names_mips3264[32] =
174 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
175 "c0_context", "c0_pagemask", "c0_wired", "$7",
176 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
177 "c0_status", "c0_cause", "c0_epc", "c0_prid",
178 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
179 "c0_xcontext", "$21", "$22", "c0_debug",
180 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
181 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
184 static const char * const mips_cp1_names_mips3264[32] =
186 "c1_fir", "c1_ufr", "$2", "$3",
187 "c1_unfr", "$5", "$6", "$7",
188 "$8", "$9", "$10", "$11",
189 "$12", "$13", "$14", "$15",
190 "$16", "$17", "$18", "$19",
191 "$20", "$21", "$22", "$23",
192 "$24", "c1_fccr", "c1_fexr", "$27",
193 "c1_fenr", "$29", "$30", "c1_fcsr"
196 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
198 { 16, 1, "c0_config1" },
199 { 16, 2, "c0_config2" },
200 { 16, 3, "c0_config3" },
201 { 18, 1, "c0_watchlo,1" },
202 { 18, 2, "c0_watchlo,2" },
203 { 18, 3, "c0_watchlo,3" },
204 { 18, 4, "c0_watchlo,4" },
205 { 18, 5, "c0_watchlo,5" },
206 { 18, 6, "c0_watchlo,6" },
207 { 18, 7, "c0_watchlo,7" },
208 { 19, 1, "c0_watchhi,1" },
209 { 19, 2, "c0_watchhi,2" },
210 { 19, 3, "c0_watchhi,3" },
211 { 19, 4, "c0_watchhi,4" },
212 { 19, 5, "c0_watchhi,5" },
213 { 19, 6, "c0_watchhi,6" },
214 { 19, 7, "c0_watchhi,7" },
215 { 25, 1, "c0_perfcnt,1" },
216 { 25, 2, "c0_perfcnt,2" },
217 { 25, 3, "c0_perfcnt,3" },
218 { 25, 4, "c0_perfcnt,4" },
219 { 25, 5, "c0_perfcnt,5" },
220 { 25, 6, "c0_perfcnt,6" },
221 { 25, 7, "c0_perfcnt,7" },
222 { 27, 1, "c0_cacheerr,1" },
223 { 27, 2, "c0_cacheerr,2" },
224 { 27, 3, "c0_cacheerr,3" },
225 { 28, 1, "c0_datalo" },
226 { 29, 1, "c0_datahi" }
229 static const char * const mips_cp0_names_mips3264r2[32] =
231 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
232 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
233 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
234 "c0_status", "c0_cause", "c0_epc", "c0_prid",
235 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
236 "c0_xcontext", "$21", "$22", "c0_debug",
237 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
238 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
241 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
243 { 4, 1, "c0_contextconfig" },
244 { 0, 1, "c0_mvpcontrol" },
245 { 0, 2, "c0_mvpconf0" },
246 { 0, 3, "c0_mvpconf1" },
247 { 1, 1, "c0_vpecontrol" },
248 { 1, 2, "c0_vpeconf0" },
249 { 1, 3, "c0_vpeconf1" },
250 { 1, 4, "c0_yqmask" },
251 { 1, 5, "c0_vpeschedule" },
252 { 1, 6, "c0_vpeschefback" },
253 { 2, 1, "c0_tcstatus" },
254 { 2, 2, "c0_tcbind" },
255 { 2, 3, "c0_tcrestart" },
256 { 2, 4, "c0_tchalt" },
257 { 2, 5, "c0_tccontext" },
258 { 2, 6, "c0_tcschedule" },
259 { 2, 7, "c0_tcschefback" },
260 { 5, 1, "c0_pagegrain" },
261 { 6, 1, "c0_srsconf0" },
262 { 6, 2, "c0_srsconf1" },
263 { 6, 3, "c0_srsconf2" },
264 { 6, 4, "c0_srsconf3" },
265 { 6, 5, "c0_srsconf4" },
266 { 12, 1, "c0_intctl" },
267 { 12, 2, "c0_srsctl" },
268 { 12, 3, "c0_srsmap" },
269 { 15, 1, "c0_ebase" },
270 { 16, 1, "c0_config1" },
271 { 16, 2, "c0_config2" },
272 { 16, 3, "c0_config3" },
273 { 18, 1, "c0_watchlo,1" },
274 { 18, 2, "c0_watchlo,2" },
275 { 18, 3, "c0_watchlo,3" },
276 { 18, 4, "c0_watchlo,4" },
277 { 18, 5, "c0_watchlo,5" },
278 { 18, 6, "c0_watchlo,6" },
279 { 18, 7, "c0_watchlo,7" },
280 { 19, 1, "c0_watchhi,1" },
281 { 19, 2, "c0_watchhi,2" },
282 { 19, 3, "c0_watchhi,3" },
283 { 19, 4, "c0_watchhi,4" },
284 { 19, 5, "c0_watchhi,5" },
285 { 19, 6, "c0_watchhi,6" },
286 { 19, 7, "c0_watchhi,7" },
287 { 23, 1, "c0_tracecontrol" },
288 { 23, 2, "c0_tracecontrol2" },
289 { 23, 3, "c0_usertracedata" },
290 { 23, 4, "c0_tracebpc" },
291 { 25, 1, "c0_perfcnt,1" },
292 { 25, 2, "c0_perfcnt,2" },
293 { 25, 3, "c0_perfcnt,3" },
294 { 25, 4, "c0_perfcnt,4" },
295 { 25, 5, "c0_perfcnt,5" },
296 { 25, 6, "c0_perfcnt,6" },
297 { 25, 7, "c0_perfcnt,7" },
298 { 27, 1, "c0_cacheerr,1" },
299 { 27, 2, "c0_cacheerr,2" },
300 { 27, 3, "c0_cacheerr,3" },
301 { 28, 1, "c0_datalo" },
302 { 28, 2, "c0_taglo1" },
303 { 28, 3, "c0_datalo1" },
304 { 28, 4, "c0_taglo2" },
305 { 28, 5, "c0_datalo2" },
306 { 28, 6, "c0_taglo3" },
307 { 28, 7, "c0_datalo3" },
308 { 29, 1, "c0_datahi" },
309 { 29, 2, "c0_taghi1" },
310 { 29, 3, "c0_datahi1" },
311 { 29, 4, "c0_taghi2" },
312 { 29, 5, "c0_datahi2" },
313 { 29, 6, "c0_taghi3" },
314 { 29, 7, "c0_datahi3" },
317 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
318 static const char * const mips_cp0_names_sb1[32] =
320 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
321 "c0_context", "c0_pagemask", "c0_wired", "$7",
322 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
323 "c0_status", "c0_cause", "c0_epc", "c0_prid",
324 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
325 "c0_xcontext", "$21", "$22", "c0_debug",
326 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
327 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
330 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
332 { 16, 1, "c0_config1" },
333 { 18, 1, "c0_watchlo,1" },
334 { 19, 1, "c0_watchhi,1" },
335 { 22, 0, "c0_perftrace" },
336 { 23, 3, "c0_edebug" },
337 { 25, 1, "c0_perfcnt,1" },
338 { 25, 2, "c0_perfcnt,2" },
339 { 25, 3, "c0_perfcnt,3" },
340 { 25, 4, "c0_perfcnt,4" },
341 { 25, 5, "c0_perfcnt,5" },
342 { 25, 6, "c0_perfcnt,6" },
343 { 25, 7, "c0_perfcnt,7" },
344 { 26, 1, "c0_buserr_pa" },
345 { 27, 1, "c0_cacheerr_d" },
346 { 27, 3, "c0_cacheerr_d_pa" },
347 { 28, 1, "c0_datalo_i" },
348 { 28, 2, "c0_taglo_d" },
349 { 28, 3, "c0_datalo_d" },
350 { 29, 1, "c0_datahi_i" },
351 { 29, 2, "c0_taghi_d" },
352 { 29, 3, "c0_datahi_d" },
355 /* Xlr cop0 register names. */
356 static const char * const mips_cp0_names_xlr[32] = {
357 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
358 "c0_context", "c0_pagemask", "c0_wired", "$7",
359 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
360 "c0_status", "c0_cause", "c0_epc", "c0_prid",
361 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
362 "c0_xcontext", "$21", "$22", "c0_debug",
363 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
364 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
367 /* XLR's CP0 Select Registers. */
369 static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
370 { 9, 6, "c0_extintreq" },
371 { 9, 7, "c0_extintmask" },
372 { 15, 1, "c0_ebase" },
373 { 16, 1, "c0_config1" },
374 { 16, 2, "c0_config2" },
375 { 16, 3, "c0_config3" },
376 { 16, 7, "c0_procid2" },
377 { 18, 1, "c0_watchlo,1" },
378 { 18, 2, "c0_watchlo,2" },
379 { 18, 3, "c0_watchlo,3" },
380 { 18, 4, "c0_watchlo,4" },
381 { 18, 5, "c0_watchlo,5" },
382 { 18, 6, "c0_watchlo,6" },
383 { 18, 7, "c0_watchlo,7" },
384 { 19, 1, "c0_watchhi,1" },
385 { 19, 2, "c0_watchhi,2" },
386 { 19, 3, "c0_watchhi,3" },
387 { 19, 4, "c0_watchhi,4" },
388 { 19, 5, "c0_watchhi,5" },
389 { 19, 6, "c0_watchhi,6" },
390 { 19, 7, "c0_watchhi,7" },
391 { 25, 1, "c0_perfcnt,1" },
392 { 25, 2, "c0_perfcnt,2" },
393 { 25, 3, "c0_perfcnt,3" },
394 { 25, 4, "c0_perfcnt,4" },
395 { 25, 5, "c0_perfcnt,5" },
396 { 25, 6, "c0_perfcnt,6" },
397 { 25, 7, "c0_perfcnt,7" },
398 { 27, 1, "c0_cacheerr,1" },
399 { 27, 2, "c0_cacheerr,2" },
400 { 27, 3, "c0_cacheerr,3" },
401 { 28, 1, "c0_datalo" },
402 { 29, 1, "c0_datahi" }
405 static const char * const mips_hwr_names_numeric[32] =
407 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
408 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
409 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
410 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
413 static const char * const mips_hwr_names_mips3264r2[32] =
415 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
416 "$4", "$5", "$6", "$7",
417 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
418 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
419 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
422 static const char * const msa_control_names[32] =
424 "msa_ir", "msa_csr", "msa_access", "msa_save",
425 "msa_modify", "msa_request", "msa_map", "msa_unmap",
426 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
427 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
428 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
431 struct mips_abi_choice
434 const char * const *gpr_names;
435 const char * const *fpr_names;
438 struct mips_abi_choice mips_abi_choices[] =
440 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
441 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
442 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
443 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
446 struct mips_arch_choice
450 unsigned long bfd_mach;
454 const char * const *cp0_names;
455 const struct mips_cp0sel_name *cp0sel_names;
456 unsigned int cp0sel_names_len;
457 const char * const *cp1_names;
458 const char * const *hwr_names;
461 const struct mips_arch_choice mips_arch_choices[] =
463 { "numeric", 0, 0, 0, 0, 0,
464 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
465 mips_hwr_names_numeric },
467 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
468 mips_cp0_names_r3000, NULL, 0, mips_cp1_names_numeric,
469 mips_hwr_names_numeric },
470 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
471 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
472 mips_hwr_names_numeric },
473 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
474 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
475 mips_hwr_names_numeric },
476 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
477 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
478 mips_hwr_names_numeric },
479 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
480 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
481 mips_hwr_names_numeric },
482 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
483 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
484 mips_hwr_names_numeric },
485 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
486 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
487 mips_hwr_names_numeric },
488 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
489 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
490 mips_hwr_names_numeric },
491 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
492 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
493 mips_hwr_names_numeric },
494 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
495 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
496 mips_hwr_names_numeric },
497 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
498 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
499 mips_hwr_names_numeric },
500 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
501 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
502 mips_hwr_names_numeric },
503 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
504 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
505 mips_hwr_names_numeric },
506 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
507 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
508 mips_hwr_names_numeric },
509 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
510 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_numeric,
511 mips_hwr_names_numeric },
512 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
513 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
514 mips_hwr_names_numeric },
515 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
516 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
517 mips_hwr_names_numeric },
518 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
519 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
520 mips_hwr_names_numeric },
521 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
522 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
523 mips_hwr_names_numeric },
524 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
525 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
526 mips_hwr_names_numeric },
527 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
528 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
529 mips_hwr_names_numeric },
530 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
531 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
532 mips_hwr_names_numeric },
533 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
534 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
535 mips_hwr_names_numeric },
536 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
537 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
538 mips_hwr_names_numeric },
540 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
541 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
542 _MIPS32 Architecture For Programmers Volume I: Introduction to the
543 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
545 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
546 ISA_MIPS32, ASE_SMARTMIPS,
547 mips_cp0_names_mips3264,
548 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
549 mips_cp1_names_mips3264, mips_hwr_names_numeric },
551 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
553 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
554 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
555 mips_cp0_names_mips3264r2,
556 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
557 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
559 { "mips32r3", 1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
561 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
562 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
563 mips_cp0_names_mips3264r2,
564 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
565 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
567 { "mips32r5", 1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
569 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
570 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
571 mips_cp0_names_mips3264r2,
572 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
573 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
575 { "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
577 (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
579 mips_cp0_names_mips3264r2,
580 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
581 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
583 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
584 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
585 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
586 mips_cp0_names_mips3264,
587 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
588 mips_cp1_names_mips3264, mips_hwr_names_numeric },
590 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
592 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
593 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
594 mips_cp0_names_mips3264r2,
595 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
596 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
598 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
600 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
601 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
602 mips_cp0_names_mips3264r2,
603 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
604 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
606 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
608 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
609 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
610 mips_cp0_names_mips3264r2,
611 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
612 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
614 { "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
616 (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
617 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2),
618 mips_cp0_names_mips3264r2,
619 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
620 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
622 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
623 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
625 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
626 mips_cp1_names_mips3264, mips_hwr_names_numeric },
628 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
629 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
630 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
632 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
633 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
634 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
636 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
637 ISA_MIPS64R2 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
638 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
640 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
641 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
642 mips_cp1_names_mips3264, mips_hwr_names_numeric },
644 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
645 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
646 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
648 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
649 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
650 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
652 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
653 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
654 mips_cp0_names_numeric,
655 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
657 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
658 ISA_MIPS64 | INSN_XLR, 0,
660 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
661 mips_cp1_names_mips3264, mips_hwr_names_numeric },
663 /* XLP is mostly like XLR, with the prominent exception it is being
665 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
666 ISA_MIPS64R2 | INSN_XLR, 0,
668 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
669 mips_cp1_names_mips3264, mips_hwr_names_numeric },
671 /* This entry, mips16, is here only for ISA/processor selection; do
672 not print its name. */
673 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0,
674 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
675 mips_hwr_names_numeric },
678 /* ISA and processor type to disassemble for, and register names to use.
679 set_default_mips_dis_options and parse_mips_dis_options fill in these
681 static int mips_processor;
684 static int micromips_ase;
685 static const char * const *mips_gpr_names;
686 static const char * const *mips_fpr_names;
687 static const char * const *mips_cp0_names;
688 static const struct mips_cp0sel_name *mips_cp0sel_names;
689 static int mips_cp0sel_names_len;
690 static const char * const *mips_cp1_names;
691 static const char * const *mips_hwr_names;
694 static int no_aliases; /* If set disassemble as most general inst. */
696 static const struct mips_abi_choice *
697 choose_abi_by_name (const char *name, unsigned int namelen)
699 const struct mips_abi_choice *c;
702 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
703 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
704 && strlen (mips_abi_choices[i].name) == namelen)
705 c = &mips_abi_choices[i];
710 static const struct mips_arch_choice *
711 choose_arch_by_name (const char *name, unsigned int namelen)
713 const struct mips_arch_choice *c = NULL;
716 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
717 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
718 && strlen (mips_arch_choices[i].name) == namelen)
719 c = &mips_arch_choices[i];
724 static const struct mips_arch_choice *
725 choose_arch_by_number (unsigned long mach)
727 static unsigned long hint_bfd_mach;
728 static const struct mips_arch_choice *hint_arch_choice;
729 const struct mips_arch_choice *c;
732 /* We optimize this because even if the user specifies no
733 flags, this will be done for every instruction! */
734 if (hint_bfd_mach == mach
735 && hint_arch_choice != NULL
736 && hint_arch_choice->bfd_mach == hint_bfd_mach)
737 return hint_arch_choice;
739 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
741 if (mips_arch_choices[i].bfd_mach_valid
742 && mips_arch_choices[i].bfd_mach == mach)
744 c = &mips_arch_choices[i];
745 hint_bfd_mach = mach;
746 hint_arch_choice = c;
752 /* Check if the object uses NewABI conventions. */
755 is_newabi (Elf_Internal_Ehdr *header)
757 /* There are no old-style ABIs which use 64-bit ELF. */
758 if (header->e_ident[EI_CLASS] == ELFCLASS64)
761 /* If a 32-bit ELF file, n32 is a new-style ABI. */
762 if ((header->e_flags & EF_MIPS_ABI2) != 0)
768 /* Check if the object has microMIPS ASE code. */
771 is_micromips (Elf_Internal_Ehdr *header)
773 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
780 set_default_mips_dis_options (struct disassemble_info *info)
782 const struct mips_arch_choice *chosen_arch;
784 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
785 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
786 CP0 register, and HWR names. */
787 mips_isa = ISA_MIPS3;
788 mips_processor = CPU_R3000;
791 mips_gpr_names = mips_gpr_names_oldabi;
792 mips_fpr_names = mips_fpr_names_numeric;
793 mips_cp0_names = mips_cp0_names_numeric;
794 mips_cp0sel_names = NULL;
795 mips_cp0sel_names_len = 0;
796 mips_cp1_names = mips_cp1_names_numeric;
797 mips_hwr_names = mips_hwr_names_numeric;
800 /* Update settings according to the ELF file header flags. */
801 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
803 Elf_Internal_Ehdr *header;
805 header = elf_elfheader (info->section->owner);
806 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
807 if (is_newabi (header))
808 mips_gpr_names = mips_gpr_names_newabi;
809 /* If a microMIPS binary, then don't use MIPS16 bindings. */
810 micromips_ase = is_micromips (header);
813 /* Set ISA, architecture, and cp0 register names as best we can. */
814 #if ! SYMTAB_AVAILABLE
815 /* This is running out on a target machine, not in a host tool.
816 FIXME: Where does mips_target_info come from? */
817 target_processor = mips_target_info.processor;
818 mips_isa = mips_target_info.isa;
819 mips_ase = mips_target_info.ase;
821 chosen_arch = choose_arch_by_number (info->mach);
822 if (chosen_arch != NULL)
824 mips_processor = chosen_arch->processor;
825 mips_isa = chosen_arch->isa;
826 mips_ase = chosen_arch->ase;
827 mips_cp0_names = chosen_arch->cp0_names;
828 mips_cp0sel_names = chosen_arch->cp0sel_names;
829 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
830 mips_cp1_names = chosen_arch->cp1_names;
831 mips_hwr_names = chosen_arch->hwr_names;
837 parse_mips_dis_option (const char *option, unsigned int len)
839 unsigned int i, optionlen, vallen;
841 const struct mips_abi_choice *chosen_abi;
842 const struct mips_arch_choice *chosen_arch;
844 /* Try to match options that are simple flags */
845 if (CONST_STRNEQ (option, "no-aliases"))
851 if (CONST_STRNEQ (option, "msa"))
854 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
855 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
856 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
857 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
858 mips_ase |= ASE_MSA64;
862 if (CONST_STRNEQ (option, "virt"))
864 mips_ase |= ASE_VIRT;
865 if (mips_isa & ISA_MIPS64R2
866 || mips_isa & ISA_MIPS64R3
867 || mips_isa & ISA_MIPS64R5
868 || mips_isa & ISA_MIPS64R6)
869 mips_ase |= ASE_VIRT64;
873 if (CONST_STRNEQ (option, "xpa"))
880 /* Look for the = that delimits the end of the option name. */
881 for (i = 0; i < len; i++)
882 if (option[i] == '=')
885 if (i == 0) /* Invalid option: no name before '='. */
887 if (i == len) /* Invalid option: no '='. */
889 if (i == (len - 1)) /* Invalid option: no value after '='. */
893 val = option + (optionlen + 1);
894 vallen = len - (optionlen + 1);
896 if (strncmp ("gpr-names", option, optionlen) == 0
897 && strlen ("gpr-names") == optionlen)
899 chosen_abi = choose_abi_by_name (val, vallen);
900 if (chosen_abi != NULL)
901 mips_gpr_names = chosen_abi->gpr_names;
905 if (strncmp ("fpr-names", option, optionlen) == 0
906 && strlen ("fpr-names") == optionlen)
908 chosen_abi = choose_abi_by_name (val, vallen);
909 if (chosen_abi != NULL)
910 mips_fpr_names = chosen_abi->fpr_names;
914 if (strncmp ("cp0-names", option, optionlen) == 0
915 && strlen ("cp0-names") == optionlen)
917 chosen_arch = choose_arch_by_name (val, vallen);
918 if (chosen_arch != NULL)
920 mips_cp0_names = chosen_arch->cp0_names;
921 mips_cp0sel_names = chosen_arch->cp0sel_names;
922 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
927 if (strncmp ("cp1-names", option, optionlen) == 0
928 && strlen ("cp1-names") == optionlen)
930 chosen_arch = choose_arch_by_name (val, vallen);
931 if (chosen_arch != NULL)
932 mips_cp1_names = chosen_arch->cp1_names;
936 if (strncmp ("hwr-names", option, optionlen) == 0
937 && strlen ("hwr-names") == optionlen)
939 chosen_arch = choose_arch_by_name (val, vallen);
940 if (chosen_arch != NULL)
941 mips_hwr_names = chosen_arch->hwr_names;
945 if (strncmp ("reg-names", option, optionlen) == 0
946 && strlen ("reg-names") == optionlen)
948 /* We check both ABI and ARCH here unconditionally, so
949 that "numeric" will do the desirable thing: select
950 numeric register names for all registers. Other than
951 that, a given name probably won't match both. */
952 chosen_abi = choose_abi_by_name (val, vallen);
953 if (chosen_abi != NULL)
955 mips_gpr_names = chosen_abi->gpr_names;
956 mips_fpr_names = chosen_abi->fpr_names;
958 chosen_arch = choose_arch_by_name (val, vallen);
959 if (chosen_arch != NULL)
961 mips_cp0_names = chosen_arch->cp0_names;
962 mips_cp0sel_names = chosen_arch->cp0sel_names;
963 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
964 mips_cp1_names = chosen_arch->cp1_names;
965 mips_hwr_names = chosen_arch->hwr_names;
970 /* Invalid option. */
974 parse_mips_dis_options (const char *options)
976 const char *option_end;
981 while (*options != '\0')
983 /* Skip empty options. */
990 /* We know that *options is neither NUL or a comma. */
991 option_end = options + 1;
992 while (*option_end != ',' && *option_end != '\0')
995 parse_mips_dis_option (options, option_end - options);
997 /* Go on to the next one. If option_end points to a comma, it
998 will be skipped above. */
999 options = option_end;
1003 static const struct mips_cp0sel_name *
1004 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1006 unsigned int cp0reg,
1011 for (i = 0; i < len; i++)
1012 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1017 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1020 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1021 enum mips_reg_operand_type type, int regno)
1026 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1030 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1034 if (opcode->pinfo & (FP_D | FP_S))
1035 info->fprintf_func (info->stream, "$fcc%d", regno);
1037 info->fprintf_func (info->stream, "$cc%d", regno);
1041 if (opcode->membership & INSN_5400)
1042 info->fprintf_func (info->stream, "$f%d", regno);
1044 info->fprintf_func (info->stream, "$v%d", regno);
1048 info->fprintf_func (info->stream, "$ac%d", regno);
1052 if (opcode->name[strlen (opcode->name) - 1] == '0')
1053 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
1054 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1055 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
1057 info->fprintf_func (info->stream, "$%d", regno);
1061 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1065 info->fprintf_func (info->stream, "$vf%d", regno);
1069 info->fprintf_func (info->stream, "$vi%d", regno);
1072 case OP_REG_R5900_I:
1073 info->fprintf_func (info->stream, "$I");
1076 case OP_REG_R5900_Q:
1077 info->fprintf_func (info->stream, "$Q");
1080 case OP_REG_R5900_R:
1081 info->fprintf_func (info->stream, "$R");
1084 case OP_REG_R5900_ACC:
1085 info->fprintf_func (info->stream, "$ACC");
1089 info->fprintf_func (info->stream, "$w%d", regno);
1092 case OP_REG_MSA_CTRL:
1093 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1099 /* Used to track the state carried over from previous operands in
1101 struct mips_print_arg_state {
1102 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1103 where the value is known to be unsigned and small. */
1104 unsigned int last_int;
1106 /* The type and number of the last OP_REG seen. We only use this for
1107 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1108 enum mips_reg_operand_type last_reg_type;
1109 unsigned int last_regno;
1110 unsigned int dest_regno;
1111 unsigned int seen_dest;
1114 /* Initialize STATE for the start of an instruction. */
1117 init_print_arg_state (struct mips_print_arg_state *state)
1119 memset (state, 0, sizeof (*state));
1122 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1123 whose value is given by UVAL. */
1126 print_vu0_channel (struct disassemble_info *info,
1127 const struct mips_operand *operand, unsigned int uval)
1129 if (operand->size == 4)
1130 info->fprintf_func (info->stream, "%s%s%s%s",
1131 uval & 8 ? "x" : "",
1132 uval & 4 ? "y" : "",
1133 uval & 2 ? "z" : "",
1134 uval & 1 ? "w" : "");
1135 else if (operand->size == 2)
1136 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1141 /* Record information about a register operand. */
1144 mips_seen_register (struct mips_print_arg_state *state,
1146 enum mips_reg_operand_type reg_type)
1148 state->last_reg_type = reg_type;
1149 state->last_regno = regno;
1151 if (!state->seen_dest)
1153 state->seen_dest = 1;
1154 state->dest_regno = regno;
1158 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1159 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1160 the base address for OP_PCREL operands. */
1163 print_insn_arg (struct disassemble_info *info,
1164 struct mips_print_arg_state *state,
1165 const struct mips_opcode *opcode,
1166 const struct mips_operand *operand,
1170 const fprintf_ftype infprintf = info->fprintf_func;
1171 void *is = info->stream;
1173 switch (operand->type)
1177 const struct mips_int_operand *int_op;
1179 int_op = (const struct mips_int_operand *) operand;
1180 uval = mips_decode_int_operand (int_op, uval);
1181 state->last_int = uval;
1182 if (int_op->print_hex)
1183 infprintf (is, "0x%x", uval);
1185 infprintf (is, "%d", uval);
1191 const struct mips_mapped_int_operand *mint_op;
1193 mint_op = (const struct mips_mapped_int_operand *) operand;
1194 uval = mint_op->int_map[uval];
1195 state->last_int = uval;
1196 if (mint_op->print_hex)
1197 infprintf (is, "0x%x", uval);
1199 infprintf (is, "%d", uval);
1205 const struct mips_msb_operand *msb_op;
1207 msb_op = (const struct mips_msb_operand *) operand;
1208 uval += msb_op->bias;
1209 if (msb_op->add_lsb)
1210 uval -= state->last_int;
1211 infprintf (is, "0x%x", uval);
1216 case OP_OPTIONAL_REG:
1218 const struct mips_reg_operand *reg_op;
1220 reg_op = (const struct mips_reg_operand *) operand;
1221 uval = mips_decode_reg_operand (reg_op, uval);
1222 print_reg (info, opcode, reg_op->reg_type, uval);
1224 mips_seen_register (state, uval, reg_op->reg_type);
1230 const struct mips_reg_pair_operand *pair_op;
1232 pair_op = (const struct mips_reg_pair_operand *) operand;
1233 print_reg (info, opcode, pair_op->reg_type,
1234 pair_op->reg1_map[uval]);
1235 infprintf (is, ",");
1236 print_reg (info, opcode, pair_op->reg_type,
1237 pair_op->reg2_map[uval]);
1243 const struct mips_pcrel_operand *pcrel_op;
1245 pcrel_op = (const struct mips_pcrel_operand *) operand;
1246 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1248 /* Preserve the ISA bit for the GDB disassembler,
1249 otherwise clear it. */
1250 if (info->flavour != bfd_target_unknown_flavour)
1253 (*info->print_address_func) (info->target, info);
1258 infprintf (is, "%d", uval);
1261 case OP_ADDIUSP_INT:
1265 sval = mips_signed_operand (operand, uval) * 4;
1266 if (sval >= -8 && sval < 8)
1268 infprintf (is, "%d", sval);
1272 case OP_CLO_CLZ_DEST:
1274 unsigned int reg1, reg2;
1278 /* If one is zero use the other. */
1279 if (reg1 == reg2 || reg2 == 0)
1280 infprintf (is, "%s", mips_gpr_names[reg1]);
1282 infprintf (is, "%s", mips_gpr_names[reg2]);
1284 /* Bogus, result depends on processor. */
1285 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1286 mips_gpr_names[reg2]);
1292 case OP_NON_ZERO_REG:
1294 print_reg (info, opcode, OP_REG_GP, uval & 31);
1295 mips_seen_register (state, uval, OP_REG_GP);
1299 case OP_LWM_SWM_LIST:
1300 if (operand->size == 2)
1303 infprintf (is, "%s,%s",
1305 mips_gpr_names[31]);
1307 infprintf (is, "%s-%s,%s",
1309 mips_gpr_names[16 + uval],
1310 mips_gpr_names[31]);
1316 s_reg_encode = uval & 0xf;
1317 if (s_reg_encode != 0)
1319 if (s_reg_encode == 1)
1320 infprintf (is, "%s", mips_gpr_names[16]);
1321 else if (s_reg_encode < 9)
1322 infprintf (is, "%s-%s",
1324 mips_gpr_names[15 + s_reg_encode]);
1325 else if (s_reg_encode == 9)
1326 infprintf (is, "%s-%s,%s",
1329 mips_gpr_names[30]);
1331 infprintf (is, "UNKNOWN");
1334 if (uval & 0x10) /* For ra. */
1336 if (s_reg_encode == 0)
1337 infprintf (is, "%s", mips_gpr_names[31]);
1339 infprintf (is, ",%s", mips_gpr_names[31]);
1344 case OP_ENTRY_EXIT_LIST:
1347 unsigned int amask, smask;
1350 amask = (uval >> 3) & 7;
1351 if (amask > 0 && amask < 5)
1353 infprintf (is, "%s", mips_gpr_names[4]);
1355 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1359 smask = (uval >> 1) & 3;
1362 infprintf (is, "%s??", sep);
1367 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1369 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1375 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1379 if (amask == 5 || amask == 6)
1381 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1383 infprintf (is, "-%s", mips_fpr_names[1]);
1388 case OP_SAVE_RESTORE_LIST:
1389 /* Should be handled by the caller due to extend behavior. */
1392 case OP_MDMX_IMM_REG:
1398 if ((vsel & 0x10) == 0)
1403 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1404 if ((vsel & 1) == 0)
1406 print_reg (info, opcode, OP_REG_VEC, uval);
1407 infprintf (is, "[%d]", vsel >> 1);
1409 else if ((vsel & 0x08) == 0)
1410 print_reg (info, opcode, OP_REG_VEC, uval);
1412 infprintf (is, "0x%x", uval);
1416 case OP_REPEAT_PREV_REG:
1417 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1420 case OP_REPEAT_DEST_REG:
1421 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1425 infprintf (is, "$pc");
1429 case OP_VU0_MATCH_SUFFIX:
1430 print_vu0_channel (info, operand, uval);
1434 infprintf (is, "[%d]", uval);
1438 infprintf (is, "[");
1439 print_reg (info, opcode, OP_REG_GP, uval);
1440 infprintf (is, "]");
1445 /* Validate the arguments for INSN, which is described by OPCODE.
1446 Use DECODE_OPERAND to get the encoding of each operand. */
1449 validate_insn_args (const struct mips_opcode *opcode,
1450 const struct mips_operand *(*decode_operand) (const char *),
1453 struct mips_print_arg_state state;
1454 const struct mips_operand *operand;
1458 init_print_arg_state (&state);
1459 for (s = opcode->args; *s; ++s)
1473 operand = decode_operand (s);
1477 uval = mips_extract_operand (operand, insn);
1478 switch (operand->type)
1481 case OP_OPTIONAL_REG:
1483 const struct mips_reg_operand *reg_op;
1485 reg_op = (const struct mips_reg_operand *) operand;
1486 uval = mips_decode_reg_operand (reg_op, uval);
1487 mips_seen_register (&state, uval, reg_op->reg_type);
1493 unsigned int reg1, reg2;
1498 if (reg1 != reg2 || reg1 == 0)
1505 const struct mips_check_prev_operand *prev_op;
1507 prev_op = (const struct mips_check_prev_operand *) operand;
1509 if (!prev_op->zero_ok && uval == 0)
1512 if (((prev_op->less_than_ok && uval < state.last_regno)
1513 || (prev_op->greater_than_ok && uval > state.last_regno)
1514 || (prev_op->equal_ok && uval == state.last_regno)))
1520 case OP_NON_ZERO_REG:
1533 case OP_ADDIUSP_INT:
1534 case OP_CLO_CLZ_DEST:
1535 case OP_LWM_SWM_LIST:
1536 case OP_ENTRY_EXIT_LIST:
1537 case OP_MDMX_IMM_REG:
1538 case OP_REPEAT_PREV_REG:
1539 case OP_REPEAT_DEST_REG:
1542 case OP_VU0_MATCH_SUFFIX:
1547 case OP_SAVE_RESTORE_LIST:
1548 /* Should be handled by the caller due to extend behavior. */
1552 if (*s == 'm' || *s == '+' || *s == '-')
1559 /* Print the arguments for INSN, which is described by OPCODE.
1560 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1561 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1562 operand is for a branch or jump. */
1565 print_insn_args (struct disassemble_info *info,
1566 const struct mips_opcode *opcode,
1567 const struct mips_operand *(*decode_operand) (const char *),
1568 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1570 const fprintf_ftype infprintf = info->fprintf_func;
1571 void *is = info->stream;
1572 struct mips_print_arg_state state;
1573 const struct mips_operand *operand;
1576 init_print_arg_state (&state);
1577 for (s = opcode->args; *s; ++s)
1584 infprintf (is, "%c", *s);
1589 infprintf (is, "%c%c", *s, *s);
1593 operand = decode_operand (s);
1596 /* xgettext:c-format */
1598 _("# internal error, undefined operand in `%s %s'"),
1599 opcode->name, opcode->args);
1602 if (operand->type == OP_REG
1605 && opcode->name[strlen (opcode->name) - 1] == '0')
1607 /* Coprocessor register 0 with sel field (MT ASE). */
1608 const struct mips_cp0sel_name *n;
1609 unsigned int reg, sel;
1611 reg = mips_extract_operand (operand, insn);
1613 operand = decode_operand (s);
1614 sel = mips_extract_operand (operand, insn);
1616 /* CP0 register including 'sel' code for mftc0, to be
1617 printed textually if known. If not known, print both
1618 CP0 register name and sel numerically since CP0 register
1619 with sel 0 may have a name unrelated to register being
1621 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1622 mips_cp0sel_names_len,
1625 infprintf (is, "%s", n->name);
1627 infprintf (is, "$%d,%d", reg, sel);
1631 bfd_vma base_pc = insn_pc;
1633 /* Adjust the PC relative base so that branch/jump insns use
1634 the following PC as the base but genuinely PC relative
1635 operands use the current PC. */
1636 if (operand->type == OP_PCREL)
1638 const struct mips_pcrel_operand *pcrel_op;
1640 pcrel_op = (const struct mips_pcrel_operand *) operand;
1641 /* The include_isa_bit flag is sufficient to distinguish
1642 branch/jump from other PC relative operands. */
1643 if (pcrel_op->include_isa_bit)
1647 print_insn_arg (info, &state, opcode, operand, base_pc,
1648 mips_extract_operand (operand, insn));
1650 if (*s == 'm' || *s == '+' || *s == '-')
1657 /* Print the mips instruction at address MEMADDR in debugged memory,
1658 on using INFO. Returns length of the instruction, in bytes, which is
1659 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1660 this is little-endian code. */
1663 print_insn_mips (bfd_vma memaddr,
1665 struct disassemble_info *info)
1667 #define GET_OP(insn, field) \
1668 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1669 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1670 const fprintf_ftype infprintf = info->fprintf_func;
1671 const struct mips_opcode *op;
1672 static bfd_boolean init = 0;
1673 void *is = info->stream;
1675 /* Build a hash table to shorten the search time. */
1680 for (i = 0; i <= OP_MASK_OP; i++)
1682 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1684 if (op->pinfo == INSN_MACRO
1685 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1687 if (i == GET_OP (op->match, OP))
1698 info->bytes_per_chunk = INSNLEN;
1699 info->display_endian = info->endian;
1700 info->insn_info_valid = 1;
1701 info->branch_delay_insns = 0;
1702 info->data_size = 0;
1703 info->insn_type = dis_nonbranch;
1707 op = mips_hash[GET_OP (word, OP)];
1710 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1712 if (op->pinfo != INSN_MACRO
1713 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1714 && (word & op->mask) == op->match)
1716 /* We always disassemble the jalx instruction, except for MIPS r6. */
1717 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1718 && (strcmp (op->name, "jalx")
1719 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1720 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
1723 /* Figure out instruction type and branch delay information. */
1724 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1726 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
1727 info->insn_type = dis_jsr;
1729 info->insn_type = dis_branch;
1730 info->branch_delay_insns = 1;
1732 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1733 | INSN_COND_BRANCH_LIKELY)) != 0)
1735 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1736 info->insn_type = dis_condjsr;
1738 info->insn_type = dis_condbranch;
1739 info->branch_delay_insns = 1;
1741 else if ((op->pinfo & (INSN_STORE_MEMORY
1742 | INSN_LOAD_MEMORY)) != 0)
1743 info->insn_type = dis_dref;
1745 if (!validate_insn_args (op, decode_mips_operand, word))
1748 infprintf (is, "%s", op->name);
1749 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1753 infprintf (is, ".");
1754 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1755 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1760 infprintf (is, "\t");
1761 print_insn_args (info, op, decode_mips_operand, word,
1771 /* Handle undefined instructions. */
1772 info->insn_type = dis_noninsn;
1773 infprintf (is, "0x%x", word);
1777 /* Disassemble an operand for a mips16 instruction. */
1780 print_mips16_insn_arg (struct disassemble_info *info,
1781 struct mips_print_arg_state *state,
1782 const struct mips_opcode *opcode,
1783 char type, bfd_vma memaddr,
1784 unsigned insn, bfd_boolean use_extend,
1785 unsigned extend, bfd_boolean is_offset)
1787 const fprintf_ftype infprintf = info->fprintf_func;
1788 void *is = info->stream;
1789 const struct mips_operand *operand, *ext_operand;
1801 infprintf (is, "%c", type);
1805 operand = decode_mips16_operand (type, FALSE);
1808 /* xgettext:c-format */
1809 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1810 opcode->name, opcode->args);
1814 if (operand->type == OP_SAVE_RESTORE_LIST)
1816 /* Handle this case here because of the complex interation
1817 with the EXTEND opcode. */
1818 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1821 amask = extend & 0xf;
1822 if (amask == MIPS16_ALL_ARGS)
1827 else if (amask == MIPS16_ALL_STATICS)
1835 nstatics = amask & 3;
1841 infprintf (is, "%s", mips_gpr_names[4]);
1843 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1847 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1848 if (frame_size == 0 && !use_extend)
1850 infprintf (is, "%s%d", sep, frame_size);
1852 if (insn & 0x40) /* $ra */
1853 infprintf (is, ",%s", mips_gpr_names[31]);
1855 nsreg = (extend >> 8) & 0x7;
1857 if (insn & 0x20) /* $s0 */
1859 if (insn & 0x10) /* $s1 */
1861 if (nsreg > 0) /* $s2-$s8 */
1862 smask |= ((1 << nsreg) - 1) << 2;
1864 for (i = 0; i < 9; i++)
1865 if (smask & (1 << i))
1867 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1868 /* Skip over string of set bits. */
1869 for (j = i; smask & (2 << j); j++)
1872 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1875 /* Statics $ax - $a3. */
1877 infprintf (is, ",%s", mips_gpr_names[7]);
1878 else if (nstatics > 0)
1879 infprintf (is, ",%s-%s",
1880 mips_gpr_names[7 - nstatics + 1],
1885 if (is_offset && operand->type == OP_INT)
1887 const struct mips_int_operand *int_op;
1889 int_op = (const struct mips_int_operand *) operand;
1890 info->insn_type = dis_dref;
1891 info->data_size = 1 << int_op->shift;
1894 if (operand->size == 26)
1895 /* In this case INSN is the first two bytes of the instruction
1896 and EXTEND is the second two bytes. */
1897 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
1900 /* Calculate the full field value. */
1901 uval = mips_extract_operand (operand, insn);
1904 ext_operand = decode_mips16_operand (type, TRUE);
1905 if (ext_operand != operand)
1907 operand = ext_operand;
1908 if (operand->size == 16)
1909 uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1910 else if (operand->size == 15)
1911 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1913 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
1918 baseaddr = memaddr + 2;
1919 if (operand->type == OP_PCREL)
1921 const struct mips_pcrel_operand *pcrel_op;
1923 pcrel_op = (const struct mips_pcrel_operand *) operand;
1924 if (!pcrel_op->include_isa_bit && use_extend)
1925 baseaddr = memaddr - 2;
1926 else if (!pcrel_op->include_isa_bit)
1930 /* If this instruction is in the delay slot of a JR
1931 instruction, the base address is the address of the
1932 JR instruction. If it is in the delay slot of a JALR
1933 instruction, the base address is the address of the
1934 JALR instruction. This test is unreliable: we have
1935 no way of knowing whether the previous word is
1936 instruction or data. */
1937 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1938 && (((info->endian == BFD_ENDIAN_BIG
1939 ? bfd_getb16 (buffer)
1940 : bfd_getl16 (buffer))
1941 & 0xf800) == 0x1800))
1942 baseaddr = memaddr - 4;
1943 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1945 && (((info->endian == BFD_ENDIAN_BIG
1946 ? bfd_getb16 (buffer)
1947 : bfd_getl16 (buffer))
1948 & 0xf81f) == 0xe800))
1949 baseaddr = memaddr - 2;
1955 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
1961 /* Check if the given address is the last word of a MIPS16 PLT entry.
1962 This word is data and depending on the value it may interfere with
1963 disassembly of further PLT entries. We make use of the fact PLT
1964 symbols are marked BSF_SYNTHETIC. */
1966 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
1970 && (info->symbols[0]->flags & BSF_SYNTHETIC)
1971 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
1977 /* Disassemble mips16 instructions. */
1980 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1982 const fprintf_ftype infprintf = info->fprintf_func;
1987 bfd_boolean use_extend;
1989 const struct mips_opcode *op, *opend;
1990 struct mips_print_arg_state state;
1991 void *is = info->stream;
1993 info->bytes_per_chunk = 2;
1994 info->display_endian = info->endian;
1995 info->insn_info_valid = 1;
1996 info->branch_delay_insns = 0;
1997 info->data_size = 0;
2001 #define GET_OP(insn, field) \
2002 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2003 /* Decode PLT entry's GOT slot address word. */
2004 if (is_mips16_plt_tail (info, memaddr))
2006 info->insn_type = dis_noninsn;
2007 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2010 unsigned int gotslot;
2012 if (info->endian == BFD_ENDIAN_BIG)
2013 gotslot = bfd_getb32 (buffer);
2015 gotslot = bfd_getl32 (buffer);
2016 infprintf (is, ".word\t0x%x", gotslot);
2023 info->insn_type = dis_nonbranch;
2024 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2028 (*info->memory_error_func) (status, memaddr, info);
2034 if (info->endian == BFD_ENDIAN_BIG)
2035 insn = bfd_getb16 (buffer);
2037 insn = bfd_getl16 (buffer);
2039 /* Handle the extend opcode specially. */
2041 if ((insn & 0xf800) == 0xf000)
2044 extend = insn & 0x7ff;
2048 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2051 infprintf (is, "extend 0x%x", (unsigned int) extend);
2052 (*info->memory_error_func) (status, memaddr, info);
2056 if (info->endian == BFD_ENDIAN_BIG)
2057 insn = bfd_getb16 (buffer);
2059 insn = bfd_getl16 (buffer);
2061 /* Check for an extend opcode followed by an extend opcode. */
2062 if ((insn & 0xf800) == 0xf000)
2064 infprintf (is, "extend 0x%x", (unsigned int) extend);
2065 info->insn_type = dis_noninsn;
2072 /* FIXME: Should probably use a hash table on the major opcode here. */
2074 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2075 for (op = mips16_opcodes; op < opend; op++)
2077 if (op->pinfo != INSN_MACRO
2078 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2079 && (insn & op->mask) == op->match)
2083 if (op->args[0] == 'a' || op->args[0] == 'i')
2087 infprintf (is, "extend 0x%x", (unsigned int) extend);
2088 info->insn_type = dis_noninsn;
2096 status = (*info->read_memory_func) (memaddr, buffer, 2,
2101 if (info->endian == BFD_ENDIAN_BIG)
2102 extend = bfd_getb16 (buffer);
2104 extend = bfd_getl16 (buffer);
2109 infprintf (is, "%s", op->name);
2110 if (op->args[0] != '\0')
2111 infprintf (is, "\t");
2113 init_print_arg_state (&state);
2114 for (s = op->args; *s != '\0'; s++)
2118 && GET_OP (insn, RX) == GET_OP (insn, RY))
2120 /* Skip the register and the comma. */
2126 && GET_OP (insn, RZ) == GET_OP (insn, RX))
2128 /* Skip the register and the comma. */
2132 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
2133 use_extend, extend, s[1] == '(');
2136 /* Figure out branch instruction type and delay slot information. */
2137 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2138 info->branch_delay_insns = 1;
2139 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2140 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2142 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2143 info->insn_type = dis_jsr;
2145 info->insn_type = dis_branch;
2147 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2148 info->insn_type = dis_condbranch;
2156 infprintf (is, "0x%x", extend | 0xf000);
2157 infprintf (is, "0x%x", insn);
2158 info->insn_type = dis_noninsn;
2163 /* Disassemble microMIPS instructions. */
2166 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2168 const fprintf_ftype infprintf = info->fprintf_func;
2169 const struct mips_opcode *op, *opend;
2170 void *is = info->stream;
2172 unsigned int higher;
2173 unsigned int length;
2177 info->bytes_per_chunk = 2;
2178 info->display_endian = info->endian;
2179 info->insn_info_valid = 1;
2180 info->branch_delay_insns = 0;
2181 info->data_size = 0;
2182 info->insn_type = dis_nonbranch;
2186 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2189 (*info->memory_error_func) (status, memaddr, info);
2195 if (info->endian == BFD_ENDIAN_BIG)
2196 insn = bfd_getb16 (buffer);
2198 insn = bfd_getl16 (buffer);
2200 if ((insn & 0xfc00) == 0x7c00)
2202 /* This is a 48-bit microMIPS instruction. */
2205 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2208 infprintf (is, "micromips 0x%x", higher);
2209 (*info->memory_error_func) (status, memaddr + 2, info);
2212 if (info->endian == BFD_ENDIAN_BIG)
2213 insn = bfd_getb16 (buffer);
2215 insn = bfd_getl16 (buffer);
2216 higher = (higher << 16) | insn;
2218 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
2221 infprintf (is, "micromips 0x%x", higher);
2222 (*info->memory_error_func) (status, memaddr + 4, info);
2225 if (info->endian == BFD_ENDIAN_BIG)
2226 insn = bfd_getb16 (buffer);
2228 insn = bfd_getl16 (buffer);
2229 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
2231 info->insn_type = dis_noninsn;
2234 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2236 /* This is a 32-bit microMIPS instruction. */
2239 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2242 infprintf (is, "micromips 0x%x", higher);
2243 (*info->memory_error_func) (status, memaddr + 2, info);
2247 if (info->endian == BFD_ENDIAN_BIG)
2248 insn = bfd_getb16 (buffer);
2250 insn = bfd_getl16 (buffer);
2252 insn = insn | (higher << 16);
2257 /* FIXME: Should probably use a hash table on the major opcode here. */
2259 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2260 for (op = micromips_opcodes; op < opend; op++)
2262 if (op->pinfo != INSN_MACRO
2263 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2264 && (insn & op->mask) == op->match
2265 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2266 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2268 if (!validate_insn_args (op, decode_micromips_operand, insn))
2271 infprintf (is, "%s", op->name);
2275 infprintf (is, "\t");
2276 print_insn_args (info, op, decode_micromips_operand, insn,
2277 memaddr + 1, length);
2280 /* Figure out instruction type and branch delay information. */
2282 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2283 info->branch_delay_insns = 1;
2284 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2285 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2287 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2288 info->insn_type = dis_jsr;
2290 info->insn_type = dis_branch;
2292 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2293 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2295 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2296 info->insn_type = dis_condjsr;
2298 info->insn_type = dis_condbranch;
2301 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2302 info->insn_type = dis_dref;
2308 infprintf (is, "0x%x", insn);
2309 info->insn_type = dis_noninsn;
2314 /* Return 1 if a symbol associated with the location being disassembled
2315 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2316 all the symbols at the address being considered assuming if at least
2317 one of them indicates code compression, then such code has been
2318 genuinely produced here (other symbols could have been derived from
2319 function symbols defined elsewhere or could define data). Otherwise,
2323 is_compressed_mode_p (struct disassemble_info *info)
2328 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2329 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2331 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2333 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2335 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2336 && info->symtab[i]->section == info->section)
2338 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2340 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2342 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2349 /* In an environment where we do not know the symbol type of the
2350 instruction we are forced to assume that the low order bit of the
2351 instructions' address may mark it as a mips16 instruction. If we
2352 are single stepping, or the pc is within the disassembled function,
2353 this works. Otherwise, we need a clue. Sometimes. */
2356 _print_insn_mips (bfd_vma memaddr,
2357 struct disassemble_info *info,
2358 enum bfd_endian endianness)
2360 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
2361 bfd_byte buffer[INSNLEN];
2364 set_default_mips_dis_options (info);
2365 parse_mips_dis_options (info->disassembler_options);
2367 if (info->mach == bfd_mach_mips16)
2368 return print_insn_mips16 (memaddr, info);
2369 if (info->mach == bfd_mach_mips_micromips)
2370 return print_insn_micromips (memaddr, info);
2372 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
2375 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2376 /* Only a few tools will work this way. */
2378 return print_insn_compr (memaddr, info);
2381 #if SYMTAB_AVAILABLE
2382 if (is_compressed_mode_p (info))
2383 return print_insn_compr (memaddr, info);
2386 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2391 if (endianness == BFD_ENDIAN_BIG)
2392 insn = bfd_getb32 (buffer);
2394 insn = bfd_getl32 (buffer);
2396 return print_insn_mips (memaddr, insn, info);
2400 (*info->memory_error_func) (status, memaddr, info);
2406 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2408 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2412 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2414 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2418 print_mips_disassembler_options (FILE *stream)
2422 fprintf (stream, _("\n\
2423 The following MIPS specific disassembler options are supported for use\n\
2424 with the -M switch (multiple options should be separated by commas):\n"));
2426 fprintf (stream, _("\n\
2427 msa Recognize MSA instructions.\n"));
2429 fprintf (stream, _("\n\
2430 virt Recognize the virtualization ASE instructions.\n"));
2432 fprintf (stream, _("\n\
2433 xpa Recognize the eXtended Physical Address (XPA) ASE instructions.\n"));
2435 fprintf (stream, _("\n\
2436 gpr-names=ABI Print GPR names according to specified ABI.\n\
2437 Default: based on binary being disassembled.\n"));
2439 fprintf (stream, _("\n\
2440 fpr-names=ABI Print FPR names according to specified ABI.\n\
2441 Default: numeric.\n"));
2443 fprintf (stream, _("\n\
2444 cp0-names=ARCH Print CP0 register names according to\n\
2445 specified architecture.\n\
2446 Default: based on binary being disassembled.\n"));
2448 fprintf (stream, _("\n\
2449 hwr-names=ARCH Print HWR names according to specified \n\
2451 Default: based on binary being disassembled.\n"));
2453 fprintf (stream, _("\n\
2454 reg-names=ABI Print GPR and FPR names according to\n\
2455 specified ABI.\n"));
2457 fprintf (stream, _("\n\
2458 reg-names=ARCH Print CP0 register and HWR names according to\n\
2459 specified architecture.\n"));
2461 fprintf (stream, _("\n\
2462 For the options above, the following values are supported for \"ABI\":\n\
2464 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2465 fprintf (stream, " %s", mips_abi_choices[i].name);
2466 fprintf (stream, _("\n"));
2468 fprintf (stream, _("\n\
2469 For the options above, The following values are supported for \"ARCH\":\n\
2471 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2472 if (*mips_arch_choices[i].name != '\0')
2473 fprintf (stream, " %s", mips_arch_choices[i].name);
2474 fprintf (stream, _("\n"));
2476 fprintf (stream, _("\n"));