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 /* The mips16 registers. */
55 static const unsigned int mips16_to_32_reg_map
[] =
57 16, 17, 2, 3, 4, 5, 6, 7
60 #define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]]
63 static const char * const mips_gpr_names_numeric
[32] =
65 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
66 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
67 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
68 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
71 static const char * const mips_gpr_names_oldabi
[32] =
73 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
74 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
75 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
76 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
79 static const char * const mips_gpr_names_newabi
[32] =
81 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
82 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
83 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
84 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
87 static const char * const mips_fpr_names_numeric
[32] =
89 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
90 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
91 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
92 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
95 static const char * const mips_fpr_names_32
[32] =
97 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
98 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
99 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
100 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
103 static const char * const mips_fpr_names_n32
[32] =
105 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
106 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
107 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
108 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
111 static const char * const mips_fpr_names_64
[32] =
113 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
114 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
115 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
116 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
119 static const char * const mips_cp0_names_numeric
[32] =
121 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
122 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
123 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
124 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
127 static const char * const mips_cp0_names_r3000
[32] =
129 "c0_index", "c0_random", "c0_entrylo", "$3",
130 "c0_context", "$5", "$6", "$7",
131 "c0_badvaddr", "$9", "c0_entryhi", "$11",
132 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
133 "$16", "$17", "$18", "$19",
134 "$20", "$21", "$22", "$23",
135 "$24", "$25", "$26", "$27",
136 "$28", "$29", "$30", "$31",
139 static const char * const mips_cp0_names_r4000
[32] =
141 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
142 "c0_context", "c0_pagemask", "c0_wired", "$7",
143 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
144 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
145 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
146 "c0_xcontext", "$21", "$22", "$23",
147 "$24", "$25", "c0_ecc", "c0_cacheerr",
148 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
151 static const char * const mips_cp0_names_r5900
[32] =
153 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
154 "c0_context", "c0_pagemask", "c0_wired", "$7",
155 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
156 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
157 "c0_config", "$17", "$18", "$19",
158 "$20", "$21", "$22", "c0_badpaddr",
159 "c0_depc", "c0_perfcnt", "$26", "$27",
160 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
163 static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900
[] =
166 { 24, 3, "c0_iabm" },
168 { 24, 5, "c0_dabm" },
170 { 24, 7, "c0_dvbm" },
171 { 25, 1, "c0_perfcnt,1" },
172 { 25, 2, "c0_perfcnt,2" }
175 static const char * const mips_cp0_names_mips3264
[32] =
177 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
178 "c0_context", "c0_pagemask", "c0_wired", "$7",
179 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
180 "c0_status", "c0_cause", "c0_epc", "c0_prid",
181 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
182 "c0_xcontext", "$21", "$22", "c0_debug",
183 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
184 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
187 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] =
189 { 16, 1, "c0_config1" },
190 { 16, 2, "c0_config2" },
191 { 16, 3, "c0_config3" },
192 { 18, 1, "c0_watchlo,1" },
193 { 18, 2, "c0_watchlo,2" },
194 { 18, 3, "c0_watchlo,3" },
195 { 18, 4, "c0_watchlo,4" },
196 { 18, 5, "c0_watchlo,5" },
197 { 18, 6, "c0_watchlo,6" },
198 { 18, 7, "c0_watchlo,7" },
199 { 19, 1, "c0_watchhi,1" },
200 { 19, 2, "c0_watchhi,2" },
201 { 19, 3, "c0_watchhi,3" },
202 { 19, 4, "c0_watchhi,4" },
203 { 19, 5, "c0_watchhi,5" },
204 { 19, 6, "c0_watchhi,6" },
205 { 19, 7, "c0_watchhi,7" },
206 { 25, 1, "c0_perfcnt,1" },
207 { 25, 2, "c0_perfcnt,2" },
208 { 25, 3, "c0_perfcnt,3" },
209 { 25, 4, "c0_perfcnt,4" },
210 { 25, 5, "c0_perfcnt,5" },
211 { 25, 6, "c0_perfcnt,6" },
212 { 25, 7, "c0_perfcnt,7" },
213 { 27, 1, "c0_cacheerr,1" },
214 { 27, 2, "c0_cacheerr,2" },
215 { 27, 3, "c0_cacheerr,3" },
216 { 28, 1, "c0_datalo" },
217 { 29, 1, "c0_datahi" }
220 static const char * const mips_cp0_names_mips3264r2
[32] =
222 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
223 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
224 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
225 "c0_status", "c0_cause", "c0_epc", "c0_prid",
226 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
227 "c0_xcontext", "$21", "$22", "c0_debug",
228 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
229 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
232 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] =
234 { 4, 1, "c0_contextconfig" },
235 { 0, 1, "c0_mvpcontrol" },
236 { 0, 2, "c0_mvpconf0" },
237 { 0, 3, "c0_mvpconf1" },
238 { 1, 1, "c0_vpecontrol" },
239 { 1, 2, "c0_vpeconf0" },
240 { 1, 3, "c0_vpeconf1" },
241 { 1, 4, "c0_yqmask" },
242 { 1, 5, "c0_vpeschedule" },
243 { 1, 6, "c0_vpeschefback" },
244 { 2, 1, "c0_tcstatus" },
245 { 2, 2, "c0_tcbind" },
246 { 2, 3, "c0_tcrestart" },
247 { 2, 4, "c0_tchalt" },
248 { 2, 5, "c0_tccontext" },
249 { 2, 6, "c0_tcschedule" },
250 { 2, 7, "c0_tcschefback" },
251 { 5, 1, "c0_pagegrain" },
252 { 6, 1, "c0_srsconf0" },
253 { 6, 2, "c0_srsconf1" },
254 { 6, 3, "c0_srsconf2" },
255 { 6, 4, "c0_srsconf3" },
256 { 6, 5, "c0_srsconf4" },
257 { 12, 1, "c0_intctl" },
258 { 12, 2, "c0_srsctl" },
259 { 12, 3, "c0_srsmap" },
260 { 15, 1, "c0_ebase" },
261 { 16, 1, "c0_config1" },
262 { 16, 2, "c0_config2" },
263 { 16, 3, "c0_config3" },
264 { 18, 1, "c0_watchlo,1" },
265 { 18, 2, "c0_watchlo,2" },
266 { 18, 3, "c0_watchlo,3" },
267 { 18, 4, "c0_watchlo,4" },
268 { 18, 5, "c0_watchlo,5" },
269 { 18, 6, "c0_watchlo,6" },
270 { 18, 7, "c0_watchlo,7" },
271 { 19, 1, "c0_watchhi,1" },
272 { 19, 2, "c0_watchhi,2" },
273 { 19, 3, "c0_watchhi,3" },
274 { 19, 4, "c0_watchhi,4" },
275 { 19, 5, "c0_watchhi,5" },
276 { 19, 6, "c0_watchhi,6" },
277 { 19, 7, "c0_watchhi,7" },
278 { 23, 1, "c0_tracecontrol" },
279 { 23, 2, "c0_tracecontrol2" },
280 { 23, 3, "c0_usertracedata" },
281 { 23, 4, "c0_tracebpc" },
282 { 25, 1, "c0_perfcnt,1" },
283 { 25, 2, "c0_perfcnt,2" },
284 { 25, 3, "c0_perfcnt,3" },
285 { 25, 4, "c0_perfcnt,4" },
286 { 25, 5, "c0_perfcnt,5" },
287 { 25, 6, "c0_perfcnt,6" },
288 { 25, 7, "c0_perfcnt,7" },
289 { 27, 1, "c0_cacheerr,1" },
290 { 27, 2, "c0_cacheerr,2" },
291 { 27, 3, "c0_cacheerr,3" },
292 { 28, 1, "c0_datalo" },
293 { 28, 2, "c0_taglo1" },
294 { 28, 3, "c0_datalo1" },
295 { 28, 4, "c0_taglo2" },
296 { 28, 5, "c0_datalo2" },
297 { 28, 6, "c0_taglo3" },
298 { 28, 7, "c0_datalo3" },
299 { 29, 1, "c0_datahi" },
300 { 29, 2, "c0_taghi1" },
301 { 29, 3, "c0_datahi1" },
302 { 29, 4, "c0_taghi2" },
303 { 29, 5, "c0_datahi2" },
304 { 29, 6, "c0_taghi3" },
305 { 29, 7, "c0_datahi3" },
308 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
309 static const char * const mips_cp0_names_sb1
[32] =
311 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
312 "c0_context", "c0_pagemask", "c0_wired", "$7",
313 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
314 "c0_status", "c0_cause", "c0_epc", "c0_prid",
315 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
316 "c0_xcontext", "$21", "$22", "c0_debug",
317 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
318 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
321 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] =
323 { 16, 1, "c0_config1" },
324 { 18, 1, "c0_watchlo,1" },
325 { 19, 1, "c0_watchhi,1" },
326 { 22, 0, "c0_perftrace" },
327 { 23, 3, "c0_edebug" },
328 { 25, 1, "c0_perfcnt,1" },
329 { 25, 2, "c0_perfcnt,2" },
330 { 25, 3, "c0_perfcnt,3" },
331 { 25, 4, "c0_perfcnt,4" },
332 { 25, 5, "c0_perfcnt,5" },
333 { 25, 6, "c0_perfcnt,6" },
334 { 25, 7, "c0_perfcnt,7" },
335 { 26, 1, "c0_buserr_pa" },
336 { 27, 1, "c0_cacheerr_d" },
337 { 27, 3, "c0_cacheerr_d_pa" },
338 { 28, 1, "c0_datalo_i" },
339 { 28, 2, "c0_taglo_d" },
340 { 28, 3, "c0_datalo_d" },
341 { 29, 1, "c0_datahi_i" },
342 { 29, 2, "c0_taghi_d" },
343 { 29, 3, "c0_datahi_d" },
346 /* Xlr cop0 register names. */
347 static const char * const mips_cp0_names_xlr
[32] = {
348 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
349 "c0_context", "c0_pagemask", "c0_wired", "$7",
350 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
351 "c0_status", "c0_cause", "c0_epc", "c0_prid",
352 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
353 "c0_xcontext", "$21", "$22", "c0_debug",
354 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
355 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
358 /* XLR's CP0 Select Registers. */
360 static const struct mips_cp0sel_name mips_cp0sel_names_xlr
[] = {
361 { 9, 6, "c0_extintreq" },
362 { 9, 7, "c0_extintmask" },
363 { 15, 1, "c0_ebase" },
364 { 16, 1, "c0_config1" },
365 { 16, 2, "c0_config2" },
366 { 16, 3, "c0_config3" },
367 { 16, 7, "c0_procid2" },
368 { 18, 1, "c0_watchlo,1" },
369 { 18, 2, "c0_watchlo,2" },
370 { 18, 3, "c0_watchlo,3" },
371 { 18, 4, "c0_watchlo,4" },
372 { 18, 5, "c0_watchlo,5" },
373 { 18, 6, "c0_watchlo,6" },
374 { 18, 7, "c0_watchlo,7" },
375 { 19, 1, "c0_watchhi,1" },
376 { 19, 2, "c0_watchhi,2" },
377 { 19, 3, "c0_watchhi,3" },
378 { 19, 4, "c0_watchhi,4" },
379 { 19, 5, "c0_watchhi,5" },
380 { 19, 6, "c0_watchhi,6" },
381 { 19, 7, "c0_watchhi,7" },
382 { 25, 1, "c0_perfcnt,1" },
383 { 25, 2, "c0_perfcnt,2" },
384 { 25, 3, "c0_perfcnt,3" },
385 { 25, 4, "c0_perfcnt,4" },
386 { 25, 5, "c0_perfcnt,5" },
387 { 25, 6, "c0_perfcnt,6" },
388 { 25, 7, "c0_perfcnt,7" },
389 { 27, 1, "c0_cacheerr,1" },
390 { 27, 2, "c0_cacheerr,2" },
391 { 27, 3, "c0_cacheerr,3" },
392 { 28, 1, "c0_datalo" },
393 { 29, 1, "c0_datahi" }
396 static const char * const mips_hwr_names_numeric
[32] =
398 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
399 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
400 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
401 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
404 static const char * const mips_hwr_names_mips3264r2
[32] =
406 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
407 "$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 struct mips_abi_choice
416 const char * const *gpr_names
;
417 const char * const *fpr_names
;
420 struct mips_abi_choice mips_abi_choices
[] =
422 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
423 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
424 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
425 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
428 struct mips_arch_choice
432 unsigned long bfd_mach
;
436 const char * const *cp0_names
;
437 const struct mips_cp0sel_name
*cp0sel_names
;
438 unsigned int cp0sel_names_len
;
439 const char * const *hwr_names
;
442 const struct mips_arch_choice mips_arch_choices
[] =
444 { "numeric", 0, 0, 0, 0, 0,
445 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
447 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
, 0,
448 mips_cp0_names_r3000
, NULL
, 0, mips_hwr_names_numeric
},
449 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
, 0,
450 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
451 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
, 0,
452 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
453 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
, 0,
454 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
455 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
, 0,
456 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
457 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
, 0,
458 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
459 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
, 0,
460 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
461 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
, 0,
462 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
463 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
, 0,
464 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
465 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
, 0,
466 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
467 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
, 0,
468 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
469 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
, 0,
470 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
471 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
, 0,
472 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
473 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
, 0,
474 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
475 { "r5900", 1, bfd_mach_mips5900
, CPU_R5900
, ISA_MIPS3
, 0,
476 mips_cp0_names_r5900
, NULL
, 0, mips_hwr_names_numeric
},
477 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
, 0,
478 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
479 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
480 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
481 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
482 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
483 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
, 0,
484 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
485 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
, 0,
486 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
487 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
, 0,
488 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
489 { "r14000", 1, bfd_mach_mips14000
, CPU_R14000
, ISA_MIPS4
, 0,
490 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
491 { "r16000", 1, bfd_mach_mips16000
, CPU_R16000
, ISA_MIPS4
, 0,
492 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
493 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
, 0,
494 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
496 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
497 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
498 _MIPS32 Architecture For Programmers Volume I: Introduction to the
499 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
501 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
502 ISA_MIPS32
, ASE_SMARTMIPS
,
503 mips_cp0_names_mips3264
,
504 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
505 mips_hwr_names_numeric
},
507 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
509 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
510 | ASE_MT
| ASE_MCU
| ASE_VIRT
),
511 mips_cp0_names_mips3264r2
,
512 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
513 mips_hwr_names_mips3264r2
},
515 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
516 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
517 ISA_MIPS64
, ASE_MIPS3D
| ASE_MDMX
,
518 mips_cp0_names_mips3264
,
519 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
520 mips_hwr_names_numeric
},
522 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
524 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
525 | ASE_MDMX
| ASE_MCU
| ASE_VIRT
| ASE_VIRT64
),
526 mips_cp0_names_mips3264r2
,
527 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
528 mips_hwr_names_mips3264r2
},
530 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
531 ISA_MIPS64
| INSN_SB1
, ASE_MIPS3D
,
533 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
534 mips_hwr_names_numeric
},
536 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
537 ISA_MIPS3
| INSN_LOONGSON_2E
, 0, mips_cp0_names_numeric
,
538 NULL
, 0, mips_hwr_names_numeric
},
540 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
541 ISA_MIPS3
| INSN_LOONGSON_2F
, 0, mips_cp0_names_numeric
,
542 NULL
, 0, mips_hwr_names_numeric
},
544 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
545 ISA_MIPS64
| INSN_LOONGSON_3A
, 0, mips_cp0_names_numeric
,
546 NULL
, 0, mips_hwr_names_numeric
},
548 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
549 ISA_MIPS64R2
| INSN_OCTEON
, 0, mips_cp0_names_numeric
, NULL
, 0,
550 mips_hwr_names_numeric
},
552 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
553 ISA_MIPS64R2
| INSN_OCTEONP
, 0, mips_cp0_names_numeric
,
554 NULL
, 0, mips_hwr_names_numeric
},
556 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
557 ISA_MIPS64R2
| INSN_OCTEON2
, 0, mips_cp0_names_numeric
,
558 NULL
, 0, mips_hwr_names_numeric
},
560 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
561 ISA_MIPS64
| INSN_XLR
, 0,
563 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
564 mips_hwr_names_numeric
},
566 /* XLP is mostly like XLR, with the prominent exception it is being
568 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
569 ISA_MIPS64R2
| INSN_XLR
, 0,
571 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
572 mips_hwr_names_numeric
},
574 /* This entry, mips16, is here only for ISA/processor selection; do
575 not print its name. */
576 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
, 0,
577 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
580 /* ISA and processor type to disassemble for, and register names to use.
581 set_default_mips_dis_options and parse_mips_dis_options fill in these
583 static int mips_processor
;
586 static int micromips_ase
;
587 static const char * const *mips_gpr_names
;
588 static const char * const *mips_fpr_names
;
589 static const char * const *mips_cp0_names
;
590 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
591 static int mips_cp0sel_names_len
;
592 static const char * const *mips_hwr_names
;
595 static int no_aliases
; /* If set disassemble as most general inst. */
597 static const struct mips_abi_choice
*
598 choose_abi_by_name (const char *name
, unsigned int namelen
)
600 const struct mips_abi_choice
*c
;
603 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
604 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
605 && strlen (mips_abi_choices
[i
].name
) == namelen
)
606 c
= &mips_abi_choices
[i
];
611 static const struct mips_arch_choice
*
612 choose_arch_by_name (const char *name
, unsigned int namelen
)
614 const struct mips_arch_choice
*c
= NULL
;
617 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
618 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
619 && strlen (mips_arch_choices
[i
].name
) == namelen
)
620 c
= &mips_arch_choices
[i
];
625 static const struct mips_arch_choice
*
626 choose_arch_by_number (unsigned long mach
)
628 static unsigned long hint_bfd_mach
;
629 static const struct mips_arch_choice
*hint_arch_choice
;
630 const struct mips_arch_choice
*c
;
633 /* We optimize this because even if the user specifies no
634 flags, this will be done for every instruction! */
635 if (hint_bfd_mach
== mach
636 && hint_arch_choice
!= NULL
637 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
638 return hint_arch_choice
;
640 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
642 if (mips_arch_choices
[i
].bfd_mach_valid
643 && mips_arch_choices
[i
].bfd_mach
== mach
)
645 c
= &mips_arch_choices
[i
];
646 hint_bfd_mach
= mach
;
647 hint_arch_choice
= c
;
653 /* Check if the object uses NewABI conventions. */
656 is_newabi (Elf_Internal_Ehdr
*header
)
658 /* There are no old-style ABIs which use 64-bit ELF. */
659 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
662 /* If a 32-bit ELF file, n32 is a new-style ABI. */
663 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
669 /* Check if the object has microMIPS ASE code. */
672 is_micromips (Elf_Internal_Ehdr
*header
)
674 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
681 set_default_mips_dis_options (struct disassemble_info
*info
)
683 const struct mips_arch_choice
*chosen_arch
;
685 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
686 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
687 CP0 register, and HWR names. */
688 mips_isa
= ISA_MIPS3
;
689 mips_processor
= CPU_R3000
;
692 mips_gpr_names
= mips_gpr_names_oldabi
;
693 mips_fpr_names
= mips_fpr_names_numeric
;
694 mips_cp0_names
= mips_cp0_names_numeric
;
695 mips_cp0sel_names
= NULL
;
696 mips_cp0sel_names_len
= 0;
697 mips_hwr_names
= mips_hwr_names_numeric
;
700 /* Update settings according to the ELF file header flags. */
701 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
703 Elf_Internal_Ehdr
*header
;
705 header
= elf_elfheader (info
->section
->owner
);
706 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
707 if (is_newabi (header
))
708 mips_gpr_names
= mips_gpr_names_newabi
;
709 /* If a microMIPS binary, then don't use MIPS16 bindings. */
710 micromips_ase
= is_micromips (header
);
713 /* Set ISA, architecture, and cp0 register names as best we can. */
714 #if ! SYMTAB_AVAILABLE
715 /* This is running out on a target machine, not in a host tool.
716 FIXME: Where does mips_target_info come from? */
717 target_processor
= mips_target_info
.processor
;
718 mips_isa
= mips_target_info
.isa
;
719 mips_ase
= mips_target_info
.ase
;
721 chosen_arch
= choose_arch_by_number (info
->mach
);
722 if (chosen_arch
!= NULL
)
724 mips_processor
= chosen_arch
->processor
;
725 mips_isa
= chosen_arch
->isa
;
726 mips_ase
= chosen_arch
->ase
;
727 mips_cp0_names
= chosen_arch
->cp0_names
;
728 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
729 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
730 mips_hwr_names
= chosen_arch
->hwr_names
;
736 parse_mips_dis_option (const char *option
, unsigned int len
)
738 unsigned int i
, optionlen
, vallen
;
740 const struct mips_abi_choice
*chosen_abi
;
741 const struct mips_arch_choice
*chosen_arch
;
743 /* Try to match options that are simple flags */
744 if (CONST_STRNEQ (option
, "no-aliases"))
750 if (CONST_STRNEQ (option
, "virt"))
752 mips_ase
|= ASE_VIRT
;
753 if (mips_isa
& ISA_MIPS64R2
)
754 mips_ase
|= ASE_VIRT64
;
758 /* Look for the = that delimits the end of the option name. */
759 for (i
= 0; i
< len
; i
++)
760 if (option
[i
] == '=')
763 if (i
== 0) /* Invalid option: no name before '='. */
765 if (i
== len
) /* Invalid option: no '='. */
767 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
771 val
= option
+ (optionlen
+ 1);
772 vallen
= len
- (optionlen
+ 1);
774 if (strncmp ("gpr-names", option
, optionlen
) == 0
775 && strlen ("gpr-names") == optionlen
)
777 chosen_abi
= choose_abi_by_name (val
, vallen
);
778 if (chosen_abi
!= NULL
)
779 mips_gpr_names
= chosen_abi
->gpr_names
;
783 if (strncmp ("fpr-names", option
, optionlen
) == 0
784 && strlen ("fpr-names") == optionlen
)
786 chosen_abi
= choose_abi_by_name (val
, vallen
);
787 if (chosen_abi
!= NULL
)
788 mips_fpr_names
= chosen_abi
->fpr_names
;
792 if (strncmp ("cp0-names", option
, optionlen
) == 0
793 && strlen ("cp0-names") == optionlen
)
795 chosen_arch
= choose_arch_by_name (val
, vallen
);
796 if (chosen_arch
!= NULL
)
798 mips_cp0_names
= chosen_arch
->cp0_names
;
799 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
800 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
805 if (strncmp ("hwr-names", option
, optionlen
) == 0
806 && strlen ("hwr-names") == optionlen
)
808 chosen_arch
= choose_arch_by_name (val
, vallen
);
809 if (chosen_arch
!= NULL
)
810 mips_hwr_names
= chosen_arch
->hwr_names
;
814 if (strncmp ("reg-names", option
, optionlen
) == 0
815 && strlen ("reg-names") == optionlen
)
817 /* We check both ABI and ARCH here unconditionally, so
818 that "numeric" will do the desirable thing: select
819 numeric register names for all registers. Other than
820 that, a given name probably won't match both. */
821 chosen_abi
= choose_abi_by_name (val
, vallen
);
822 if (chosen_abi
!= NULL
)
824 mips_gpr_names
= chosen_abi
->gpr_names
;
825 mips_fpr_names
= chosen_abi
->fpr_names
;
827 chosen_arch
= choose_arch_by_name (val
, vallen
);
828 if (chosen_arch
!= NULL
)
830 mips_cp0_names
= chosen_arch
->cp0_names
;
831 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
832 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
833 mips_hwr_names
= chosen_arch
->hwr_names
;
838 /* Invalid option. */
842 parse_mips_dis_options (const char *options
)
844 const char *option_end
;
849 while (*options
!= '\0')
851 /* Skip empty options. */
858 /* We know that *options is neither NUL or a comma. */
859 option_end
= options
+ 1;
860 while (*option_end
!= ',' && *option_end
!= '\0')
863 parse_mips_dis_option (options
, option_end
- options
);
865 /* Go on to the next one. If option_end points to a comma, it
866 will be skipped above. */
867 options
= option_end
;
871 static const struct mips_cp0sel_name
*
872 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
879 for (i
= 0; i
< len
; i
++)
880 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
885 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
888 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
889 enum mips_reg_operand_type type
, int regno
)
894 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
898 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
902 if (opcode
->pinfo
& (FP_D
| FP_S
))
903 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
905 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
909 if (opcode
->membership
& INSN_5400
)
910 info
->fprintf_func (info
->stream
, "$f%d", regno
);
912 info
->fprintf_func (info
->stream
, "$v%d", regno
);
916 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
920 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
921 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
923 info
->fprintf_func (info
->stream
, "$%d", regno
);
927 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
932 /* Used to track the state carried over from previous operands in
934 struct mips_print_arg_state
{
935 /* The value of the last OP_INT seen. We only use this for OP_MSB,
936 where the value is known to be unsigned and small. */
937 unsigned int last_int
;
939 /* The type and number of the last OP_REG seen. We only use this for
940 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
941 enum mips_reg_operand_type last_reg_type
;
942 unsigned int last_regno
;
945 /* Initialize STATE for the start of an instruction. */
948 init_print_arg_state (struct mips_print_arg_state
*state
)
950 memset (state
, 0, sizeof (*state
));
953 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
954 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
955 the base address for OP_PCREL operands. */
958 print_insn_arg (struct disassemble_info
*info
,
959 struct mips_print_arg_state
*state
,
960 const struct mips_opcode
*opcode
,
961 const struct mips_operand
*operand
,
965 const fprintf_ftype infprintf
= info
->fprintf_func
;
966 void *is
= info
->stream
;
968 switch (operand
->type
)
972 const struct mips_int_operand
*int_op
;
974 int_op
= (const struct mips_int_operand
*) operand
;
975 uval
= mips_decode_int_operand (int_op
, uval
);
976 state
->last_int
= uval
;
977 if (int_op
->print_hex
)
978 infprintf (is
, "0x%x", uval
);
980 infprintf (is
, "%d", uval
);
986 const struct mips_mapped_int_operand
*mint_op
;
988 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
989 uval
= mint_op
->int_map
[uval
];
990 state
->last_int
= uval
;
991 if (mint_op
->print_hex
)
992 infprintf (is
, "0x%x", uval
);
994 infprintf (is
, "%d", uval
);
1000 const struct mips_msb_operand
*msb_op
;
1002 msb_op
= (const struct mips_msb_operand
*) operand
;
1003 uval
+= msb_op
->bias
;
1004 if (msb_op
->add_lsb
)
1005 uval
-= state
->last_int
;
1006 infprintf (is
, "0x%x", uval
);
1012 const struct mips_reg_operand
*reg_op
;
1014 reg_op
= (const struct mips_reg_operand
*) operand
;
1015 if (reg_op
->reg_map
)
1016 uval
= reg_op
->reg_map
[uval
];
1017 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1019 state
->last_reg_type
= reg_op
->reg_type
;
1020 state
->last_regno
= uval
;
1026 const struct mips_reg_pair_operand
*pair_op
;
1028 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1029 print_reg (info
, opcode
, pair_op
->reg_type
,
1030 pair_op
->reg1_map
[uval
]);
1031 infprintf (is
, ",");
1032 print_reg (info
, opcode
, pair_op
->reg_type
,
1033 pair_op
->reg2_map
[uval
]);
1039 const struct mips_pcrel_operand
*pcrel_op
;
1041 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1042 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1044 /* Preserve the ISA bit for the GDB disassembler,
1045 otherwise clear it. */
1046 if (info
->flavour
!= bfd_target_unknown_flavour
)
1049 (*info
->print_address_func
) (info
->target
, info
);
1054 infprintf (is
, "%d", uval
);
1057 case OP_ADDIUSP_INT
:
1061 sval
= mips_signed_operand (operand
, uval
) * 4;
1062 if (sval
>= -8 && sval
< 8)
1064 infprintf (is
, "%d", sval
);
1068 case OP_CLO_CLZ_DEST
:
1070 unsigned int reg1
, reg2
;
1074 /* If one is zero use the other. */
1075 if (reg1
== reg2
|| reg2
== 0)
1076 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1078 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1080 /* Bogus, result depends on processor. */
1081 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1082 mips_gpr_names
[reg2
]);
1086 case OP_LWM_SWM_LIST
:
1087 if (operand
->size
== 2)
1090 infprintf (is
, "%s,%s",
1092 mips_gpr_names
[31]);
1094 infprintf (is
, "%s-%s,%s",
1096 mips_gpr_names
[16 + uval
],
1097 mips_gpr_names
[31]);
1103 s_reg_encode
= uval
& 0xf;
1104 if (s_reg_encode
!= 0)
1106 if (s_reg_encode
== 1)
1107 infprintf (is
, "%s", mips_gpr_names
[16]);
1108 else if (s_reg_encode
< 9)
1109 infprintf (is
, "%s-%s",
1111 mips_gpr_names
[15 + s_reg_encode
]);
1112 else if (s_reg_encode
== 9)
1113 infprintf (is
, "%s-%s,%s",
1116 mips_gpr_names
[30]);
1118 infprintf (is
, "UNKNOWN");
1121 if (uval
& 0x10) /* For ra. */
1123 if (s_reg_encode
== 0)
1124 infprintf (is
, "%s", mips_gpr_names
[31]);
1126 infprintf (is
, ",%s", mips_gpr_names
[31]);
1131 case OP_MDMX_IMM_REG
:
1137 if ((vsel
& 0x10) == 0)
1142 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1143 if ((vsel
& 1) == 0)
1145 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1146 infprintf (is
, "[%d]", vsel
>> 1);
1148 else if ((vsel
& 0x08) == 0)
1149 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1151 infprintf (is
, "0x%x", uval
);
1155 case OP_REPEAT_PREV_REG
:
1156 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1159 case OP_REPEAT_DEST_REG
:
1160 /* Should always match OP_REPEAT_PREV_REG first. */
1164 infprintf (is
, "$pc");
1169 /* Print the arguments for INSN, which is described by OPCODE.
1170 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1171 as the base of OP_PCREL operands. */
1174 print_insn_args (struct disassemble_info
*info
,
1175 const struct mips_opcode
*opcode
,
1176 const struct mips_operand
*(*decode_operand
) (const char *),
1177 unsigned int insn
, bfd_vma base_pc
)
1179 const fprintf_ftype infprintf
= info
->fprintf_func
;
1180 void *is
= info
->stream
;
1181 struct mips_print_arg_state state
;
1182 const struct mips_operand
*operand
;
1185 init_print_arg_state (&state
);
1186 for (s
= opcode
->args
; *s
; ++s
)
1193 infprintf (is
, "%c", *s
);
1197 operand
= decode_operand (s
);
1200 /* xgettext:c-format */
1202 _("# internal error, undefined operand in `%s %s'"),
1203 opcode
->name
, opcode
->args
);
1206 if (operand
->type
== OP_REG
1209 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1211 /* Coprocessor register 0 with sel field (MT ASE). */
1212 const struct mips_cp0sel_name
*n
;
1213 unsigned int reg
, sel
;
1215 reg
= mips_extract_operand (operand
, insn
);
1217 operand
= decode_operand (s
);
1218 sel
= mips_extract_operand (operand
, insn
);
1220 /* CP0 register including 'sel' code for mftc0, to be
1221 printed textually if known. If not known, print both
1222 CP0 register name and sel numerically since CP0 register
1223 with sel 0 may have a name unrelated to register being
1225 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1226 mips_cp0sel_names_len
,
1229 infprintf (is
, "%s", n
->name
);
1231 infprintf (is
, "$%d,%d", reg
, sel
);
1234 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1235 mips_extract_operand (operand
, insn
));
1236 if (*s
== 'm' || *s
== '+')
1243 /* Print the mips instruction at address MEMADDR in debugged memory,
1244 on using INFO. Returns length of the instruction, in bytes, which is
1245 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1246 this is little-endian code. */
1249 print_insn_mips (bfd_vma memaddr
,
1251 struct disassemble_info
*info
)
1253 #define GET_OP(insn, field) \
1254 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1255 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1256 const fprintf_ftype infprintf
= info
->fprintf_func
;
1257 const struct mips_opcode
*op
;
1258 static bfd_boolean init
= 0;
1259 void *is
= info
->stream
;
1261 /* Build a hash table to shorten the search time. */
1266 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1268 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1270 if (op
->pinfo
== INSN_MACRO
1271 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1273 if (i
== GET_OP (op
->match
, OP
))
1284 info
->bytes_per_chunk
= INSNLEN
;
1285 info
->display_endian
= info
->endian
;
1286 info
->insn_info_valid
= 1;
1287 info
->branch_delay_insns
= 0;
1288 info
->data_size
= 0;
1289 info
->insn_type
= dis_nonbranch
;
1293 op
= mips_hash
[GET_OP (word
, OP
)];
1296 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1298 if (op
->pinfo
!= INSN_MACRO
1299 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1300 && (word
& op
->mask
) == op
->match
)
1302 /* We always allow to disassemble the jalx instruction. */
1303 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1304 && strcmp (op
->name
, "jalx"))
1307 /* Figure out instruction type and branch delay information. */
1308 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1310 if ((op
->pinfo
& (INSN_WRITE_GPR_31
1311 | INSN_WRITE_GPR_D
)) != 0)
1312 info
->insn_type
= dis_jsr
;
1314 info
->insn_type
= dis_branch
;
1315 info
->branch_delay_insns
= 1;
1317 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1318 | INSN_COND_BRANCH_LIKELY
)) != 0)
1320 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1321 info
->insn_type
= dis_condjsr
;
1323 info
->insn_type
= dis_condbranch
;
1324 info
->branch_delay_insns
= 1;
1326 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1327 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1328 info
->insn_type
= dis_dref
;
1330 infprintf (is
, "%s", op
->name
);
1334 infprintf (is
, "\t");
1335 print_insn_args (info
, op
, decode_mips_operand
, word
,
1345 /* Handle undefined instructions. */
1346 info
->insn_type
= dis_noninsn
;
1347 infprintf (is
, "0x%x", word
);
1351 /* Disassemble an operand for a mips16 instruction. */
1354 print_mips16_insn_arg (char type
,
1355 const struct mips_opcode
*op
,
1357 bfd_boolean use_extend
,
1360 struct disassemble_info
*info
)
1362 const fprintf_ftype infprintf
= info
->fprintf_func
;
1363 void *is
= info
->stream
;
1365 #define GET_OP(insn, field) \
1366 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1367 #define GET_OP_S(insn, field) \
1368 ((GET_OP (insn, field) ^ ((MIPS16OP_MASK_##field >> 1) + 1)) \
1369 - ((MIPS16OP_MASK_##field >> 1) + 1))
1375 infprintf (is
, "%c", type
);
1380 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RY
)));
1385 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RX
)));
1389 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RZ
)));
1393 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, MOVE32Z
)));
1397 infprintf (is
, "%s", mips_gpr_names
[0]);
1401 infprintf (is
, "%s", mips_gpr_names
[29]);
1405 infprintf (is
, "$pc");
1409 infprintf (is
, "%s", mips_gpr_names
[31]);
1413 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, REGR32
)]);
1417 infprintf (is
, "%s", mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1443 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1455 immed
= GET_OP (l
, RZ
);
1461 immed
= GET_OP (l
, RX
);
1467 immed
= GET_OP (l
, RZ
);
1473 immed
= GET_OP (l
, RX
);
1479 immed
= GET_OP (l
, IMM4
);
1485 immed
= GET_OP (l
, IMM5
);
1486 info
->insn_type
= dis_dref
;
1487 info
->data_size
= 1;
1492 immed
= GET_OP (l
, IMM5
);
1493 info
->insn_type
= dis_dref
;
1494 info
->data_size
= 2;
1499 immed
= GET_OP (l
, IMM5
);
1500 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1501 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1503 info
->insn_type
= dis_dref
;
1504 info
->data_size
= 4;
1510 immed
= GET_OP (l
, IMM5
);
1511 info
->insn_type
= dis_dref
;
1512 info
->data_size
= 8;
1516 immed
= GET_OP (l
, IMM5
);
1521 immed
= GET_OP (l
, IMM6
);
1525 immed
= GET_OP (l
, IMM8
);
1530 immed
= GET_OP (l
, IMM8
);
1531 /* FIXME: This might be lw, or it might be addiu to $sp or
1532 $pc. We assume it's load. */
1533 info
->insn_type
= dis_dref
;
1534 info
->data_size
= 4;
1539 immed
= GET_OP (l
, IMM8
);
1540 info
->insn_type
= dis_dref
;
1541 info
->data_size
= 8;
1545 immed
= GET_OP (l
, IMM8
);
1550 immed
= GET_OP (l
, IMM8
);
1556 immed
= GET_OP (l
, IMM8
);
1561 immed
= GET_OP (l
, IMM8
);
1568 immed
= GET_OP (l
, IMM11
);
1576 immed
= GET_OP (l
, IMM8
);
1578 /* FIXME: This can be lw or la. We assume it is lw. */
1579 info
->insn_type
= dis_dref
;
1580 info
->data_size
= 4;
1585 immed
= GET_OP (l
, IMM5
);
1587 info
->insn_type
= dis_dref
;
1588 info
->data_size
= 8;
1593 immed
= GET_OP (l
, IMM5
);
1602 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1603 immed
-= 1 << nbits
;
1605 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1612 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1613 else if (extbits
== 15)
1614 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1616 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1617 immed
&= (1 << extbits
) - 1;
1618 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1619 immed
-= 1 << extbits
;
1623 infprintf (is
, "%d", immed
);
1631 baseaddr
= memaddr
+ 2;
1633 else if (use_extend
)
1634 baseaddr
= memaddr
- 2;
1642 /* If this instruction is in the delay slot of a jr
1643 instruction, the base address is the address of the
1644 jr instruction. If it is in the delay slot of jalr
1645 instruction, the base address is the address of the
1646 jalr instruction. This test is unreliable: we have
1647 no way of knowing whether the previous word is
1648 instruction or data. */
1649 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1652 && (((info
->endian
== BFD_ENDIAN_BIG
1653 ? bfd_getb16 (buffer
)
1654 : bfd_getl16 (buffer
))
1655 & 0xf800) == 0x1800))
1656 baseaddr
= memaddr
- 4;
1659 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1662 && (((info
->endian
== BFD_ENDIAN_BIG
1663 ? bfd_getb16 (buffer
)
1664 : bfd_getl16 (buffer
))
1665 & 0xf81f) == 0xe800))
1666 baseaddr
= memaddr
- 2;
1669 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1671 && info
->flavour
== bfd_target_unknown_flavour
)
1672 /* For gdb disassembler, maintain odd address. */
1674 (*info
->print_address_func
) (info
->target
, info
);
1684 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1685 if (type
== 'a' && info
->flavour
== bfd_target_unknown_flavour
)
1686 /* For gdb disassembler, maintain odd address. */
1689 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1690 (*info
->print_address_func
) (info
->target
, info
);
1696 int need_comma
, amask
, smask
;
1700 l
= GET_OP (l
, IMM6
);
1702 amask
= (l
>> 3) & 7;
1704 if (amask
> 0 && amask
< 5)
1706 infprintf (is
, "%s", mips_gpr_names
[4]);
1708 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1712 smask
= (l
>> 1) & 3;
1715 infprintf (is
, "%s??", need_comma
? "," : "");
1720 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[16]);
1722 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1728 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[31]);
1732 if (amask
== 5 || amask
== 6)
1734 infprintf (is
, "%s$f0", need_comma
? "," : "");
1736 infprintf (is
, "-$f1");
1743 /* MIPS16e save/restore. */
1746 int amask
, args
, statics
;
1755 amask
= (l
>> 16) & 0xf;
1756 if (amask
== MIPS16_ALL_ARGS
)
1761 else if (amask
== MIPS16_ALL_STATICS
)
1769 statics
= amask
& 3;
1773 infprintf (is
, "%s", mips_gpr_names
[4]);
1775 infprintf (is
, "-%s", mips_gpr_names
[4 + args
- 1]);
1779 framesz
= (((l
>> 16) & 0xf0) | (l
& 0x0f)) * 8;
1780 if (framesz
== 0 && !use_extend
)
1783 infprintf (is
, "%s%d", need_comma
? "," : "", framesz
);
1785 if (l
& 0x40) /* $ra */
1786 infprintf (is
, ",%s", mips_gpr_names
[31]);
1788 nsreg
= (l
>> 24) & 0x7;
1790 if (l
& 0x20) /* $s0 */
1792 if (l
& 0x10) /* $s1 */
1794 if (nsreg
> 0) /* $s2-$s8 */
1795 smask
|= ((1 << nsreg
) - 1) << 2;
1797 /* Find first set static reg bit. */
1798 for (i
= 0; i
< 9; i
++)
1800 if (smask
& (1 << i
))
1802 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1803 /* Skip over string of set bits. */
1804 for (j
= i
; smask
& (2 << j
); j
++)
1807 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1812 /* Statics $ax - $a3. */
1814 infprintf (is
, ",%s", mips_gpr_names
[7]);
1815 else if (statics
> 0)
1816 infprintf (is
, ",%s-%s",
1817 mips_gpr_names
[7 - statics
+ 1],
1823 /* xgettext:c-format */
1825 _("# internal disassembler error, "
1826 "unrecognised modifier (%c)"),
1833 /* Check if the given address is the last word of a MIPS16 PLT entry.
1834 This word is data and depending on the value it may interfere with
1835 disassembly of further PLT entries. We make use of the fact PLT
1836 symbols are marked BSF_SYNTHETIC. */
1838 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
1842 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
1843 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
1849 /* Disassemble mips16 instructions. */
1852 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
1854 const fprintf_ftype infprintf
= info
->fprintf_func
;
1859 bfd_boolean use_extend
;
1861 const struct mips_opcode
*op
, *opend
;
1862 void *is
= info
->stream
;
1864 info
->bytes_per_chunk
= 2;
1865 info
->display_endian
= info
->endian
;
1866 info
->insn_info_valid
= 1;
1867 info
->branch_delay_insns
= 0;
1868 info
->data_size
= 0;
1872 /* Decode PLT entry's GOT slot address word. */
1873 if (is_mips16_plt_tail (info
, memaddr
))
1875 info
->insn_type
= dis_noninsn
;
1876 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
1879 unsigned int gotslot
;
1881 if (info
->endian
== BFD_ENDIAN_BIG
)
1882 gotslot
= bfd_getb32 (buffer
);
1884 gotslot
= bfd_getl32 (buffer
);
1885 infprintf (is
, ".word\t0x%x", gotslot
);
1892 info
->insn_type
= dis_nonbranch
;
1893 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1897 (*info
->memory_error_func
) (status
, memaddr
, info
);
1903 if (info
->endian
== BFD_ENDIAN_BIG
)
1904 insn
= bfd_getb16 (buffer
);
1906 insn
= bfd_getl16 (buffer
);
1908 /* Handle the extend opcode specially. */
1910 if ((insn
& 0xf800) == 0xf000)
1913 extend
= insn
& 0x7ff;
1917 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1920 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1921 (*info
->memory_error_func
) (status
, memaddr
, info
);
1925 if (info
->endian
== BFD_ENDIAN_BIG
)
1926 insn
= bfd_getb16 (buffer
);
1928 insn
= bfd_getl16 (buffer
);
1930 /* Check for an extend opcode followed by an extend opcode. */
1931 if ((insn
& 0xf800) == 0xf000)
1933 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1934 info
->insn_type
= dis_noninsn
;
1941 /* FIXME: Should probably use a hash table on the major opcode here. */
1943 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
1944 for (op
= mips16_opcodes
; op
< opend
; op
++)
1946 if (op
->pinfo
!= INSN_MACRO
1947 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1948 && (insn
& op
->mask
) == op
->match
)
1952 if (op
->args
[0] == 'a' || op
->args
[0] == 'i')
1956 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1957 info
->insn_type
= dis_noninsn
;
1965 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
1970 if (info
->endian
== BFD_ENDIAN_BIG
)
1971 extend
= bfd_getb16 (buffer
);
1973 extend
= bfd_getl16 (buffer
);
1978 infprintf (is
, "%s", op
->name
);
1979 if (op
->args
[0] != '\0')
1980 infprintf (is
, "\t");
1982 for (s
= op
->args
; *s
!= '\0'; s
++)
1986 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
1988 /* Skip the register and the comma. */
1994 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
1996 /* Skip the register and the comma. */
2000 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
2004 /* Figure out branch instruction type and delay slot information. */
2005 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2006 info
->branch_delay_insns
= 1;
2007 if ((op
->pinfo
& (INSN_UNCOND_BRANCH_DELAY
2008 | MIPS16_INSN_UNCOND_BRANCH
)) != 0)
2010 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2011 info
->insn_type
= dis_jsr
;
2013 info
->insn_type
= dis_branch
;
2015 else if ((op
->pinfo
& MIPS16_INSN_COND_BRANCH
) != 0)
2016 info
->insn_type
= dis_condbranch
;
2025 infprintf (is
, "0x%x", extend
| 0xf000);
2026 infprintf (is
, "0x%x", insn
);
2027 info
->insn_type
= dis_noninsn
;
2032 /* Disassemble microMIPS instructions. */
2035 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2037 const fprintf_ftype infprintf
= info
->fprintf_func
;
2038 const struct mips_opcode
*op
, *opend
;
2039 void *is
= info
->stream
;
2041 unsigned int higher
;
2042 unsigned int length
;
2046 info
->bytes_per_chunk
= 2;
2047 info
->display_endian
= info
->endian
;
2048 info
->insn_info_valid
= 1;
2049 info
->branch_delay_insns
= 0;
2050 info
->data_size
= 0;
2051 info
->insn_type
= dis_nonbranch
;
2055 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2058 (*info
->memory_error_func
) (status
, memaddr
, info
);
2064 if (info
->endian
== BFD_ENDIAN_BIG
)
2065 insn
= bfd_getb16 (buffer
);
2067 insn
= bfd_getl16 (buffer
);
2069 if ((insn
& 0xfc00) == 0x7c00)
2071 /* This is a 48-bit microMIPS instruction. */
2074 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2077 infprintf (is
, "micromips 0x%x", higher
);
2078 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2081 if (info
->endian
== BFD_ENDIAN_BIG
)
2082 insn
= bfd_getb16 (buffer
);
2084 insn
= bfd_getl16 (buffer
);
2085 higher
= (higher
<< 16) | insn
;
2087 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
2090 infprintf (is
, "micromips 0x%x", higher
);
2091 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2094 if (info
->endian
== BFD_ENDIAN_BIG
)
2095 insn
= bfd_getb16 (buffer
);
2097 insn
= bfd_getl16 (buffer
);
2098 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2100 info
->insn_type
= dis_noninsn
;
2103 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2105 /* This is a 32-bit microMIPS instruction. */
2108 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2111 infprintf (is
, "micromips 0x%x", higher
);
2112 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2116 if (info
->endian
== BFD_ENDIAN_BIG
)
2117 insn
= bfd_getb16 (buffer
);
2119 insn
= bfd_getl16 (buffer
);
2121 insn
= insn
| (higher
<< 16);
2126 /* FIXME: Should probably use a hash table on the major opcode here. */
2128 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2129 for (op
= micromips_opcodes
; op
< opend
; op
++)
2131 if (op
->pinfo
!= INSN_MACRO
2132 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2133 && (insn
& op
->mask
) == op
->match
2134 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2135 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2137 infprintf (is
, "%s", op
->name
);
2141 infprintf (is
, "\t");
2142 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2143 memaddr
+ length
+ 1);
2146 /* Figure out instruction type and branch delay information. */
2148 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2149 info
->branch_delay_insns
= 1;
2150 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2151 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2153 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_GPR_T
)) != 0)
2154 info
->insn_type
= dis_jsr
;
2156 info
->insn_type
= dis_branch
;
2158 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2159 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2161 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2162 info
->insn_type
= dis_condjsr
;
2164 info
->insn_type
= dis_condbranch
;
2167 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY_DELAY
)) != 0)
2168 info
->insn_type
= dis_dref
;
2174 infprintf (is
, "0x%x", insn
);
2175 info
->insn_type
= dis_noninsn
;
2180 /* Return 1 if a symbol associated with the location being disassembled
2181 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2182 all the symbols at the address being considered assuming if at least
2183 one of them indicates code compression, then such code has been
2184 genuinely produced here (other symbols could have been derived from
2185 function symbols defined elsewhere or could define data). Otherwise,
2189 is_compressed_mode_p (struct disassemble_info
*info
)
2194 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2195 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2197 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2199 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2201 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2202 && info
->symtab
[i
]->section
== info
->section
)
2204 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2206 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2208 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2215 /* In an environment where we do not know the symbol type of the
2216 instruction we are forced to assume that the low order bit of the
2217 instructions' address may mark it as a mips16 instruction. If we
2218 are single stepping, or the pc is within the disassembled function,
2219 this works. Otherwise, we need a clue. Sometimes. */
2222 _print_insn_mips (bfd_vma memaddr
,
2223 struct disassemble_info
*info
,
2224 enum bfd_endian endianness
)
2226 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
2227 bfd_byte buffer
[INSNLEN
];
2230 set_default_mips_dis_options (info
);
2231 parse_mips_dis_options (info
->disassembler_options
);
2233 if (info
->mach
== bfd_mach_mips16
)
2234 return print_insn_mips16 (memaddr
, info
);
2235 if (info
->mach
== bfd_mach_mips_micromips
)
2236 return print_insn_micromips (memaddr
, info
);
2238 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
2241 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2242 /* Only a few tools will work this way. */
2244 return print_insn_compr (memaddr
, info
);
2247 #if SYMTAB_AVAILABLE
2248 if (is_compressed_mode_p (info
))
2249 return print_insn_compr (memaddr
, info
);
2252 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2257 if (endianness
== BFD_ENDIAN_BIG
)
2258 insn
= bfd_getb32 (buffer
);
2260 insn
= bfd_getl32 (buffer
);
2262 return print_insn_mips (memaddr
, insn
, info
);
2266 (*info
->memory_error_func
) (status
, memaddr
, info
);
2272 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2274 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2278 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2280 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2284 print_mips_disassembler_options (FILE *stream
)
2288 fprintf (stream
, _("\n\
2289 The following MIPS specific disassembler options are supported for use\n\
2290 with the -M switch (multiple options should be separated by commas):\n"));
2292 fprintf (stream
, _("\n\
2293 virt Recognize the virtualization ASE instructions.\n"));
2295 fprintf (stream
, _("\n\
2296 gpr-names=ABI Print GPR names according to specified ABI.\n\
2297 Default: based on binary being disassembled.\n"));
2299 fprintf (stream
, _("\n\
2300 fpr-names=ABI Print FPR names according to specified ABI.\n\
2301 Default: numeric.\n"));
2303 fprintf (stream
, _("\n\
2304 cp0-names=ARCH Print CP0 register names according to\n\
2305 specified architecture.\n\
2306 Default: based on binary being disassembled.\n"));
2308 fprintf (stream
, _("\n\
2309 hwr-names=ARCH Print HWR names according to specified \n\
2311 Default: based on binary being disassembled.\n"));
2313 fprintf (stream
, _("\n\
2314 reg-names=ABI Print GPR and FPR names according to\n\
2315 specified ABI.\n"));
2317 fprintf (stream
, _("\n\
2318 reg-names=ARCH Print CP0 register and HWR names according to\n\
2319 specified architecture.\n"));
2321 fprintf (stream
, _("\n\
2322 For the options above, the following values are supported for \"ABI\":\n\
2324 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2325 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2326 fprintf (stream
, _("\n"));
2328 fprintf (stream
, _("\n\
2329 For the options above, The following values are supported for \"ARCH\":\n\
2331 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2332 if (*mips_arch_choices
[i
].name
!= '\0')
2333 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2334 fprintf (stream
, _("\n"));
2336 fprintf (stream
, _("\n"));