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_OCTEON
| INSN_OCTEONP
, mips_cp0_names_numeric
,
610 NULL
, 0, mips_hwr_names_numeric
},
612 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
613 ISA_MIPS64
| INSN_XLR
,
615 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
616 mips_hwr_names_numeric
},
618 /* This entry, mips16, is here only for ISA/processor selection; do
619 not print its name. */
620 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
,
621 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
624 /* ISA and processor type to disassemble for, and register names to use.
625 set_default_mips_dis_options and parse_mips_dis_options fill in these
627 static int mips_processor
;
629 static int micromips_ase
;
630 static const char * const *mips_gpr_names
;
631 static const char * const *mips_fpr_names
;
632 static const char * const *mips_cp0_names
;
633 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
634 static int mips_cp0sel_names_len
;
635 static const char * const *mips_hwr_names
;
638 static int no_aliases
; /* If set disassemble as most general inst. */
640 static const struct mips_abi_choice
*
641 choose_abi_by_name (const char *name
, unsigned int namelen
)
643 const struct mips_abi_choice
*c
;
646 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
647 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
648 && strlen (mips_abi_choices
[i
].name
) == namelen
)
649 c
= &mips_abi_choices
[i
];
654 static const struct mips_arch_choice
*
655 choose_arch_by_name (const char *name
, unsigned int namelen
)
657 const struct mips_arch_choice
*c
= NULL
;
660 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
661 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
662 && strlen (mips_arch_choices
[i
].name
) == namelen
)
663 c
= &mips_arch_choices
[i
];
668 static const struct mips_arch_choice
*
669 choose_arch_by_number (unsigned long mach
)
671 static unsigned long hint_bfd_mach
;
672 static const struct mips_arch_choice
*hint_arch_choice
;
673 const struct mips_arch_choice
*c
;
676 /* We optimize this because even if the user specifies no
677 flags, this will be done for every instruction! */
678 if (hint_bfd_mach
== mach
679 && hint_arch_choice
!= NULL
680 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
681 return hint_arch_choice
;
683 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
685 if (mips_arch_choices
[i
].bfd_mach_valid
686 && mips_arch_choices
[i
].bfd_mach
== mach
)
688 c
= &mips_arch_choices
[i
];
689 hint_bfd_mach
= mach
;
690 hint_arch_choice
= c
;
696 /* Check if the object uses NewABI conventions. */
699 is_newabi (Elf_Internal_Ehdr
*header
)
701 /* There are no old-style ABIs which use 64-bit ELF. */
702 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
705 /* If a 32-bit ELF file, n32 is a new-style ABI. */
706 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
712 /* Check if the object has microMIPS ASE code. */
715 is_micromips (Elf_Internal_Ehdr
*header
)
717 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
724 set_default_mips_dis_options (struct disassemble_info
*info
)
726 const struct mips_arch_choice
*chosen_arch
;
728 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
729 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
730 CP0 register, and HWR names. */
731 mips_isa
= ISA_MIPS3
;
732 mips_processor
= CPU_R3000
;
734 mips_gpr_names
= mips_gpr_names_oldabi
;
735 mips_fpr_names
= mips_fpr_names_numeric
;
736 mips_cp0_names
= mips_cp0_names_numeric
;
737 mips_cp0sel_names
= NULL
;
738 mips_cp0sel_names_len
= 0;
739 mips_hwr_names
= mips_hwr_names_numeric
;
742 /* Update settings according to the ELF file header flags. */
743 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
745 Elf_Internal_Ehdr
*header
;
747 header
= elf_elfheader (info
->section
->owner
);
748 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
749 if (is_newabi (header
))
750 mips_gpr_names
= mips_gpr_names_newabi
;
751 /* If a microMIPS binary, then don't use MIPS16 bindings. */
752 micromips_ase
= is_micromips (header
);
755 /* Set ISA, architecture, and cp0 register names as best we can. */
756 #if ! SYMTAB_AVAILABLE
757 /* This is running out on a target machine, not in a host tool.
758 FIXME: Where does mips_target_info come from? */
759 target_processor
= mips_target_info
.processor
;
760 mips_isa
= mips_target_info
.isa
;
762 chosen_arch
= choose_arch_by_number (info
->mach
);
763 if (chosen_arch
!= NULL
)
765 mips_processor
= chosen_arch
->processor
;
766 mips_isa
= chosen_arch
->isa
;
767 mips_cp0_names
= chosen_arch
->cp0_names
;
768 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
769 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
770 mips_hwr_names
= chosen_arch
->hwr_names
;
776 parse_mips_dis_option (const char *option
, unsigned int len
)
778 unsigned int i
, optionlen
, vallen
;
780 const struct mips_abi_choice
*chosen_abi
;
781 const struct mips_arch_choice
*chosen_arch
;
783 /* Try to match options that are simple flags */
784 if (CONST_STRNEQ (option
, "no-aliases"))
790 /* Look for the = that delimits the end of the option name. */
791 for (i
= 0; i
< len
; i
++)
792 if (option
[i
] == '=')
795 if (i
== 0) /* Invalid option: no name before '='. */
797 if (i
== len
) /* Invalid option: no '='. */
799 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
803 val
= option
+ (optionlen
+ 1);
804 vallen
= len
- (optionlen
+ 1);
806 if (strncmp ("gpr-names", option
, optionlen
) == 0
807 && strlen ("gpr-names") == optionlen
)
809 chosen_abi
= choose_abi_by_name (val
, vallen
);
810 if (chosen_abi
!= NULL
)
811 mips_gpr_names
= chosen_abi
->gpr_names
;
815 if (strncmp ("fpr-names", option
, optionlen
) == 0
816 && strlen ("fpr-names") == optionlen
)
818 chosen_abi
= choose_abi_by_name (val
, vallen
);
819 if (chosen_abi
!= NULL
)
820 mips_fpr_names
= chosen_abi
->fpr_names
;
824 if (strncmp ("cp0-names", option
, optionlen
) == 0
825 && strlen ("cp0-names") == optionlen
)
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
;
837 if (strncmp ("hwr-names", option
, optionlen
) == 0
838 && strlen ("hwr-names") == optionlen
)
840 chosen_arch
= choose_arch_by_name (val
, vallen
);
841 if (chosen_arch
!= NULL
)
842 mips_hwr_names
= chosen_arch
->hwr_names
;
846 if (strncmp ("reg-names", option
, optionlen
) == 0
847 && strlen ("reg-names") == optionlen
)
849 /* We check both ABI and ARCH here unconditionally, so
850 that "numeric" will do the desirable thing: select
851 numeric register names for all registers. Other than
852 that, a given name probably won't match both. */
853 chosen_abi
= choose_abi_by_name (val
, vallen
);
854 if (chosen_abi
!= NULL
)
856 mips_gpr_names
= chosen_abi
->gpr_names
;
857 mips_fpr_names
= chosen_abi
->fpr_names
;
859 chosen_arch
= choose_arch_by_name (val
, vallen
);
860 if (chosen_arch
!= NULL
)
862 mips_cp0_names
= chosen_arch
->cp0_names
;
863 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
864 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
865 mips_hwr_names
= chosen_arch
->hwr_names
;
870 /* Invalid option. */
874 parse_mips_dis_options (const char *options
)
876 const char *option_end
;
881 while (*options
!= '\0')
883 /* Skip empty options. */
890 /* We know that *options is neither NUL or a comma. */
891 option_end
= options
+ 1;
892 while (*option_end
!= ',' && *option_end
!= '\0')
895 parse_mips_dis_option (options
, option_end
- options
);
897 /* Go on to the next one. If option_end points to a comma, it
898 will be skipped above. */
899 options
= option_end
;
903 static const struct mips_cp0sel_name
*
904 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
911 for (i
= 0; i
< len
; i
++)
912 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
917 /* Print insn arguments for 32/64-bit code. */
920 print_insn_args (const char *d
,
921 register unsigned long int l
,
923 struct disassemble_info
*info
,
924 const struct mips_opcode
*opp
)
927 unsigned int lsb
, msb
, msbd
;
931 for (; *d
!= '\0'; d
++)
940 (*info
->fprintf_func
) (info
->stream
, "%c", *d
);
944 /* Extension character; switch for second char. */
949 /* xgettext:c-format */
950 (*info
->fprintf_func
) (info
->stream
,
951 _("# internal error, incomplete extension sequence (+)"));
955 lsb
= (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
;
956 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
960 msb
= (l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
;
961 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
965 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
966 (l
>> OP_SH_UDI1
) & OP_MASK_UDI1
);
970 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
971 (l
>> OP_SH_UDI2
) & OP_MASK_UDI2
);
975 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
976 (l
>> OP_SH_UDI3
) & OP_MASK_UDI3
);
980 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
981 (l
>> OP_SH_UDI4
) & OP_MASK_UDI4
);
986 msbd
= (l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
;
987 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
992 const struct mips_cp0sel_name
*n
;
993 unsigned int cp0reg
, sel
;
995 cp0reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
996 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
998 /* CP0 register including 'sel' code for mtcN (et al.), to be
999 printed textually if known. If not known, print both
1000 CP0 register name and sel numerically since CP0 register
1001 with sel 0 may have a name unrelated to register being
1003 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
1004 mips_cp0sel_names_len
, cp0reg
, sel
);
1006 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
1008 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
1013 lsb
= ((l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
) + 32;
1014 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
1018 msb
= ((l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
) + 32;
1019 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
1023 msbd
= ((l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
) + 32;
1024 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
1027 case 't': /* Coprocessor 0 reg name */
1028 (*info
->fprintf_func
) (info
->stream
, "%s",
1029 mips_cp0_names
[(l
>> OP_SH_RT
) &
1033 case 'T': /* Coprocessor 0 reg name */
1035 const struct mips_cp0sel_name
*n
;
1036 unsigned int cp0reg
, sel
;
1038 cp0reg
= (l
>> OP_SH_RT
) & OP_MASK_RT
;
1039 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
1041 /* CP0 register including 'sel' code for mftc0, to be
1042 printed textually if known. If not known, print both
1043 CP0 register name and sel numerically since CP0 register
1044 with sel 0 may have a name unrelated to register being
1046 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
1047 mips_cp0sel_names_len
, cp0reg
, sel
);
1049 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
1051 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
1055 case 'x': /* bbit bit index */
1056 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1057 (l
>> OP_SH_BBITIND
) & OP_MASK_BBITIND
);
1060 case 'p': /* cins, cins32, exts and exts32 position */
1061 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1062 (l
>> OP_SH_CINSPOS
) & OP_MASK_CINSPOS
);
1065 case 's': /* cins and exts length-minus-one */
1066 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1067 (l
>> OP_SH_CINSLM1
) & OP_MASK_CINSLM1
);
1070 case 'S': /* cins32 and exts32 length-minus-one field */
1071 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1072 (l
>> OP_SH_CINSLM1
) & OP_MASK_CINSLM1
);
1075 case 'Q': /* seqi/snei immediate field */
1076 op
= (l
>> OP_SH_SEQI
) & OP_MASK_SEQI
;
1077 /* Sign-extend it. */
1078 op
= (op
^ 512) - 512;
1079 (*info
->fprintf_func
) (info
->stream
, "%d", op
);
1082 case 'a': /* 8-bit signed offset in bit 6 */
1083 delta
= (l
>> OP_SH_OFFSET_A
) & OP_MASK_OFFSET_A
;
1085 delta
|= ~OP_MASK_OFFSET_A
;
1086 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1089 case 'b': /* 8-bit signed offset in bit 3 */
1090 delta
= (l
>> OP_SH_OFFSET_B
) & OP_MASK_OFFSET_B
;
1092 delta
|= ~OP_MASK_OFFSET_B
;
1093 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1096 case 'c': /* 9-bit signed offset in bit 6 */
1097 delta
= (l
>> OP_SH_OFFSET_C
) & OP_MASK_OFFSET_C
;
1099 delta
|= ~OP_MASK_OFFSET_C
;
1100 /* Left shift 4 bits to print the real offset. */
1101 (*info
->fprintf_func
) (info
->stream
, "%d", delta
<< 4);
1105 (*info
->fprintf_func
) (info
->stream
, "%s",
1106 mips_gpr_names
[(l
>> OP_SH_RZ
) & OP_MASK_RZ
]);
1110 (*info
->fprintf_func
) (info
->stream
, "%s",
1111 mips_fpr_names
[(l
>> OP_SH_FZ
) & OP_MASK_FZ
]);
1115 /* xgettext:c-format */
1116 (*info
->fprintf_func
) (info
->stream
,
1117 _("# internal error, undefined extension sequence (+%c)"),
1124 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1125 (l
>> OP_SH_BP
) & OP_MASK_BP
);
1129 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1130 (l
>> OP_SH_SA3
) & OP_MASK_SA3
);
1134 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1135 (l
>> OP_SH_SA4
) & OP_MASK_SA4
);
1139 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1140 (l
>> OP_SH_IMM8
) & OP_MASK_IMM8
);
1144 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1145 (l
>> OP_SH_RS
) & OP_MASK_RS
);
1149 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1150 (l
>> OP_SH_DSPACC
) & OP_MASK_DSPACC
);
1154 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1155 (l
>> OP_SH_WRDSP
) & OP_MASK_WRDSP
);
1159 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1160 (l
>> OP_SH_DSPACC_S
) & OP_MASK_DSPACC_S
);
1163 case '0': /* dsp 6-bit signed immediate in bit 20 */
1164 delta
= ((l
>> OP_SH_DSPSFT
) & OP_MASK_DSPSFT
);
1165 if (delta
& 0x20) /* test sign bit */
1166 delta
|= ~OP_MASK_DSPSFT
;
1167 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1170 case ':': /* dsp 7-bit signed immediate in bit 19 */
1171 delta
= ((l
>> OP_SH_DSPSFT_7
) & OP_MASK_DSPSFT_7
);
1172 if (delta
& 0x40) /* test sign bit */
1173 delta
|= ~OP_MASK_DSPSFT_7
;
1174 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1178 delta
= (l
>> OP_SH_OFFSET12
) & OP_MASK_OFFSET12
;
1181 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1185 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1186 (l
>> OP_SH_3BITPOS
) & OP_MASK_3BITPOS
);
1190 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1191 (l
>> OP_SH_RDDSP
) & OP_MASK_RDDSP
);
1194 case '@': /* dsp 10-bit signed immediate in bit 16 */
1195 delta
= ((l
>> OP_SH_IMM10
) & OP_MASK_IMM10
);
1196 if (delta
& 0x200) /* test sign bit */
1197 delta
|= ~OP_MASK_IMM10
;
1198 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1202 (*info
->fprintf_func
) (info
->stream
, "%ld",
1203 (l
>> OP_SH_MT_U
) & OP_MASK_MT_U
);
1207 (*info
->fprintf_func
) (info
->stream
, "%ld",
1208 (l
>> OP_SH_MT_H
) & OP_MASK_MT_H
);
1212 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1213 (l
>> OP_SH_MTACC_T
) & OP_MASK_MTACC_T
);
1217 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1218 (l
>> OP_SH_MTACC_D
) & OP_MASK_MTACC_D
);
1222 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
1223 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1224 (l
>> OP_SH_RD
) & OP_MASK_RD
);
1231 (*info
->fprintf_func
) (info
->stream
, "%s",
1232 mips_gpr_names
[(l
>> OP_SH_RS
) & OP_MASK_RS
]);
1237 (*info
->fprintf_func
) (info
->stream
, "%s",
1238 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1243 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1244 (l
>> OP_SH_IMMEDIATE
) & OP_MASK_IMMEDIATE
);
1247 case 'j': /* Same as i, but sign-extended. */
1249 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
1252 (*info
->fprintf_func
) (info
->stream
, "%d",
1257 (*info
->fprintf_func
) (info
->stream
, "0x%x",
1258 (unsigned int) ((l
>> OP_SH_PREFX
)
1263 (*info
->fprintf_func
) (info
->stream
, "0x%x",
1264 (unsigned int) ((l
>> OP_SH_CACHE
)
1269 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
1270 | (((l
>> OP_SH_TARGET
) & OP_MASK_TARGET
) << 2));
1271 /* For gdb disassembler, force odd address on jalx. */
1272 if (info
->flavour
== bfd_target_unknown_flavour
1273 && strcmp (opp
->name
, "jalx") == 0)
1275 (*info
->print_address_func
) (info
->target
, info
);
1279 /* Sign extend the displacement. */
1280 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
1283 info
->target
= (delta
<< 2) + pc
+ INSNLEN
;
1284 (*info
->print_address_func
) (info
->target
, info
);
1288 (*info
->fprintf_func
) (info
->stream
, "%s",
1289 mips_gpr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1294 /* First check for both rd and rt being equal. */
1295 unsigned int reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
1296 if (reg
== ((l
>> OP_SH_RT
) & OP_MASK_RT
))
1297 (*info
->fprintf_func
) (info
->stream
, "%s",
1298 mips_gpr_names
[reg
]);
1301 /* If one is zero use the other. */
1303 (*info
->fprintf_func
) (info
->stream
, "%s",
1304 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1305 else if (((l
>> OP_SH_RT
) & OP_MASK_RT
) == 0)
1306 (*info
->fprintf_func
) (info
->stream
, "%s",
1307 mips_gpr_names
[reg
]);
1308 else /* Bogus, result depends on processor. */
1309 (*info
->fprintf_func
) (info
->stream
, "%s or %s",
1310 mips_gpr_names
[reg
],
1311 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1317 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1322 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1323 (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
);
1327 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1328 (l
>> OP_SH_CODE
) & OP_MASK_CODE
);
1332 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1333 (l
>> OP_SH_CODE2
) & OP_MASK_CODE2
);
1337 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1338 (l
>> OP_SH_COPZ
) & OP_MASK_COPZ
);
1342 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1344 (l
>> OP_SH_CODE20
) & OP_MASK_CODE20
);
1348 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1349 (l
>> OP_SH_CODE19
) & OP_MASK_CODE19
);
1354 (*info
->fprintf_func
) (info
->stream
, "%s",
1355 mips_fpr_names
[(l
>> OP_SH_FS
) & OP_MASK_FS
]);
1360 (*info
->fprintf_func
) (info
->stream
, "%s",
1361 mips_fpr_names
[(l
>> OP_SH_FT
) & OP_MASK_FT
]);
1365 (*info
->fprintf_func
) (info
->stream
, "%s",
1366 mips_fpr_names
[(l
>> OP_SH_FD
) & OP_MASK_FD
]);
1370 (*info
->fprintf_func
) (info
->stream
, "%s",
1371 mips_fpr_names
[(l
>> OP_SH_FR
) & OP_MASK_FR
]);
1375 /* Coprocessor register for lwcN instructions, et al.
1377 Note that there is no load/store cp0 instructions, and
1378 that FPU (cp1) instructions disassemble this field using
1379 'T' format. Therefore, until we gain understanding of
1380 cp2 register names, we can simply print the register
1382 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1383 (l
>> OP_SH_RT
) & OP_MASK_RT
);
1387 /* Coprocessor register for mtcN instructions, et al. Note
1388 that FPU (cp1) instructions disassemble this field using
1389 'S' format. Therefore, we only need to worry about cp0,
1391 op
= (l
>> OP_SH_OP
) & OP_MASK_OP
;
1392 if (op
== OP_OP_COP0
)
1393 (*info
->fprintf_func
) (info
->stream
, "%s",
1394 mips_cp0_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1396 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1397 (l
>> OP_SH_RD
) & OP_MASK_RD
);
1401 (*info
->fprintf_func
) (info
->stream
, "%s",
1402 mips_hwr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1406 (*info
->fprintf_func
) (info
->stream
,
1407 ((opp
->pinfo
& (FP_D
| FP_S
)) != 0
1408 ? "$fcc%ld" : "$cc%ld"),
1409 (l
>> OP_SH_BCC
) & OP_MASK_BCC
);
1413 (*info
->fprintf_func
) (info
->stream
, "$fcc%ld",
1414 (l
>> OP_SH_CCC
) & OP_MASK_CCC
);
1418 (*info
->fprintf_func
) (info
->stream
, "%ld",
1419 (l
>> OP_SH_PERFREG
) & OP_MASK_PERFREG
);
1423 (*info
->fprintf_func
) (info
->stream
, "%ld",
1424 (l
>> OP_SH_VECBYTE
) & OP_MASK_VECBYTE
);
1428 (*info
->fprintf_func
) (info
->stream
, "%ld",
1429 (l
>> OP_SH_VECALIGN
) & OP_MASK_VECALIGN
);
1433 (*info
->fprintf_func
) (info
->stream
, "%ld",
1434 (l
>> OP_SH_SEL
) & OP_MASK_SEL
);
1438 (*info
->fprintf_func
) (info
->stream
, "%ld",
1439 (l
>> OP_SH_ALN
) & OP_MASK_ALN
);
1444 unsigned int vsel
= (l
>> OP_SH_VSEL
) & OP_MASK_VSEL
;
1446 if ((vsel
& 0x10) == 0)
1451 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1452 if ((vsel
& 1) == 0)
1454 (*info
->fprintf_func
) (info
->stream
, "$v%ld[%d]",
1455 (l
>> OP_SH_FT
) & OP_MASK_FT
,
1458 else if ((vsel
& 0x08) == 0)
1460 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1461 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1465 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1466 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1472 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1473 (l
>> OP_SH_FD
) & OP_MASK_FD
);
1477 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1478 (l
>> OP_SH_FS
) & OP_MASK_FS
);
1482 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1483 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1487 /* xgettext:c-format */
1488 (*info
->fprintf_func
) (info
->stream
,
1489 _("# internal error, undefined modifier (%c)"),
1496 /* Print the mips instruction at address MEMADDR in debugged memory,
1497 on using INFO. Returns length of the instruction, in bytes, which is
1498 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1499 this is little-endian code. */
1502 print_insn_mips (bfd_vma memaddr
,
1503 unsigned long int word
,
1504 struct disassemble_info
*info
)
1506 const struct mips_opcode
*op
;
1507 static bfd_boolean init
= 0;
1508 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1510 /* Build a hash table to shorten the search time. */
1515 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1517 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1519 if (op
->pinfo
== INSN_MACRO
1520 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1522 if (i
== ((op
->match
>> OP_SH_OP
) & OP_MASK_OP
))
1533 info
->bytes_per_chunk
= INSNLEN
;
1534 info
->display_endian
= info
->endian
;
1535 info
->insn_info_valid
= 1;
1536 info
->branch_delay_insns
= 0;
1537 info
->data_size
= 0;
1538 info
->insn_type
= dis_nonbranch
;
1542 op
= mips_hash
[(word
>> OP_SH_OP
) & OP_MASK_OP
];
1545 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1547 if (op
->pinfo
!= INSN_MACRO
1548 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1549 && (word
& op
->mask
) == op
->match
)
1553 /* We always allow to disassemble the jalx instruction. */
1554 if (! OPCODE_IS_MEMBER (op
, mips_isa
, mips_processor
)
1555 && strcmp (op
->name
, "jalx"))
1558 /* Figure out instruction type and branch delay information. */
1559 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1561 if ((op
->pinfo
& (INSN_WRITE_GPR_31
1562 | INSN_WRITE_GPR_D
)) != 0)
1563 info
->insn_type
= dis_jsr
;
1565 info
->insn_type
= dis_branch
;
1566 info
->branch_delay_insns
= 1;
1568 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1569 | INSN_COND_BRANCH_LIKELY
)) != 0)
1571 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1572 info
->insn_type
= dis_condjsr
;
1574 info
->insn_type
= dis_condbranch
;
1575 info
->branch_delay_insns
= 1;
1577 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1578 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1579 info
->insn_type
= dis_dref
;
1581 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
1584 if (d
!= NULL
&& *d
!= '\0')
1586 (*info
->fprintf_func
) (info
->stream
, "\t");
1587 print_insn_args (d
, word
, memaddr
, info
, op
);
1595 /* Handle undefined instructions. */
1596 info
->insn_type
= dis_noninsn
;
1597 (*info
->fprintf_func
) (info
->stream
, "0x%lx", word
);
1601 /* Disassemble an operand for a mips16 instruction. */
1604 print_mips16_insn_arg (char type
,
1605 const struct mips_opcode
*op
,
1607 bfd_boolean use_extend
,
1610 struct disassemble_info
*info
)
1617 (*info
->fprintf_func
) (info
->stream
, "%c", type
);
1622 (*info
->fprintf_func
) (info
->stream
, "%s",
1623 mips16_reg_names(((l
>> MIPS16OP_SH_RY
)
1624 & MIPS16OP_MASK_RY
)));
1629 (*info
->fprintf_func
) (info
->stream
, "%s",
1630 mips16_reg_names(((l
>> MIPS16OP_SH_RX
)
1631 & MIPS16OP_MASK_RX
)));
1635 (*info
->fprintf_func
) (info
->stream
, "%s",
1636 mips16_reg_names(((l
>> MIPS16OP_SH_RZ
)
1637 & MIPS16OP_MASK_RZ
)));
1641 (*info
->fprintf_func
) (info
->stream
, "%s",
1642 mips16_reg_names(((l
>> MIPS16OP_SH_MOVE32Z
)
1643 & MIPS16OP_MASK_MOVE32Z
)));
1647 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1651 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[29]);
1655 (*info
->fprintf_func
) (info
->stream
, "$pc");
1659 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[31]);
1663 (*info
->fprintf_func
) (info
->stream
, "%s",
1664 mips_gpr_names
[((l
>> MIPS16OP_SH_REGR32
)
1665 & MIPS16OP_MASK_REGR32
)]);
1669 (*info
->fprintf_func
) (info
->stream
, "%s",
1670 mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1696 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1708 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1714 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1720 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1726 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1732 immed
= (l
>> MIPS16OP_SH_IMM4
) & MIPS16OP_MASK_IMM4
;
1738 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1739 info
->insn_type
= dis_dref
;
1740 info
->data_size
= 1;
1745 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1746 info
->insn_type
= dis_dref
;
1747 info
->data_size
= 2;
1752 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1753 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1754 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1756 info
->insn_type
= dis_dref
;
1757 info
->data_size
= 4;
1763 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1764 info
->insn_type
= dis_dref
;
1765 info
->data_size
= 8;
1769 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1774 immed
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1778 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1783 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1784 /* FIXME: This might be lw, or it might be addiu to $sp or
1785 $pc. We assume it's load. */
1786 info
->insn_type
= dis_dref
;
1787 info
->data_size
= 4;
1792 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1793 info
->insn_type
= dis_dref
;
1794 info
->data_size
= 8;
1798 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1803 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1809 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1814 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1821 immed
= (l
>> MIPS16OP_SH_IMM11
) & MIPS16OP_MASK_IMM11
;
1829 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1831 /* FIXME: This can be lw or la. We assume it is lw. */
1832 info
->insn_type
= dis_dref
;
1833 info
->data_size
= 4;
1838 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1840 info
->insn_type
= dis_dref
;
1841 info
->data_size
= 8;
1846 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1855 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1856 immed
-= 1 << nbits
;
1858 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1865 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1866 else if (extbits
== 15)
1867 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1869 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1870 immed
&= (1 << extbits
) - 1;
1871 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1872 immed
-= 1 << extbits
;
1876 (*info
->fprintf_func
) (info
->stream
, "%d", immed
);
1884 baseaddr
= memaddr
+ 2;
1886 else if (use_extend
)
1887 baseaddr
= memaddr
- 2;
1895 /* If this instruction is in the delay slot of a jr
1896 instruction, the base address is the address of the
1897 jr instruction. If it is in the delay slot of jalr
1898 instruction, the base address is the address of the
1899 jalr instruction. This test is unreliable: we have
1900 no way of knowing whether the previous word is
1901 instruction or data. */
1902 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1905 && (((info
->endian
== BFD_ENDIAN_BIG
1906 ? bfd_getb16 (buffer
)
1907 : bfd_getl16 (buffer
))
1908 & 0xf800) == 0x1800))
1909 baseaddr
= memaddr
- 4;
1912 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1915 && (((info
->endian
== BFD_ENDIAN_BIG
1916 ? bfd_getb16 (buffer
)
1917 : bfd_getl16 (buffer
))
1918 & 0xf81f) == 0xe800))
1919 baseaddr
= memaddr
- 2;
1922 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1924 && info
->flavour
== bfd_target_unknown_flavour
)
1925 /* For gdb disassembler, maintain odd address. */
1927 (*info
->print_address_func
) (info
->target
, info
);
1934 int jalx
= l
& 0x400;
1938 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1939 if (!jalx
&& info
->flavour
== bfd_target_unknown_flavour
)
1940 /* For gdb disassembler, maintain odd address. */
1943 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1944 (*info
->print_address_func
) (info
->target
, info
);
1950 int need_comma
, amask
, smask
;
1954 l
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1956 amask
= (l
>> 3) & 7;
1958 if (amask
> 0 && amask
< 5)
1960 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
1962 (*info
->fprintf_func
) (info
->stream
, "-%s",
1963 mips_gpr_names
[amask
+ 3]);
1967 smask
= (l
>> 1) & 3;
1970 (*info
->fprintf_func
) (info
->stream
, "%s??",
1971 need_comma
? "," : "");
1976 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1977 need_comma
? "," : "",
1978 mips_gpr_names
[16]);
1980 (*info
->fprintf_func
) (info
->stream
, "-%s",
1981 mips_gpr_names
[smask
+ 15]);
1987 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1988 need_comma
? "," : "",
1989 mips_gpr_names
[31]);
1993 if (amask
== 5 || amask
== 6)
1995 (*info
->fprintf_func
) (info
->stream
, "%s$f0",
1996 need_comma
? "," : "");
1998 (*info
->fprintf_func
) (info
->stream
, "-$f1");
2005 /* MIPS16e save/restore. */
2008 int amask
, args
, statics
;
2017 amask
= (l
>> 16) & 0xf;
2018 if (amask
== MIPS16_ALL_ARGS
)
2023 else if (amask
== MIPS16_ALL_STATICS
)
2031 statics
= amask
& 3;
2035 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
2037 (*info
->fprintf_func
) (info
->stream
, "-%s",
2038 mips_gpr_names
[4 + args
- 1]);
2042 framesz
= (((l
>> 16) & 0xf0) | (l
& 0x0f)) * 8;
2043 if (framesz
== 0 && !use_extend
)
2046 (*info
->fprintf_func
) (info
->stream
, "%s%d",
2047 need_comma
? "," : "",
2050 if (l
& 0x40) /* $ra */
2051 (*info
->fprintf_func
) (info
->stream
, ",%s", mips_gpr_names
[31]);
2053 nsreg
= (l
>> 24) & 0x7;
2055 if (l
& 0x20) /* $s0 */
2057 if (l
& 0x10) /* $s1 */
2059 if (nsreg
> 0) /* $s2-$s8 */
2060 smask
|= ((1 << nsreg
) - 1) << 2;
2062 /* Find first set static reg bit. */
2063 for (i
= 0; i
< 9; i
++)
2065 if (smask
& (1 << i
))
2067 (*info
->fprintf_func
) (info
->stream
, ",%s",
2068 mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
2069 /* Skip over string of set bits. */
2070 for (j
= i
; smask
& (2 << j
); j
++)
2073 (*info
->fprintf_func
) (info
->stream
, "-%s",
2074 mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
2079 /* Statics $ax - $a3. */
2081 (*info
->fprintf_func
) (info
->stream
, ",%s", mips_gpr_names
[7]);
2082 else if (statics
> 0)
2083 (*info
->fprintf_func
) (info
->stream
, ",%s-%s",
2084 mips_gpr_names
[7 - statics
+ 1],
2090 /* xgettext:c-format */
2091 (*info
->fprintf_func
)
2093 _("# internal disassembler error, unrecognised modifier (%c)"),
2099 /* Disassemble mips16 instructions. */
2102 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2108 bfd_boolean use_extend
;
2110 const struct mips_opcode
*op
, *opend
;
2112 info
->bytes_per_chunk
= 2;
2113 info
->display_endian
= info
->endian
;
2114 info
->insn_info_valid
= 1;
2115 info
->branch_delay_insns
= 0;
2116 info
->data_size
= 0;
2117 info
->insn_type
= dis_nonbranch
;
2121 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2124 (*info
->memory_error_func
) (status
, memaddr
, info
);
2130 if (info
->endian
== BFD_ENDIAN_BIG
)
2131 insn
= bfd_getb16 (buffer
);
2133 insn
= bfd_getl16 (buffer
);
2135 /* Handle the extend opcode specially. */
2137 if ((insn
& 0xf800) == 0xf000)
2140 extend
= insn
& 0x7ff;
2144 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2147 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
2148 (unsigned int) extend
);
2149 (*info
->memory_error_func
) (status
, memaddr
, info
);
2153 if (info
->endian
== BFD_ENDIAN_BIG
)
2154 insn
= bfd_getb16 (buffer
);
2156 insn
= bfd_getl16 (buffer
);
2158 /* Check for an extend opcode followed by an extend opcode. */
2159 if ((insn
& 0xf800) == 0xf000)
2161 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
2162 (unsigned int) extend
);
2163 info
->insn_type
= dis_noninsn
;
2170 /* FIXME: Should probably use a hash table on the major opcode here. */
2172 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2173 for (op
= mips16_opcodes
; op
< opend
; op
++)
2175 if (op
->pinfo
!= INSN_MACRO
2176 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2177 && (insn
& op
->mask
) == op
->match
)
2181 if (strchr (op
->args
, 'a') != NULL
)
2185 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
2186 (unsigned int) extend
);
2187 info
->insn_type
= dis_noninsn
;
2195 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2200 if (info
->endian
== BFD_ENDIAN_BIG
)
2201 extend
= bfd_getb16 (buffer
);
2203 extend
= bfd_getl16 (buffer
);
2208 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
2209 if (op
->args
[0] != '\0')
2210 (*info
->fprintf_func
) (info
->stream
, "\t");
2212 for (s
= op
->args
; *s
!= '\0'; s
++)
2216 && (((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)
2217 == ((insn
>> MIPS16OP_SH_RY
) & MIPS16OP_MASK_RY
)))
2219 /* Skip the register and the comma. */
2225 && (((insn
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
)
2226 == ((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)))
2228 /* Skip the register and the comma. */
2232 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
2236 /* Figure out branch instruction type and delay slot information. */
2237 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2238 info
->branch_delay_insns
= 1;
2239 if ((op
->pinfo
& (INSN_UNCOND_BRANCH_DELAY
2240 | MIPS16_INSN_UNCOND_BRANCH
)) != 0)
2242 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2243 info
->insn_type
= dis_jsr
;
2245 info
->insn_type
= dis_branch
;
2247 else if ((op
->pinfo
& MIPS16_INSN_COND_BRANCH
) != 0)
2248 info
->insn_type
= dis_condbranch
;
2255 (*info
->fprintf_func
) (info
->stream
, "0x%x", extend
| 0xf000);
2256 (*info
->fprintf_func
) (info
->stream
, "0x%x", insn
);
2257 info
->insn_type
= dis_noninsn
;
2262 /* Disassemble microMIPS instructions. */
2265 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2267 const fprintf_ftype infprintf
= info
->fprintf_func
;
2268 const struct mips_opcode
*op
, *opend
;
2269 unsigned int lsb
, msbd
, msb
;
2270 void *is
= info
->stream
;
2283 info
->bytes_per_chunk
= 2;
2284 info
->display_endian
= info
->endian
;
2285 info
->insn_info_valid
= 1;
2286 info
->branch_delay_insns
= 0;
2287 info
->data_size
= 0;
2288 info
->insn_type
= dis_nonbranch
;
2292 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2295 (*info
->memory_error_func
) (status
, memaddr
, info
);
2301 if (info
->endian
== BFD_ENDIAN_BIG
)
2302 insn
= bfd_getb16 (buffer
);
2304 insn
= bfd_getl16 (buffer
);
2306 if ((insn
& 0xfc00) == 0x7c00)
2308 /* This is a 48-bit microMIPS instruction. */
2311 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2314 infprintf (is
, "micromips 0x%x", higher
);
2315 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2318 if (info
->endian
== BFD_ENDIAN_BIG
)
2319 insn
= bfd_getb16 (buffer
);
2321 insn
= bfd_getl16 (buffer
);
2322 higher
= (higher
<< 16) | insn
;
2324 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
2327 infprintf (is
, "micromips 0x%x", higher
);
2328 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2331 if (info
->endian
== BFD_ENDIAN_BIG
)
2332 insn
= bfd_getb16 (buffer
);
2334 insn
= bfd_getl16 (buffer
);
2335 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2337 info
->insn_type
= dis_noninsn
;
2340 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2342 /* This is a 32-bit microMIPS instruction. */
2345 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2348 infprintf (is
, "micromips 0x%x", higher
);
2349 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2353 if (info
->endian
== BFD_ENDIAN_BIG
)
2354 insn
= bfd_getb16 (buffer
);
2356 insn
= bfd_getl16 (buffer
);
2358 insn
= insn
| (higher
<< 16);
2363 /* FIXME: Should probably use a hash table on the major opcode here. */
2365 #define GET_OP(insn, field) \
2366 (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2367 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2368 for (op
= micromips_opcodes
; op
< opend
; op
++)
2370 if (op
->pinfo
!= INSN_MACRO
2371 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2372 && (insn
& op
->mask
) == op
->match
2373 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2374 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2378 infprintf (is
, "%s", op
->name
);
2379 if (op
->args
[0] != '\0')
2380 infprintf (is
, "\t");
2382 for (s
= op
->args
; *s
!= '\0'; s
++)
2389 infprintf (is
, "%c", *s
);
2393 delta
= GET_OP (insn
, OFFSET10
);
2396 infprintf (is
, "%d", delta
);
2400 infprintf (is
, "0x%lx", GET_OP (insn
, STYPE
));
2404 infprintf (is
, "0x%lx", GET_OP (insn
, SHAMT
));
2408 infprintf (is
, "0x%lx", GET_OP (insn
, 3BITPOS
));
2412 infprintf (is
, "0x%lx", GET_OP (insn
, TRAP
));
2416 delta
= GET_OP (insn
, OFFSET12
);
2419 infprintf (is
, "%d", delta
);
2423 if (strcmp (op
->name
, "jalx") == 0)
2424 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff)
2425 | (GET_OP (insn
, TARGET
) << 2));
2427 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x07ffffff)
2428 | ((GET_OP (insn
, TARGET
)) << 1));
2429 /* For gdb disassembler, force odd address on jalx. */
2430 if (info
->flavour
== bfd_target_unknown_flavour
2431 && strcmp (op
->name
, "jalx") == 0)
2433 (*info
->print_address_func
) (info
->target
, info
);
2440 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS
)]);
2444 infprintf (is
, "0x%lx", GET_OP (insn
, CODE
));
2448 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RD
)]);
2452 infprintf (is
, "0x%lx", GET_OP (insn
, PREFX
));
2457 infprintf (is
, "0x%lx", GET_OP (insn
, IMMEDIATE
));
2460 case 'j': /* Same as i, but sign-extended. */
2462 delta
= (GET_OP (insn
, DELTA
) ^ 0x8000) - 0x8000;
2463 infprintf (is
, "%d", delta
);
2467 infprintf (is
, "0x%x", GET_OP (insn
, CACHE
));
2474 immed
= GET_OP (insn
, RT
);
2475 s_reg_encode
= immed
& 0xf;
2476 if (s_reg_encode
!= 0)
2478 if (s_reg_encode
== 1)
2479 infprintf (is
, "%s", mips_gpr_names
[16]);
2480 else if (s_reg_encode
< 9)
2481 infprintf (is
, "%s-%s",
2483 mips_gpr_names
[15 + s_reg_encode
]);
2484 else if (s_reg_encode
== 9)
2485 infprintf (is
, "%s-%s,%s",
2488 mips_gpr_names
[30]);
2490 infprintf (is
, "UNKNOWN");
2493 if (immed
& 0x10) /* For ra. */
2495 if (s_reg_encode
== 0)
2496 infprintf (is
, "%s", mips_gpr_names
[31]);
2498 infprintf (is
, ",%s", mips_gpr_names
[31]);
2504 /* Sign-extend the displacement. */
2505 delta
= (GET_OP (insn
, DELTA
) ^ 0x8000) - 0x8000;
2506 info
->target
= (delta
<< 1) + memaddr
+ length
;
2507 (*info
->print_address_func
) (info
->target
, info
);
2511 infprintf (is
, "0x%lx", GET_OP (insn
, CODE2
));
2516 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RT
)]);
2520 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS3
)]);
2524 infprintf (is
, "%s", mips_gpr_names
[0]);
2528 infprintf (is
, "0x%lx", GET_OP (insn
, CODE10
));
2532 infprintf (is
, "0x%lx", GET_OP (insn
, COPZ
));
2536 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FD
)]);
2540 /* Coprocessor register for lwcN instructions, et al.
2542 Note that there is no load/store cp0 instructions, and
2543 that FPU (cp1) instructions disassemble this field using
2544 'T' format. Therefore, until we gain understanding of
2545 cp2 register names, we can simply print the register
2547 infprintf (is
, "$%ld", GET_OP (insn
, RT
));
2551 /* Coprocessor register for mtcN instructions, et al. Note
2552 that FPU (cp1) instructions disassemble this field using
2553 'S' format. Therefore, we only need to worry about cp0,
2555 The microMIPS encoding does not have a coprocessor
2556 identifier field as such, so we must work out the
2557 coprocessor number by looking at the opcode. */
2559 & ~((MICROMIPSOP_MASK_RT
<< MICROMIPSOP_SH_RT
)
2560 | (MICROMIPSOP_MASK_RS
<< MICROMIPSOP_SH_RS
)))
2562 case 0x000000fc: /* mfc0 */
2563 case 0x000002fc: /* mtc0 */
2564 case 0x580000fc: /* dmfc0 */
2565 case 0x580002fc: /* dmtc0 */
2566 infprintf (is
, "%s", mips_cp0_names
[GET_OP (insn
, RS
)]);
2569 infprintf (is
, "$%ld", GET_OP (insn
, RS
));
2575 infprintf (is
, "%ld", GET_OP (insn
, SEL
));
2579 infprintf (is
, "%s", mips_hwr_names
[GET_OP (insn
, RS
)]);
2583 infprintf (is
, "$fcc%ld", GET_OP (insn
, CCC
));
2588 (op
->pinfo
& (FP_D
| FP_S
)) != 0
2589 ? "$fcc%ld" : "$cc%ld",
2590 GET_OP (insn
, BCC
));
2594 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FR
)]);
2599 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FS
)]);
2603 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FT
)]);
2607 /* Extension character; switch for second char. */
2612 lsb
= GET_OP (insn
, EXTLSB
);
2613 infprintf (is
, "0x%x", lsb
);
2617 msb
= GET_OP (insn
, INSMSB
);
2618 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2623 msbd
= GET_OP (insn
, EXTMSBD
);
2624 infprintf (is
, "0x%x", msbd
+ 1);
2629 const struct mips_cp0sel_name
*n
;
2630 unsigned int cp0reg
, sel
;
2632 cp0reg
= GET_OP (insn
, RS
);
2633 sel
= GET_OP (insn
, SEL
);
2635 /* CP0 register including 'sel' code for mtcN
2636 (et al.), to be printed textually if known.
2637 If not known, print both CP0 register name and
2638 sel numerically since CP0 register with sel 0 may
2639 have a name unrelated to register being printed. */
2640 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2641 mips_cp0sel_names_len
,
2644 infprintf (is
, "%s", n
->name
);
2646 infprintf (is
, "$%d,%d", cp0reg
, sel
);
2651 lsb
= GET_OP (insn
, EXTLSB
) + 32;
2652 infprintf (is
, "0x%x", lsb
);
2656 msb
= GET_OP (insn
, INSMSB
) + 32;
2657 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2661 msbd
= GET_OP (insn
, EXTMSBD
) + 32;
2662 infprintf (is
, "0x%x", msbd
+ 1);
2666 /* xgettext:c-format */
2668 _("# internal disassembler error, "
2669 "unrecognized modifier (+%c)"),
2676 /* Extension character; switch for second char. */
2680 case 'a': /* global pointer. */
2681 infprintf (is
, "%s", mips_gpr_names
[28]);
2685 regno
= micromips_to_32_reg_b_map
[GET_OP (insn
, MB
)];
2686 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2690 regno
= micromips_to_32_reg_c_map
[GET_OP (insn
, MC
)];
2691 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2695 regno
= micromips_to_32_reg_d_map
[GET_OP (insn
, MD
)];
2696 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2700 regno
= micromips_to_32_reg_e_map
[GET_OP (insn
, ME
)];
2701 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2705 /* Save lastregno for "mt" to print out later. */
2706 lastregno
= micromips_to_32_reg_f_map
[GET_OP (insn
, MF
)];
2707 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2711 regno
= micromips_to_32_reg_g_map
[GET_OP (insn
, MG
)];
2712 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2716 regno
= micromips_to_32_reg_h_map
[GET_OP (insn
, MH
)];
2717 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2721 regno
= micromips_to_32_reg_i_map
[GET_OP (insn
, MI
)];
2722 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2726 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, MJ
)]);
2730 regno
= micromips_to_32_reg_l_map
[GET_OP (insn
, ML
)];
2731 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2735 regno
= micromips_to_32_reg_m_map
[GET_OP (insn
, MM
)];
2736 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2740 regno
= micromips_to_32_reg_n_map
[GET_OP (insn
, MN
)];
2741 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2745 /* Save lastregno for "mt" to print out later. */
2746 lastregno
= GET_OP (insn
, MP
);
2747 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2751 regno
= micromips_to_32_reg_q_map
[GET_OP (insn
, MQ
)];
2752 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2755 case 'r': /* program counter. */
2756 infprintf (is
, "$pc");
2759 case 's': /* stack pointer. */
2761 infprintf (is
, "%s", mips_gpr_names
[29]);
2765 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2769 infprintf (is
, "%s", mips_gpr_names
[0]);
2773 /* Sign-extend the immediate. */
2774 immed
= ((GET_OP (insn
, IMMA
) ^ 0x40) - 0x40) << 2;
2775 infprintf (is
, "%d", immed
);
2779 immed
= micromips_imm_b_map
[GET_OP (insn
, IMMB
)];
2780 infprintf (is
, "%d", immed
);
2784 immed
= micromips_imm_c_map
[GET_OP (insn
, IMMC
)];
2785 infprintf (is
, "0x%lx", immed
);
2789 /* Sign-extend the displacement. */
2790 delta
= (GET_OP (insn
, IMMD
) ^ 0x200) - 0x200;
2791 info
->target
= (delta
<< 1) + memaddr
+ length
;
2792 (*info
->print_address_func
) (info
->target
, info
);
2796 /* Sign-extend the displacement. */
2797 delta
= (GET_OP (insn
, IMME
) ^ 0x40) - 0x40;
2798 info
->target
= (delta
<< 1) + memaddr
+ length
;
2799 (*info
->print_address_func
) (info
->target
, info
);
2803 immed
= GET_OP (insn
, IMMF
);
2804 infprintf (is
, "0x%x", immed
);
2808 immed
= (insn
>> MICROMIPSOP_SH_IMMG
) + 1;
2809 immed
= (immed
& MICROMIPSOP_MASK_IMMG
) - 1;
2810 infprintf (is
, "%d", immed
);
2814 immed
= GET_OP (insn
, IMMH
) << 1;
2815 infprintf (is
, "%d", immed
);
2819 immed
= (insn
>> MICROMIPSOP_SH_IMMI
) + 1;
2820 immed
= (immed
& MICROMIPSOP_MASK_IMMI
) - 1;
2821 infprintf (is
, "%d", immed
);
2825 immed
= GET_OP (insn
, IMMJ
) << 2;
2826 infprintf (is
, "%d", immed
);
2830 immed
= GET_OP (insn
, IMML
);
2831 infprintf (is
, "%d", immed
);
2835 immed
= (insn
>> MICROMIPSOP_SH_IMMM
) - 1;
2836 immed
= (immed
& MICROMIPSOP_MASK_IMMM
) + 1;
2837 infprintf (is
, "%d", immed
);
2841 immed
= GET_OP (insn
, IMMN
);
2843 infprintf (is
, "%s,%s",
2845 mips_gpr_names
[31]);
2847 infprintf (is
, "%s-%s,%s",
2849 mips_gpr_names
[16 + immed
],
2850 mips_gpr_names
[31]);
2854 immed
= GET_OP (insn
, IMMO
);
2855 infprintf (is
, "0x%x", immed
);
2859 immed
= GET_OP (insn
, IMMP
) << 2;
2860 infprintf (is
, "%d", immed
);
2864 /* Sign-extend the immediate. */
2865 immed
= (GET_OP (insn
, IMMQ
) ^ 0x400000) - 0x400000;
2867 infprintf (is
, "%d", immed
);
2871 immed
= GET_OP (insn
, IMMU
) << 2;
2872 infprintf (is
, "%d", immed
);
2876 immed
= GET_OP (insn
, IMMW
) << 2;
2877 infprintf (is
, "%d", immed
);
2881 /* Sign-extend the immediate. */
2882 immed
= (GET_OP (insn
, IMMX
) ^ 0x8) - 0x8;
2883 infprintf (is
, "%d", immed
);
2887 /* Sign-extend the immediate. */
2888 immed
= (GET_OP (insn
, IMMY
) ^ 0x100) - 0x100;
2889 if (immed
>= -2 && immed
<= 1)
2892 infprintf (is
, "%d", immed
);
2896 /* xgettext:c-format */
2898 _("# internal disassembler error, "
2899 "unrecognized modifier (m%c)"),
2906 /* xgettext:c-format */
2908 _("# internal disassembler error, "
2909 "unrecognized modifier (%c)"),
2915 /* Figure out instruction type and branch delay information. */
2917 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2918 info
->branch_delay_insns
= 1;
2919 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2920 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2922 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_GPR_T
)) != 0)
2923 info
->insn_type
= dis_jsr
;
2925 info
->insn_type
= dis_branch
;
2927 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2928 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2930 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2931 info
->insn_type
= dis_condjsr
;
2933 info
->insn_type
= dis_condbranch
;
2936 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY_DELAY
)) != 0)
2937 info
->insn_type
= dis_dref
;
2944 infprintf (is
, "0x%x", insn
);
2945 info
->insn_type
= dis_noninsn
;
2950 /* Return 1 if a symbol associated with the location being disassembled
2951 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2952 all the symbols at the address being considered assuming if at least
2953 one of them indicates code compression, then such code has been
2954 genuinely produced here (other symbols could have been derived from
2955 function symbols defined elsewhere or could define data). Otherwise,
2959 is_compressed_mode_p (struct disassemble_info
*info
)
2961 elf_symbol_type
*symbol
;
2965 for (i
= 0; i
< info
->num_symbols
; i
++)
2967 pos
= info
->symtab_pos
+ i
;
2969 if (bfd_asymbol_flavour (info
->symtab
[pos
]) != bfd_target_elf_flavour
)
2972 symbol
= (elf_symbol_type
*) info
->symtab
[pos
];
2974 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2976 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2983 /* In an environment where we do not know the symbol type of the
2984 instruction we are forced to assume that the low order bit of the
2985 instructions' address may mark it as a mips16 instruction. If we
2986 are single stepping, or the pc is within the disassembled function,
2987 this works. Otherwise, we need a clue. Sometimes. */
2990 _print_insn_mips (bfd_vma memaddr
,
2991 struct disassemble_info
*info
,
2992 enum bfd_endian endianness
)
2994 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
2995 bfd_byte buffer
[INSNLEN
];
2998 set_default_mips_dis_options (info
);
2999 parse_mips_dis_options (info
->disassembler_options
);
3001 if (info
->mach
== bfd_mach_mips16
)
3002 return print_insn_mips16 (memaddr
, info
);
3003 if (info
->mach
== bfd_mach_mips_micromips
)
3004 return print_insn_micromips (memaddr
, info
);
3006 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
3009 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
3010 /* Only a few tools will work this way. */
3012 return print_insn_compr (memaddr
, info
);
3015 #if SYMTAB_AVAILABLE
3016 if (is_compressed_mode_p (info
))
3017 return print_insn_compr (memaddr
, info
);
3020 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
3025 if (endianness
== BFD_ENDIAN_BIG
)
3026 insn
= (unsigned long) bfd_getb32 (buffer
);
3028 insn
= (unsigned long) bfd_getl32 (buffer
);
3030 return print_insn_mips (memaddr
, insn
, info
);
3034 (*info
->memory_error_func
) (status
, memaddr
, info
);
3040 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3042 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
3046 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3048 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
3052 print_mips_disassembler_options (FILE *stream
)
3056 fprintf (stream
, _("\n\
3057 The following MIPS specific disassembler options are supported for use\n\
3058 with the -M switch (multiple options should be separated by commas):\n"));
3060 fprintf (stream
, _("\n\
3061 gpr-names=ABI Print GPR names according to specified ABI.\n\
3062 Default: based on binary being disassembled.\n"));
3064 fprintf (stream
, _("\n\
3065 fpr-names=ABI Print FPR names according to specified ABI.\n\
3066 Default: numeric.\n"));
3068 fprintf (stream
, _("\n\
3069 cp0-names=ARCH Print CP0 register names according to\n\
3070 specified architecture.\n\
3071 Default: based on binary being disassembled.\n"));
3073 fprintf (stream
, _("\n\
3074 hwr-names=ARCH Print HWR names according to specified \n\
3076 Default: based on binary being disassembled.\n"));
3078 fprintf (stream
, _("\n\
3079 reg-names=ABI Print GPR and FPR names according to\n\
3080 specified ABI.\n"));
3082 fprintf (stream
, _("\n\
3083 reg-names=ARCH Print CP0 register and HWR names according to\n\
3084 specified architecture.\n"));
3086 fprintf (stream
, _("\n\
3087 For the options above, the following values are supported for \"ABI\":\n\
3089 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
3090 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
3091 fprintf (stream
, _("\n"));
3093 fprintf (stream
, _("\n\
3094 For the options above, The following values are supported for \"ARCH\":\n\
3096 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
3097 if (*mips_arch_choices
[i
].name
!= '\0')
3098 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
3099 fprintf (stream
, _("\n"));
3101 fprintf (stream
, _("\n"));