1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2012
4 Free Software Foundation, Inc.
5 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
7 This file is part of the GNU opcodes library.
9 This library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
26 #include "libiberty.h"
27 #include "opcode/mips.h"
30 /* FIXME: These are needed to figure out if the code is mips16 or
31 not. The low bit of the address is often a good indicator. No
32 symbol table is available when this code runs out in an embedded
33 system as when it is used for disassembler support in a monitor. */
35 #if !defined(EMBEDDED_ENV)
36 #define SYMTAB_AVAILABLE 1
41 /* Mips instructions are at maximum this many bytes long. */
45 /* FIXME: These should be shared with gdb somehow. */
47 struct mips_cp0sel_name
51 const char * const name
;
54 static const char * const mips_gpr_names_numeric
[32] =
56 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
57 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
58 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
59 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
62 static const char * const mips_gpr_names_oldabi
[32] =
64 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
65 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
66 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
67 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
70 static const char * const mips_gpr_names_newabi
[32] =
72 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
73 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
74 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
75 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
78 static const char * const mips_fpr_names_numeric
[32] =
80 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
81 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
82 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
83 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
86 static const char * const mips_fpr_names_32
[32] =
88 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
89 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
90 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
91 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
94 static const char * const mips_fpr_names_n32
[32] =
96 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
97 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
98 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
99 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
102 static const char * const mips_fpr_names_64
[32] =
104 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
105 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
106 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
107 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
110 static const char * const mips_cp0_names_numeric
[32] =
112 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
113 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
114 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
115 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
118 static const char * const mips_cp1_names_numeric
[32] =
120 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
121 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
122 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
123 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
126 static const char * const mips_cp0_names_r3000
[32] =
128 "c0_index", "c0_random", "c0_entrylo", "$3",
129 "c0_context", "$5", "$6", "$7",
130 "c0_badvaddr", "$9", "c0_entryhi", "$11",
131 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
132 "$16", "$17", "$18", "$19",
133 "$20", "$21", "$22", "$23",
134 "$24", "$25", "$26", "$27",
135 "$28", "$29", "$30", "$31",
138 static const char * const mips_cp0_names_r4000
[32] =
140 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
141 "c0_context", "c0_pagemask", "c0_wired", "$7",
142 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
143 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
144 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
145 "c0_xcontext", "$21", "$22", "$23",
146 "$24", "$25", "c0_ecc", "c0_cacheerr",
147 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
150 static const char * const mips_cp0_names_r5900
[32] =
152 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
153 "c0_context", "c0_pagemask", "c0_wired", "$7",
154 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
155 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
156 "c0_config", "$17", "$18", "$19",
157 "$20", "$21", "$22", "c0_badpaddr",
158 "c0_depc", "c0_perfcnt", "$26", "$27",
159 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
162 static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900
[] =
165 { 24, 3, "c0_iabm" },
167 { 24, 5, "c0_dabm" },
169 { 24, 7, "c0_dvbm" },
170 { 25, 1, "c0_perfcnt,1" },
171 { 25, 2, "c0_perfcnt,2" }
174 static const char * const mips_cp0_names_mips3264
[32] =
176 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
177 "c0_context", "c0_pagemask", "c0_wired", "$7",
178 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
179 "c0_status", "c0_cause", "c0_epc", "c0_prid",
180 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
181 "c0_xcontext", "$21", "$22", "c0_debug",
182 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
183 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
186 static const char * const mips_cp1_names_mips3264
[32] =
188 "c1_fir", "c1_ufr", "$2", "$3",
189 "c1_unfr", "$5", "$6", "$7",
190 "$8", "$9", "$10", "$11",
191 "$12", "$13", "$14", "$15",
192 "$16", "$17", "$18", "$19",
193 "$20", "$21", "$22", "$23",
194 "$24", "c1_fccr", "c1_fexr", "$27",
195 "c1_fenr", "$29", "$30", "c1_fcsr"
198 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] =
200 { 16, 1, "c0_config1" },
201 { 16, 2, "c0_config2" },
202 { 16, 3, "c0_config3" },
203 { 18, 1, "c0_watchlo,1" },
204 { 18, 2, "c0_watchlo,2" },
205 { 18, 3, "c0_watchlo,3" },
206 { 18, 4, "c0_watchlo,4" },
207 { 18, 5, "c0_watchlo,5" },
208 { 18, 6, "c0_watchlo,6" },
209 { 18, 7, "c0_watchlo,7" },
210 { 19, 1, "c0_watchhi,1" },
211 { 19, 2, "c0_watchhi,2" },
212 { 19, 3, "c0_watchhi,3" },
213 { 19, 4, "c0_watchhi,4" },
214 { 19, 5, "c0_watchhi,5" },
215 { 19, 6, "c0_watchhi,6" },
216 { 19, 7, "c0_watchhi,7" },
217 { 25, 1, "c0_perfcnt,1" },
218 { 25, 2, "c0_perfcnt,2" },
219 { 25, 3, "c0_perfcnt,3" },
220 { 25, 4, "c0_perfcnt,4" },
221 { 25, 5, "c0_perfcnt,5" },
222 { 25, 6, "c0_perfcnt,6" },
223 { 25, 7, "c0_perfcnt,7" },
224 { 27, 1, "c0_cacheerr,1" },
225 { 27, 2, "c0_cacheerr,2" },
226 { 27, 3, "c0_cacheerr,3" },
227 { 28, 1, "c0_datalo" },
228 { 29, 1, "c0_datahi" }
231 static const char * const mips_cp0_names_mips3264r2
[32] =
233 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
234 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
235 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
236 "c0_status", "c0_cause", "c0_epc", "c0_prid",
237 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
238 "c0_xcontext", "$21", "$22", "c0_debug",
239 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
240 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
243 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] =
245 { 4, 1, "c0_contextconfig" },
246 { 0, 1, "c0_mvpcontrol" },
247 { 0, 2, "c0_mvpconf0" },
248 { 0, 3, "c0_mvpconf1" },
249 { 1, 1, "c0_vpecontrol" },
250 { 1, 2, "c0_vpeconf0" },
251 { 1, 3, "c0_vpeconf1" },
252 { 1, 4, "c0_yqmask" },
253 { 1, 5, "c0_vpeschedule" },
254 { 1, 6, "c0_vpeschefback" },
255 { 2, 1, "c0_tcstatus" },
256 { 2, 2, "c0_tcbind" },
257 { 2, 3, "c0_tcrestart" },
258 { 2, 4, "c0_tchalt" },
259 { 2, 5, "c0_tccontext" },
260 { 2, 6, "c0_tcschedule" },
261 { 2, 7, "c0_tcschefback" },
262 { 5, 1, "c0_pagegrain" },
263 { 6, 1, "c0_srsconf0" },
264 { 6, 2, "c0_srsconf1" },
265 { 6, 3, "c0_srsconf2" },
266 { 6, 4, "c0_srsconf3" },
267 { 6, 5, "c0_srsconf4" },
268 { 12, 1, "c0_intctl" },
269 { 12, 2, "c0_srsctl" },
270 { 12, 3, "c0_srsmap" },
271 { 15, 1, "c0_ebase" },
272 { 16, 1, "c0_config1" },
273 { 16, 2, "c0_config2" },
274 { 16, 3, "c0_config3" },
275 { 18, 1, "c0_watchlo,1" },
276 { 18, 2, "c0_watchlo,2" },
277 { 18, 3, "c0_watchlo,3" },
278 { 18, 4, "c0_watchlo,4" },
279 { 18, 5, "c0_watchlo,5" },
280 { 18, 6, "c0_watchlo,6" },
281 { 18, 7, "c0_watchlo,7" },
282 { 19, 1, "c0_watchhi,1" },
283 { 19, 2, "c0_watchhi,2" },
284 { 19, 3, "c0_watchhi,3" },
285 { 19, 4, "c0_watchhi,4" },
286 { 19, 5, "c0_watchhi,5" },
287 { 19, 6, "c0_watchhi,6" },
288 { 19, 7, "c0_watchhi,7" },
289 { 23, 1, "c0_tracecontrol" },
290 { 23, 2, "c0_tracecontrol2" },
291 { 23, 3, "c0_usertracedata" },
292 { 23, 4, "c0_tracebpc" },
293 { 25, 1, "c0_perfcnt,1" },
294 { 25, 2, "c0_perfcnt,2" },
295 { 25, 3, "c0_perfcnt,3" },
296 { 25, 4, "c0_perfcnt,4" },
297 { 25, 5, "c0_perfcnt,5" },
298 { 25, 6, "c0_perfcnt,6" },
299 { 25, 7, "c0_perfcnt,7" },
300 { 27, 1, "c0_cacheerr,1" },
301 { 27, 2, "c0_cacheerr,2" },
302 { 27, 3, "c0_cacheerr,3" },
303 { 28, 1, "c0_datalo" },
304 { 28, 2, "c0_taglo1" },
305 { 28, 3, "c0_datalo1" },
306 { 28, 4, "c0_taglo2" },
307 { 28, 5, "c0_datalo2" },
308 { 28, 6, "c0_taglo3" },
309 { 28, 7, "c0_datalo3" },
310 { 29, 1, "c0_datahi" },
311 { 29, 2, "c0_taghi1" },
312 { 29, 3, "c0_datahi1" },
313 { 29, 4, "c0_taghi2" },
314 { 29, 5, "c0_datahi2" },
315 { 29, 6, "c0_taghi3" },
316 { 29, 7, "c0_datahi3" },
319 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
320 static const char * const mips_cp0_names_sb1
[32] =
322 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
323 "c0_context", "c0_pagemask", "c0_wired", "$7",
324 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
325 "c0_status", "c0_cause", "c0_epc", "c0_prid",
326 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
327 "c0_xcontext", "$21", "$22", "c0_debug",
328 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
329 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
332 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] =
334 { 16, 1, "c0_config1" },
335 { 18, 1, "c0_watchlo,1" },
336 { 19, 1, "c0_watchhi,1" },
337 { 22, 0, "c0_perftrace" },
338 { 23, 3, "c0_edebug" },
339 { 25, 1, "c0_perfcnt,1" },
340 { 25, 2, "c0_perfcnt,2" },
341 { 25, 3, "c0_perfcnt,3" },
342 { 25, 4, "c0_perfcnt,4" },
343 { 25, 5, "c0_perfcnt,5" },
344 { 25, 6, "c0_perfcnt,6" },
345 { 25, 7, "c0_perfcnt,7" },
346 { 26, 1, "c0_buserr_pa" },
347 { 27, 1, "c0_cacheerr_d" },
348 { 27, 3, "c0_cacheerr_d_pa" },
349 { 28, 1, "c0_datalo_i" },
350 { 28, 2, "c0_taglo_d" },
351 { 28, 3, "c0_datalo_d" },
352 { 29, 1, "c0_datahi_i" },
353 { 29, 2, "c0_taghi_d" },
354 { 29, 3, "c0_datahi_d" },
357 /* Xlr cop0 register names. */
358 static const char * const mips_cp0_names_xlr
[32] = {
359 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
360 "c0_context", "c0_pagemask", "c0_wired", "$7",
361 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
362 "c0_status", "c0_cause", "c0_epc", "c0_prid",
363 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
364 "c0_xcontext", "$21", "$22", "c0_debug",
365 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
366 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
369 /* XLR's CP0 Select Registers. */
371 static const struct mips_cp0sel_name mips_cp0sel_names_xlr
[] = {
372 { 9, 6, "c0_extintreq" },
373 { 9, 7, "c0_extintmask" },
374 { 15, 1, "c0_ebase" },
375 { 16, 1, "c0_config1" },
376 { 16, 2, "c0_config2" },
377 { 16, 3, "c0_config3" },
378 { 16, 7, "c0_procid2" },
379 { 18, 1, "c0_watchlo,1" },
380 { 18, 2, "c0_watchlo,2" },
381 { 18, 3, "c0_watchlo,3" },
382 { 18, 4, "c0_watchlo,4" },
383 { 18, 5, "c0_watchlo,5" },
384 { 18, 6, "c0_watchlo,6" },
385 { 18, 7, "c0_watchlo,7" },
386 { 19, 1, "c0_watchhi,1" },
387 { 19, 2, "c0_watchhi,2" },
388 { 19, 3, "c0_watchhi,3" },
389 { 19, 4, "c0_watchhi,4" },
390 { 19, 5, "c0_watchhi,5" },
391 { 19, 6, "c0_watchhi,6" },
392 { 19, 7, "c0_watchhi,7" },
393 { 25, 1, "c0_perfcnt,1" },
394 { 25, 2, "c0_perfcnt,2" },
395 { 25, 3, "c0_perfcnt,3" },
396 { 25, 4, "c0_perfcnt,4" },
397 { 25, 5, "c0_perfcnt,5" },
398 { 25, 6, "c0_perfcnt,6" },
399 { 25, 7, "c0_perfcnt,7" },
400 { 27, 1, "c0_cacheerr,1" },
401 { 27, 2, "c0_cacheerr,2" },
402 { 27, 3, "c0_cacheerr,3" },
403 { 28, 1, "c0_datalo" },
404 { 29, 1, "c0_datahi" }
407 static const char * const mips_hwr_names_numeric
[32] =
409 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
410 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
411 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
412 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
415 static const char * const mips_hwr_names_mips3264r2
[32] =
417 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
418 "$4", "$5", "$6", "$7",
419 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
420 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
421 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
424 static const char * const msa_control_names
[32] =
426 "msa_ir", "msa_csr", "msa_access", "msa_save",
427 "msa_modify", "msa_request", "msa_map", "msa_unmap",
428 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
429 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
430 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
433 struct mips_abi_choice
436 const char * const *gpr_names
;
437 const char * const *fpr_names
;
440 struct mips_abi_choice mips_abi_choices
[] =
442 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
443 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
444 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
445 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
448 struct mips_arch_choice
452 unsigned long bfd_mach
;
456 const char * const *cp0_names
;
457 const struct mips_cp0sel_name
*cp0sel_names
;
458 unsigned int cp0sel_names_len
;
459 const char * const *cp1_names
;
460 const char * const *hwr_names
;
463 const struct mips_arch_choice mips_arch_choices
[] =
465 { "numeric", 0, 0, 0, 0, 0,
466 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
467 mips_hwr_names_numeric
},
469 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
, 0,
470 mips_cp0_names_r3000
, NULL
, 0, mips_cp1_names_numeric
,
471 mips_hwr_names_numeric
},
472 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
, 0,
473 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
474 mips_hwr_names_numeric
},
475 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
, 0,
476 mips_cp0_names_r4000
, NULL
, 0, mips_cp1_names_numeric
,
477 mips_hwr_names_numeric
},
478 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
, 0,
479 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
480 mips_hwr_names_numeric
},
481 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
, 0,
482 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
483 mips_hwr_names_numeric
},
484 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
, 0,
485 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
486 mips_hwr_names_numeric
},
487 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
, 0,
488 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
489 mips_hwr_names_numeric
},
490 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
, 0,
491 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
492 mips_hwr_names_numeric
},
493 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
, 0,
494 mips_cp0_names_r4000
, NULL
, 0, mips_cp1_names_numeric
,
495 mips_hwr_names_numeric
},
496 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
, 0,
497 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
498 mips_hwr_names_numeric
},
499 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
, 0,
500 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
501 mips_hwr_names_numeric
},
502 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
, 0,
503 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
504 mips_hwr_names_numeric
},
505 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
, 0,
506 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
507 mips_hwr_names_numeric
},
508 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
, 0,
509 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
510 mips_hwr_names_numeric
},
511 { "r5900", 1, bfd_mach_mips5900
, CPU_R5900
, ISA_MIPS3
, 0,
512 mips_cp0_names_r5900
, NULL
, 0, mips_cp1_names_numeric
,
513 mips_hwr_names_numeric
},
514 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
, 0,
515 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
516 mips_hwr_names_numeric
},
517 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
518 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
519 mips_hwr_names_numeric
},
520 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
521 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
522 mips_hwr_names_numeric
},
523 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
, 0,
524 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
525 mips_hwr_names_numeric
},
526 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
, 0,
527 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
528 mips_hwr_names_numeric
},
529 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
, 0,
530 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
531 mips_hwr_names_numeric
},
532 { "r14000", 1, bfd_mach_mips14000
, CPU_R14000
, ISA_MIPS4
, 0,
533 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
534 mips_hwr_names_numeric
},
535 { "r16000", 1, bfd_mach_mips16000
, CPU_R16000
, ISA_MIPS4
, 0,
536 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
537 mips_hwr_names_numeric
},
538 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
, 0,
539 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
540 mips_hwr_names_numeric
},
542 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
543 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
544 _MIPS32 Architecture For Programmers Volume I: Introduction to the
545 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
547 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
548 ISA_MIPS32
, ASE_SMARTMIPS
,
549 mips_cp0_names_mips3264
,
550 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
551 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
553 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
555 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
556 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
),
557 mips_cp0_names_mips3264r2
,
558 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
559 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
561 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
562 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
563 ISA_MIPS64
, ASE_MIPS3D
| ASE_MDMX
,
564 mips_cp0_names_mips3264
,
565 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
566 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
568 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
570 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
571 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
),
572 mips_cp0_names_mips3264r2
,
573 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
574 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
576 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
577 ISA_MIPS64
| INSN_SB1
, ASE_MIPS3D
,
579 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
580 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
582 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
583 ISA_MIPS3
| INSN_LOONGSON_2E
, 0, mips_cp0_names_numeric
,
584 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
586 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
587 ISA_MIPS3
| INSN_LOONGSON_2F
, 0, mips_cp0_names_numeric
,
588 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
590 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
591 ISA_MIPS64
| INSN_LOONGSON_3A
, 0, mips_cp0_names_numeric
,
592 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
594 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
595 ISA_MIPS64R2
| INSN_OCTEON
, 0, mips_cp0_names_numeric
, NULL
, 0,
596 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
598 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
599 ISA_MIPS64R2
| INSN_OCTEONP
, 0, mips_cp0_names_numeric
,
600 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
602 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
603 ISA_MIPS64R2
| INSN_OCTEON2
, 0, mips_cp0_names_numeric
,
604 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
606 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
607 ISA_MIPS64
| INSN_XLR
, 0,
609 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
610 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
612 /* XLP is mostly like XLR, with the prominent exception it is being
614 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
615 ISA_MIPS64R2
| INSN_XLR
, 0,
617 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
618 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
620 /* This entry, mips16, is here only for ISA/processor selection; do
621 not print its name. */
622 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
, 0,
623 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
624 mips_hwr_names_numeric
},
627 /* ISA and processor type to disassemble for, and register names to use.
628 set_default_mips_dis_options and parse_mips_dis_options fill in these
630 static int mips_processor
;
633 static int micromips_ase
;
634 static const char * const *mips_gpr_names
;
635 static const char * const *mips_fpr_names
;
636 static const char * const *mips_cp0_names
;
637 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
638 static int mips_cp0sel_names_len
;
639 static const char * const *mips_cp1_names
;
640 static const char * const *mips_hwr_names
;
643 static int no_aliases
; /* If set disassemble as most general inst. */
645 static const struct mips_abi_choice
*
646 choose_abi_by_name (const char *name
, unsigned int namelen
)
648 const struct mips_abi_choice
*c
;
651 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
652 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
653 && strlen (mips_abi_choices
[i
].name
) == namelen
)
654 c
= &mips_abi_choices
[i
];
659 static const struct mips_arch_choice
*
660 choose_arch_by_name (const char *name
, unsigned int namelen
)
662 const struct mips_arch_choice
*c
= NULL
;
665 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
666 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
667 && strlen (mips_arch_choices
[i
].name
) == namelen
)
668 c
= &mips_arch_choices
[i
];
673 static const struct mips_arch_choice
*
674 choose_arch_by_number (unsigned long mach
)
676 static unsigned long hint_bfd_mach
;
677 static const struct mips_arch_choice
*hint_arch_choice
;
678 const struct mips_arch_choice
*c
;
681 /* We optimize this because even if the user specifies no
682 flags, this will be done for every instruction! */
683 if (hint_bfd_mach
== mach
684 && hint_arch_choice
!= NULL
685 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
686 return hint_arch_choice
;
688 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
690 if (mips_arch_choices
[i
].bfd_mach_valid
691 && mips_arch_choices
[i
].bfd_mach
== mach
)
693 c
= &mips_arch_choices
[i
];
694 hint_bfd_mach
= mach
;
695 hint_arch_choice
= c
;
701 /* Check if the object uses NewABI conventions. */
704 is_newabi (Elf_Internal_Ehdr
*header
)
706 /* There are no old-style ABIs which use 64-bit ELF. */
707 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
710 /* If a 32-bit ELF file, n32 is a new-style ABI. */
711 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
717 /* Check if the object has microMIPS ASE code. */
720 is_micromips (Elf_Internal_Ehdr
*header
)
722 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
729 set_default_mips_dis_options (struct disassemble_info
*info
)
731 const struct mips_arch_choice
*chosen_arch
;
733 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
734 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
735 CP0 register, and HWR names. */
736 mips_isa
= ISA_MIPS3
;
737 mips_processor
= CPU_R3000
;
740 mips_gpr_names
= mips_gpr_names_oldabi
;
741 mips_fpr_names
= mips_fpr_names_numeric
;
742 mips_cp0_names
= mips_cp0_names_numeric
;
743 mips_cp0sel_names
= NULL
;
744 mips_cp0sel_names_len
= 0;
745 mips_cp1_names
= mips_cp1_names_numeric
;
746 mips_hwr_names
= mips_hwr_names_numeric
;
749 /* Update settings according to the ELF file header flags. */
750 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
752 Elf_Internal_Ehdr
*header
;
754 header
= elf_elfheader (info
->section
->owner
);
755 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
756 if (is_newabi (header
))
757 mips_gpr_names
= mips_gpr_names_newabi
;
758 /* If a microMIPS binary, then don't use MIPS16 bindings. */
759 micromips_ase
= is_micromips (header
);
762 /* Set ISA, architecture, and cp0 register names as best we can. */
763 #if ! SYMTAB_AVAILABLE
764 /* This is running out on a target machine, not in a host tool.
765 FIXME: Where does mips_target_info come from? */
766 target_processor
= mips_target_info
.processor
;
767 mips_isa
= mips_target_info
.isa
;
768 mips_ase
= mips_target_info
.ase
;
770 chosen_arch
= choose_arch_by_number (info
->mach
);
771 if (chosen_arch
!= NULL
)
773 mips_processor
= chosen_arch
->processor
;
774 mips_isa
= chosen_arch
->isa
;
775 mips_ase
= chosen_arch
->ase
;
776 mips_cp0_names
= chosen_arch
->cp0_names
;
777 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
778 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
779 mips_cp1_names
= chosen_arch
->cp1_names
;
780 mips_hwr_names
= chosen_arch
->hwr_names
;
786 parse_mips_dis_option (const char *option
, unsigned int len
)
788 unsigned int i
, optionlen
, vallen
;
790 const struct mips_abi_choice
*chosen_abi
;
791 const struct mips_arch_choice
*chosen_arch
;
793 /* Try to match options that are simple flags */
794 if (CONST_STRNEQ (option
, "no-aliases"))
800 if (CONST_STRNEQ (option
, "msa"))
803 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
)
804 mips_ase
|= ASE_MSA64
;
808 if (CONST_STRNEQ (option
, "virt"))
810 mips_ase
|= ASE_VIRT
;
811 if (mips_isa
& ISA_MIPS64R2
)
812 mips_ase
|= ASE_VIRT64
;
816 /* Look for the = that delimits the end of the option name. */
817 for (i
= 0; i
< len
; i
++)
818 if (option
[i
] == '=')
821 if (i
== 0) /* Invalid option: no name before '='. */
823 if (i
== len
) /* Invalid option: no '='. */
825 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
829 val
= option
+ (optionlen
+ 1);
830 vallen
= len
- (optionlen
+ 1);
832 if (strncmp ("gpr-names", option
, optionlen
) == 0
833 && strlen ("gpr-names") == optionlen
)
835 chosen_abi
= choose_abi_by_name (val
, vallen
);
836 if (chosen_abi
!= NULL
)
837 mips_gpr_names
= chosen_abi
->gpr_names
;
841 if (strncmp ("fpr-names", option
, optionlen
) == 0
842 && strlen ("fpr-names") == optionlen
)
844 chosen_abi
= choose_abi_by_name (val
, vallen
);
845 if (chosen_abi
!= NULL
)
846 mips_fpr_names
= chosen_abi
->fpr_names
;
850 if (strncmp ("cp0-names", option
, optionlen
) == 0
851 && strlen ("cp0-names") == optionlen
)
853 chosen_arch
= choose_arch_by_name (val
, vallen
);
854 if (chosen_arch
!= NULL
)
856 mips_cp0_names
= chosen_arch
->cp0_names
;
857 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
858 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
863 if (strncmp ("cp1-names", option
, optionlen
) == 0
864 && strlen ("cp1-names") == optionlen
)
866 chosen_arch
= choose_arch_by_name (val
, vallen
);
867 if (chosen_arch
!= NULL
)
868 mips_cp1_names
= chosen_arch
->cp1_names
;
872 if (strncmp ("hwr-names", option
, optionlen
) == 0
873 && strlen ("hwr-names") == optionlen
)
875 chosen_arch
= choose_arch_by_name (val
, vallen
);
876 if (chosen_arch
!= NULL
)
877 mips_hwr_names
= chosen_arch
->hwr_names
;
881 if (strncmp ("reg-names", option
, optionlen
) == 0
882 && strlen ("reg-names") == optionlen
)
884 /* We check both ABI and ARCH here unconditionally, so
885 that "numeric" will do the desirable thing: select
886 numeric register names for all registers. Other than
887 that, a given name probably won't match both. */
888 chosen_abi
= choose_abi_by_name (val
, vallen
);
889 if (chosen_abi
!= NULL
)
891 mips_gpr_names
= chosen_abi
->gpr_names
;
892 mips_fpr_names
= chosen_abi
->fpr_names
;
894 chosen_arch
= choose_arch_by_name (val
, vallen
);
895 if (chosen_arch
!= NULL
)
897 mips_cp0_names
= chosen_arch
->cp0_names
;
898 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
899 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
900 mips_cp1_names
= chosen_arch
->cp1_names
;
901 mips_hwr_names
= chosen_arch
->hwr_names
;
906 /* Invalid option. */
910 parse_mips_dis_options (const char *options
)
912 const char *option_end
;
917 while (*options
!= '\0')
919 /* Skip empty options. */
926 /* We know that *options is neither NUL or a comma. */
927 option_end
= options
+ 1;
928 while (*option_end
!= ',' && *option_end
!= '\0')
931 parse_mips_dis_option (options
, option_end
- options
);
933 /* Go on to the next one. If option_end points to a comma, it
934 will be skipped above. */
935 options
= option_end
;
939 static const struct mips_cp0sel_name
*
940 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
947 for (i
= 0; i
< len
; i
++)
948 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
953 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
956 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
957 enum mips_reg_operand_type type
, int regno
)
962 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
966 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
970 if (opcode
->pinfo
& (FP_D
| FP_S
))
971 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
973 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
977 if (opcode
->membership
& INSN_5400
)
978 info
->fprintf_func (info
->stream
, "$f%d", regno
);
980 info
->fprintf_func (info
->stream
, "$v%d", regno
);
984 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
988 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
989 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
990 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
991 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
993 info
->fprintf_func (info
->stream
, "$%d", regno
);
997 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1001 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1005 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1008 case OP_REG_R5900_I
:
1009 info
->fprintf_func (info
->stream
, "$I");
1012 case OP_REG_R5900_Q
:
1013 info
->fprintf_func (info
->stream
, "$Q");
1016 case OP_REG_R5900_R
:
1017 info
->fprintf_func (info
->stream
, "$R");
1020 case OP_REG_R5900_ACC
:
1021 info
->fprintf_func (info
->stream
, "$ACC");
1025 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1028 case OP_REG_MSA_CTRL
:
1029 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1035 /* Used to track the state carried over from previous operands in
1037 struct mips_print_arg_state
{
1038 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1039 where the value is known to be unsigned and small. */
1040 unsigned int last_int
;
1042 /* The type and number of the last OP_REG seen. We only use this for
1043 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1044 enum mips_reg_operand_type last_reg_type
;
1045 unsigned int last_regno
;
1048 /* Initialize STATE for the start of an instruction. */
1051 init_print_arg_state (struct mips_print_arg_state
*state
)
1053 memset (state
, 0, sizeof (*state
));
1056 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1057 whose value is given by UVAL. */
1060 print_vu0_channel (struct disassemble_info
*info
,
1061 const struct mips_operand
*operand
, unsigned int uval
)
1063 if (operand
->size
== 4)
1064 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1065 uval
& 8 ? "x" : "",
1066 uval
& 4 ? "y" : "",
1067 uval
& 2 ? "z" : "",
1068 uval
& 1 ? "w" : "");
1069 else if (operand
->size
== 2)
1070 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1075 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1076 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1077 the base address for OP_PCREL operands. */
1080 print_insn_arg (struct disassemble_info
*info
,
1081 struct mips_print_arg_state
*state
,
1082 const struct mips_opcode
*opcode
,
1083 const struct mips_operand
*operand
,
1087 const fprintf_ftype infprintf
= info
->fprintf_func
;
1088 void *is
= info
->stream
;
1090 switch (operand
->type
)
1094 const struct mips_int_operand
*int_op
;
1096 int_op
= (const struct mips_int_operand
*) operand
;
1097 uval
= mips_decode_int_operand (int_op
, uval
);
1098 state
->last_int
= uval
;
1099 if (int_op
->print_hex
)
1100 infprintf (is
, "0x%x", uval
);
1102 infprintf (is
, "%d", uval
);
1108 const struct mips_mapped_int_operand
*mint_op
;
1110 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1111 uval
= mint_op
->int_map
[uval
];
1112 state
->last_int
= uval
;
1113 if (mint_op
->print_hex
)
1114 infprintf (is
, "0x%x", uval
);
1116 infprintf (is
, "%d", uval
);
1122 const struct mips_msb_operand
*msb_op
;
1124 msb_op
= (const struct mips_msb_operand
*) operand
;
1125 uval
+= msb_op
->bias
;
1126 if (msb_op
->add_lsb
)
1127 uval
-= state
->last_int
;
1128 infprintf (is
, "0x%x", uval
);
1133 case OP_OPTIONAL_REG
:
1135 const struct mips_reg_operand
*reg_op
;
1137 reg_op
= (const struct mips_reg_operand
*) operand
;
1138 uval
= mips_decode_reg_operand (reg_op
, uval
);
1139 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1141 state
->last_reg_type
= reg_op
->reg_type
;
1142 state
->last_regno
= uval
;
1148 const struct mips_reg_pair_operand
*pair_op
;
1150 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1151 print_reg (info
, opcode
, pair_op
->reg_type
,
1152 pair_op
->reg1_map
[uval
]);
1153 infprintf (is
, ",");
1154 print_reg (info
, opcode
, pair_op
->reg_type
,
1155 pair_op
->reg2_map
[uval
]);
1161 const struct mips_pcrel_operand
*pcrel_op
;
1163 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1164 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1166 /* Preserve the ISA bit for the GDB disassembler,
1167 otherwise clear it. */
1168 if (info
->flavour
!= bfd_target_unknown_flavour
)
1171 (*info
->print_address_func
) (info
->target
, info
);
1176 infprintf (is
, "%d", uval
);
1179 case OP_ADDIUSP_INT
:
1183 sval
= mips_signed_operand (operand
, uval
) * 4;
1184 if (sval
>= -8 && sval
< 8)
1186 infprintf (is
, "%d", sval
);
1190 case OP_CLO_CLZ_DEST
:
1192 unsigned int reg1
, reg2
;
1196 /* If one is zero use the other. */
1197 if (reg1
== reg2
|| reg2
== 0)
1198 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1200 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1202 /* Bogus, result depends on processor. */
1203 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1204 mips_gpr_names
[reg2
]);
1208 case OP_LWM_SWM_LIST
:
1209 if (operand
->size
== 2)
1212 infprintf (is
, "%s,%s",
1214 mips_gpr_names
[31]);
1216 infprintf (is
, "%s-%s,%s",
1218 mips_gpr_names
[16 + uval
],
1219 mips_gpr_names
[31]);
1225 s_reg_encode
= uval
& 0xf;
1226 if (s_reg_encode
!= 0)
1228 if (s_reg_encode
== 1)
1229 infprintf (is
, "%s", mips_gpr_names
[16]);
1230 else if (s_reg_encode
< 9)
1231 infprintf (is
, "%s-%s",
1233 mips_gpr_names
[15 + s_reg_encode
]);
1234 else if (s_reg_encode
== 9)
1235 infprintf (is
, "%s-%s,%s",
1238 mips_gpr_names
[30]);
1240 infprintf (is
, "UNKNOWN");
1243 if (uval
& 0x10) /* For ra. */
1245 if (s_reg_encode
== 0)
1246 infprintf (is
, "%s", mips_gpr_names
[31]);
1248 infprintf (is
, ",%s", mips_gpr_names
[31]);
1253 case OP_ENTRY_EXIT_LIST
:
1256 unsigned int amask
, smask
;
1259 amask
= (uval
>> 3) & 7;
1260 if (amask
> 0 && amask
< 5)
1262 infprintf (is
, "%s", mips_gpr_names
[4]);
1264 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1268 smask
= (uval
>> 1) & 3;
1271 infprintf (is
, "%s??", sep
);
1276 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1278 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1284 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1288 if (amask
== 5 || amask
== 6)
1290 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1292 infprintf (is
, "-%s", mips_fpr_names
[1]);
1297 case OP_SAVE_RESTORE_LIST
:
1298 /* Should be handled by the caller due to extend behavior. */
1301 case OP_MDMX_IMM_REG
:
1307 if ((vsel
& 0x10) == 0)
1312 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1313 if ((vsel
& 1) == 0)
1315 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1316 infprintf (is
, "[%d]", vsel
>> 1);
1318 else if ((vsel
& 0x08) == 0)
1319 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1321 infprintf (is
, "0x%x", uval
);
1325 case OP_REPEAT_PREV_REG
:
1326 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1329 case OP_REPEAT_DEST_REG
:
1330 /* Should always match OP_REPEAT_PREV_REG first. */
1334 infprintf (is
, "$pc");
1338 case OP_VU0_MATCH_SUFFIX
:
1339 print_vu0_channel (info
, operand
, uval
);
1343 infprintf (is
, "[%d]", uval
);
1347 infprintf (is
, "[");
1348 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1349 infprintf (is
, "]");
1354 /* Print the arguments for INSN, which is described by OPCODE.
1355 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1356 as the base of OP_PCREL operands. */
1359 print_insn_args (struct disassemble_info
*info
,
1360 const struct mips_opcode
*opcode
,
1361 const struct mips_operand
*(*decode_operand
) (const char *),
1362 unsigned int insn
, bfd_vma base_pc
)
1364 const fprintf_ftype infprintf
= info
->fprintf_func
;
1365 void *is
= info
->stream
;
1366 struct mips_print_arg_state state
;
1367 const struct mips_operand
*operand
;
1370 init_print_arg_state (&state
);
1371 for (s
= opcode
->args
; *s
; ++s
)
1378 infprintf (is
, "%c", *s
);
1383 infprintf (is
, "%c%c", *s
, *s
);
1387 operand
= decode_operand (s
);
1390 /* xgettext:c-format */
1392 _("# internal error, undefined operand in `%s %s'"),
1393 opcode
->name
, opcode
->args
);
1396 if (operand
->type
== OP_REG
1399 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1401 /* Coprocessor register 0 with sel field (MT ASE). */
1402 const struct mips_cp0sel_name
*n
;
1403 unsigned int reg
, sel
;
1405 reg
= mips_extract_operand (operand
, insn
);
1407 operand
= decode_operand (s
);
1408 sel
= mips_extract_operand (operand
, insn
);
1410 /* CP0 register including 'sel' code for mftc0, to be
1411 printed textually if known. If not known, print both
1412 CP0 register name and sel numerically since CP0 register
1413 with sel 0 may have a name unrelated to register being
1415 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1416 mips_cp0sel_names_len
,
1419 infprintf (is
, "%s", n
->name
);
1421 infprintf (is
, "$%d,%d", reg
, sel
);
1424 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1425 mips_extract_operand (operand
, insn
));
1426 if (*s
== 'm' || *s
== '+')
1433 /* Print the mips instruction at address MEMADDR in debugged memory,
1434 on using INFO. Returns length of the instruction, in bytes, which is
1435 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1436 this is little-endian code. */
1439 print_insn_mips (bfd_vma memaddr
,
1441 struct disassemble_info
*info
)
1443 #define GET_OP(insn, field) \
1444 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1445 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1446 const fprintf_ftype infprintf
= info
->fprintf_func
;
1447 const struct mips_opcode
*op
;
1448 static bfd_boolean init
= 0;
1449 void *is
= info
->stream
;
1451 /* Build a hash table to shorten the search time. */
1456 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1458 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1460 if (op
->pinfo
== INSN_MACRO
1461 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1463 if (i
== GET_OP (op
->match
, OP
))
1474 info
->bytes_per_chunk
= INSNLEN
;
1475 info
->display_endian
= info
->endian
;
1476 info
->insn_info_valid
= 1;
1477 info
->branch_delay_insns
= 0;
1478 info
->data_size
= 0;
1479 info
->insn_type
= dis_nonbranch
;
1483 op
= mips_hash
[GET_OP (word
, OP
)];
1486 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1488 if (op
->pinfo
!= INSN_MACRO
1489 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1490 && (word
& op
->mask
) == op
->match
)
1492 /* We always allow to disassemble the jalx instruction. */
1493 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1494 && strcmp (op
->name
, "jalx"))
1497 /* Figure out instruction type and branch delay information. */
1498 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1500 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1501 info
->insn_type
= dis_jsr
;
1503 info
->insn_type
= dis_branch
;
1504 info
->branch_delay_insns
= 1;
1506 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1507 | INSN_COND_BRANCH_LIKELY
)) != 0)
1509 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1510 info
->insn_type
= dis_condjsr
;
1512 info
->insn_type
= dis_condbranch
;
1513 info
->branch_delay_insns
= 1;
1515 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1516 | INSN_LOAD_MEMORY
)) != 0)
1517 info
->insn_type
= dis_dref
;
1519 infprintf (is
, "%s", op
->name
);
1520 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1524 infprintf (is
, ".");
1525 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1526 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1531 infprintf (is
, "\t");
1532 print_insn_args (info
, op
, decode_mips_operand
, word
,
1542 /* Handle undefined instructions. */
1543 info
->insn_type
= dis_noninsn
;
1544 infprintf (is
, "0x%x", word
);
1548 /* Disassemble an operand for a mips16 instruction. */
1551 print_mips16_insn_arg (struct disassemble_info
*info
,
1552 struct mips_print_arg_state
*state
,
1553 const struct mips_opcode
*opcode
,
1554 char type
, bfd_vma memaddr
,
1555 unsigned insn
, bfd_boolean use_extend
,
1556 unsigned extend
, bfd_boolean is_offset
)
1558 const fprintf_ftype infprintf
= info
->fprintf_func
;
1559 void *is
= info
->stream
;
1560 const struct mips_operand
*operand
, *ext_operand
;
1572 infprintf (is
, "%c", type
);
1576 operand
= decode_mips16_operand (type
, FALSE
);
1579 /* xgettext:c-format */
1580 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
1581 opcode
->name
, opcode
->args
);
1585 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1587 /* Handle this case here because of the complex interation
1588 with the EXTEND opcode. */
1589 unsigned int amask
, nargs
, nstatics
, nsreg
, smask
, frame_size
, i
, j
;
1592 amask
= extend
& 0xf;
1593 if (amask
== MIPS16_ALL_ARGS
)
1598 else if (amask
== MIPS16_ALL_STATICS
)
1606 nstatics
= amask
& 3;
1612 infprintf (is
, "%s", mips_gpr_names
[4]);
1614 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1618 frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
1619 if (frame_size
== 0 && !use_extend
)
1621 infprintf (is
, "%s%d", sep
, frame_size
);
1623 if (insn
& 0x40) /* $ra */
1624 infprintf (is
, ",%s", mips_gpr_names
[31]);
1626 nsreg
= (extend
>> 8) & 0x7;
1628 if (insn
& 0x20) /* $s0 */
1630 if (insn
& 0x10) /* $s1 */
1632 if (nsreg
> 0) /* $s2-$s8 */
1633 smask
|= ((1 << nsreg
) - 1) << 2;
1635 for (i
= 0; i
< 9; i
++)
1636 if (smask
& (1 << i
))
1638 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1639 /* Skip over string of set bits. */
1640 for (j
= i
; smask
& (2 << j
); j
++)
1643 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1646 /* Statics $ax - $a3. */
1648 infprintf (is
, ",%s", mips_gpr_names
[7]);
1649 else if (nstatics
> 0)
1650 infprintf (is
, ",%s-%s",
1651 mips_gpr_names
[7 - nstatics
+ 1],
1656 if (is_offset
&& operand
->type
== OP_INT
)
1658 const struct mips_int_operand
*int_op
;
1660 int_op
= (const struct mips_int_operand
*) operand
;
1661 info
->insn_type
= dis_dref
;
1662 info
->data_size
= 1 << int_op
->shift
;
1665 if (operand
->size
== 26)
1666 /* In this case INSN is the first two bytes of the instruction
1667 and EXTEND is the second two bytes. */
1668 uval
= ((insn
& 0x1f) << 21) | ((insn
& 0x3e0) << 11) | extend
;
1671 /* Calculate the full field value. */
1672 uval
= mips_extract_operand (operand
, insn
);
1675 ext_operand
= decode_mips16_operand (type
, TRUE
);
1676 if (ext_operand
!= operand
)
1678 operand
= ext_operand
;
1679 if (operand
->size
== 16)
1680 uval
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1681 else if (operand
->size
== 15)
1682 uval
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1684 uval
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1689 baseaddr
= memaddr
+ 2;
1690 if (operand
->type
== OP_PCREL
)
1692 const struct mips_pcrel_operand
*pcrel_op
;
1694 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1695 if (!pcrel_op
->include_isa_bit
&& use_extend
)
1696 baseaddr
= memaddr
- 2;
1697 else if (!pcrel_op
->include_isa_bit
)
1701 /* If this instruction is in the delay slot of a JR
1702 instruction, the base address is the address of the
1703 JR instruction. If it is in the delay slot of a JALR
1704 instruction, the base address is the address of the
1705 JALR instruction. This test is unreliable: we have
1706 no way of knowing whether the previous word is
1707 instruction or data. */
1708 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
1709 && (((info
->endian
== BFD_ENDIAN_BIG
1710 ? bfd_getb16 (buffer
)
1711 : bfd_getl16 (buffer
))
1712 & 0xf800) == 0x1800))
1713 baseaddr
= memaddr
- 4;
1714 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
1716 && (((info
->endian
== BFD_ENDIAN_BIG
1717 ? bfd_getb16 (buffer
)
1718 : bfd_getl16 (buffer
))
1719 & 0xf81f) == 0xe800))
1720 baseaddr
= memaddr
- 2;
1726 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
1732 /* Check if the given address is the last word of a MIPS16 PLT entry.
1733 This word is data and depending on the value it may interfere with
1734 disassembly of further PLT entries. We make use of the fact PLT
1735 symbols are marked BSF_SYNTHETIC. */
1737 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
1741 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
1742 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
1748 /* Disassemble mips16 instructions. */
1751 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
1753 const fprintf_ftype infprintf
= info
->fprintf_func
;
1758 bfd_boolean use_extend
;
1760 const struct mips_opcode
*op
, *opend
;
1761 struct mips_print_arg_state state
;
1762 void *is
= info
->stream
;
1764 info
->bytes_per_chunk
= 2;
1765 info
->display_endian
= info
->endian
;
1766 info
->insn_info_valid
= 1;
1767 info
->branch_delay_insns
= 0;
1768 info
->data_size
= 0;
1772 #define GET_OP(insn, field) \
1773 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1774 /* Decode PLT entry's GOT slot address word. */
1775 if (is_mips16_plt_tail (info
, memaddr
))
1777 info
->insn_type
= dis_noninsn
;
1778 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
1781 unsigned int gotslot
;
1783 if (info
->endian
== BFD_ENDIAN_BIG
)
1784 gotslot
= bfd_getb32 (buffer
);
1786 gotslot
= bfd_getl32 (buffer
);
1787 infprintf (is
, ".word\t0x%x", gotslot
);
1794 info
->insn_type
= dis_nonbranch
;
1795 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1799 (*info
->memory_error_func
) (status
, memaddr
, info
);
1805 if (info
->endian
== BFD_ENDIAN_BIG
)
1806 insn
= bfd_getb16 (buffer
);
1808 insn
= bfd_getl16 (buffer
);
1810 /* Handle the extend opcode specially. */
1812 if ((insn
& 0xf800) == 0xf000)
1815 extend
= insn
& 0x7ff;
1819 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1822 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1823 (*info
->memory_error_func
) (status
, memaddr
, info
);
1827 if (info
->endian
== BFD_ENDIAN_BIG
)
1828 insn
= bfd_getb16 (buffer
);
1830 insn
= bfd_getl16 (buffer
);
1832 /* Check for an extend opcode followed by an extend opcode. */
1833 if ((insn
& 0xf800) == 0xf000)
1835 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1836 info
->insn_type
= dis_noninsn
;
1843 /* FIXME: Should probably use a hash table on the major opcode here. */
1845 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
1846 for (op
= mips16_opcodes
; op
< opend
; op
++)
1848 if (op
->pinfo
!= INSN_MACRO
1849 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1850 && (insn
& op
->mask
) == op
->match
)
1854 if (op
->args
[0] == 'a' || op
->args
[0] == 'i')
1858 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1859 info
->insn_type
= dis_noninsn
;
1867 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
1872 if (info
->endian
== BFD_ENDIAN_BIG
)
1873 extend
= bfd_getb16 (buffer
);
1875 extend
= bfd_getl16 (buffer
);
1880 infprintf (is
, "%s", op
->name
);
1881 if (op
->args
[0] != '\0')
1882 infprintf (is
, "\t");
1884 init_print_arg_state (&state
);
1885 for (s
= op
->args
; *s
!= '\0'; s
++)
1889 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
1891 /* Skip the register and the comma. */
1897 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
1899 /* Skip the register and the comma. */
1903 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
, insn
,
1904 use_extend
, extend
, s
[1] == '(');
1907 /* Figure out branch instruction type and delay slot information. */
1908 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1909 info
->branch_delay_insns
= 1;
1910 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
1911 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
1913 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1914 info
->insn_type
= dis_jsr
;
1916 info
->insn_type
= dis_branch
;
1918 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
1919 info
->insn_type
= dis_condbranch
;
1927 infprintf (is
, "0x%x", extend
| 0xf000);
1928 infprintf (is
, "0x%x", insn
);
1929 info
->insn_type
= dis_noninsn
;
1934 /* Disassemble microMIPS instructions. */
1937 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
1939 const fprintf_ftype infprintf
= info
->fprintf_func
;
1940 const struct mips_opcode
*op
, *opend
;
1941 void *is
= info
->stream
;
1943 unsigned int higher
;
1944 unsigned int length
;
1948 info
->bytes_per_chunk
= 2;
1949 info
->display_endian
= info
->endian
;
1950 info
->insn_info_valid
= 1;
1951 info
->branch_delay_insns
= 0;
1952 info
->data_size
= 0;
1953 info
->insn_type
= dis_nonbranch
;
1957 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1960 (*info
->memory_error_func
) (status
, memaddr
, info
);
1966 if (info
->endian
== BFD_ENDIAN_BIG
)
1967 insn
= bfd_getb16 (buffer
);
1969 insn
= bfd_getl16 (buffer
);
1971 if ((insn
& 0xfc00) == 0x7c00)
1973 /* This is a 48-bit microMIPS instruction. */
1976 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
1979 infprintf (is
, "micromips 0x%x", higher
);
1980 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
1983 if (info
->endian
== BFD_ENDIAN_BIG
)
1984 insn
= bfd_getb16 (buffer
);
1986 insn
= bfd_getl16 (buffer
);
1987 higher
= (higher
<< 16) | insn
;
1989 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
1992 infprintf (is
, "micromips 0x%x", higher
);
1993 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
1996 if (info
->endian
== BFD_ENDIAN_BIG
)
1997 insn
= bfd_getb16 (buffer
);
1999 insn
= bfd_getl16 (buffer
);
2000 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2002 info
->insn_type
= dis_noninsn
;
2005 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2007 /* This is a 32-bit microMIPS instruction. */
2010 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2013 infprintf (is
, "micromips 0x%x", higher
);
2014 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2018 if (info
->endian
== BFD_ENDIAN_BIG
)
2019 insn
= bfd_getb16 (buffer
);
2021 insn
= bfd_getl16 (buffer
);
2023 insn
= insn
| (higher
<< 16);
2028 /* FIXME: Should probably use a hash table on the major opcode here. */
2030 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2031 for (op
= micromips_opcodes
; op
< opend
; op
++)
2033 if (op
->pinfo
!= INSN_MACRO
2034 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2035 && (insn
& op
->mask
) == op
->match
2036 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2037 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2039 infprintf (is
, "%s", op
->name
);
2043 infprintf (is
, "\t");
2044 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2045 memaddr
+ length
+ 1);
2048 /* Figure out instruction type and branch delay information. */
2050 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2051 info
->branch_delay_insns
= 1;
2052 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2053 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2055 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2056 info
->insn_type
= dis_jsr
;
2058 info
->insn_type
= dis_branch
;
2060 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2061 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2063 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2064 info
->insn_type
= dis_condjsr
;
2066 info
->insn_type
= dis_condbranch
;
2069 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2070 info
->insn_type
= dis_dref
;
2076 infprintf (is
, "0x%x", insn
);
2077 info
->insn_type
= dis_noninsn
;
2082 /* Return 1 if a symbol associated with the location being disassembled
2083 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2084 all the symbols at the address being considered assuming if at least
2085 one of them indicates code compression, then such code has been
2086 genuinely produced here (other symbols could have been derived from
2087 function symbols defined elsewhere or could define data). Otherwise,
2091 is_compressed_mode_p (struct disassemble_info
*info
)
2096 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2097 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2099 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2101 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2103 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2104 && info
->symtab
[i
]->section
== info
->section
)
2106 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2108 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2110 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2117 /* In an environment where we do not know the symbol type of the
2118 instruction we are forced to assume that the low order bit of the
2119 instructions' address may mark it as a mips16 instruction. If we
2120 are single stepping, or the pc is within the disassembled function,
2121 this works. Otherwise, we need a clue. Sometimes. */
2124 _print_insn_mips (bfd_vma memaddr
,
2125 struct disassemble_info
*info
,
2126 enum bfd_endian endianness
)
2128 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
2129 bfd_byte buffer
[INSNLEN
];
2132 set_default_mips_dis_options (info
);
2133 parse_mips_dis_options (info
->disassembler_options
);
2135 if (info
->mach
== bfd_mach_mips16
)
2136 return print_insn_mips16 (memaddr
, info
);
2137 if (info
->mach
== bfd_mach_mips_micromips
)
2138 return print_insn_micromips (memaddr
, info
);
2140 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
2143 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2144 /* Only a few tools will work this way. */
2146 return print_insn_compr (memaddr
, info
);
2149 #if SYMTAB_AVAILABLE
2150 if (is_compressed_mode_p (info
))
2151 return print_insn_compr (memaddr
, info
);
2154 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2159 if (endianness
== BFD_ENDIAN_BIG
)
2160 insn
= bfd_getb32 (buffer
);
2162 insn
= bfd_getl32 (buffer
);
2164 return print_insn_mips (memaddr
, insn
, info
);
2168 (*info
->memory_error_func
) (status
, memaddr
, info
);
2174 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2176 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2180 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2182 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2186 print_mips_disassembler_options (FILE *stream
)
2190 fprintf (stream
, _("\n\
2191 The following MIPS specific disassembler options are supported for use\n\
2192 with the -M switch (multiple options should be separated by commas):\n"));
2194 fprintf (stream
, _("\n\
2195 msa Recognize MSA instructions.\n"));
2197 fprintf (stream
, _("\n\
2198 virt Recognize the virtualization ASE instructions.\n"));
2200 fprintf (stream
, _("\n\
2201 gpr-names=ABI Print GPR names according to specified ABI.\n\
2202 Default: based on binary being disassembled.\n"));
2204 fprintf (stream
, _("\n\
2205 fpr-names=ABI Print FPR names according to specified ABI.\n\
2206 Default: numeric.\n"));
2208 fprintf (stream
, _("\n\
2209 cp0-names=ARCH Print CP0 register names according to\n\
2210 specified architecture.\n\
2211 Default: based on binary being disassembled.\n"));
2213 fprintf (stream
, _("\n\
2214 hwr-names=ARCH Print HWR names according to specified \n\
2216 Default: based on binary being disassembled.\n"));
2218 fprintf (stream
, _("\n\
2219 reg-names=ABI Print GPR and FPR names according to\n\
2220 specified ABI.\n"));
2222 fprintf (stream
, _("\n\
2223 reg-names=ARCH Print CP0 register and HWR names according to\n\
2224 specified architecture.\n"));
2226 fprintf (stream
, _("\n\
2227 For the options above, the following values are supported for \"ABI\":\n\
2229 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2230 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2231 fprintf (stream
, _("\n"));
2233 fprintf (stream
, _("\n\
2234 For the options above, The following values are supported for \"ARCH\":\n\
2236 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2237 if (*mips_arch_choices
[i
].name
!= '\0')
2238 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2239 fprintf (stream
, _("\n"));
2241 fprintf (stream
, _("\n"));