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
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 /* The microMIPS registers with type b. */
61 #define micromips_to_32_reg_b_map mips16_to_32_reg_map
63 /* The microMIPS registers with type c. */
64 #define micromips_to_32_reg_c_map mips16_to_32_reg_map
66 /* The microMIPS registers with type d. */
67 #define micromips_to_32_reg_d_map mips16_to_32_reg_map
69 /* The microMIPS registers with type e. */
70 #define micromips_to_32_reg_e_map mips16_to_32_reg_map
72 /* The microMIPS registers with type f. */
73 #define micromips_to_32_reg_f_map mips16_to_32_reg_map
75 /* The microMIPS registers with type g. */
76 #define micromips_to_32_reg_g_map mips16_to_32_reg_map
78 /* The microMIPS registers with type h. */
79 static const unsigned int micromips_to_32_reg_h_map
[] =
81 5, 5, 6, 4, 4, 4, 4, 4
84 /* The microMIPS registers with type i. */
85 static const unsigned int micromips_to_32_reg_i_map
[] =
87 6, 7, 7, 21, 22, 5, 6, 7
90 /* The microMIPS registers with type j: 32 registers. */
92 /* The microMIPS registers with type l. */
93 #define micromips_to_32_reg_l_map mips16_to_32_reg_map
95 /* The microMIPS registers with type m. */
96 static const unsigned int micromips_to_32_reg_m_map
[] =
98 0, 17, 2, 3, 16, 18, 19, 20
101 /* The microMIPS registers with type n. */
102 #define micromips_to_32_reg_n_map micromips_to_32_reg_m_map
104 /* The microMIPS registers with type p: 32 registers. */
106 /* The microMIPS registers with type q. */
107 static const unsigned int micromips_to_32_reg_q_map
[] =
109 0, 17, 2, 3, 4, 5, 6, 7
112 /* reg type s is $29. */
114 /* reg type t is the same as the last register. */
116 /* reg type y is $31. */
118 /* reg type z is $0. */
120 /* micromips imm B type. */
121 static const int micromips_imm_b_map
[8] =
123 1, 4, 8, 12, 16, 20, 24, -1
126 /* micromips imm C type. */
127 static const int micromips_imm_c_map
[16] =
129 128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 255, 32768, 65535
132 /* micromips imm D type: (-512..511)<<1. */
133 /* micromips imm E type: (-64..63)<<1. */
134 /* micromips imm F type: (0..63). */
135 /* micromips imm G type: (-1..14). */
136 /* micromips imm H type: (0..15)<<1. */
137 /* micromips imm I type: (-1..126). */
138 /* micromips imm J type: (0..15)<<2. */
139 /* micromips imm L type: (0..15). */
140 /* micromips imm M type: (1..8). */
141 /* micromips imm W type: (0..63)<<2. */
142 /* micromips imm X type: (-8..7). */
143 /* micromips imm Y type: (-258..-3, 2..257)<<2. */
145 #define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]]
148 static const char * const mips_gpr_names_numeric
[32] =
150 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
151 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
152 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
153 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
156 static const char * const mips_gpr_names_oldabi
[32] =
158 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
159 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
160 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
161 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
164 static const char * const mips_gpr_names_newabi
[32] =
166 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
167 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
168 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
169 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
172 static const char * const mips_fpr_names_numeric
[32] =
174 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
175 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
176 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
177 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
180 static const char * const mips_fpr_names_32
[32] =
182 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
183 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
184 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
185 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
188 static const char * const mips_fpr_names_n32
[32] =
190 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
191 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
192 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
193 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
196 static const char * const mips_fpr_names_64
[32] =
198 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
199 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
200 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
201 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
204 static const char * const mips_cp0_names_numeric
[32] =
206 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
207 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
208 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
209 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
212 static const char * const mips_cp0_names_r3000
[32] =
214 "c0_index", "c0_random", "c0_entrylo", "$3",
215 "c0_context", "$5", "$6", "$7",
216 "c0_badvaddr", "$9", "c0_entryhi", "$11",
217 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
218 "$16", "$17", "$18", "$19",
219 "$20", "$21", "$22", "$23",
220 "$24", "$25", "$26", "$27",
221 "$28", "$29", "$30", "$31",
224 static const char * const mips_cp0_names_r4000
[32] =
226 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
227 "c0_context", "c0_pagemask", "c0_wired", "$7",
228 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
229 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
230 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
231 "c0_xcontext", "$21", "$22", "$23",
232 "$24", "$25", "c0_ecc", "c0_cacheerr",
233 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
236 static const char * const mips_cp0_names_mips3264
[32] =
238 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
239 "c0_context", "c0_pagemask", "c0_wired", "$7",
240 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
241 "c0_status", "c0_cause", "c0_epc", "c0_prid",
242 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
243 "c0_xcontext", "$21", "$22", "c0_debug",
244 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
245 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
248 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] =
250 { 16, 1, "c0_config1" },
251 { 16, 2, "c0_config2" },
252 { 16, 3, "c0_config3" },
253 { 18, 1, "c0_watchlo,1" },
254 { 18, 2, "c0_watchlo,2" },
255 { 18, 3, "c0_watchlo,3" },
256 { 18, 4, "c0_watchlo,4" },
257 { 18, 5, "c0_watchlo,5" },
258 { 18, 6, "c0_watchlo,6" },
259 { 18, 7, "c0_watchlo,7" },
260 { 19, 1, "c0_watchhi,1" },
261 { 19, 2, "c0_watchhi,2" },
262 { 19, 3, "c0_watchhi,3" },
263 { 19, 4, "c0_watchhi,4" },
264 { 19, 5, "c0_watchhi,5" },
265 { 19, 6, "c0_watchhi,6" },
266 { 19, 7, "c0_watchhi,7" },
267 { 25, 1, "c0_perfcnt,1" },
268 { 25, 2, "c0_perfcnt,2" },
269 { 25, 3, "c0_perfcnt,3" },
270 { 25, 4, "c0_perfcnt,4" },
271 { 25, 5, "c0_perfcnt,5" },
272 { 25, 6, "c0_perfcnt,6" },
273 { 25, 7, "c0_perfcnt,7" },
274 { 27, 1, "c0_cacheerr,1" },
275 { 27, 2, "c0_cacheerr,2" },
276 { 27, 3, "c0_cacheerr,3" },
277 { 28, 1, "c0_datalo" },
278 { 29, 1, "c0_datahi" }
281 static const char * const mips_cp0_names_mips3264r2
[32] =
283 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
284 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
285 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
286 "c0_status", "c0_cause", "c0_epc", "c0_prid",
287 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
288 "c0_xcontext", "$21", "$22", "c0_debug",
289 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
290 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
293 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] =
295 { 4, 1, "c0_contextconfig" },
296 { 0, 1, "c0_mvpcontrol" },
297 { 0, 2, "c0_mvpconf0" },
298 { 0, 3, "c0_mvpconf1" },
299 { 1, 1, "c0_vpecontrol" },
300 { 1, 2, "c0_vpeconf0" },
301 { 1, 3, "c0_vpeconf1" },
302 { 1, 4, "c0_yqmask" },
303 { 1, 5, "c0_vpeschedule" },
304 { 1, 6, "c0_vpeschefback" },
305 { 2, 1, "c0_tcstatus" },
306 { 2, 2, "c0_tcbind" },
307 { 2, 3, "c0_tcrestart" },
308 { 2, 4, "c0_tchalt" },
309 { 2, 5, "c0_tccontext" },
310 { 2, 6, "c0_tcschedule" },
311 { 2, 7, "c0_tcschefback" },
312 { 5, 1, "c0_pagegrain" },
313 { 6, 1, "c0_srsconf0" },
314 { 6, 2, "c0_srsconf1" },
315 { 6, 3, "c0_srsconf2" },
316 { 6, 4, "c0_srsconf3" },
317 { 6, 5, "c0_srsconf4" },
318 { 12, 1, "c0_intctl" },
319 { 12, 2, "c0_srsctl" },
320 { 12, 3, "c0_srsmap" },
321 { 15, 1, "c0_ebase" },
322 { 16, 1, "c0_config1" },
323 { 16, 2, "c0_config2" },
324 { 16, 3, "c0_config3" },
325 { 18, 1, "c0_watchlo,1" },
326 { 18, 2, "c0_watchlo,2" },
327 { 18, 3, "c0_watchlo,3" },
328 { 18, 4, "c0_watchlo,4" },
329 { 18, 5, "c0_watchlo,5" },
330 { 18, 6, "c0_watchlo,6" },
331 { 18, 7, "c0_watchlo,7" },
332 { 19, 1, "c0_watchhi,1" },
333 { 19, 2, "c0_watchhi,2" },
334 { 19, 3, "c0_watchhi,3" },
335 { 19, 4, "c0_watchhi,4" },
336 { 19, 5, "c0_watchhi,5" },
337 { 19, 6, "c0_watchhi,6" },
338 { 19, 7, "c0_watchhi,7" },
339 { 23, 1, "c0_tracecontrol" },
340 { 23, 2, "c0_tracecontrol2" },
341 { 23, 3, "c0_usertracedata" },
342 { 23, 4, "c0_tracebpc" },
343 { 25, 1, "c0_perfcnt,1" },
344 { 25, 2, "c0_perfcnt,2" },
345 { 25, 3, "c0_perfcnt,3" },
346 { 25, 4, "c0_perfcnt,4" },
347 { 25, 5, "c0_perfcnt,5" },
348 { 25, 6, "c0_perfcnt,6" },
349 { 25, 7, "c0_perfcnt,7" },
350 { 27, 1, "c0_cacheerr,1" },
351 { 27, 2, "c0_cacheerr,2" },
352 { 27, 3, "c0_cacheerr,3" },
353 { 28, 1, "c0_datalo" },
354 { 28, 2, "c0_taglo1" },
355 { 28, 3, "c0_datalo1" },
356 { 28, 4, "c0_taglo2" },
357 { 28, 5, "c0_datalo2" },
358 { 28, 6, "c0_taglo3" },
359 { 28, 7, "c0_datalo3" },
360 { 29, 1, "c0_datahi" },
361 { 29, 2, "c0_taghi1" },
362 { 29, 3, "c0_datahi1" },
363 { 29, 4, "c0_taghi2" },
364 { 29, 5, "c0_datahi2" },
365 { 29, 6, "c0_taghi3" },
366 { 29, 7, "c0_datahi3" },
369 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
370 static const char * const mips_cp0_names_sb1
[32] =
372 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
373 "c0_context", "c0_pagemask", "c0_wired", "$7",
374 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
375 "c0_status", "c0_cause", "c0_epc", "c0_prid",
376 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
377 "c0_xcontext", "$21", "$22", "c0_debug",
378 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
379 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
382 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] =
384 { 16, 1, "c0_config1" },
385 { 18, 1, "c0_watchlo,1" },
386 { 19, 1, "c0_watchhi,1" },
387 { 22, 0, "c0_perftrace" },
388 { 23, 3, "c0_edebug" },
389 { 25, 1, "c0_perfcnt,1" },
390 { 25, 2, "c0_perfcnt,2" },
391 { 25, 3, "c0_perfcnt,3" },
392 { 25, 4, "c0_perfcnt,4" },
393 { 25, 5, "c0_perfcnt,5" },
394 { 25, 6, "c0_perfcnt,6" },
395 { 25, 7, "c0_perfcnt,7" },
396 { 26, 1, "c0_buserr_pa" },
397 { 27, 1, "c0_cacheerr_d" },
398 { 27, 3, "c0_cacheerr_d_pa" },
399 { 28, 1, "c0_datalo_i" },
400 { 28, 2, "c0_taglo_d" },
401 { 28, 3, "c0_datalo_d" },
402 { 29, 1, "c0_datahi_i" },
403 { 29, 2, "c0_taghi_d" },
404 { 29, 3, "c0_datahi_d" },
407 /* Xlr cop0 register names. */
408 static const char * const mips_cp0_names_xlr
[32] = {
409 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
410 "c0_context", "c0_pagemask", "c0_wired", "$7",
411 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
412 "c0_status", "c0_cause", "c0_epc", "c0_prid",
413 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
414 "c0_xcontext", "$21", "$22", "c0_debug",
415 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
416 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
419 /* XLR's CP0 Select Registers. */
421 static const struct mips_cp0sel_name mips_cp0sel_names_xlr
[] = {
422 { 9, 6, "c0_extintreq" },
423 { 9, 7, "c0_extintmask" },
424 { 15, 1, "c0_ebase" },
425 { 16, 1, "c0_config1" },
426 { 16, 2, "c0_config2" },
427 { 16, 3, "c0_config3" },
428 { 16, 7, "c0_procid2" },
429 { 18, 1, "c0_watchlo,1" },
430 { 18, 2, "c0_watchlo,2" },
431 { 18, 3, "c0_watchlo,3" },
432 { 18, 4, "c0_watchlo,4" },
433 { 18, 5, "c0_watchlo,5" },
434 { 18, 6, "c0_watchlo,6" },
435 { 18, 7, "c0_watchlo,7" },
436 { 19, 1, "c0_watchhi,1" },
437 { 19, 2, "c0_watchhi,2" },
438 { 19, 3, "c0_watchhi,3" },
439 { 19, 4, "c0_watchhi,4" },
440 { 19, 5, "c0_watchhi,5" },
441 { 19, 6, "c0_watchhi,6" },
442 { 19, 7, "c0_watchhi,7" },
443 { 25, 1, "c0_perfcnt,1" },
444 { 25, 2, "c0_perfcnt,2" },
445 { 25, 3, "c0_perfcnt,3" },
446 { 25, 4, "c0_perfcnt,4" },
447 { 25, 5, "c0_perfcnt,5" },
448 { 25, 6, "c0_perfcnt,6" },
449 { 25, 7, "c0_perfcnt,7" },
450 { 27, 1, "c0_cacheerr,1" },
451 { 27, 2, "c0_cacheerr,2" },
452 { 27, 3, "c0_cacheerr,3" },
453 { 28, 1, "c0_datalo" },
454 { 29, 1, "c0_datahi" }
457 static const char * const mips_hwr_names_numeric
[32] =
459 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
460 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
461 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
462 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
465 static const char * const mips_hwr_names_mips3264r2
[32] =
467 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
468 "$4", "$5", "$6", "$7",
469 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
470 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
471 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
474 struct mips_abi_choice
477 const char * const *gpr_names
;
478 const char * const *fpr_names
;
481 struct mips_abi_choice mips_abi_choices
[] =
483 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
484 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
485 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
486 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
489 struct mips_arch_choice
493 unsigned long bfd_mach
;
496 const char * const *cp0_names
;
497 const struct mips_cp0sel_name
*cp0sel_names
;
498 unsigned int cp0sel_names_len
;
499 const char * const *hwr_names
;
502 const struct mips_arch_choice mips_arch_choices
[] =
504 { "numeric", 0, 0, 0, 0,
505 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
507 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
,
508 mips_cp0_names_r3000
, NULL
, 0, mips_hwr_names_numeric
},
509 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
,
510 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
511 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
,
512 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
513 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
,
514 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
515 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
,
516 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
517 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
,
518 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
519 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
,
520 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
521 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
,
522 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
523 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
,
524 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
525 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
,
526 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
527 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
,
528 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
529 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
,
530 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
531 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
,
532 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
533 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
,
534 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
535 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
,
536 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
537 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
,
538 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
539 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
,
540 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
541 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
,
542 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
543 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
,
544 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
545 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
,
546 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
547 { "r14000", 1, bfd_mach_mips14000
, CPU_R14000
, ISA_MIPS4
,
548 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
549 { "r16000", 1, bfd_mach_mips16000
, CPU_R16000
, ISA_MIPS4
,
550 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
551 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
,
552 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
554 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
555 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
556 _MIPS32 Architecture For Programmers Volume I: Introduction to the
557 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
559 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
560 ISA_MIPS32
| INSN_SMARTMIPS
,
561 mips_cp0_names_mips3264
,
562 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
563 mips_hwr_names_numeric
},
565 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
566 (ISA_MIPS32R2
| INSN_SMARTMIPS
| INSN_DSP
| INSN_DSPR2
567 | INSN_MIPS3D
| INSN_MT
| INSN_MCU
),
568 mips_cp0_names_mips3264r2
,
569 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
570 mips_hwr_names_mips3264r2
},
572 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
573 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
574 ISA_MIPS64
| INSN_MIPS3D
| INSN_MDMX
,
575 mips_cp0_names_mips3264
,
576 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
577 mips_hwr_names_numeric
},
579 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
580 (ISA_MIPS64R2
| INSN_MIPS3D
| INSN_DSP
| INSN_DSPR2
581 | INSN_DSP64
| INSN_MT
| INSN_MDMX
| INSN_MCU
),
582 mips_cp0_names_mips3264r2
,
583 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
584 mips_hwr_names_mips3264r2
},
586 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
587 ISA_MIPS64
| INSN_MIPS3D
| INSN_SB1
,
589 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
590 mips_hwr_names_numeric
},
592 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
593 ISA_MIPS3
| INSN_LOONGSON_2E
, mips_cp0_names_numeric
,
594 NULL
, 0, mips_hwr_names_numeric
},
596 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
597 ISA_MIPS3
| INSN_LOONGSON_2F
, mips_cp0_names_numeric
,
598 NULL
, 0, mips_hwr_names_numeric
},
600 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
601 ISA_MIPS64
| INSN_LOONGSON_3A
, mips_cp0_names_numeric
,
602 NULL
, 0, mips_hwr_names_numeric
},
604 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
605 ISA_MIPS64R2
| INSN_OCTEON
, mips_cp0_names_numeric
, NULL
, 0,
606 mips_hwr_names_numeric
},
608 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
609 ISA_MIPS64R2
| INSN_OCTEONP
, mips_cp0_names_numeric
,
610 NULL
, 0, mips_hwr_names_numeric
},
612 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
613 ISA_MIPS64R2
| INSN_OCTEON2
, mips_cp0_names_numeric
,
614 NULL
, 0, mips_hwr_names_numeric
},
616 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
617 ISA_MIPS64
| INSN_XLR
,
619 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
620 mips_hwr_names_numeric
},
622 /* XLP is mostly like XLR, with the prominent exception it is being
624 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
625 ISA_MIPS64R2
| INSN_XLR
,
627 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
628 mips_hwr_names_numeric
},
630 /* This entry, mips16, is here only for ISA/processor selection; do
631 not print its name. */
632 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
,
633 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
636 /* ISA and processor type to disassemble for, and register names to use.
637 set_default_mips_dis_options and parse_mips_dis_options fill in these
639 static int mips_processor
;
641 static int micromips_ase
;
642 static const char * const *mips_gpr_names
;
643 static const char * const *mips_fpr_names
;
644 static const char * const *mips_cp0_names
;
645 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
646 static int mips_cp0sel_names_len
;
647 static const char * const *mips_hwr_names
;
650 static int no_aliases
; /* If set disassemble as most general inst. */
652 static const struct mips_abi_choice
*
653 choose_abi_by_name (const char *name
, unsigned int namelen
)
655 const struct mips_abi_choice
*c
;
658 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
659 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
660 && strlen (mips_abi_choices
[i
].name
) == namelen
)
661 c
= &mips_abi_choices
[i
];
666 static const struct mips_arch_choice
*
667 choose_arch_by_name (const char *name
, unsigned int namelen
)
669 const struct mips_arch_choice
*c
= NULL
;
672 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
673 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
674 && strlen (mips_arch_choices
[i
].name
) == namelen
)
675 c
= &mips_arch_choices
[i
];
680 static const struct mips_arch_choice
*
681 choose_arch_by_number (unsigned long mach
)
683 static unsigned long hint_bfd_mach
;
684 static const struct mips_arch_choice
*hint_arch_choice
;
685 const struct mips_arch_choice
*c
;
688 /* We optimize this because even if the user specifies no
689 flags, this will be done for every instruction! */
690 if (hint_bfd_mach
== mach
691 && hint_arch_choice
!= NULL
692 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
693 return hint_arch_choice
;
695 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
697 if (mips_arch_choices
[i
].bfd_mach_valid
698 && mips_arch_choices
[i
].bfd_mach
== mach
)
700 c
= &mips_arch_choices
[i
];
701 hint_bfd_mach
= mach
;
702 hint_arch_choice
= c
;
708 /* Check if the object uses NewABI conventions. */
711 is_newabi (Elf_Internal_Ehdr
*header
)
713 /* There are no old-style ABIs which use 64-bit ELF. */
714 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
717 /* If a 32-bit ELF file, n32 is a new-style ABI. */
718 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
724 /* Check if the object has microMIPS ASE code. */
727 is_micromips (Elf_Internal_Ehdr
*header
)
729 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
736 set_default_mips_dis_options (struct disassemble_info
*info
)
738 const struct mips_arch_choice
*chosen_arch
;
740 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
741 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
742 CP0 register, and HWR names. */
743 mips_isa
= ISA_MIPS3
;
744 mips_processor
= CPU_R3000
;
746 mips_gpr_names
= mips_gpr_names_oldabi
;
747 mips_fpr_names
= mips_fpr_names_numeric
;
748 mips_cp0_names
= mips_cp0_names_numeric
;
749 mips_cp0sel_names
= NULL
;
750 mips_cp0sel_names_len
= 0;
751 mips_hwr_names
= mips_hwr_names_numeric
;
754 /* Update settings according to the ELF file header flags. */
755 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
757 Elf_Internal_Ehdr
*header
;
759 header
= elf_elfheader (info
->section
->owner
);
760 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
761 if (is_newabi (header
))
762 mips_gpr_names
= mips_gpr_names_newabi
;
763 /* If a microMIPS binary, then don't use MIPS16 bindings. */
764 micromips_ase
= is_micromips (header
);
767 /* Set ISA, architecture, and cp0 register names as best we can. */
768 #if ! SYMTAB_AVAILABLE
769 /* This is running out on a target machine, not in a host tool.
770 FIXME: Where does mips_target_info come from? */
771 target_processor
= mips_target_info
.processor
;
772 mips_isa
= mips_target_info
.isa
;
774 chosen_arch
= choose_arch_by_number (info
->mach
);
775 if (chosen_arch
!= NULL
)
777 mips_processor
= chosen_arch
->processor
;
778 mips_isa
= chosen_arch
->isa
;
779 mips_cp0_names
= chosen_arch
->cp0_names
;
780 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
781 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
782 mips_hwr_names
= chosen_arch
->hwr_names
;
788 parse_mips_dis_option (const char *option
, unsigned int len
)
790 unsigned int i
, optionlen
, vallen
;
792 const struct mips_abi_choice
*chosen_abi
;
793 const struct mips_arch_choice
*chosen_arch
;
795 /* Try to match options that are simple flags */
796 if (CONST_STRNEQ (option
, "no-aliases"))
802 /* Look for the = that delimits the end of the option name. */
803 for (i
= 0; i
< len
; i
++)
804 if (option
[i
] == '=')
807 if (i
== 0) /* Invalid option: no name before '='. */
809 if (i
== len
) /* Invalid option: no '='. */
811 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
815 val
= option
+ (optionlen
+ 1);
816 vallen
= len
- (optionlen
+ 1);
818 if (strncmp ("gpr-names", option
, optionlen
) == 0
819 && strlen ("gpr-names") == optionlen
)
821 chosen_abi
= choose_abi_by_name (val
, vallen
);
822 if (chosen_abi
!= NULL
)
823 mips_gpr_names
= chosen_abi
->gpr_names
;
827 if (strncmp ("fpr-names", option
, optionlen
) == 0
828 && strlen ("fpr-names") == optionlen
)
830 chosen_abi
= choose_abi_by_name (val
, vallen
);
831 if (chosen_abi
!= NULL
)
832 mips_fpr_names
= chosen_abi
->fpr_names
;
836 if (strncmp ("cp0-names", option
, optionlen
) == 0
837 && strlen ("cp0-names") == optionlen
)
839 chosen_arch
= choose_arch_by_name (val
, vallen
);
840 if (chosen_arch
!= NULL
)
842 mips_cp0_names
= chosen_arch
->cp0_names
;
843 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
844 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
849 if (strncmp ("hwr-names", option
, optionlen
) == 0
850 && strlen ("hwr-names") == optionlen
)
852 chosen_arch
= choose_arch_by_name (val
, vallen
);
853 if (chosen_arch
!= NULL
)
854 mips_hwr_names
= chosen_arch
->hwr_names
;
858 if (strncmp ("reg-names", option
, optionlen
) == 0
859 && strlen ("reg-names") == optionlen
)
861 /* We check both ABI and ARCH here unconditionally, so
862 that "numeric" will do the desirable thing: select
863 numeric register names for all registers. Other than
864 that, a given name probably won't match both. */
865 chosen_abi
= choose_abi_by_name (val
, vallen
);
866 if (chosen_abi
!= NULL
)
868 mips_gpr_names
= chosen_abi
->gpr_names
;
869 mips_fpr_names
= chosen_abi
->fpr_names
;
871 chosen_arch
= choose_arch_by_name (val
, vallen
);
872 if (chosen_arch
!= NULL
)
874 mips_cp0_names
= chosen_arch
->cp0_names
;
875 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
876 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
877 mips_hwr_names
= chosen_arch
->hwr_names
;
882 /* Invalid option. */
886 parse_mips_dis_options (const char *options
)
888 const char *option_end
;
893 while (*options
!= '\0')
895 /* Skip empty options. */
902 /* We know that *options is neither NUL or a comma. */
903 option_end
= options
+ 1;
904 while (*option_end
!= ',' && *option_end
!= '\0')
907 parse_mips_dis_option (options
, option_end
- options
);
909 /* Go on to the next one. If option_end points to a comma, it
910 will be skipped above. */
911 options
= option_end
;
915 static const struct mips_cp0sel_name
*
916 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
923 for (i
= 0; i
< len
; i
++)
924 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
929 /* Print insn arguments for 32/64-bit code. */
932 print_insn_args (const char *d
,
933 register unsigned long int l
,
935 struct disassemble_info
*info
,
936 const struct mips_opcode
*opp
)
939 unsigned int lsb
, msb
, msbd
;
943 for (; *d
!= '\0'; d
++)
952 (*info
->fprintf_func
) (info
->stream
, "%c", *d
);
956 /* Extension character; switch for second char. */
961 /* xgettext:c-format */
962 (*info
->fprintf_func
) (info
->stream
,
963 _("# internal error, incomplete extension sequence (+)"));
967 lsb
= (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
;
968 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
972 msb
= (l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
;
973 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
977 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
978 (l
>> OP_SH_UDI1
) & OP_MASK_UDI1
);
982 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
983 (l
>> OP_SH_UDI2
) & OP_MASK_UDI2
);
987 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
988 (l
>> OP_SH_UDI3
) & OP_MASK_UDI3
);
992 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
993 (l
>> OP_SH_UDI4
) & OP_MASK_UDI4
);
998 msbd
= (l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
;
999 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
1004 const struct mips_cp0sel_name
*n
;
1005 unsigned int cp0reg
, sel
;
1007 cp0reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
1008 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
1010 /* CP0 register including 'sel' code for mtcN (et al.), to be
1011 printed textually if known. If not known, print both
1012 CP0 register name and sel numerically since CP0 register
1013 with sel 0 may have a name unrelated to register being
1015 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
1016 mips_cp0sel_names_len
, cp0reg
, sel
);
1018 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
1020 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
1025 lsb
= ((l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
) + 32;
1026 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
1030 msb
= ((l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
) + 32;
1031 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
1035 msbd
= ((l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
) + 32;
1036 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
1039 case 't': /* Coprocessor 0 reg name */
1040 (*info
->fprintf_func
) (info
->stream
, "%s",
1041 mips_cp0_names
[(l
>> OP_SH_RT
) &
1045 case 'T': /* Coprocessor 0 reg name */
1047 const struct mips_cp0sel_name
*n
;
1048 unsigned int cp0reg
, sel
;
1050 cp0reg
= (l
>> OP_SH_RT
) & OP_MASK_RT
;
1051 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
1053 /* CP0 register including 'sel' code for mftc0, to be
1054 printed textually if known. If not known, print both
1055 CP0 register name and sel numerically since CP0 register
1056 with sel 0 may have a name unrelated to register being
1058 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
1059 mips_cp0sel_names_len
, cp0reg
, sel
);
1061 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
1063 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
1067 case 'x': /* bbit bit index */
1068 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1069 (l
>> OP_SH_BBITIND
) & OP_MASK_BBITIND
);
1072 case 'p': /* cins, cins32, exts and exts32 position */
1073 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1074 (l
>> OP_SH_CINSPOS
) & OP_MASK_CINSPOS
);
1077 case 's': /* cins and exts length-minus-one */
1078 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1079 (l
>> OP_SH_CINSLM1
) & OP_MASK_CINSLM1
);
1082 case 'S': /* cins32 and exts32 length-minus-one field */
1083 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1084 (l
>> OP_SH_CINSLM1
) & OP_MASK_CINSLM1
);
1087 case 'Q': /* seqi/snei immediate field */
1088 op
= (l
>> OP_SH_SEQI
) & OP_MASK_SEQI
;
1089 /* Sign-extend it. */
1090 op
= (op
^ 512) - 512;
1091 (*info
->fprintf_func
) (info
->stream
, "%d", op
);
1094 case 'a': /* 8-bit signed offset in bit 6 */
1095 delta
= (l
>> OP_SH_OFFSET_A
) & OP_MASK_OFFSET_A
;
1097 delta
|= ~OP_MASK_OFFSET_A
;
1098 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1101 case 'b': /* 8-bit signed offset in bit 3 */
1102 delta
= (l
>> OP_SH_OFFSET_B
) & OP_MASK_OFFSET_B
;
1104 delta
|= ~OP_MASK_OFFSET_B
;
1105 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1108 case 'c': /* 9-bit signed offset in bit 6 */
1109 delta
= (l
>> OP_SH_OFFSET_C
) & OP_MASK_OFFSET_C
;
1111 delta
|= ~OP_MASK_OFFSET_C
;
1112 /* Left shift 4 bits to print the real offset. */
1113 (*info
->fprintf_func
) (info
->stream
, "%d", delta
<< 4);
1117 (*info
->fprintf_func
) (info
->stream
, "%s",
1118 mips_gpr_names
[(l
>> OP_SH_RZ
) & OP_MASK_RZ
]);
1122 (*info
->fprintf_func
) (info
->stream
, "%s",
1123 mips_fpr_names
[(l
>> OP_SH_FZ
) & OP_MASK_FZ
]);
1127 /* xgettext:c-format */
1128 (*info
->fprintf_func
) (info
->stream
,
1129 _("# internal error, undefined extension sequence (+%c)"),
1136 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1137 (l
>> OP_SH_BP
) & OP_MASK_BP
);
1141 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1142 (l
>> OP_SH_SA3
) & OP_MASK_SA3
);
1146 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1147 (l
>> OP_SH_SA4
) & OP_MASK_SA4
);
1151 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1152 (l
>> OP_SH_IMM8
) & OP_MASK_IMM8
);
1156 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1157 (l
>> OP_SH_RS
) & OP_MASK_RS
);
1161 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1162 (l
>> OP_SH_DSPACC
) & OP_MASK_DSPACC
);
1166 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1167 (l
>> OP_SH_WRDSP
) & OP_MASK_WRDSP
);
1171 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1172 (l
>> OP_SH_DSPACC_S
) & OP_MASK_DSPACC_S
);
1175 case '0': /* dsp 6-bit signed immediate in bit 20 */
1176 delta
= ((l
>> OP_SH_DSPSFT
) & OP_MASK_DSPSFT
);
1177 if (delta
& 0x20) /* test sign bit */
1178 delta
|= ~OP_MASK_DSPSFT
;
1179 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1182 case ':': /* dsp 7-bit signed immediate in bit 19 */
1183 delta
= ((l
>> OP_SH_DSPSFT_7
) & OP_MASK_DSPSFT_7
);
1184 if (delta
& 0x40) /* test sign bit */
1185 delta
|= ~OP_MASK_DSPSFT_7
;
1186 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1190 delta
= (l
>> OP_SH_OFFSET12
) & OP_MASK_OFFSET12
;
1193 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1197 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1198 (l
>> OP_SH_3BITPOS
) & OP_MASK_3BITPOS
);
1202 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1203 (l
>> OP_SH_RDDSP
) & OP_MASK_RDDSP
);
1206 case '@': /* dsp 10-bit signed immediate in bit 16 */
1207 delta
= ((l
>> OP_SH_IMM10
) & OP_MASK_IMM10
);
1208 if (delta
& 0x200) /* test sign bit */
1209 delta
|= ~OP_MASK_IMM10
;
1210 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1214 (*info
->fprintf_func
) (info
->stream
, "%ld",
1215 (l
>> OP_SH_MT_U
) & OP_MASK_MT_U
);
1219 (*info
->fprintf_func
) (info
->stream
, "%ld",
1220 (l
>> OP_SH_MT_H
) & OP_MASK_MT_H
);
1224 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1225 (l
>> OP_SH_MTACC_T
) & OP_MASK_MTACC_T
);
1229 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1230 (l
>> OP_SH_MTACC_D
) & OP_MASK_MTACC_D
);
1234 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
1235 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1236 (l
>> OP_SH_RD
) & OP_MASK_RD
);
1243 (*info
->fprintf_func
) (info
->stream
, "%s",
1244 mips_gpr_names
[(l
>> OP_SH_RS
) & OP_MASK_RS
]);
1249 (*info
->fprintf_func
) (info
->stream
, "%s",
1250 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1255 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1256 (l
>> OP_SH_IMMEDIATE
) & OP_MASK_IMMEDIATE
);
1259 case 'j': /* Same as i, but sign-extended. */
1261 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
1264 (*info
->fprintf_func
) (info
->stream
, "%d",
1269 (*info
->fprintf_func
) (info
->stream
, "0x%x",
1270 (unsigned int) ((l
>> OP_SH_PREFX
)
1275 (*info
->fprintf_func
) (info
->stream
, "0x%x",
1276 (unsigned int) ((l
>> OP_SH_CACHE
)
1281 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
1282 | (((l
>> OP_SH_TARGET
) & OP_MASK_TARGET
) << 2));
1283 /* For gdb disassembler, force odd address on jalx. */
1284 if (info
->flavour
== bfd_target_unknown_flavour
1285 && strcmp (opp
->name
, "jalx") == 0)
1287 (*info
->print_address_func
) (info
->target
, info
);
1291 /* Sign extend the displacement. */
1292 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
1295 info
->target
= (delta
<< 2) + pc
+ INSNLEN
;
1296 (*info
->print_address_func
) (info
->target
, info
);
1300 (*info
->fprintf_func
) (info
->stream
, "%s",
1301 mips_gpr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1306 /* First check for both rd and rt being equal. */
1307 unsigned int reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
1308 if (reg
== ((l
>> OP_SH_RT
) & OP_MASK_RT
))
1309 (*info
->fprintf_func
) (info
->stream
, "%s",
1310 mips_gpr_names
[reg
]);
1313 /* If one is zero use the other. */
1315 (*info
->fprintf_func
) (info
->stream
, "%s",
1316 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1317 else if (((l
>> OP_SH_RT
) & OP_MASK_RT
) == 0)
1318 (*info
->fprintf_func
) (info
->stream
, "%s",
1319 mips_gpr_names
[reg
]);
1320 else /* Bogus, result depends on processor. */
1321 (*info
->fprintf_func
) (info
->stream
, "%s or %s",
1322 mips_gpr_names
[reg
],
1323 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1329 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1334 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1335 (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
);
1339 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1340 (l
>> OP_SH_CODE
) & OP_MASK_CODE
);
1344 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1345 (l
>> OP_SH_CODE2
) & OP_MASK_CODE2
);
1349 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1350 (l
>> OP_SH_COPZ
) & OP_MASK_COPZ
);
1354 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1356 (l
>> OP_SH_CODE20
) & OP_MASK_CODE20
);
1360 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1361 (l
>> OP_SH_CODE19
) & OP_MASK_CODE19
);
1366 (*info
->fprintf_func
) (info
->stream
, "%s",
1367 mips_fpr_names
[(l
>> OP_SH_FS
) & OP_MASK_FS
]);
1372 (*info
->fprintf_func
) (info
->stream
, "%s",
1373 mips_fpr_names
[(l
>> OP_SH_FT
) & OP_MASK_FT
]);
1377 (*info
->fprintf_func
) (info
->stream
, "%s",
1378 mips_fpr_names
[(l
>> OP_SH_FD
) & OP_MASK_FD
]);
1382 (*info
->fprintf_func
) (info
->stream
, "%s",
1383 mips_fpr_names
[(l
>> OP_SH_FR
) & OP_MASK_FR
]);
1387 /* Coprocessor register for lwcN instructions, et al.
1389 Note that there is no load/store cp0 instructions, and
1390 that FPU (cp1) instructions disassemble this field using
1391 'T' format. Therefore, until we gain understanding of
1392 cp2 register names, we can simply print the register
1394 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1395 (l
>> OP_SH_RT
) & OP_MASK_RT
);
1399 /* Coprocessor register for mtcN instructions, et al. Note
1400 that FPU (cp1) instructions disassemble this field using
1401 'S' format. Therefore, we only need to worry about cp0,
1403 op
= (l
>> OP_SH_OP
) & OP_MASK_OP
;
1404 if (op
== OP_OP_COP0
)
1405 (*info
->fprintf_func
) (info
->stream
, "%s",
1406 mips_cp0_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1408 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1409 (l
>> OP_SH_RD
) & OP_MASK_RD
);
1413 (*info
->fprintf_func
) (info
->stream
, "%s",
1414 mips_hwr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1418 (*info
->fprintf_func
) (info
->stream
,
1419 ((opp
->pinfo
& (FP_D
| FP_S
)) != 0
1420 ? "$fcc%ld" : "$cc%ld"),
1421 (l
>> OP_SH_BCC
) & OP_MASK_BCC
);
1425 (*info
->fprintf_func
) (info
->stream
, "$fcc%ld",
1426 (l
>> OP_SH_CCC
) & OP_MASK_CCC
);
1430 (*info
->fprintf_func
) (info
->stream
, "%ld",
1431 (l
>> OP_SH_PERFREG
) & OP_MASK_PERFREG
);
1435 (*info
->fprintf_func
) (info
->stream
, "%ld",
1436 (l
>> OP_SH_VECBYTE
) & OP_MASK_VECBYTE
);
1440 (*info
->fprintf_func
) (info
->stream
, "%ld",
1441 (l
>> OP_SH_VECALIGN
) & OP_MASK_VECALIGN
);
1445 (*info
->fprintf_func
) (info
->stream
, "%ld",
1446 (l
>> OP_SH_SEL
) & OP_MASK_SEL
);
1450 (*info
->fprintf_func
) (info
->stream
, "%ld",
1451 (l
>> OP_SH_ALN
) & OP_MASK_ALN
);
1456 unsigned int vsel
= (l
>> OP_SH_VSEL
) & OP_MASK_VSEL
;
1458 if ((vsel
& 0x10) == 0)
1463 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1464 if ((vsel
& 1) == 0)
1466 (*info
->fprintf_func
) (info
->stream
, "$v%ld[%d]",
1467 (l
>> OP_SH_FT
) & OP_MASK_FT
,
1470 else if ((vsel
& 0x08) == 0)
1472 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1473 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1477 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1478 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1484 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1485 (l
>> OP_SH_FD
) & OP_MASK_FD
);
1489 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1490 (l
>> OP_SH_FS
) & OP_MASK_FS
);
1494 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1495 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1499 /* xgettext:c-format */
1500 (*info
->fprintf_func
) (info
->stream
,
1501 _("# internal error, undefined modifier (%c)"),
1508 /* Print the mips instruction at address MEMADDR in debugged memory,
1509 on using INFO. Returns length of the instruction, in bytes, which is
1510 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1511 this is little-endian code. */
1514 print_insn_mips (bfd_vma memaddr
,
1515 unsigned long int word
,
1516 struct disassemble_info
*info
)
1518 const struct mips_opcode
*op
;
1519 static bfd_boolean init
= 0;
1520 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1522 /* Build a hash table to shorten the search time. */
1527 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1529 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1531 if (op
->pinfo
== INSN_MACRO
1532 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1534 if (i
== ((op
->match
>> OP_SH_OP
) & OP_MASK_OP
))
1545 info
->bytes_per_chunk
= INSNLEN
;
1546 info
->display_endian
= info
->endian
;
1547 info
->insn_info_valid
= 1;
1548 info
->branch_delay_insns
= 0;
1549 info
->data_size
= 0;
1550 info
->insn_type
= dis_nonbranch
;
1554 op
= mips_hash
[(word
>> OP_SH_OP
) & OP_MASK_OP
];
1557 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1559 if (op
->pinfo
!= INSN_MACRO
1560 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1561 && (word
& op
->mask
) == op
->match
)
1565 /* We always allow to disassemble the jalx instruction. */
1566 if (! OPCODE_IS_MEMBER (op
, mips_isa
, mips_processor
)
1567 && strcmp (op
->name
, "jalx"))
1570 /* Figure out instruction type and branch delay information. */
1571 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1573 if ((op
->pinfo
& (INSN_WRITE_GPR_31
1574 | INSN_WRITE_GPR_D
)) != 0)
1575 info
->insn_type
= dis_jsr
;
1577 info
->insn_type
= dis_branch
;
1578 info
->branch_delay_insns
= 1;
1580 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1581 | INSN_COND_BRANCH_LIKELY
)) != 0)
1583 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1584 info
->insn_type
= dis_condjsr
;
1586 info
->insn_type
= dis_condbranch
;
1587 info
->branch_delay_insns
= 1;
1589 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1590 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1591 info
->insn_type
= dis_dref
;
1593 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
1596 if (d
!= NULL
&& *d
!= '\0')
1598 (*info
->fprintf_func
) (info
->stream
, "\t");
1599 print_insn_args (d
, word
, memaddr
, info
, op
);
1607 /* Handle undefined instructions. */
1608 info
->insn_type
= dis_noninsn
;
1609 (*info
->fprintf_func
) (info
->stream
, "0x%lx", word
);
1613 /* Disassemble an operand for a mips16 instruction. */
1616 print_mips16_insn_arg (char type
,
1617 const struct mips_opcode
*op
,
1619 bfd_boolean use_extend
,
1622 struct disassemble_info
*info
)
1629 (*info
->fprintf_func
) (info
->stream
, "%c", type
);
1634 (*info
->fprintf_func
) (info
->stream
, "%s",
1635 mips16_reg_names(((l
>> MIPS16OP_SH_RY
)
1636 & MIPS16OP_MASK_RY
)));
1641 (*info
->fprintf_func
) (info
->stream
, "%s",
1642 mips16_reg_names(((l
>> MIPS16OP_SH_RX
)
1643 & MIPS16OP_MASK_RX
)));
1647 (*info
->fprintf_func
) (info
->stream
, "%s",
1648 mips16_reg_names(((l
>> MIPS16OP_SH_RZ
)
1649 & MIPS16OP_MASK_RZ
)));
1653 (*info
->fprintf_func
) (info
->stream
, "%s",
1654 mips16_reg_names(((l
>> MIPS16OP_SH_MOVE32Z
)
1655 & MIPS16OP_MASK_MOVE32Z
)));
1659 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1663 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[29]);
1667 (*info
->fprintf_func
) (info
->stream
, "$pc");
1671 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[31]);
1675 (*info
->fprintf_func
) (info
->stream
, "%s",
1676 mips_gpr_names
[((l
>> MIPS16OP_SH_REGR32
)
1677 & MIPS16OP_MASK_REGR32
)]);
1681 (*info
->fprintf_func
) (info
->stream
, "%s",
1682 mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1708 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1720 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1726 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1732 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1738 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1744 immed
= (l
>> MIPS16OP_SH_IMM4
) & MIPS16OP_MASK_IMM4
;
1750 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1751 info
->insn_type
= dis_dref
;
1752 info
->data_size
= 1;
1757 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1758 info
->insn_type
= dis_dref
;
1759 info
->data_size
= 2;
1764 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1765 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1766 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1768 info
->insn_type
= dis_dref
;
1769 info
->data_size
= 4;
1775 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1776 info
->insn_type
= dis_dref
;
1777 info
->data_size
= 8;
1781 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1786 immed
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1790 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1795 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1796 /* FIXME: This might be lw, or it might be addiu to $sp or
1797 $pc. We assume it's load. */
1798 info
->insn_type
= dis_dref
;
1799 info
->data_size
= 4;
1804 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1805 info
->insn_type
= dis_dref
;
1806 info
->data_size
= 8;
1810 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1815 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1821 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1826 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1833 immed
= (l
>> MIPS16OP_SH_IMM11
) & MIPS16OP_MASK_IMM11
;
1841 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1843 /* FIXME: This can be lw or la. We assume it is lw. */
1844 info
->insn_type
= dis_dref
;
1845 info
->data_size
= 4;
1850 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1852 info
->insn_type
= dis_dref
;
1853 info
->data_size
= 8;
1858 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1867 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1868 immed
-= 1 << nbits
;
1870 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1877 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1878 else if (extbits
== 15)
1879 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1881 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1882 immed
&= (1 << extbits
) - 1;
1883 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1884 immed
-= 1 << extbits
;
1888 (*info
->fprintf_func
) (info
->stream
, "%d", immed
);
1896 baseaddr
= memaddr
+ 2;
1898 else if (use_extend
)
1899 baseaddr
= memaddr
- 2;
1907 /* If this instruction is in the delay slot of a jr
1908 instruction, the base address is the address of the
1909 jr instruction. If it is in the delay slot of jalr
1910 instruction, the base address is the address of the
1911 jalr instruction. This test is unreliable: we have
1912 no way of knowing whether the previous word is
1913 instruction or data. */
1914 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1917 && (((info
->endian
== BFD_ENDIAN_BIG
1918 ? bfd_getb16 (buffer
)
1919 : bfd_getl16 (buffer
))
1920 & 0xf800) == 0x1800))
1921 baseaddr
= memaddr
- 4;
1924 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1927 && (((info
->endian
== BFD_ENDIAN_BIG
1928 ? bfd_getb16 (buffer
)
1929 : bfd_getl16 (buffer
))
1930 & 0xf81f) == 0xe800))
1931 baseaddr
= memaddr
- 2;
1934 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1936 && info
->flavour
== bfd_target_unknown_flavour
)
1937 /* For gdb disassembler, maintain odd address. */
1939 (*info
->print_address_func
) (info
->target
, info
);
1946 int jalx
= l
& 0x400;
1950 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1951 if (!jalx
&& info
->flavour
== bfd_target_unknown_flavour
)
1952 /* For gdb disassembler, maintain odd address. */
1955 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1956 (*info
->print_address_func
) (info
->target
, info
);
1962 int need_comma
, amask
, smask
;
1966 l
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1968 amask
= (l
>> 3) & 7;
1970 if (amask
> 0 && amask
< 5)
1972 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
1974 (*info
->fprintf_func
) (info
->stream
, "-%s",
1975 mips_gpr_names
[amask
+ 3]);
1979 smask
= (l
>> 1) & 3;
1982 (*info
->fprintf_func
) (info
->stream
, "%s??",
1983 need_comma
? "," : "");
1988 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1989 need_comma
? "," : "",
1990 mips_gpr_names
[16]);
1992 (*info
->fprintf_func
) (info
->stream
, "-%s",
1993 mips_gpr_names
[smask
+ 15]);
1999 (*info
->fprintf_func
) (info
->stream
, "%s%s",
2000 need_comma
? "," : "",
2001 mips_gpr_names
[31]);
2005 if (amask
== 5 || amask
== 6)
2007 (*info
->fprintf_func
) (info
->stream
, "%s$f0",
2008 need_comma
? "," : "");
2010 (*info
->fprintf_func
) (info
->stream
, "-$f1");
2017 /* MIPS16e save/restore. */
2020 int amask
, args
, statics
;
2029 amask
= (l
>> 16) & 0xf;
2030 if (amask
== MIPS16_ALL_ARGS
)
2035 else if (amask
== MIPS16_ALL_STATICS
)
2043 statics
= amask
& 3;
2047 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
2049 (*info
->fprintf_func
) (info
->stream
, "-%s",
2050 mips_gpr_names
[4 + args
- 1]);
2054 framesz
= (((l
>> 16) & 0xf0) | (l
& 0x0f)) * 8;
2055 if (framesz
== 0 && !use_extend
)
2058 (*info
->fprintf_func
) (info
->stream
, "%s%d",
2059 need_comma
? "," : "",
2062 if (l
& 0x40) /* $ra */
2063 (*info
->fprintf_func
) (info
->stream
, ",%s", mips_gpr_names
[31]);
2065 nsreg
= (l
>> 24) & 0x7;
2067 if (l
& 0x20) /* $s0 */
2069 if (l
& 0x10) /* $s1 */
2071 if (nsreg
> 0) /* $s2-$s8 */
2072 smask
|= ((1 << nsreg
) - 1) << 2;
2074 /* Find first set static reg bit. */
2075 for (i
= 0; i
< 9; i
++)
2077 if (smask
& (1 << i
))
2079 (*info
->fprintf_func
) (info
->stream
, ",%s",
2080 mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
2081 /* Skip over string of set bits. */
2082 for (j
= i
; smask
& (2 << j
); j
++)
2085 (*info
->fprintf_func
) (info
->stream
, "-%s",
2086 mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
2091 /* Statics $ax - $a3. */
2093 (*info
->fprintf_func
) (info
->stream
, ",%s", mips_gpr_names
[7]);
2094 else if (statics
> 0)
2095 (*info
->fprintf_func
) (info
->stream
, ",%s-%s",
2096 mips_gpr_names
[7 - statics
+ 1],
2102 /* xgettext:c-format */
2103 (*info
->fprintf_func
)
2105 _("# internal disassembler error, unrecognised modifier (%c)"),
2111 /* Disassemble mips16 instructions. */
2114 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2120 bfd_boolean use_extend
;
2122 const struct mips_opcode
*op
, *opend
;
2124 info
->bytes_per_chunk
= 2;
2125 info
->display_endian
= info
->endian
;
2126 info
->insn_info_valid
= 1;
2127 info
->branch_delay_insns
= 0;
2128 info
->data_size
= 0;
2129 info
->insn_type
= dis_nonbranch
;
2133 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2136 (*info
->memory_error_func
) (status
, memaddr
, info
);
2142 if (info
->endian
== BFD_ENDIAN_BIG
)
2143 insn
= bfd_getb16 (buffer
);
2145 insn
= bfd_getl16 (buffer
);
2147 /* Handle the extend opcode specially. */
2149 if ((insn
& 0xf800) == 0xf000)
2152 extend
= insn
& 0x7ff;
2156 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2159 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
2160 (unsigned int) extend
);
2161 (*info
->memory_error_func
) (status
, memaddr
, info
);
2165 if (info
->endian
== BFD_ENDIAN_BIG
)
2166 insn
= bfd_getb16 (buffer
);
2168 insn
= bfd_getl16 (buffer
);
2170 /* Check for an extend opcode followed by an extend opcode. */
2171 if ((insn
& 0xf800) == 0xf000)
2173 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
2174 (unsigned int) extend
);
2175 info
->insn_type
= dis_noninsn
;
2182 /* FIXME: Should probably use a hash table on the major opcode here. */
2184 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2185 for (op
= mips16_opcodes
; op
< opend
; op
++)
2187 if (op
->pinfo
!= INSN_MACRO
2188 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2189 && (insn
& op
->mask
) == op
->match
)
2193 if (strchr (op
->args
, 'a') != NULL
)
2197 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
2198 (unsigned int) extend
);
2199 info
->insn_type
= dis_noninsn
;
2207 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2212 if (info
->endian
== BFD_ENDIAN_BIG
)
2213 extend
= bfd_getb16 (buffer
);
2215 extend
= bfd_getl16 (buffer
);
2220 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
2221 if (op
->args
[0] != '\0')
2222 (*info
->fprintf_func
) (info
->stream
, "\t");
2224 for (s
= op
->args
; *s
!= '\0'; s
++)
2228 && (((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)
2229 == ((insn
>> MIPS16OP_SH_RY
) & MIPS16OP_MASK_RY
)))
2231 /* Skip the register and the comma. */
2237 && (((insn
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
)
2238 == ((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)))
2240 /* Skip the register and the comma. */
2244 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
2248 /* Figure out branch instruction type and delay slot information. */
2249 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2250 info
->branch_delay_insns
= 1;
2251 if ((op
->pinfo
& (INSN_UNCOND_BRANCH_DELAY
2252 | MIPS16_INSN_UNCOND_BRANCH
)) != 0)
2254 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2255 info
->insn_type
= dis_jsr
;
2257 info
->insn_type
= dis_branch
;
2259 else if ((op
->pinfo
& MIPS16_INSN_COND_BRANCH
) != 0)
2260 info
->insn_type
= dis_condbranch
;
2267 (*info
->fprintf_func
) (info
->stream
, "0x%x", extend
| 0xf000);
2268 (*info
->fprintf_func
) (info
->stream
, "0x%x", insn
);
2269 info
->insn_type
= dis_noninsn
;
2274 /* Disassemble microMIPS instructions. */
2277 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2279 const fprintf_ftype infprintf
= info
->fprintf_func
;
2280 const struct mips_opcode
*op
, *opend
;
2281 unsigned int lsb
, msbd
, msb
;
2282 void *is
= info
->stream
;
2295 info
->bytes_per_chunk
= 2;
2296 info
->display_endian
= info
->endian
;
2297 info
->insn_info_valid
= 1;
2298 info
->branch_delay_insns
= 0;
2299 info
->data_size
= 0;
2300 info
->insn_type
= dis_nonbranch
;
2304 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2307 (*info
->memory_error_func
) (status
, memaddr
, info
);
2313 if (info
->endian
== BFD_ENDIAN_BIG
)
2314 insn
= bfd_getb16 (buffer
);
2316 insn
= bfd_getl16 (buffer
);
2318 if ((insn
& 0xfc00) == 0x7c00)
2320 /* This is a 48-bit microMIPS instruction. */
2323 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2326 infprintf (is
, "micromips 0x%x", higher
);
2327 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2330 if (info
->endian
== BFD_ENDIAN_BIG
)
2331 insn
= bfd_getb16 (buffer
);
2333 insn
= bfd_getl16 (buffer
);
2334 higher
= (higher
<< 16) | insn
;
2336 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
2339 infprintf (is
, "micromips 0x%x", higher
);
2340 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2343 if (info
->endian
== BFD_ENDIAN_BIG
)
2344 insn
= bfd_getb16 (buffer
);
2346 insn
= bfd_getl16 (buffer
);
2347 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2349 info
->insn_type
= dis_noninsn
;
2352 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2354 /* This is a 32-bit microMIPS instruction. */
2357 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2360 infprintf (is
, "micromips 0x%x", higher
);
2361 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2365 if (info
->endian
== BFD_ENDIAN_BIG
)
2366 insn
= bfd_getb16 (buffer
);
2368 insn
= bfd_getl16 (buffer
);
2370 insn
= insn
| (higher
<< 16);
2375 /* FIXME: Should probably use a hash table on the major opcode here. */
2377 #define GET_OP(insn, field) \
2378 (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2379 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2380 for (op
= micromips_opcodes
; op
< opend
; op
++)
2382 if (op
->pinfo
!= INSN_MACRO
2383 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2384 && (insn
& op
->mask
) == op
->match
2385 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2386 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2390 infprintf (is
, "%s", op
->name
);
2391 if (op
->args
[0] != '\0')
2392 infprintf (is
, "\t");
2394 for (s
= op
->args
; *s
!= '\0'; s
++)
2401 infprintf (is
, "%c", *s
);
2405 delta
= GET_OP (insn
, OFFSET10
);
2408 infprintf (is
, "%d", delta
);
2412 infprintf (is
, "0x%lx", GET_OP (insn
, STYPE
));
2416 infprintf (is
, "0x%lx", GET_OP (insn
, SHAMT
));
2420 infprintf (is
, "0x%lx", GET_OP (insn
, 3BITPOS
));
2424 infprintf (is
, "0x%lx", GET_OP (insn
, TRAP
));
2428 delta
= GET_OP (insn
, OFFSET12
);
2431 infprintf (is
, "%d", delta
);
2435 if (strcmp (op
->name
, "jalx") == 0)
2436 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff)
2437 | (GET_OP (insn
, TARGET
) << 2));
2439 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x07ffffff)
2440 | ((GET_OP (insn
, TARGET
)) << 1));
2441 /* For gdb disassembler, force odd address on jalx. */
2442 if (info
->flavour
== bfd_target_unknown_flavour
2443 && strcmp (op
->name
, "jalx") == 0)
2445 (*info
->print_address_func
) (info
->target
, info
);
2452 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS
)]);
2456 infprintf (is
, "0x%lx", GET_OP (insn
, CODE
));
2460 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RD
)]);
2464 infprintf (is
, "0x%lx", GET_OP (insn
, PREFX
));
2469 infprintf (is
, "0x%lx", GET_OP (insn
, IMMEDIATE
));
2472 case 'j': /* Same as i, but sign-extended. */
2474 delta
= (GET_OP (insn
, DELTA
) ^ 0x8000) - 0x8000;
2475 infprintf (is
, "%d", delta
);
2479 infprintf (is
, "0x%x", GET_OP (insn
, CACHE
));
2486 immed
= GET_OP (insn
, RT
);
2487 s_reg_encode
= immed
& 0xf;
2488 if (s_reg_encode
!= 0)
2490 if (s_reg_encode
== 1)
2491 infprintf (is
, "%s", mips_gpr_names
[16]);
2492 else if (s_reg_encode
< 9)
2493 infprintf (is
, "%s-%s",
2495 mips_gpr_names
[15 + s_reg_encode
]);
2496 else if (s_reg_encode
== 9)
2497 infprintf (is
, "%s-%s,%s",
2500 mips_gpr_names
[30]);
2502 infprintf (is
, "UNKNOWN");
2505 if (immed
& 0x10) /* For ra. */
2507 if (s_reg_encode
== 0)
2508 infprintf (is
, "%s", mips_gpr_names
[31]);
2510 infprintf (is
, ",%s", mips_gpr_names
[31]);
2516 /* Sign-extend the displacement. */
2517 delta
= (GET_OP (insn
, DELTA
) ^ 0x8000) - 0x8000;
2518 info
->target
= (delta
<< 1) + memaddr
+ length
;
2519 (*info
->print_address_func
) (info
->target
, info
);
2523 infprintf (is
, "0x%lx", GET_OP (insn
, CODE2
));
2528 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RT
)]);
2532 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS3
)]);
2536 infprintf (is
, "%s", mips_gpr_names
[0]);
2540 infprintf (is
, "0x%lx", GET_OP (insn
, CODE10
));
2544 infprintf (is
, "0x%lx", GET_OP (insn
, COPZ
));
2548 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FD
)]);
2552 /* Coprocessor register for lwcN instructions, et al.
2554 Note that there is no load/store cp0 instructions, and
2555 that FPU (cp1) instructions disassemble this field using
2556 'T' format. Therefore, until we gain understanding of
2557 cp2 register names, we can simply print the register
2559 infprintf (is
, "$%ld", GET_OP (insn
, RT
));
2563 /* Coprocessor register for mtcN instructions, et al. Note
2564 that FPU (cp1) instructions disassemble this field using
2565 'S' format. Therefore, we only need to worry about cp0,
2567 The microMIPS encoding does not have a coprocessor
2568 identifier field as such, so we must work out the
2569 coprocessor number by looking at the opcode. */
2571 & ~((MICROMIPSOP_MASK_RT
<< MICROMIPSOP_SH_RT
)
2572 | (MICROMIPSOP_MASK_RS
<< MICROMIPSOP_SH_RS
)))
2574 case 0x000000fc: /* mfc0 */
2575 case 0x000002fc: /* mtc0 */
2576 case 0x580000fc: /* dmfc0 */
2577 case 0x580002fc: /* dmtc0 */
2578 infprintf (is
, "%s", mips_cp0_names
[GET_OP (insn
, RS
)]);
2581 infprintf (is
, "$%ld", GET_OP (insn
, RS
));
2587 infprintf (is
, "%ld", GET_OP (insn
, SEL
));
2591 infprintf (is
, "%s", mips_hwr_names
[GET_OP (insn
, RS
)]);
2595 infprintf (is
, "$fcc%ld", GET_OP (insn
, CCC
));
2600 (op
->pinfo
& (FP_D
| FP_S
)) != 0
2601 ? "$fcc%ld" : "$cc%ld",
2602 GET_OP (insn
, BCC
));
2606 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FR
)]);
2611 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FS
)]);
2615 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FT
)]);
2619 /* Extension character; switch for second char. */
2624 lsb
= GET_OP (insn
, EXTLSB
);
2625 infprintf (is
, "0x%x", lsb
);
2629 msb
= GET_OP (insn
, INSMSB
);
2630 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2635 msbd
= GET_OP (insn
, EXTMSBD
);
2636 infprintf (is
, "0x%x", msbd
+ 1);
2641 const struct mips_cp0sel_name
*n
;
2642 unsigned int cp0reg
, sel
;
2644 cp0reg
= GET_OP (insn
, RS
);
2645 sel
= GET_OP (insn
, SEL
);
2647 /* CP0 register including 'sel' code for mtcN
2648 (et al.), to be printed textually if known.
2649 If not known, print both CP0 register name and
2650 sel numerically since CP0 register with sel 0 may
2651 have a name unrelated to register being printed. */
2652 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2653 mips_cp0sel_names_len
,
2656 infprintf (is
, "%s", n
->name
);
2658 infprintf (is
, "$%d,%d", cp0reg
, sel
);
2663 lsb
= GET_OP (insn
, EXTLSB
) + 32;
2664 infprintf (is
, "0x%x", lsb
);
2668 msb
= GET_OP (insn
, INSMSB
) + 32;
2669 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2673 msbd
= GET_OP (insn
, EXTMSBD
) + 32;
2674 infprintf (is
, "0x%x", msbd
+ 1);
2678 /* xgettext:c-format */
2680 _("# internal disassembler error, "
2681 "unrecognized modifier (+%c)"),
2688 /* Extension character; switch for second char. */
2692 case 'a': /* global pointer. */
2693 infprintf (is
, "%s", mips_gpr_names
[28]);
2697 regno
= micromips_to_32_reg_b_map
[GET_OP (insn
, MB
)];
2698 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2702 regno
= micromips_to_32_reg_c_map
[GET_OP (insn
, MC
)];
2703 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2707 regno
= micromips_to_32_reg_d_map
[GET_OP (insn
, MD
)];
2708 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2712 regno
= micromips_to_32_reg_e_map
[GET_OP (insn
, ME
)];
2713 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2717 /* Save lastregno for "mt" to print out later. */
2718 lastregno
= micromips_to_32_reg_f_map
[GET_OP (insn
, MF
)];
2719 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2723 regno
= micromips_to_32_reg_g_map
[GET_OP (insn
, MG
)];
2724 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2728 regno
= micromips_to_32_reg_h_map
[GET_OP (insn
, MH
)];
2729 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2733 regno
= micromips_to_32_reg_i_map
[GET_OP (insn
, MI
)];
2734 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2738 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, MJ
)]);
2742 regno
= micromips_to_32_reg_l_map
[GET_OP (insn
, ML
)];
2743 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2747 regno
= micromips_to_32_reg_m_map
[GET_OP (insn
, MM
)];
2748 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2752 regno
= micromips_to_32_reg_n_map
[GET_OP (insn
, MN
)];
2753 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2757 /* Save lastregno for "mt" to print out later. */
2758 lastregno
= GET_OP (insn
, MP
);
2759 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2763 regno
= micromips_to_32_reg_q_map
[GET_OP (insn
, MQ
)];
2764 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2767 case 'r': /* program counter. */
2768 infprintf (is
, "$pc");
2771 case 's': /* stack pointer. */
2773 infprintf (is
, "%s", mips_gpr_names
[29]);
2777 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2781 infprintf (is
, "%s", mips_gpr_names
[0]);
2785 /* Sign-extend the immediate. */
2786 immed
= ((GET_OP (insn
, IMMA
) ^ 0x40) - 0x40) << 2;
2787 infprintf (is
, "%d", immed
);
2791 immed
= micromips_imm_b_map
[GET_OP (insn
, IMMB
)];
2792 infprintf (is
, "%d", immed
);
2796 immed
= micromips_imm_c_map
[GET_OP (insn
, IMMC
)];
2797 infprintf (is
, "0x%lx", immed
);
2801 /* Sign-extend the displacement. */
2802 delta
= (GET_OP (insn
, IMMD
) ^ 0x200) - 0x200;
2803 info
->target
= (delta
<< 1) + memaddr
+ length
;
2804 (*info
->print_address_func
) (info
->target
, info
);
2808 /* Sign-extend the displacement. */
2809 delta
= (GET_OP (insn
, IMME
) ^ 0x40) - 0x40;
2810 info
->target
= (delta
<< 1) + memaddr
+ length
;
2811 (*info
->print_address_func
) (info
->target
, info
);
2815 immed
= GET_OP (insn
, IMMF
);
2816 infprintf (is
, "0x%x", immed
);
2820 immed
= (insn
>> MICROMIPSOP_SH_IMMG
) + 1;
2821 immed
= (immed
& MICROMIPSOP_MASK_IMMG
) - 1;
2822 infprintf (is
, "%d", immed
);
2826 immed
= GET_OP (insn
, IMMH
) << 1;
2827 infprintf (is
, "%d", immed
);
2831 immed
= (insn
>> MICROMIPSOP_SH_IMMI
) + 1;
2832 immed
= (immed
& MICROMIPSOP_MASK_IMMI
) - 1;
2833 infprintf (is
, "%d", immed
);
2837 immed
= GET_OP (insn
, IMMJ
) << 2;
2838 infprintf (is
, "%d", immed
);
2842 immed
= GET_OP (insn
, IMML
);
2843 infprintf (is
, "%d", immed
);
2847 immed
= (insn
>> MICROMIPSOP_SH_IMMM
) - 1;
2848 immed
= (immed
& MICROMIPSOP_MASK_IMMM
) + 1;
2849 infprintf (is
, "%d", immed
);
2853 immed
= GET_OP (insn
, IMMN
);
2855 infprintf (is
, "%s,%s",
2857 mips_gpr_names
[31]);
2859 infprintf (is
, "%s-%s,%s",
2861 mips_gpr_names
[16 + immed
],
2862 mips_gpr_names
[31]);
2866 immed
= GET_OP (insn
, IMMO
);
2867 infprintf (is
, "0x%x", immed
);
2871 immed
= GET_OP (insn
, IMMP
) << 2;
2872 infprintf (is
, "%d", immed
);
2876 /* Sign-extend the immediate. */
2877 immed
= (GET_OP (insn
, IMMQ
) ^ 0x400000) - 0x400000;
2879 infprintf (is
, "%d", immed
);
2883 immed
= GET_OP (insn
, IMMU
) << 2;
2884 infprintf (is
, "%d", immed
);
2888 immed
= GET_OP (insn
, IMMW
) << 2;
2889 infprintf (is
, "%d", immed
);
2893 /* Sign-extend the immediate. */
2894 immed
= (GET_OP (insn
, IMMX
) ^ 0x8) - 0x8;
2895 infprintf (is
, "%d", immed
);
2899 /* Sign-extend the immediate. */
2900 immed
= (GET_OP (insn
, IMMY
) ^ 0x100) - 0x100;
2901 if (immed
>= -2 && immed
<= 1)
2904 infprintf (is
, "%d", immed
);
2908 /* xgettext:c-format */
2910 _("# internal disassembler error, "
2911 "unrecognized modifier (m%c)"),
2918 /* xgettext:c-format */
2920 _("# internal disassembler error, "
2921 "unrecognized modifier (%c)"),
2927 /* Figure out instruction type and branch delay information. */
2929 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2930 info
->branch_delay_insns
= 1;
2931 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2932 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2934 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_GPR_T
)) != 0)
2935 info
->insn_type
= dis_jsr
;
2937 info
->insn_type
= dis_branch
;
2939 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2940 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2942 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2943 info
->insn_type
= dis_condjsr
;
2945 info
->insn_type
= dis_condbranch
;
2948 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY_DELAY
)) != 0)
2949 info
->insn_type
= dis_dref
;
2956 infprintf (is
, "0x%x", insn
);
2957 info
->insn_type
= dis_noninsn
;
2962 /* Return 1 if a symbol associated with the location being disassembled
2963 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2964 all the symbols at the address being considered assuming if at least
2965 one of them indicates code compression, then such code has been
2966 genuinely produced here (other symbols could have been derived from
2967 function symbols defined elsewhere or could define data). Otherwise,
2971 is_compressed_mode_p (struct disassemble_info
*info
)
2973 elf_symbol_type
*symbol
;
2977 for (i
= 0; i
< info
->num_symbols
; i
++)
2979 pos
= info
->symtab_pos
+ i
;
2981 if (bfd_asymbol_flavour (info
->symtab
[pos
]) != bfd_target_elf_flavour
)
2984 symbol
= (elf_symbol_type
*) info
->symtab
[pos
];
2986 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2988 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2995 /* In an environment where we do not know the symbol type of the
2996 instruction we are forced to assume that the low order bit of the
2997 instructions' address may mark it as a mips16 instruction. If we
2998 are single stepping, or the pc is within the disassembled function,
2999 this works. Otherwise, we need a clue. Sometimes. */
3002 _print_insn_mips (bfd_vma memaddr
,
3003 struct disassemble_info
*info
,
3004 enum bfd_endian endianness
)
3006 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
3007 bfd_byte buffer
[INSNLEN
];
3010 set_default_mips_dis_options (info
);
3011 parse_mips_dis_options (info
->disassembler_options
);
3013 if (info
->mach
== bfd_mach_mips16
)
3014 return print_insn_mips16 (memaddr
, info
);
3015 if (info
->mach
== bfd_mach_mips_micromips
)
3016 return print_insn_micromips (memaddr
, info
);
3018 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
3021 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
3022 /* Only a few tools will work this way. */
3024 return print_insn_compr (memaddr
, info
);
3027 #if SYMTAB_AVAILABLE
3028 if (is_compressed_mode_p (info
))
3029 return print_insn_compr (memaddr
, info
);
3032 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
3037 if (endianness
== BFD_ENDIAN_BIG
)
3038 insn
= (unsigned long) bfd_getb32 (buffer
);
3040 insn
= (unsigned long) bfd_getl32 (buffer
);
3042 return print_insn_mips (memaddr
, insn
, info
);
3046 (*info
->memory_error_func
) (status
, memaddr
, info
);
3052 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3054 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
3058 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3060 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
3064 print_mips_disassembler_options (FILE *stream
)
3068 fprintf (stream
, _("\n\
3069 The following MIPS specific disassembler options are supported for use\n\
3070 with the -M switch (multiple options should be separated by commas):\n"));
3072 fprintf (stream
, _("\n\
3073 gpr-names=ABI Print GPR names according to specified ABI.\n\
3074 Default: based on binary being disassembled.\n"));
3076 fprintf (stream
, _("\n\
3077 fpr-names=ABI Print FPR names according to specified ABI.\n\
3078 Default: numeric.\n"));
3080 fprintf (stream
, _("\n\
3081 cp0-names=ARCH Print CP0 register names according to\n\
3082 specified architecture.\n\
3083 Default: based on binary being disassembled.\n"));
3085 fprintf (stream
, _("\n\
3086 hwr-names=ARCH Print HWR names according to specified \n\
3088 Default: based on binary being disassembled.\n"));
3090 fprintf (stream
, _("\n\
3091 reg-names=ABI Print GPR and FPR names according to\n\
3092 specified ABI.\n"));
3094 fprintf (stream
, _("\n\
3095 reg-names=ARCH Print CP0 register and HWR names according to\n\
3096 specified architecture.\n"));
3098 fprintf (stream
, _("\n\
3099 For the options above, the following values are supported for \"ABI\":\n\
3101 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
3102 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
3103 fprintf (stream
, _("\n"));
3105 fprintf (stream
, _("\n\
3106 For the options above, The following values are supported for \"ARCH\":\n\
3108 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
3109 if (*mips_arch_choices
[i
].name
!= '\0')
3110 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
3111 fprintf (stream
, _("\n"));
3113 fprintf (stream
, _("\n"));