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 /* This entry, mips16, is here only for ISA/processor selection; do
623 not print its name. */
624 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
,
625 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
628 /* ISA and processor type to disassemble for, and register names to use.
629 set_default_mips_dis_options and parse_mips_dis_options fill in these
631 static int mips_processor
;
633 static int micromips_ase
;
634 static const char * const *mips_gpr_names
;
635 static const char * const *mips_fpr_names
;
636 static const char * const *mips_cp0_names
;
637 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
638 static int mips_cp0sel_names_len
;
639 static const char * const *mips_hwr_names
;
642 static int no_aliases
; /* If set disassemble as most general inst. */
644 static const struct mips_abi_choice
*
645 choose_abi_by_name (const char *name
, unsigned int namelen
)
647 const struct mips_abi_choice
*c
;
650 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
651 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
652 && strlen (mips_abi_choices
[i
].name
) == namelen
)
653 c
= &mips_abi_choices
[i
];
658 static const struct mips_arch_choice
*
659 choose_arch_by_name (const char *name
, unsigned int namelen
)
661 const struct mips_arch_choice
*c
= NULL
;
664 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
665 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
666 && strlen (mips_arch_choices
[i
].name
) == namelen
)
667 c
= &mips_arch_choices
[i
];
672 static const struct mips_arch_choice
*
673 choose_arch_by_number (unsigned long mach
)
675 static unsigned long hint_bfd_mach
;
676 static const struct mips_arch_choice
*hint_arch_choice
;
677 const struct mips_arch_choice
*c
;
680 /* We optimize this because even if the user specifies no
681 flags, this will be done for every instruction! */
682 if (hint_bfd_mach
== mach
683 && hint_arch_choice
!= NULL
684 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
685 return hint_arch_choice
;
687 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
689 if (mips_arch_choices
[i
].bfd_mach_valid
690 && mips_arch_choices
[i
].bfd_mach
== mach
)
692 c
= &mips_arch_choices
[i
];
693 hint_bfd_mach
= mach
;
694 hint_arch_choice
= c
;
700 /* Check if the object uses NewABI conventions. */
703 is_newabi (Elf_Internal_Ehdr
*header
)
705 /* There are no old-style ABIs which use 64-bit ELF. */
706 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
709 /* If a 32-bit ELF file, n32 is a new-style ABI. */
710 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
716 /* Check if the object has microMIPS ASE code. */
719 is_micromips (Elf_Internal_Ehdr
*header
)
721 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
728 set_default_mips_dis_options (struct disassemble_info
*info
)
730 const struct mips_arch_choice
*chosen_arch
;
732 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
733 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
734 CP0 register, and HWR names. */
735 mips_isa
= ISA_MIPS3
;
736 mips_processor
= CPU_R3000
;
738 mips_gpr_names
= mips_gpr_names_oldabi
;
739 mips_fpr_names
= mips_fpr_names_numeric
;
740 mips_cp0_names
= mips_cp0_names_numeric
;
741 mips_cp0sel_names
= NULL
;
742 mips_cp0sel_names_len
= 0;
743 mips_hwr_names
= mips_hwr_names_numeric
;
746 /* Update settings according to the ELF file header flags. */
747 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
749 Elf_Internal_Ehdr
*header
;
751 header
= elf_elfheader (info
->section
->owner
);
752 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
753 if (is_newabi (header
))
754 mips_gpr_names
= mips_gpr_names_newabi
;
755 /* If a microMIPS binary, then don't use MIPS16 bindings. */
756 micromips_ase
= is_micromips (header
);
759 /* Set ISA, architecture, and cp0 register names as best we can. */
760 #if ! SYMTAB_AVAILABLE
761 /* This is running out on a target machine, not in a host tool.
762 FIXME: Where does mips_target_info come from? */
763 target_processor
= mips_target_info
.processor
;
764 mips_isa
= mips_target_info
.isa
;
766 chosen_arch
= choose_arch_by_number (info
->mach
);
767 if (chosen_arch
!= NULL
)
769 mips_processor
= chosen_arch
->processor
;
770 mips_isa
= chosen_arch
->isa
;
771 mips_cp0_names
= chosen_arch
->cp0_names
;
772 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
773 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
774 mips_hwr_names
= chosen_arch
->hwr_names
;
780 parse_mips_dis_option (const char *option
, unsigned int len
)
782 unsigned int i
, optionlen
, vallen
;
784 const struct mips_abi_choice
*chosen_abi
;
785 const struct mips_arch_choice
*chosen_arch
;
787 /* Try to match options that are simple flags */
788 if (CONST_STRNEQ (option
, "no-aliases"))
794 /* Look for the = that delimits the end of the option name. */
795 for (i
= 0; i
< len
; i
++)
796 if (option
[i
] == '=')
799 if (i
== 0) /* Invalid option: no name before '='. */
801 if (i
== len
) /* Invalid option: no '='. */
803 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
807 val
= option
+ (optionlen
+ 1);
808 vallen
= len
- (optionlen
+ 1);
810 if (strncmp ("gpr-names", option
, optionlen
) == 0
811 && strlen ("gpr-names") == optionlen
)
813 chosen_abi
= choose_abi_by_name (val
, vallen
);
814 if (chosen_abi
!= NULL
)
815 mips_gpr_names
= chosen_abi
->gpr_names
;
819 if (strncmp ("fpr-names", option
, optionlen
) == 0
820 && strlen ("fpr-names") == optionlen
)
822 chosen_abi
= choose_abi_by_name (val
, vallen
);
823 if (chosen_abi
!= NULL
)
824 mips_fpr_names
= chosen_abi
->fpr_names
;
828 if (strncmp ("cp0-names", option
, optionlen
) == 0
829 && strlen ("cp0-names") == optionlen
)
831 chosen_arch
= choose_arch_by_name (val
, vallen
);
832 if (chosen_arch
!= NULL
)
834 mips_cp0_names
= chosen_arch
->cp0_names
;
835 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
836 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
841 if (strncmp ("hwr-names", option
, optionlen
) == 0
842 && strlen ("hwr-names") == optionlen
)
844 chosen_arch
= choose_arch_by_name (val
, vallen
);
845 if (chosen_arch
!= NULL
)
846 mips_hwr_names
= chosen_arch
->hwr_names
;
850 if (strncmp ("reg-names", option
, optionlen
) == 0
851 && strlen ("reg-names") == optionlen
)
853 /* We check both ABI and ARCH here unconditionally, so
854 that "numeric" will do the desirable thing: select
855 numeric register names for all registers. Other than
856 that, a given name probably won't match both. */
857 chosen_abi
= choose_abi_by_name (val
, vallen
);
858 if (chosen_abi
!= NULL
)
860 mips_gpr_names
= chosen_abi
->gpr_names
;
861 mips_fpr_names
= chosen_abi
->fpr_names
;
863 chosen_arch
= choose_arch_by_name (val
, vallen
);
864 if (chosen_arch
!= NULL
)
866 mips_cp0_names
= chosen_arch
->cp0_names
;
867 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
868 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
869 mips_hwr_names
= chosen_arch
->hwr_names
;
874 /* Invalid option. */
878 parse_mips_dis_options (const char *options
)
880 const char *option_end
;
885 while (*options
!= '\0')
887 /* Skip empty options. */
894 /* We know that *options is neither NUL or a comma. */
895 option_end
= options
+ 1;
896 while (*option_end
!= ',' && *option_end
!= '\0')
899 parse_mips_dis_option (options
, option_end
- options
);
901 /* Go on to the next one. If option_end points to a comma, it
902 will be skipped above. */
903 options
= option_end
;
907 static const struct mips_cp0sel_name
*
908 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
915 for (i
= 0; i
< len
; i
++)
916 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
921 /* Print insn arguments for 32/64-bit code. */
924 print_insn_args (const char *d
,
925 register unsigned long int l
,
927 struct disassemble_info
*info
,
928 const struct mips_opcode
*opp
)
931 unsigned int lsb
, msb
, msbd
;
935 for (; *d
!= '\0'; d
++)
944 (*info
->fprintf_func
) (info
->stream
, "%c", *d
);
948 /* Extension character; switch for second char. */
953 /* xgettext:c-format */
954 (*info
->fprintf_func
) (info
->stream
,
955 _("# internal error, incomplete extension sequence (+)"));
959 lsb
= (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
;
960 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
964 msb
= (l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
;
965 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
969 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
970 (l
>> OP_SH_UDI1
) & OP_MASK_UDI1
);
974 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
975 (l
>> OP_SH_UDI2
) & OP_MASK_UDI2
);
979 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
980 (l
>> OP_SH_UDI3
) & OP_MASK_UDI3
);
984 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
985 (l
>> OP_SH_UDI4
) & OP_MASK_UDI4
);
990 msbd
= (l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
;
991 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
996 const struct mips_cp0sel_name
*n
;
997 unsigned int cp0reg
, sel
;
999 cp0reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
1000 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
1002 /* CP0 register including 'sel' code for mtcN (et al.), to be
1003 printed textually if known. If not known, print both
1004 CP0 register name and sel numerically since CP0 register
1005 with sel 0 may have a name unrelated to register being
1007 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
1008 mips_cp0sel_names_len
, cp0reg
, sel
);
1010 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
1012 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
1017 lsb
= ((l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
) + 32;
1018 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
1022 msb
= ((l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
) + 32;
1023 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
1027 msbd
= ((l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
) + 32;
1028 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
1031 case 't': /* Coprocessor 0 reg name */
1032 (*info
->fprintf_func
) (info
->stream
, "%s",
1033 mips_cp0_names
[(l
>> OP_SH_RT
) &
1037 case 'T': /* Coprocessor 0 reg name */
1039 const struct mips_cp0sel_name
*n
;
1040 unsigned int cp0reg
, sel
;
1042 cp0reg
= (l
>> OP_SH_RT
) & OP_MASK_RT
;
1043 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
1045 /* CP0 register including 'sel' code for mftc0, to be
1046 printed textually if known. If not known, print both
1047 CP0 register name and sel numerically since CP0 register
1048 with sel 0 may have a name unrelated to register being
1050 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
1051 mips_cp0sel_names_len
, cp0reg
, sel
);
1053 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
1055 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
1059 case 'x': /* bbit bit index */
1060 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1061 (l
>> OP_SH_BBITIND
) & OP_MASK_BBITIND
);
1064 case 'p': /* cins, cins32, exts and exts32 position */
1065 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1066 (l
>> OP_SH_CINSPOS
) & OP_MASK_CINSPOS
);
1069 case 's': /* cins and exts length-minus-one */
1070 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1071 (l
>> OP_SH_CINSLM1
) & OP_MASK_CINSLM1
);
1074 case 'S': /* cins32 and exts32 length-minus-one field */
1075 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1076 (l
>> OP_SH_CINSLM1
) & OP_MASK_CINSLM1
);
1079 case 'Q': /* seqi/snei immediate field */
1080 op
= (l
>> OP_SH_SEQI
) & OP_MASK_SEQI
;
1081 /* Sign-extend it. */
1082 op
= (op
^ 512) - 512;
1083 (*info
->fprintf_func
) (info
->stream
, "%d", op
);
1086 case 'a': /* 8-bit signed offset in bit 6 */
1087 delta
= (l
>> OP_SH_OFFSET_A
) & OP_MASK_OFFSET_A
;
1089 delta
|= ~OP_MASK_OFFSET_A
;
1090 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1093 case 'b': /* 8-bit signed offset in bit 3 */
1094 delta
= (l
>> OP_SH_OFFSET_B
) & OP_MASK_OFFSET_B
;
1096 delta
|= ~OP_MASK_OFFSET_B
;
1097 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1100 case 'c': /* 9-bit signed offset in bit 6 */
1101 delta
= (l
>> OP_SH_OFFSET_C
) & OP_MASK_OFFSET_C
;
1103 delta
|= ~OP_MASK_OFFSET_C
;
1104 /* Left shift 4 bits to print the real offset. */
1105 (*info
->fprintf_func
) (info
->stream
, "%d", delta
<< 4);
1109 (*info
->fprintf_func
) (info
->stream
, "%s",
1110 mips_gpr_names
[(l
>> OP_SH_RZ
) & OP_MASK_RZ
]);
1114 (*info
->fprintf_func
) (info
->stream
, "%s",
1115 mips_fpr_names
[(l
>> OP_SH_FZ
) & OP_MASK_FZ
]);
1119 /* xgettext:c-format */
1120 (*info
->fprintf_func
) (info
->stream
,
1121 _("# internal error, undefined extension sequence (+%c)"),
1128 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1129 (l
>> OP_SH_BP
) & OP_MASK_BP
);
1133 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1134 (l
>> OP_SH_SA3
) & OP_MASK_SA3
);
1138 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1139 (l
>> OP_SH_SA4
) & OP_MASK_SA4
);
1143 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1144 (l
>> OP_SH_IMM8
) & OP_MASK_IMM8
);
1148 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1149 (l
>> OP_SH_RS
) & OP_MASK_RS
);
1153 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1154 (l
>> OP_SH_DSPACC
) & OP_MASK_DSPACC
);
1158 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1159 (l
>> OP_SH_WRDSP
) & OP_MASK_WRDSP
);
1163 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1164 (l
>> OP_SH_DSPACC_S
) & OP_MASK_DSPACC_S
);
1167 case '0': /* dsp 6-bit signed immediate in bit 20 */
1168 delta
= ((l
>> OP_SH_DSPSFT
) & OP_MASK_DSPSFT
);
1169 if (delta
& 0x20) /* test sign bit */
1170 delta
|= ~OP_MASK_DSPSFT
;
1171 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1174 case ':': /* dsp 7-bit signed immediate in bit 19 */
1175 delta
= ((l
>> OP_SH_DSPSFT_7
) & OP_MASK_DSPSFT_7
);
1176 if (delta
& 0x40) /* test sign bit */
1177 delta
|= ~OP_MASK_DSPSFT_7
;
1178 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1182 delta
= (l
>> OP_SH_OFFSET12
) & OP_MASK_OFFSET12
;
1185 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1189 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1190 (l
>> OP_SH_3BITPOS
) & OP_MASK_3BITPOS
);
1194 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1195 (l
>> OP_SH_RDDSP
) & OP_MASK_RDDSP
);
1198 case '@': /* dsp 10-bit signed immediate in bit 16 */
1199 delta
= ((l
>> OP_SH_IMM10
) & OP_MASK_IMM10
);
1200 if (delta
& 0x200) /* test sign bit */
1201 delta
|= ~OP_MASK_IMM10
;
1202 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
1206 (*info
->fprintf_func
) (info
->stream
, "%ld",
1207 (l
>> OP_SH_MT_U
) & OP_MASK_MT_U
);
1211 (*info
->fprintf_func
) (info
->stream
, "%ld",
1212 (l
>> OP_SH_MT_H
) & OP_MASK_MT_H
);
1216 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1217 (l
>> OP_SH_MTACC_T
) & OP_MASK_MTACC_T
);
1221 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
1222 (l
>> OP_SH_MTACC_D
) & OP_MASK_MTACC_D
);
1226 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
1227 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1228 (l
>> OP_SH_RD
) & OP_MASK_RD
);
1235 (*info
->fprintf_func
) (info
->stream
, "%s",
1236 mips_gpr_names
[(l
>> OP_SH_RS
) & OP_MASK_RS
]);
1241 (*info
->fprintf_func
) (info
->stream
, "%s",
1242 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1247 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1248 (l
>> OP_SH_IMMEDIATE
) & OP_MASK_IMMEDIATE
);
1251 case 'j': /* Same as i, but sign-extended. */
1253 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
1256 (*info
->fprintf_func
) (info
->stream
, "%d",
1261 (*info
->fprintf_func
) (info
->stream
, "0x%x",
1262 (unsigned int) ((l
>> OP_SH_PREFX
)
1267 (*info
->fprintf_func
) (info
->stream
, "0x%x",
1268 (unsigned int) ((l
>> OP_SH_CACHE
)
1273 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
1274 | (((l
>> OP_SH_TARGET
) & OP_MASK_TARGET
) << 2));
1275 /* For gdb disassembler, force odd address on jalx. */
1276 if (info
->flavour
== bfd_target_unknown_flavour
1277 && strcmp (opp
->name
, "jalx") == 0)
1279 (*info
->print_address_func
) (info
->target
, info
);
1283 /* Sign extend the displacement. */
1284 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
1287 info
->target
= (delta
<< 2) + pc
+ INSNLEN
;
1288 (*info
->print_address_func
) (info
->target
, info
);
1292 (*info
->fprintf_func
) (info
->stream
, "%s",
1293 mips_gpr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1298 /* First check for both rd and rt being equal. */
1299 unsigned int reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
1300 if (reg
== ((l
>> OP_SH_RT
) & OP_MASK_RT
))
1301 (*info
->fprintf_func
) (info
->stream
, "%s",
1302 mips_gpr_names
[reg
]);
1305 /* If one is zero use the other. */
1307 (*info
->fprintf_func
) (info
->stream
, "%s",
1308 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1309 else if (((l
>> OP_SH_RT
) & OP_MASK_RT
) == 0)
1310 (*info
->fprintf_func
) (info
->stream
, "%s",
1311 mips_gpr_names
[reg
]);
1312 else /* Bogus, result depends on processor. */
1313 (*info
->fprintf_func
) (info
->stream
, "%s or %s",
1314 mips_gpr_names
[reg
],
1315 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1321 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1326 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1327 (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
);
1331 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1332 (l
>> OP_SH_CODE
) & OP_MASK_CODE
);
1336 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1337 (l
>> OP_SH_CODE2
) & OP_MASK_CODE2
);
1341 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1342 (l
>> OP_SH_COPZ
) & OP_MASK_COPZ
);
1346 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1348 (l
>> OP_SH_CODE20
) & OP_MASK_CODE20
);
1352 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1353 (l
>> OP_SH_CODE19
) & OP_MASK_CODE19
);
1358 (*info
->fprintf_func
) (info
->stream
, "%s",
1359 mips_fpr_names
[(l
>> OP_SH_FS
) & OP_MASK_FS
]);
1364 (*info
->fprintf_func
) (info
->stream
, "%s",
1365 mips_fpr_names
[(l
>> OP_SH_FT
) & OP_MASK_FT
]);
1369 (*info
->fprintf_func
) (info
->stream
, "%s",
1370 mips_fpr_names
[(l
>> OP_SH_FD
) & OP_MASK_FD
]);
1374 (*info
->fprintf_func
) (info
->stream
, "%s",
1375 mips_fpr_names
[(l
>> OP_SH_FR
) & OP_MASK_FR
]);
1379 /* Coprocessor register for lwcN instructions, et al.
1381 Note that there is no load/store cp0 instructions, and
1382 that FPU (cp1) instructions disassemble this field using
1383 'T' format. Therefore, until we gain understanding of
1384 cp2 register names, we can simply print the register
1386 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1387 (l
>> OP_SH_RT
) & OP_MASK_RT
);
1391 /* Coprocessor register for mtcN instructions, et al. Note
1392 that FPU (cp1) instructions disassemble this field using
1393 'S' format. Therefore, we only need to worry about cp0,
1395 op
= (l
>> OP_SH_OP
) & OP_MASK_OP
;
1396 if (op
== OP_OP_COP0
)
1397 (*info
->fprintf_func
) (info
->stream
, "%s",
1398 mips_cp0_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1400 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1401 (l
>> OP_SH_RD
) & OP_MASK_RD
);
1405 (*info
->fprintf_func
) (info
->stream
, "%s",
1406 mips_hwr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1410 (*info
->fprintf_func
) (info
->stream
,
1411 ((opp
->pinfo
& (FP_D
| FP_S
)) != 0
1412 ? "$fcc%ld" : "$cc%ld"),
1413 (l
>> OP_SH_BCC
) & OP_MASK_BCC
);
1417 (*info
->fprintf_func
) (info
->stream
, "$fcc%ld",
1418 (l
>> OP_SH_CCC
) & OP_MASK_CCC
);
1422 (*info
->fprintf_func
) (info
->stream
, "%ld",
1423 (l
>> OP_SH_PERFREG
) & OP_MASK_PERFREG
);
1427 (*info
->fprintf_func
) (info
->stream
, "%ld",
1428 (l
>> OP_SH_VECBYTE
) & OP_MASK_VECBYTE
);
1432 (*info
->fprintf_func
) (info
->stream
, "%ld",
1433 (l
>> OP_SH_VECALIGN
) & OP_MASK_VECALIGN
);
1437 (*info
->fprintf_func
) (info
->stream
, "%ld",
1438 (l
>> OP_SH_SEL
) & OP_MASK_SEL
);
1442 (*info
->fprintf_func
) (info
->stream
, "%ld",
1443 (l
>> OP_SH_ALN
) & OP_MASK_ALN
);
1448 unsigned int vsel
= (l
>> OP_SH_VSEL
) & OP_MASK_VSEL
;
1450 if ((vsel
& 0x10) == 0)
1455 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1456 if ((vsel
& 1) == 0)
1458 (*info
->fprintf_func
) (info
->stream
, "$v%ld[%d]",
1459 (l
>> OP_SH_FT
) & OP_MASK_FT
,
1462 else if ((vsel
& 0x08) == 0)
1464 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1465 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1469 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1470 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1476 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1477 (l
>> OP_SH_FD
) & OP_MASK_FD
);
1481 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1482 (l
>> OP_SH_FS
) & OP_MASK_FS
);
1486 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1487 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1491 /* xgettext:c-format */
1492 (*info
->fprintf_func
) (info
->stream
,
1493 _("# internal error, undefined modifier (%c)"),
1500 /* Print the mips instruction at address MEMADDR in debugged memory,
1501 on using INFO. Returns length of the instruction, in bytes, which is
1502 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1503 this is little-endian code. */
1506 print_insn_mips (bfd_vma memaddr
,
1507 unsigned long int word
,
1508 struct disassemble_info
*info
)
1510 const struct mips_opcode
*op
;
1511 static bfd_boolean init
= 0;
1512 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1514 /* Build a hash table to shorten the search time. */
1519 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1521 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1523 if (op
->pinfo
== INSN_MACRO
1524 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1526 if (i
== ((op
->match
>> OP_SH_OP
) & OP_MASK_OP
))
1537 info
->bytes_per_chunk
= INSNLEN
;
1538 info
->display_endian
= info
->endian
;
1539 info
->insn_info_valid
= 1;
1540 info
->branch_delay_insns
= 0;
1541 info
->data_size
= 0;
1542 info
->insn_type
= dis_nonbranch
;
1546 op
= mips_hash
[(word
>> OP_SH_OP
) & OP_MASK_OP
];
1549 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1551 if (op
->pinfo
!= INSN_MACRO
1552 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1553 && (word
& op
->mask
) == op
->match
)
1557 /* We always allow to disassemble the jalx instruction. */
1558 if (! OPCODE_IS_MEMBER (op
, mips_isa
, mips_processor
)
1559 && strcmp (op
->name
, "jalx"))
1562 /* Figure out instruction type and branch delay information. */
1563 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1565 if ((op
->pinfo
& (INSN_WRITE_GPR_31
1566 | INSN_WRITE_GPR_D
)) != 0)
1567 info
->insn_type
= dis_jsr
;
1569 info
->insn_type
= dis_branch
;
1570 info
->branch_delay_insns
= 1;
1572 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1573 | INSN_COND_BRANCH_LIKELY
)) != 0)
1575 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1576 info
->insn_type
= dis_condjsr
;
1578 info
->insn_type
= dis_condbranch
;
1579 info
->branch_delay_insns
= 1;
1581 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1582 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1583 info
->insn_type
= dis_dref
;
1585 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
1588 if (d
!= NULL
&& *d
!= '\0')
1590 (*info
->fprintf_func
) (info
->stream
, "\t");
1591 print_insn_args (d
, word
, memaddr
, info
, op
);
1599 /* Handle undefined instructions. */
1600 info
->insn_type
= dis_noninsn
;
1601 (*info
->fprintf_func
) (info
->stream
, "0x%lx", word
);
1605 /* Disassemble an operand for a mips16 instruction. */
1608 print_mips16_insn_arg (char type
,
1609 const struct mips_opcode
*op
,
1611 bfd_boolean use_extend
,
1614 struct disassemble_info
*info
)
1621 (*info
->fprintf_func
) (info
->stream
, "%c", type
);
1626 (*info
->fprintf_func
) (info
->stream
, "%s",
1627 mips16_reg_names(((l
>> MIPS16OP_SH_RY
)
1628 & MIPS16OP_MASK_RY
)));
1633 (*info
->fprintf_func
) (info
->stream
, "%s",
1634 mips16_reg_names(((l
>> MIPS16OP_SH_RX
)
1635 & MIPS16OP_MASK_RX
)));
1639 (*info
->fprintf_func
) (info
->stream
, "%s",
1640 mips16_reg_names(((l
>> MIPS16OP_SH_RZ
)
1641 & MIPS16OP_MASK_RZ
)));
1645 (*info
->fprintf_func
) (info
->stream
, "%s",
1646 mips16_reg_names(((l
>> MIPS16OP_SH_MOVE32Z
)
1647 & MIPS16OP_MASK_MOVE32Z
)));
1651 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1655 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[29]);
1659 (*info
->fprintf_func
) (info
->stream
, "$pc");
1663 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[31]);
1667 (*info
->fprintf_func
) (info
->stream
, "%s",
1668 mips_gpr_names
[((l
>> MIPS16OP_SH_REGR32
)
1669 & MIPS16OP_MASK_REGR32
)]);
1673 (*info
->fprintf_func
) (info
->stream
, "%s",
1674 mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1700 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1712 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1718 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1724 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1730 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1736 immed
= (l
>> MIPS16OP_SH_IMM4
) & MIPS16OP_MASK_IMM4
;
1742 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1743 info
->insn_type
= dis_dref
;
1744 info
->data_size
= 1;
1749 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1750 info
->insn_type
= dis_dref
;
1751 info
->data_size
= 2;
1756 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1757 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1758 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1760 info
->insn_type
= dis_dref
;
1761 info
->data_size
= 4;
1767 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1768 info
->insn_type
= dis_dref
;
1769 info
->data_size
= 8;
1773 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1778 immed
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1782 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1787 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1788 /* FIXME: This might be lw, or it might be addiu to $sp or
1789 $pc. We assume it's load. */
1790 info
->insn_type
= dis_dref
;
1791 info
->data_size
= 4;
1796 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1797 info
->insn_type
= dis_dref
;
1798 info
->data_size
= 8;
1802 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1807 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1813 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1818 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1825 immed
= (l
>> MIPS16OP_SH_IMM11
) & MIPS16OP_MASK_IMM11
;
1833 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1835 /* FIXME: This can be lw or la. We assume it is lw. */
1836 info
->insn_type
= dis_dref
;
1837 info
->data_size
= 4;
1842 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1844 info
->insn_type
= dis_dref
;
1845 info
->data_size
= 8;
1850 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1859 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1860 immed
-= 1 << nbits
;
1862 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1869 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1870 else if (extbits
== 15)
1871 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1873 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1874 immed
&= (1 << extbits
) - 1;
1875 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1876 immed
-= 1 << extbits
;
1880 (*info
->fprintf_func
) (info
->stream
, "%d", immed
);
1888 baseaddr
= memaddr
+ 2;
1890 else if (use_extend
)
1891 baseaddr
= memaddr
- 2;
1899 /* If this instruction is in the delay slot of a jr
1900 instruction, the base address is the address of the
1901 jr instruction. If it is in the delay slot of jalr
1902 instruction, the base address is the address of the
1903 jalr instruction. This test is unreliable: we have
1904 no way of knowing whether the previous word is
1905 instruction or data. */
1906 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1909 && (((info
->endian
== BFD_ENDIAN_BIG
1910 ? bfd_getb16 (buffer
)
1911 : bfd_getl16 (buffer
))
1912 & 0xf800) == 0x1800))
1913 baseaddr
= memaddr
- 4;
1916 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1919 && (((info
->endian
== BFD_ENDIAN_BIG
1920 ? bfd_getb16 (buffer
)
1921 : bfd_getl16 (buffer
))
1922 & 0xf81f) == 0xe800))
1923 baseaddr
= memaddr
- 2;
1926 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1928 && info
->flavour
== bfd_target_unknown_flavour
)
1929 /* For gdb disassembler, maintain odd address. */
1931 (*info
->print_address_func
) (info
->target
, info
);
1938 int jalx
= l
& 0x400;
1942 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1943 if (!jalx
&& info
->flavour
== bfd_target_unknown_flavour
)
1944 /* For gdb disassembler, maintain odd address. */
1947 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1948 (*info
->print_address_func
) (info
->target
, info
);
1954 int need_comma
, amask
, smask
;
1958 l
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1960 amask
= (l
>> 3) & 7;
1962 if (amask
> 0 && amask
< 5)
1964 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
1966 (*info
->fprintf_func
) (info
->stream
, "-%s",
1967 mips_gpr_names
[amask
+ 3]);
1971 smask
= (l
>> 1) & 3;
1974 (*info
->fprintf_func
) (info
->stream
, "%s??",
1975 need_comma
? "," : "");
1980 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1981 need_comma
? "," : "",
1982 mips_gpr_names
[16]);
1984 (*info
->fprintf_func
) (info
->stream
, "-%s",
1985 mips_gpr_names
[smask
+ 15]);
1991 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1992 need_comma
? "," : "",
1993 mips_gpr_names
[31]);
1997 if (amask
== 5 || amask
== 6)
1999 (*info
->fprintf_func
) (info
->stream
, "%s$f0",
2000 need_comma
? "," : "");
2002 (*info
->fprintf_func
) (info
->stream
, "-$f1");
2009 /* MIPS16e save/restore. */
2012 int amask
, args
, statics
;
2021 amask
= (l
>> 16) & 0xf;
2022 if (amask
== MIPS16_ALL_ARGS
)
2027 else if (amask
== MIPS16_ALL_STATICS
)
2035 statics
= amask
& 3;
2039 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
2041 (*info
->fprintf_func
) (info
->stream
, "-%s",
2042 mips_gpr_names
[4 + args
- 1]);
2046 framesz
= (((l
>> 16) & 0xf0) | (l
& 0x0f)) * 8;
2047 if (framesz
== 0 && !use_extend
)
2050 (*info
->fprintf_func
) (info
->stream
, "%s%d",
2051 need_comma
? "," : "",
2054 if (l
& 0x40) /* $ra */
2055 (*info
->fprintf_func
) (info
->stream
, ",%s", mips_gpr_names
[31]);
2057 nsreg
= (l
>> 24) & 0x7;
2059 if (l
& 0x20) /* $s0 */
2061 if (l
& 0x10) /* $s1 */
2063 if (nsreg
> 0) /* $s2-$s8 */
2064 smask
|= ((1 << nsreg
) - 1) << 2;
2066 /* Find first set static reg bit. */
2067 for (i
= 0; i
< 9; i
++)
2069 if (smask
& (1 << i
))
2071 (*info
->fprintf_func
) (info
->stream
, ",%s",
2072 mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
2073 /* Skip over string of set bits. */
2074 for (j
= i
; smask
& (2 << j
); j
++)
2077 (*info
->fprintf_func
) (info
->stream
, "-%s",
2078 mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
2083 /* Statics $ax - $a3. */
2085 (*info
->fprintf_func
) (info
->stream
, ",%s", mips_gpr_names
[7]);
2086 else if (statics
> 0)
2087 (*info
->fprintf_func
) (info
->stream
, ",%s-%s",
2088 mips_gpr_names
[7 - statics
+ 1],
2094 /* xgettext:c-format */
2095 (*info
->fprintf_func
)
2097 _("# internal disassembler error, unrecognised modifier (%c)"),
2103 /* Disassemble mips16 instructions. */
2106 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2112 bfd_boolean use_extend
;
2114 const struct mips_opcode
*op
, *opend
;
2116 info
->bytes_per_chunk
= 2;
2117 info
->display_endian
= info
->endian
;
2118 info
->insn_info_valid
= 1;
2119 info
->branch_delay_insns
= 0;
2120 info
->data_size
= 0;
2121 info
->insn_type
= dis_nonbranch
;
2125 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2128 (*info
->memory_error_func
) (status
, memaddr
, info
);
2134 if (info
->endian
== BFD_ENDIAN_BIG
)
2135 insn
= bfd_getb16 (buffer
);
2137 insn
= bfd_getl16 (buffer
);
2139 /* Handle the extend opcode specially. */
2141 if ((insn
& 0xf800) == 0xf000)
2144 extend
= insn
& 0x7ff;
2148 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2151 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
2152 (unsigned int) extend
);
2153 (*info
->memory_error_func
) (status
, memaddr
, info
);
2157 if (info
->endian
== BFD_ENDIAN_BIG
)
2158 insn
= bfd_getb16 (buffer
);
2160 insn
= bfd_getl16 (buffer
);
2162 /* Check for an extend opcode followed by an extend opcode. */
2163 if ((insn
& 0xf800) == 0xf000)
2165 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
2166 (unsigned int) extend
);
2167 info
->insn_type
= dis_noninsn
;
2174 /* FIXME: Should probably use a hash table on the major opcode here. */
2176 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2177 for (op
= mips16_opcodes
; op
< opend
; op
++)
2179 if (op
->pinfo
!= INSN_MACRO
2180 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2181 && (insn
& op
->mask
) == op
->match
)
2185 if (strchr (op
->args
, 'a') != NULL
)
2189 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
2190 (unsigned int) extend
);
2191 info
->insn_type
= dis_noninsn
;
2199 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2204 if (info
->endian
== BFD_ENDIAN_BIG
)
2205 extend
= bfd_getb16 (buffer
);
2207 extend
= bfd_getl16 (buffer
);
2212 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
2213 if (op
->args
[0] != '\0')
2214 (*info
->fprintf_func
) (info
->stream
, "\t");
2216 for (s
= op
->args
; *s
!= '\0'; s
++)
2220 && (((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)
2221 == ((insn
>> MIPS16OP_SH_RY
) & MIPS16OP_MASK_RY
)))
2223 /* Skip the register and the comma. */
2229 && (((insn
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
)
2230 == ((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)))
2232 /* Skip the register and the comma. */
2236 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
2240 /* Figure out branch instruction type and delay slot information. */
2241 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2242 info
->branch_delay_insns
= 1;
2243 if ((op
->pinfo
& (INSN_UNCOND_BRANCH_DELAY
2244 | MIPS16_INSN_UNCOND_BRANCH
)) != 0)
2246 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2247 info
->insn_type
= dis_jsr
;
2249 info
->insn_type
= dis_branch
;
2251 else if ((op
->pinfo
& MIPS16_INSN_COND_BRANCH
) != 0)
2252 info
->insn_type
= dis_condbranch
;
2259 (*info
->fprintf_func
) (info
->stream
, "0x%x", extend
| 0xf000);
2260 (*info
->fprintf_func
) (info
->stream
, "0x%x", insn
);
2261 info
->insn_type
= dis_noninsn
;
2266 /* Disassemble microMIPS instructions. */
2269 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2271 const fprintf_ftype infprintf
= info
->fprintf_func
;
2272 const struct mips_opcode
*op
, *opend
;
2273 unsigned int lsb
, msbd
, msb
;
2274 void *is
= info
->stream
;
2287 info
->bytes_per_chunk
= 2;
2288 info
->display_endian
= info
->endian
;
2289 info
->insn_info_valid
= 1;
2290 info
->branch_delay_insns
= 0;
2291 info
->data_size
= 0;
2292 info
->insn_type
= dis_nonbranch
;
2296 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2299 (*info
->memory_error_func
) (status
, memaddr
, info
);
2305 if (info
->endian
== BFD_ENDIAN_BIG
)
2306 insn
= bfd_getb16 (buffer
);
2308 insn
= bfd_getl16 (buffer
);
2310 if ((insn
& 0xfc00) == 0x7c00)
2312 /* This is a 48-bit microMIPS instruction. */
2315 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2318 infprintf (is
, "micromips 0x%x", higher
);
2319 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2322 if (info
->endian
== BFD_ENDIAN_BIG
)
2323 insn
= bfd_getb16 (buffer
);
2325 insn
= bfd_getl16 (buffer
);
2326 higher
= (higher
<< 16) | insn
;
2328 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
2331 infprintf (is
, "micromips 0x%x", higher
);
2332 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2335 if (info
->endian
== BFD_ENDIAN_BIG
)
2336 insn
= bfd_getb16 (buffer
);
2338 insn
= bfd_getl16 (buffer
);
2339 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2341 info
->insn_type
= dis_noninsn
;
2344 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2346 /* This is a 32-bit microMIPS instruction. */
2349 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2352 infprintf (is
, "micromips 0x%x", higher
);
2353 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2357 if (info
->endian
== BFD_ENDIAN_BIG
)
2358 insn
= bfd_getb16 (buffer
);
2360 insn
= bfd_getl16 (buffer
);
2362 insn
= insn
| (higher
<< 16);
2367 /* FIXME: Should probably use a hash table on the major opcode here. */
2369 #define GET_OP(insn, field) \
2370 (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2371 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2372 for (op
= micromips_opcodes
; op
< opend
; op
++)
2374 if (op
->pinfo
!= INSN_MACRO
2375 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2376 && (insn
& op
->mask
) == op
->match
2377 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2378 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2382 infprintf (is
, "%s", op
->name
);
2383 if (op
->args
[0] != '\0')
2384 infprintf (is
, "\t");
2386 for (s
= op
->args
; *s
!= '\0'; s
++)
2393 infprintf (is
, "%c", *s
);
2397 delta
= GET_OP (insn
, OFFSET10
);
2400 infprintf (is
, "%d", delta
);
2404 infprintf (is
, "0x%lx", GET_OP (insn
, STYPE
));
2408 infprintf (is
, "0x%lx", GET_OP (insn
, SHAMT
));
2412 infprintf (is
, "0x%lx", GET_OP (insn
, 3BITPOS
));
2416 infprintf (is
, "0x%lx", GET_OP (insn
, TRAP
));
2420 delta
= GET_OP (insn
, OFFSET12
);
2423 infprintf (is
, "%d", delta
);
2427 if (strcmp (op
->name
, "jalx") == 0)
2428 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff)
2429 | (GET_OP (insn
, TARGET
) << 2));
2431 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x07ffffff)
2432 | ((GET_OP (insn
, TARGET
)) << 1));
2433 /* For gdb disassembler, force odd address on jalx. */
2434 if (info
->flavour
== bfd_target_unknown_flavour
2435 && strcmp (op
->name
, "jalx") == 0)
2437 (*info
->print_address_func
) (info
->target
, info
);
2444 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS
)]);
2448 infprintf (is
, "0x%lx", GET_OP (insn
, CODE
));
2452 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RD
)]);
2456 infprintf (is
, "0x%lx", GET_OP (insn
, PREFX
));
2461 infprintf (is
, "0x%lx", GET_OP (insn
, IMMEDIATE
));
2464 case 'j': /* Same as i, but sign-extended. */
2466 delta
= (GET_OP (insn
, DELTA
) ^ 0x8000) - 0x8000;
2467 infprintf (is
, "%d", delta
);
2471 infprintf (is
, "0x%x", GET_OP (insn
, CACHE
));
2478 immed
= GET_OP (insn
, RT
);
2479 s_reg_encode
= immed
& 0xf;
2480 if (s_reg_encode
!= 0)
2482 if (s_reg_encode
== 1)
2483 infprintf (is
, "%s", mips_gpr_names
[16]);
2484 else if (s_reg_encode
< 9)
2485 infprintf (is
, "%s-%s",
2487 mips_gpr_names
[15 + s_reg_encode
]);
2488 else if (s_reg_encode
== 9)
2489 infprintf (is
, "%s-%s,%s",
2492 mips_gpr_names
[30]);
2494 infprintf (is
, "UNKNOWN");
2497 if (immed
& 0x10) /* For ra. */
2499 if (s_reg_encode
== 0)
2500 infprintf (is
, "%s", mips_gpr_names
[31]);
2502 infprintf (is
, ",%s", mips_gpr_names
[31]);
2508 /* Sign-extend the displacement. */
2509 delta
= (GET_OP (insn
, DELTA
) ^ 0x8000) - 0x8000;
2510 info
->target
= (delta
<< 1) + memaddr
+ length
;
2511 (*info
->print_address_func
) (info
->target
, info
);
2515 infprintf (is
, "0x%lx", GET_OP (insn
, CODE2
));
2520 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RT
)]);
2524 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS3
)]);
2528 infprintf (is
, "%s", mips_gpr_names
[0]);
2532 infprintf (is
, "0x%lx", GET_OP (insn
, CODE10
));
2536 infprintf (is
, "0x%lx", GET_OP (insn
, COPZ
));
2540 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FD
)]);
2544 /* Coprocessor register for lwcN instructions, et al.
2546 Note that there is no load/store cp0 instructions, and
2547 that FPU (cp1) instructions disassemble this field using
2548 'T' format. Therefore, until we gain understanding of
2549 cp2 register names, we can simply print the register
2551 infprintf (is
, "$%ld", GET_OP (insn
, RT
));
2555 /* Coprocessor register for mtcN instructions, et al. Note
2556 that FPU (cp1) instructions disassemble this field using
2557 'S' format. Therefore, we only need to worry about cp0,
2559 The microMIPS encoding does not have a coprocessor
2560 identifier field as such, so we must work out the
2561 coprocessor number by looking at the opcode. */
2563 & ~((MICROMIPSOP_MASK_RT
<< MICROMIPSOP_SH_RT
)
2564 | (MICROMIPSOP_MASK_RS
<< MICROMIPSOP_SH_RS
)))
2566 case 0x000000fc: /* mfc0 */
2567 case 0x000002fc: /* mtc0 */
2568 case 0x580000fc: /* dmfc0 */
2569 case 0x580002fc: /* dmtc0 */
2570 infprintf (is
, "%s", mips_cp0_names
[GET_OP (insn
, RS
)]);
2573 infprintf (is
, "$%ld", GET_OP (insn
, RS
));
2579 infprintf (is
, "%ld", GET_OP (insn
, SEL
));
2583 infprintf (is
, "%s", mips_hwr_names
[GET_OP (insn
, RS
)]);
2587 infprintf (is
, "$fcc%ld", GET_OP (insn
, CCC
));
2592 (op
->pinfo
& (FP_D
| FP_S
)) != 0
2593 ? "$fcc%ld" : "$cc%ld",
2594 GET_OP (insn
, BCC
));
2598 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FR
)]);
2603 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FS
)]);
2607 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FT
)]);
2611 /* Extension character; switch for second char. */
2616 lsb
= GET_OP (insn
, EXTLSB
);
2617 infprintf (is
, "0x%x", lsb
);
2621 msb
= GET_OP (insn
, INSMSB
);
2622 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2627 msbd
= GET_OP (insn
, EXTMSBD
);
2628 infprintf (is
, "0x%x", msbd
+ 1);
2633 const struct mips_cp0sel_name
*n
;
2634 unsigned int cp0reg
, sel
;
2636 cp0reg
= GET_OP (insn
, RS
);
2637 sel
= GET_OP (insn
, SEL
);
2639 /* CP0 register including 'sel' code for mtcN
2640 (et al.), to be printed textually if known.
2641 If not known, print both CP0 register name and
2642 sel numerically since CP0 register with sel 0 may
2643 have a name unrelated to register being printed. */
2644 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2645 mips_cp0sel_names_len
,
2648 infprintf (is
, "%s", n
->name
);
2650 infprintf (is
, "$%d,%d", cp0reg
, sel
);
2655 lsb
= GET_OP (insn
, EXTLSB
) + 32;
2656 infprintf (is
, "0x%x", lsb
);
2660 msb
= GET_OP (insn
, INSMSB
) + 32;
2661 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2665 msbd
= GET_OP (insn
, EXTMSBD
) + 32;
2666 infprintf (is
, "0x%x", msbd
+ 1);
2670 /* xgettext:c-format */
2672 _("# internal disassembler error, "
2673 "unrecognized modifier (+%c)"),
2680 /* Extension character; switch for second char. */
2684 case 'a': /* global pointer. */
2685 infprintf (is
, "%s", mips_gpr_names
[28]);
2689 regno
= micromips_to_32_reg_b_map
[GET_OP (insn
, MB
)];
2690 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2694 regno
= micromips_to_32_reg_c_map
[GET_OP (insn
, MC
)];
2695 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2699 regno
= micromips_to_32_reg_d_map
[GET_OP (insn
, MD
)];
2700 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2704 regno
= micromips_to_32_reg_e_map
[GET_OP (insn
, ME
)];
2705 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2709 /* Save lastregno for "mt" to print out later. */
2710 lastregno
= micromips_to_32_reg_f_map
[GET_OP (insn
, MF
)];
2711 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2715 regno
= micromips_to_32_reg_g_map
[GET_OP (insn
, MG
)];
2716 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2720 regno
= micromips_to_32_reg_h_map
[GET_OP (insn
, MH
)];
2721 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2725 regno
= micromips_to_32_reg_i_map
[GET_OP (insn
, MI
)];
2726 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2730 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, MJ
)]);
2734 regno
= micromips_to_32_reg_l_map
[GET_OP (insn
, ML
)];
2735 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2739 regno
= micromips_to_32_reg_m_map
[GET_OP (insn
, MM
)];
2740 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2744 regno
= micromips_to_32_reg_n_map
[GET_OP (insn
, MN
)];
2745 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2749 /* Save lastregno for "mt" to print out later. */
2750 lastregno
= GET_OP (insn
, MP
);
2751 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2755 regno
= micromips_to_32_reg_q_map
[GET_OP (insn
, MQ
)];
2756 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2759 case 'r': /* program counter. */
2760 infprintf (is
, "$pc");
2763 case 's': /* stack pointer. */
2765 infprintf (is
, "%s", mips_gpr_names
[29]);
2769 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2773 infprintf (is
, "%s", mips_gpr_names
[0]);
2777 /* Sign-extend the immediate. */
2778 immed
= ((GET_OP (insn
, IMMA
) ^ 0x40) - 0x40) << 2;
2779 infprintf (is
, "%d", immed
);
2783 immed
= micromips_imm_b_map
[GET_OP (insn
, IMMB
)];
2784 infprintf (is
, "%d", immed
);
2788 immed
= micromips_imm_c_map
[GET_OP (insn
, IMMC
)];
2789 infprintf (is
, "0x%lx", immed
);
2793 /* Sign-extend the displacement. */
2794 delta
= (GET_OP (insn
, IMMD
) ^ 0x200) - 0x200;
2795 info
->target
= (delta
<< 1) + memaddr
+ length
;
2796 (*info
->print_address_func
) (info
->target
, info
);
2800 /* Sign-extend the displacement. */
2801 delta
= (GET_OP (insn
, IMME
) ^ 0x40) - 0x40;
2802 info
->target
= (delta
<< 1) + memaddr
+ length
;
2803 (*info
->print_address_func
) (info
->target
, info
);
2807 immed
= GET_OP (insn
, IMMF
);
2808 infprintf (is
, "0x%x", immed
);
2812 immed
= (insn
>> MICROMIPSOP_SH_IMMG
) + 1;
2813 immed
= (immed
& MICROMIPSOP_MASK_IMMG
) - 1;
2814 infprintf (is
, "%d", immed
);
2818 immed
= GET_OP (insn
, IMMH
) << 1;
2819 infprintf (is
, "%d", immed
);
2823 immed
= (insn
>> MICROMIPSOP_SH_IMMI
) + 1;
2824 immed
= (immed
& MICROMIPSOP_MASK_IMMI
) - 1;
2825 infprintf (is
, "%d", immed
);
2829 immed
= GET_OP (insn
, IMMJ
) << 2;
2830 infprintf (is
, "%d", immed
);
2834 immed
= GET_OP (insn
, IMML
);
2835 infprintf (is
, "%d", immed
);
2839 immed
= (insn
>> MICROMIPSOP_SH_IMMM
) - 1;
2840 immed
= (immed
& MICROMIPSOP_MASK_IMMM
) + 1;
2841 infprintf (is
, "%d", immed
);
2845 immed
= GET_OP (insn
, IMMN
);
2847 infprintf (is
, "%s,%s",
2849 mips_gpr_names
[31]);
2851 infprintf (is
, "%s-%s,%s",
2853 mips_gpr_names
[16 + immed
],
2854 mips_gpr_names
[31]);
2858 immed
= GET_OP (insn
, IMMO
);
2859 infprintf (is
, "0x%x", immed
);
2863 immed
= GET_OP (insn
, IMMP
) << 2;
2864 infprintf (is
, "%d", immed
);
2868 /* Sign-extend the immediate. */
2869 immed
= (GET_OP (insn
, IMMQ
) ^ 0x400000) - 0x400000;
2871 infprintf (is
, "%d", immed
);
2875 immed
= GET_OP (insn
, IMMU
) << 2;
2876 infprintf (is
, "%d", immed
);
2880 immed
= GET_OP (insn
, IMMW
) << 2;
2881 infprintf (is
, "%d", immed
);
2885 /* Sign-extend the immediate. */
2886 immed
= (GET_OP (insn
, IMMX
) ^ 0x8) - 0x8;
2887 infprintf (is
, "%d", immed
);
2891 /* Sign-extend the immediate. */
2892 immed
= (GET_OP (insn
, IMMY
) ^ 0x100) - 0x100;
2893 if (immed
>= -2 && immed
<= 1)
2896 infprintf (is
, "%d", immed
);
2900 /* xgettext:c-format */
2902 _("# internal disassembler error, "
2903 "unrecognized modifier (m%c)"),
2910 /* xgettext:c-format */
2912 _("# internal disassembler error, "
2913 "unrecognized modifier (%c)"),
2919 /* Figure out instruction type and branch delay information. */
2921 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2922 info
->branch_delay_insns
= 1;
2923 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2924 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2926 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_GPR_T
)) != 0)
2927 info
->insn_type
= dis_jsr
;
2929 info
->insn_type
= dis_branch
;
2931 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2932 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2934 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2935 info
->insn_type
= dis_condjsr
;
2937 info
->insn_type
= dis_condbranch
;
2940 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY_DELAY
)) != 0)
2941 info
->insn_type
= dis_dref
;
2948 infprintf (is
, "0x%x", insn
);
2949 info
->insn_type
= dis_noninsn
;
2954 /* Return 1 if a symbol associated with the location being disassembled
2955 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2956 all the symbols at the address being considered assuming if at least
2957 one of them indicates code compression, then such code has been
2958 genuinely produced here (other symbols could have been derived from
2959 function symbols defined elsewhere or could define data). Otherwise,
2963 is_compressed_mode_p (struct disassemble_info
*info
)
2965 elf_symbol_type
*symbol
;
2969 for (i
= 0; i
< info
->num_symbols
; i
++)
2971 pos
= info
->symtab_pos
+ i
;
2973 if (bfd_asymbol_flavour (info
->symtab
[pos
]) != bfd_target_elf_flavour
)
2976 symbol
= (elf_symbol_type
*) info
->symtab
[pos
];
2978 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2980 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2987 /* In an environment where we do not know the symbol type of the
2988 instruction we are forced to assume that the low order bit of the
2989 instructions' address may mark it as a mips16 instruction. If we
2990 are single stepping, or the pc is within the disassembled function,
2991 this works. Otherwise, we need a clue. Sometimes. */
2994 _print_insn_mips (bfd_vma memaddr
,
2995 struct disassemble_info
*info
,
2996 enum bfd_endian endianness
)
2998 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
2999 bfd_byte buffer
[INSNLEN
];
3002 set_default_mips_dis_options (info
);
3003 parse_mips_dis_options (info
->disassembler_options
);
3005 if (info
->mach
== bfd_mach_mips16
)
3006 return print_insn_mips16 (memaddr
, info
);
3007 if (info
->mach
== bfd_mach_mips_micromips
)
3008 return print_insn_micromips (memaddr
, info
);
3010 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
3013 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
3014 /* Only a few tools will work this way. */
3016 return print_insn_compr (memaddr
, info
);
3019 #if SYMTAB_AVAILABLE
3020 if (is_compressed_mode_p (info
))
3021 return print_insn_compr (memaddr
, info
);
3024 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
3029 if (endianness
== BFD_ENDIAN_BIG
)
3030 insn
= (unsigned long) bfd_getb32 (buffer
);
3032 insn
= (unsigned long) bfd_getl32 (buffer
);
3034 return print_insn_mips (memaddr
, insn
, info
);
3038 (*info
->memory_error_func
) (status
, memaddr
, info
);
3044 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3046 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
3050 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3052 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
3056 print_mips_disassembler_options (FILE *stream
)
3060 fprintf (stream
, _("\n\
3061 The following MIPS specific disassembler options are supported for use\n\
3062 with the -M switch (multiple options should be separated by commas):\n"));
3064 fprintf (stream
, _("\n\
3065 gpr-names=ABI Print GPR names according to specified ABI.\n\
3066 Default: based on binary being disassembled.\n"));
3068 fprintf (stream
, _("\n\
3069 fpr-names=ABI Print FPR names according to specified ABI.\n\
3070 Default: numeric.\n"));
3072 fprintf (stream
, _("\n\
3073 cp0-names=ARCH Print CP0 register names according to\n\
3074 specified architecture.\n\
3075 Default: based on binary being disassembled.\n"));
3077 fprintf (stream
, _("\n\
3078 hwr-names=ARCH Print HWR names according to specified \n\
3080 Default: based on binary being disassembled.\n"));
3082 fprintf (stream
, _("\n\
3083 reg-names=ABI Print GPR and FPR names according to\n\
3084 specified ABI.\n"));
3086 fprintf (stream
, _("\n\
3087 reg-names=ARCH Print CP0 register and HWR names according to\n\
3088 specified architecture.\n"));
3090 fprintf (stream
, _("\n\
3091 For the options above, the following values are supported for \"ABI\":\n\
3093 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
3094 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
3095 fprintf (stream
, _("\n"));
3097 fprintf (stream
, _("\n\
3098 For the options above, The following values are supported for \"ARCH\":\n\
3100 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
3101 if (*mips_arch_choices
[i
].name
!= '\0')
3102 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
3103 fprintf (stream
, _("\n"));
3105 fprintf (stream
, _("\n"));