1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2012
4 Free Software Foundation, Inc.
5 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
7 This file is part of the GNU opcodes library.
9 This library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
26 #include "libiberty.h"
27 #include "opcode/mips.h"
30 /* FIXME: These are needed to figure out if the code is mips16 or
31 not. The low bit of the address is often a good indicator. No
32 symbol table is available when this code runs out in an embedded
33 system as when it is used for disassembler support in a monitor. */
35 #if !defined(EMBEDDED_ENV)
36 #define SYMTAB_AVAILABLE 1
41 /* Mips instructions are at maximum this many bytes long. */
45 /* FIXME: These should be shared with gdb somehow. */
47 struct mips_cp0sel_name
51 const char * const name
;
54 /* The mips16 registers. */
55 static const unsigned int mips16_to_32_reg_map
[] =
57 16, 17, 2, 3, 4, 5, 6, 7
60 /* The microMIPS registers with type b. */
61 #define micromips_to_32_reg_b_map mips16_to_32_reg_map
63 /* The microMIPS registers with type c. */
64 #define micromips_to_32_reg_c_map mips16_to_32_reg_map
66 /* The microMIPS registers with type d. */
67 #define micromips_to_32_reg_d_map mips16_to_32_reg_map
69 /* The microMIPS registers with type e. */
70 #define micromips_to_32_reg_e_map mips16_to_32_reg_map
72 /* The microMIPS registers with type f. */
73 #define micromips_to_32_reg_f_map mips16_to_32_reg_map
75 /* The microMIPS registers with type g. */
76 #define micromips_to_32_reg_g_map mips16_to_32_reg_map
78 /* The microMIPS registers with type h. */
79 static const unsigned int micromips_to_32_reg_h_map
[] =
81 5, 5, 6, 4, 4, 4, 4, 4
84 /* The microMIPS registers with type i. */
85 static const unsigned int micromips_to_32_reg_i_map
[] =
87 6, 7, 7, 21, 22, 5, 6, 7
90 /* The microMIPS registers with type j: 32 registers. */
92 /* The microMIPS registers with type l. */
93 #define micromips_to_32_reg_l_map mips16_to_32_reg_map
95 /* The microMIPS registers with type m. */
96 static const unsigned int micromips_to_32_reg_m_map
[] =
98 0, 17, 2, 3, 16, 18, 19, 20
101 /* The microMIPS registers with type n. */
102 #define micromips_to_32_reg_n_map micromips_to_32_reg_m_map
104 /* The microMIPS registers with type p: 32 registers. */
106 /* The microMIPS registers with type q. */
107 static const unsigned int micromips_to_32_reg_q_map
[] =
109 0, 17, 2, 3, 4, 5, 6, 7
112 /* reg type s is $29. */
114 /* reg type t is the same as the last register. */
116 /* reg type y is $31. */
118 /* reg type z is $0. */
120 /* micromips imm B type. */
121 static const int micromips_imm_b_map
[8] =
123 1, 4, 8, 12, 16, 20, 24, -1
126 /* micromips imm C type. */
127 static const int micromips_imm_c_map
[16] =
129 128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 255, 32768, 65535
132 /* micromips imm D type: (-512..511)<<1. */
133 /* micromips imm E type: (-64..63)<<1. */
134 /* micromips imm F type: (0..63). */
135 /* micromips imm G type: (-1..14). */
136 /* micromips imm H type: (0..15)<<1. */
137 /* micromips imm I type: (-1..126). */
138 /* micromips imm J type: (0..15)<<2. */
139 /* micromips imm L type: (0..15). */
140 /* micromips imm M type: (1..8). */
141 /* micromips imm W type: (0..63)<<2. */
142 /* micromips imm X type: (-8..7). */
143 /* micromips imm Y type: (-258..-3, 2..257)<<2. */
145 #define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]]
148 static const char * const mips_gpr_names_numeric
[32] =
150 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
151 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
152 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
153 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
156 static const char * const mips_gpr_names_oldabi
[32] =
158 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
159 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
160 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
161 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
164 static const char * const mips_gpr_names_newabi
[32] =
166 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
167 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
168 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
169 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
172 static const char * const mips_fpr_names_numeric
[32] =
174 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
175 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
176 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
177 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
180 static const char * const mips_fpr_names_32
[32] =
182 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
183 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
184 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
185 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
188 static const char * const mips_fpr_names_n32
[32] =
190 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
191 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
192 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
193 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
196 static const char * const mips_fpr_names_64
[32] =
198 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
199 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
200 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
201 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
204 static const char * const mips_cp0_names_numeric
[32] =
206 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
207 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
208 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
209 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
212 static const char * const mips_cp0_names_r3000
[32] =
214 "c0_index", "c0_random", "c0_entrylo", "$3",
215 "c0_context", "$5", "$6", "$7",
216 "c0_badvaddr", "$9", "c0_entryhi", "$11",
217 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
218 "$16", "$17", "$18", "$19",
219 "$20", "$21", "$22", "$23",
220 "$24", "$25", "$26", "$27",
221 "$28", "$29", "$30", "$31",
224 static const char * const mips_cp0_names_r4000
[32] =
226 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
227 "c0_context", "c0_pagemask", "c0_wired", "$7",
228 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
229 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
230 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
231 "c0_xcontext", "$21", "$22", "$23",
232 "$24", "$25", "c0_ecc", "c0_cacheerr",
233 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
236 static const char * const mips_cp0_names_mips3264
[32] =
238 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
239 "c0_context", "c0_pagemask", "c0_wired", "$7",
240 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
241 "c0_status", "c0_cause", "c0_epc", "c0_prid",
242 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
243 "c0_xcontext", "$21", "$22", "c0_debug",
244 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
245 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
248 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] =
250 { 16, 1, "c0_config1" },
251 { 16, 2, "c0_config2" },
252 { 16, 3, "c0_config3" },
253 { 18, 1, "c0_watchlo,1" },
254 { 18, 2, "c0_watchlo,2" },
255 { 18, 3, "c0_watchlo,3" },
256 { 18, 4, "c0_watchlo,4" },
257 { 18, 5, "c0_watchlo,5" },
258 { 18, 6, "c0_watchlo,6" },
259 { 18, 7, "c0_watchlo,7" },
260 { 19, 1, "c0_watchhi,1" },
261 { 19, 2, "c0_watchhi,2" },
262 { 19, 3, "c0_watchhi,3" },
263 { 19, 4, "c0_watchhi,4" },
264 { 19, 5, "c0_watchhi,5" },
265 { 19, 6, "c0_watchhi,6" },
266 { 19, 7, "c0_watchhi,7" },
267 { 25, 1, "c0_perfcnt,1" },
268 { 25, 2, "c0_perfcnt,2" },
269 { 25, 3, "c0_perfcnt,3" },
270 { 25, 4, "c0_perfcnt,4" },
271 { 25, 5, "c0_perfcnt,5" },
272 { 25, 6, "c0_perfcnt,6" },
273 { 25, 7, "c0_perfcnt,7" },
274 { 27, 1, "c0_cacheerr,1" },
275 { 27, 2, "c0_cacheerr,2" },
276 { 27, 3, "c0_cacheerr,3" },
277 { 28, 1, "c0_datalo" },
278 { 29, 1, "c0_datahi" }
281 static const char * const mips_cp0_names_mips3264r2
[32] =
283 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
284 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
285 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
286 "c0_status", "c0_cause", "c0_epc", "c0_prid",
287 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
288 "c0_xcontext", "$21", "$22", "c0_debug",
289 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
290 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
293 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] =
295 { 4, 1, "c0_contextconfig" },
296 { 0, 1, "c0_mvpcontrol" },
297 { 0, 2, "c0_mvpconf0" },
298 { 0, 3, "c0_mvpconf1" },
299 { 1, 1, "c0_vpecontrol" },
300 { 1, 2, "c0_vpeconf0" },
301 { 1, 3, "c0_vpeconf1" },
302 { 1, 4, "c0_yqmask" },
303 { 1, 5, "c0_vpeschedule" },
304 { 1, 6, "c0_vpeschefback" },
305 { 2, 1, "c0_tcstatus" },
306 { 2, 2, "c0_tcbind" },
307 { 2, 3, "c0_tcrestart" },
308 { 2, 4, "c0_tchalt" },
309 { 2, 5, "c0_tccontext" },
310 { 2, 6, "c0_tcschedule" },
311 { 2, 7, "c0_tcschefback" },
312 { 5, 1, "c0_pagegrain" },
313 { 6, 1, "c0_srsconf0" },
314 { 6, 2, "c0_srsconf1" },
315 { 6, 3, "c0_srsconf2" },
316 { 6, 4, "c0_srsconf3" },
317 { 6, 5, "c0_srsconf4" },
318 { 12, 1, "c0_intctl" },
319 { 12, 2, "c0_srsctl" },
320 { 12, 3, "c0_srsmap" },
321 { 15, 1, "c0_ebase" },
322 { 16, 1, "c0_config1" },
323 { 16, 2, "c0_config2" },
324 { 16, 3, "c0_config3" },
325 { 18, 1, "c0_watchlo,1" },
326 { 18, 2, "c0_watchlo,2" },
327 { 18, 3, "c0_watchlo,3" },
328 { 18, 4, "c0_watchlo,4" },
329 { 18, 5, "c0_watchlo,5" },
330 { 18, 6, "c0_watchlo,6" },
331 { 18, 7, "c0_watchlo,7" },
332 { 19, 1, "c0_watchhi,1" },
333 { 19, 2, "c0_watchhi,2" },
334 { 19, 3, "c0_watchhi,3" },
335 { 19, 4, "c0_watchhi,4" },
336 { 19, 5, "c0_watchhi,5" },
337 { 19, 6, "c0_watchhi,6" },
338 { 19, 7, "c0_watchhi,7" },
339 { 23, 1, "c0_tracecontrol" },
340 { 23, 2, "c0_tracecontrol2" },
341 { 23, 3, "c0_usertracedata" },
342 { 23, 4, "c0_tracebpc" },
343 { 25, 1, "c0_perfcnt,1" },
344 { 25, 2, "c0_perfcnt,2" },
345 { 25, 3, "c0_perfcnt,3" },
346 { 25, 4, "c0_perfcnt,4" },
347 { 25, 5, "c0_perfcnt,5" },
348 { 25, 6, "c0_perfcnt,6" },
349 { 25, 7, "c0_perfcnt,7" },
350 { 27, 1, "c0_cacheerr,1" },
351 { 27, 2, "c0_cacheerr,2" },
352 { 27, 3, "c0_cacheerr,3" },
353 { 28, 1, "c0_datalo" },
354 { 28, 2, "c0_taglo1" },
355 { 28, 3, "c0_datalo1" },
356 { 28, 4, "c0_taglo2" },
357 { 28, 5, "c0_datalo2" },
358 { 28, 6, "c0_taglo3" },
359 { 28, 7, "c0_datalo3" },
360 { 29, 1, "c0_datahi" },
361 { 29, 2, "c0_taghi1" },
362 { 29, 3, "c0_datahi1" },
363 { 29, 4, "c0_taghi2" },
364 { 29, 5, "c0_datahi2" },
365 { 29, 6, "c0_taghi3" },
366 { 29, 7, "c0_datahi3" },
369 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
370 static const char * const mips_cp0_names_sb1
[32] =
372 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
373 "c0_context", "c0_pagemask", "c0_wired", "$7",
374 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
375 "c0_status", "c0_cause", "c0_epc", "c0_prid",
376 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
377 "c0_xcontext", "$21", "$22", "c0_debug",
378 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
379 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
382 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] =
384 { 16, 1, "c0_config1" },
385 { 18, 1, "c0_watchlo,1" },
386 { 19, 1, "c0_watchhi,1" },
387 { 22, 0, "c0_perftrace" },
388 { 23, 3, "c0_edebug" },
389 { 25, 1, "c0_perfcnt,1" },
390 { 25, 2, "c0_perfcnt,2" },
391 { 25, 3, "c0_perfcnt,3" },
392 { 25, 4, "c0_perfcnt,4" },
393 { 25, 5, "c0_perfcnt,5" },
394 { 25, 6, "c0_perfcnt,6" },
395 { 25, 7, "c0_perfcnt,7" },
396 { 26, 1, "c0_buserr_pa" },
397 { 27, 1, "c0_cacheerr_d" },
398 { 27, 3, "c0_cacheerr_d_pa" },
399 { 28, 1, "c0_datalo_i" },
400 { 28, 2, "c0_taglo_d" },
401 { 28, 3, "c0_datalo_d" },
402 { 29, 1, "c0_datahi_i" },
403 { 29, 2, "c0_taghi_d" },
404 { 29, 3, "c0_datahi_d" },
407 /* Xlr cop0 register names. */
408 static const char * const mips_cp0_names_xlr
[32] = {
409 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
410 "c0_context", "c0_pagemask", "c0_wired", "$7",
411 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
412 "c0_status", "c0_cause", "c0_epc", "c0_prid",
413 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
414 "c0_xcontext", "$21", "$22", "c0_debug",
415 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
416 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
419 /* XLR's CP0 Select Registers. */
421 static const struct mips_cp0sel_name mips_cp0sel_names_xlr
[] = {
422 { 9, 6, "c0_extintreq" },
423 { 9, 7, "c0_extintmask" },
424 { 15, 1, "c0_ebase" },
425 { 16, 1, "c0_config1" },
426 { 16, 2, "c0_config2" },
427 { 16, 3, "c0_config3" },
428 { 16, 7, "c0_procid2" },
429 { 18, 1, "c0_watchlo,1" },
430 { 18, 2, "c0_watchlo,2" },
431 { 18, 3, "c0_watchlo,3" },
432 { 18, 4, "c0_watchlo,4" },
433 { 18, 5, "c0_watchlo,5" },
434 { 18, 6, "c0_watchlo,6" },
435 { 18, 7, "c0_watchlo,7" },
436 { 19, 1, "c0_watchhi,1" },
437 { 19, 2, "c0_watchhi,2" },
438 { 19, 3, "c0_watchhi,3" },
439 { 19, 4, "c0_watchhi,4" },
440 { 19, 5, "c0_watchhi,5" },
441 { 19, 6, "c0_watchhi,6" },
442 { 19, 7, "c0_watchhi,7" },
443 { 25, 1, "c0_perfcnt,1" },
444 { 25, 2, "c0_perfcnt,2" },
445 { 25, 3, "c0_perfcnt,3" },
446 { 25, 4, "c0_perfcnt,4" },
447 { 25, 5, "c0_perfcnt,5" },
448 { 25, 6, "c0_perfcnt,6" },
449 { 25, 7, "c0_perfcnt,7" },
450 { 27, 1, "c0_cacheerr,1" },
451 { 27, 2, "c0_cacheerr,2" },
452 { 27, 3, "c0_cacheerr,3" },
453 { 28, 1, "c0_datalo" },
454 { 29, 1, "c0_datahi" }
457 static const char * const mips_hwr_names_numeric
[32] =
459 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
460 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
461 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
462 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
465 static const char * const mips_hwr_names_mips3264r2
[32] =
467 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
468 "$4", "$5", "$6", "$7",
469 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
470 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
471 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
474 struct mips_abi_choice
477 const char * const *gpr_names
;
478 const char * const *fpr_names
;
481 struct mips_abi_choice mips_abi_choices
[] =
483 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
484 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
485 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
486 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
489 struct mips_arch_choice
493 unsigned long bfd_mach
;
496 const char * const *cp0_names
;
497 const struct mips_cp0sel_name
*cp0sel_names
;
498 unsigned int cp0sel_names_len
;
499 const char * const *hwr_names
;
502 const struct mips_arch_choice mips_arch_choices
[] =
504 { "numeric", 0, 0, 0, 0,
505 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
507 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
,
508 mips_cp0_names_r3000
, NULL
, 0, mips_hwr_names_numeric
},
509 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
,
510 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
511 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
,
512 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
513 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
,
514 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
515 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
,
516 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
517 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
,
518 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
519 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
,
520 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
521 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
,
522 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
523 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
,
524 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
525 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
,
526 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
527 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
,
528 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
529 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
,
530 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
531 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
,
532 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
533 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
,
534 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
535 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
,
536 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
537 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
,
538 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
539 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
,
540 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
541 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
,
542 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
543 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
,
544 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
545 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
,
546 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
547 { "r14000", 1, bfd_mach_mips14000
, CPU_R14000
, ISA_MIPS4
,
548 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
549 { "r16000", 1, bfd_mach_mips16000
, CPU_R16000
, ISA_MIPS4
,
550 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
551 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
,
552 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
554 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
555 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
556 _MIPS32 Architecture For Programmers Volume I: Introduction to the
557 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
559 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
560 ISA_MIPS32
| INSN_SMARTMIPS
,
561 mips_cp0_names_mips3264
,
562 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
563 mips_hwr_names_numeric
},
565 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
566 (ISA_MIPS32R2
| INSN_SMARTMIPS
| INSN_DSP
| INSN_DSPR2
567 | INSN_MIPS3D
| INSN_MT
| INSN_MCU
),
568 mips_cp0_names_mips3264r2
,
569 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
570 mips_hwr_names_mips3264r2
},
572 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
573 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
574 ISA_MIPS64
| INSN_MIPS3D
| INSN_MDMX
,
575 mips_cp0_names_mips3264
,
576 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
577 mips_hwr_names_numeric
},
579 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
580 (ISA_MIPS64R2
| INSN_MIPS3D
| INSN_DSP
| INSN_DSPR2
581 | INSN_DSP64
| INSN_MT
| INSN_MDMX
| INSN_MCU
),
582 mips_cp0_names_mips3264r2
,
583 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
584 mips_hwr_names_mips3264r2
},
586 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
587 ISA_MIPS64
| INSN_MIPS3D
| INSN_SB1
,
589 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
590 mips_hwr_names_numeric
},
592 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
593 ISA_MIPS3
| INSN_LOONGSON_2E
, mips_cp0_names_numeric
,
594 NULL
, 0, mips_hwr_names_numeric
},
596 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
597 ISA_MIPS3
| INSN_LOONGSON_2F
, mips_cp0_names_numeric
,
598 NULL
, 0, mips_hwr_names_numeric
},
600 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
601 ISA_MIPS64
| INSN_LOONGSON_3A
, mips_cp0_names_numeric
,
602 NULL
, 0, mips_hwr_names_numeric
},
604 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
605 ISA_MIPS64R2
| INSN_OCTEON
, mips_cp0_names_numeric
, NULL
, 0,
606 mips_hwr_names_numeric
},
608 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
609 ISA_MIPS64R2
| INSN_OCTEONP
, mips_cp0_names_numeric
,
610 NULL
, 0, mips_hwr_names_numeric
},
612 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
613 ISA_MIPS64R2
| INSN_OCTEON2
, mips_cp0_names_numeric
,
614 NULL
, 0, mips_hwr_names_numeric
},
616 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
617 ISA_MIPS64
| INSN_XLR
,
619 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
620 mips_hwr_names_numeric
},
622 /* XLP is mostly like XLR, with the prominent exception it is being
624 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
625 ISA_MIPS64R2
| INSN_XLR
,
627 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
628 mips_hwr_names_numeric
},
630 /* This entry, mips16, is here only for ISA/processor selection; do
631 not print its name. */
632 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
,
633 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
636 /* ISA and processor type to disassemble for, and register names to use.
637 set_default_mips_dis_options and parse_mips_dis_options fill in these
639 static int mips_processor
;
641 static int micromips_ase
;
642 static const char * const *mips_gpr_names
;
643 static const char * const *mips_fpr_names
;
644 static const char * const *mips_cp0_names
;
645 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
646 static int mips_cp0sel_names_len
;
647 static const char * const *mips_hwr_names
;
650 static int no_aliases
; /* If set disassemble as most general inst. */
652 static const struct mips_abi_choice
*
653 choose_abi_by_name (const char *name
, unsigned int namelen
)
655 const struct mips_abi_choice
*c
;
658 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
659 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
660 && strlen (mips_abi_choices
[i
].name
) == namelen
)
661 c
= &mips_abi_choices
[i
];
666 static const struct mips_arch_choice
*
667 choose_arch_by_name (const char *name
, unsigned int namelen
)
669 const struct mips_arch_choice
*c
= NULL
;
672 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
673 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
674 && strlen (mips_arch_choices
[i
].name
) == namelen
)
675 c
= &mips_arch_choices
[i
];
680 static const struct mips_arch_choice
*
681 choose_arch_by_number (unsigned long mach
)
683 static unsigned long hint_bfd_mach
;
684 static const struct mips_arch_choice
*hint_arch_choice
;
685 const struct mips_arch_choice
*c
;
688 /* We optimize this because even if the user specifies no
689 flags, this will be done for every instruction! */
690 if (hint_bfd_mach
== mach
691 && hint_arch_choice
!= NULL
692 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
693 return hint_arch_choice
;
695 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
697 if (mips_arch_choices
[i
].bfd_mach_valid
698 && mips_arch_choices
[i
].bfd_mach
== mach
)
700 c
= &mips_arch_choices
[i
];
701 hint_bfd_mach
= mach
;
702 hint_arch_choice
= c
;
708 /* Check if the object uses NewABI conventions. */
711 is_newabi (Elf_Internal_Ehdr
*header
)
713 /* There are no old-style ABIs which use 64-bit ELF. */
714 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
717 /* If a 32-bit ELF file, n32 is a new-style ABI. */
718 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
724 /* Check if the object has microMIPS ASE code. */
727 is_micromips (Elf_Internal_Ehdr
*header
)
729 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
736 set_default_mips_dis_options (struct disassemble_info
*info
)
738 const struct mips_arch_choice
*chosen_arch
;
740 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
741 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
742 CP0 register, and HWR names. */
743 mips_isa
= ISA_MIPS3
;
744 mips_processor
= CPU_R3000
;
746 mips_gpr_names
= mips_gpr_names_oldabi
;
747 mips_fpr_names
= mips_fpr_names_numeric
;
748 mips_cp0_names
= mips_cp0_names_numeric
;
749 mips_cp0sel_names
= NULL
;
750 mips_cp0sel_names_len
= 0;
751 mips_hwr_names
= mips_hwr_names_numeric
;
754 /* Update settings according to the ELF file header flags. */
755 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
757 Elf_Internal_Ehdr
*header
;
759 header
= elf_elfheader (info
->section
->owner
);
760 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
761 if (is_newabi (header
))
762 mips_gpr_names
= mips_gpr_names_newabi
;
763 /* If a microMIPS binary, then don't use MIPS16 bindings. */
764 micromips_ase
= is_micromips (header
);
767 /* Set ISA, architecture, and cp0 register names as best we can. */
768 #if ! SYMTAB_AVAILABLE
769 /* This is running out on a target machine, not in a host tool.
770 FIXME: Where does mips_target_info come from? */
771 target_processor
= mips_target_info
.processor
;
772 mips_isa
= mips_target_info
.isa
;
774 chosen_arch
= choose_arch_by_number (info
->mach
);
775 if (chosen_arch
!= NULL
)
777 mips_processor
= chosen_arch
->processor
;
778 mips_isa
= chosen_arch
->isa
;
779 mips_cp0_names
= chosen_arch
->cp0_names
;
780 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
781 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
782 mips_hwr_names
= chosen_arch
->hwr_names
;
788 parse_mips_dis_option (const char *option
, unsigned int len
)
790 unsigned int i
, optionlen
, vallen
;
792 const struct mips_abi_choice
*chosen_abi
;
793 const struct mips_arch_choice
*chosen_arch
;
795 /* Try to match options that are simple flags */
796 if (CONST_STRNEQ (option
, "no-aliases"))
802 /* Look for the = that delimits the end of the option name. */
803 for (i
= 0; i
< len
; i
++)
804 if (option
[i
] == '=')
807 if (i
== 0) /* Invalid option: no name before '='. */
809 if (i
== len
) /* Invalid option: no '='. */
811 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
815 val
= option
+ (optionlen
+ 1);
816 vallen
= len
- (optionlen
+ 1);
818 if (strncmp ("gpr-names", option
, optionlen
) == 0
819 && strlen ("gpr-names") == optionlen
)
821 chosen_abi
= choose_abi_by_name (val
, vallen
);
822 if (chosen_abi
!= NULL
)
823 mips_gpr_names
= chosen_abi
->gpr_names
;
827 if (strncmp ("fpr-names", option
, optionlen
) == 0
828 && strlen ("fpr-names") == optionlen
)
830 chosen_abi
= choose_abi_by_name (val
, vallen
);
831 if (chosen_abi
!= NULL
)
832 mips_fpr_names
= chosen_abi
->fpr_names
;
836 if (strncmp ("cp0-names", option
, optionlen
) == 0
837 && strlen ("cp0-names") == optionlen
)
839 chosen_arch
= choose_arch_by_name (val
, vallen
);
840 if (chosen_arch
!= NULL
)
842 mips_cp0_names
= chosen_arch
->cp0_names
;
843 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
844 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
849 if (strncmp ("hwr-names", option
, optionlen
) == 0
850 && strlen ("hwr-names") == optionlen
)
852 chosen_arch
= choose_arch_by_name (val
, vallen
);
853 if (chosen_arch
!= NULL
)
854 mips_hwr_names
= chosen_arch
->hwr_names
;
858 if (strncmp ("reg-names", option
, optionlen
) == 0
859 && strlen ("reg-names") == optionlen
)
861 /* We check both ABI and ARCH here unconditionally, so
862 that "numeric" will do the desirable thing: select
863 numeric register names for all registers. Other than
864 that, a given name probably won't match both. */
865 chosen_abi
= choose_abi_by_name (val
, vallen
);
866 if (chosen_abi
!= NULL
)
868 mips_gpr_names
= chosen_abi
->gpr_names
;
869 mips_fpr_names
= chosen_abi
->fpr_names
;
871 chosen_arch
= choose_arch_by_name (val
, vallen
);
872 if (chosen_arch
!= NULL
)
874 mips_cp0_names
= chosen_arch
->cp0_names
;
875 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
876 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
877 mips_hwr_names
= chosen_arch
->hwr_names
;
882 /* Invalid option. */
886 parse_mips_dis_options (const char *options
)
888 const char *option_end
;
893 while (*options
!= '\0')
895 /* Skip empty options. */
902 /* We know that *options is neither NUL or a comma. */
903 option_end
= options
+ 1;
904 while (*option_end
!= ',' && *option_end
!= '\0')
907 parse_mips_dis_option (options
, option_end
- options
);
909 /* Go on to the next one. If option_end points to a comma, it
910 will be skipped above. */
911 options
= option_end
;
915 static const struct mips_cp0sel_name
*
916 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
923 for (i
= 0; i
< len
; i
++)
924 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
929 /* Print insn arguments for 32/64-bit code. */
932 print_insn_args (const char *d
,
935 struct disassemble_info
*info
,
936 const struct mips_opcode
*opp
)
938 const fprintf_ftype infprintf
= info
->fprintf_func
;
939 unsigned int lsb
, msb
, msbd
;
940 void *is
= info
->stream
;
945 #define GET_OP(insn, field) \
946 (((insn) >> OP_SH_##field) & OP_MASK_##field)
947 #define GET_OP_S(insn, field) \
948 ((GET_OP (insn, field) ^ ((OP_MASK_##field >> 1) + 1)) \
949 - ((OP_MASK_##field >> 1) + 1))
950 for (; *d
!= '\0'; d
++)
959 infprintf (is
, "%c", *d
);
963 /* Extension character; switch for second char. */
968 /* xgettext:c-format */
970 _("# internal error, "
971 "incomplete extension sequence (+)"));
975 lsb
= GET_OP (l
, SHAMT
);
976 infprintf (is
, "0x%x", lsb
);
980 msb
= GET_OP (l
, INSMSB
);
981 infprintf (is
, "0x%x", msb
- lsb
+ 1);
985 infprintf (is
, "0x%x", GET_OP (l
, UDI1
));
989 infprintf (is
, "0x%x", GET_OP (l
, UDI2
));
993 infprintf (is
, "0x%x", GET_OP (l
, UDI3
));
997 infprintf (is
, "0x%x", GET_OP (l
, UDI4
));
1002 msbd
= GET_OP (l
, EXTMSBD
);
1003 infprintf (is
, "0x%x", msbd
+ 1);
1008 const struct mips_cp0sel_name
*n
;
1009 unsigned int cp0reg
, sel
;
1011 cp0reg
= GET_OP (l
, RD
);
1012 sel
= GET_OP (l
, SEL
);
1014 /* CP0 register including 'sel' code for mtcN (et al.), to be
1015 printed textually if known. If not known, print both
1016 CP0 register name and sel numerically since CP0 register
1017 with sel 0 may have a name unrelated to register being
1019 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
1020 mips_cp0sel_names_len
, cp0reg
, sel
);
1022 infprintf (is
, "%s", n
->name
);
1024 infprintf (is
, "$%d,%d", cp0reg
, sel
);
1029 lsb
= GET_OP (l
, SHAMT
) + 32;
1030 infprintf (is
, "0x%x", lsb
);
1034 msb
= GET_OP (l
, INSMSB
) + 32;
1035 infprintf (is
, "0x%x", msb
- lsb
+ 1);
1039 msbd
= GET_OP (l
, EXTMSBD
) + 32;
1040 infprintf (is
, "0x%x", msbd
+ 1);
1043 case 't': /* Coprocessor 0 reg name */
1044 infprintf (is
, "%s", mips_cp0_names
[GET_OP (l
, RT
)]);
1047 case 'T': /* Coprocessor 0 reg name */
1049 const struct mips_cp0sel_name
*n
;
1050 unsigned int cp0reg
, sel
;
1052 cp0reg
= GET_OP (l
, RT
);
1053 sel
= GET_OP (l
, SEL
);
1055 /* CP0 register including 'sel' code for mftc0, to be
1056 printed textually if known. If not known, print both
1057 CP0 register name and sel numerically since CP0 register
1058 with sel 0 may have a name unrelated to register being
1060 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
1061 mips_cp0sel_names_len
, cp0reg
, sel
);
1063 infprintf (is
, "%s", n
->name
);
1065 infprintf (is
, "$%d,%d", cp0reg
, sel
);
1069 case 'x': /* bbit bit index */
1070 infprintf (is
, "0x%x", GET_OP (l
, BBITIND
));
1073 case 'p': /* cins, cins32, exts and exts32 position */
1074 infprintf (is
, "0x%x", GET_OP (l
, CINSPOS
));
1077 case 's': /* cins and exts length-minus-one */
1078 infprintf (is
, "0x%x", GET_OP (l
, CINSLM1
));
1081 case 'S': /* cins32 and exts32 length-minus-one field */
1082 infprintf (is
, "0x%x", GET_OP (l
, CINSLM1
));
1085 case 'Q': /* seqi/snei immediate field */
1086 infprintf (is
, "%d", GET_OP_S (l
, SEQI
));
1089 case 'a': /* 8-bit signed offset in bit 6 */
1090 infprintf (is
, "%d", GET_OP_S (l
, OFFSET_A
));
1093 case 'b': /* 8-bit signed offset in bit 3 */
1094 infprintf (is
, "%d", GET_OP_S (l
, OFFSET_B
));
1097 case 'c': /* 9-bit signed offset in bit 6 */
1098 /* Left shift 4 bits to print the real offset. */
1099 infprintf (is
, "%d", GET_OP_S (l
, OFFSET_C
) << 4);
1103 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RZ
)]);
1107 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FZ
)]);
1111 /* xgettext:c-format */
1113 _("# internal error, "
1114 "undefined extension sequence (+%c)"),
1121 infprintf (is
, "0x%x", GET_OP (l
, BP
));
1125 infprintf (is
, "0x%x", GET_OP (l
, SA3
));
1129 infprintf (is
, "0x%x", GET_OP (l
, SA4
));
1133 infprintf (is
, "0x%x", GET_OP (l
, IMM8
));
1137 infprintf (is
, "0x%x", GET_OP (l
, RS
));
1141 infprintf (is
, "$ac%d", GET_OP (l
, DSPACC
));
1145 infprintf (is
, "0x%x", GET_OP (l
, WRDSP
));
1149 infprintf (is
, "$ac%d", GET_OP (l
, DSPACC_S
));
1152 case '0': /* dsp 6-bit signed immediate in bit 20 */
1153 infprintf (is
, "%d", GET_OP_S (l
, DSPSFT
));
1156 case ':': /* dsp 7-bit signed immediate in bit 19 */
1157 infprintf (is
, "%d", GET_OP_S (l
, DSPSFT_7
));
1161 infprintf (is
, "%d", GET_OP_S (l
, OFFSET12
));
1165 infprintf (is
, "0x%x", GET_OP (l
, 3BITPOS
));
1169 infprintf (is
, "0x%x", GET_OP (l
, RDDSP
));
1172 case '@': /* dsp 10-bit signed immediate in bit 16 */
1173 infprintf (is
, "%d", GET_OP_S (l
, IMM10
));
1177 infprintf (is
, "%d", GET_OP (l
, MT_U
));
1181 infprintf (is
, "%d", GET_OP (l
, MT_H
));
1185 infprintf (is
, "$ac%d", GET_OP (l
, MTACC_T
));
1189 infprintf (is
, "$ac%d", GET_OP (l
, MTACC_D
));
1193 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
1194 infprintf (is
, "$%d", GET_OP (l
, RD
));
1201 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RS
)]);
1206 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RT
)]);
1211 infprintf (is
, "0x%x", GET_OP (l
, IMMEDIATE
));
1214 case 'j': /* Same as i, but sign-extended. */
1216 infprintf (is
, "%d", GET_OP_S (l
, DELTA
));
1220 infprintf (is
, "0x%x", GET_OP (l
, PREFX
));
1224 infprintf (is
, "0x%x", GET_OP (l
, CACHE
));
1228 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
1229 | (GET_OP (l
, TARGET
) << 2));
1230 /* For gdb disassembler, force odd address on jalx. */
1231 if (info
->flavour
== bfd_target_unknown_flavour
1232 && strcmp (opp
->name
, "jalx") == 0)
1234 (*info
->print_address_func
) (info
->target
, info
);
1238 /* Sign extend the displacement. */
1239 info
->target
= (GET_OP_S (l
, DELTA
) << 2) + pc
+ INSNLEN
;
1240 (*info
->print_address_func
) (info
->target
, info
);
1244 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RD
)]);
1249 /* First check for both rd and rt being equal. */
1250 unsigned int reg
= GET_OP (l
, RD
);
1251 if (reg
== GET_OP (l
, RT
))
1252 infprintf (is
, "%s", mips_gpr_names
[reg
]);
1255 /* If one is zero use the other. */
1257 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RT
)]);
1258 else if (GET_OP (l
, RT
) == 0)
1259 infprintf (is
, "%s", mips_gpr_names
[reg
]);
1260 else /* Bogus, result depends on processor. */
1261 infprintf (is
, "%s or %s",
1262 mips_gpr_names
[reg
],
1263 mips_gpr_names
[GET_OP (l
, RT
)]);
1269 infprintf (is
, "%s", mips_gpr_names
[0]);
1274 infprintf (is
, "0x%x", GET_OP (l
, SHAMT
));
1278 infprintf (is
, "0x%x", GET_OP (l
, CODE
));
1282 infprintf (is
, "0x%x", GET_OP (l
, CODE2
));
1286 infprintf (is
, "0x%x", GET_OP (l
, COPZ
));
1290 infprintf (is
, "0x%x", GET_OP (l
, CODE20
));
1294 infprintf (is
, "0x%x", GET_OP (l
, CODE19
));
1299 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FS
)]);
1304 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FT
)]);
1308 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FD
)]);
1312 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FR
)]);
1316 /* Coprocessor register for lwcN instructions, et al.
1318 Note that there is no load/store cp0 instructions, and
1319 that FPU (cp1) instructions disassemble this field using
1320 'T' format. Therefore, until we gain understanding of
1321 cp2 register names, we can simply print the register
1323 infprintf (is
, "$%d", GET_OP (l
, RT
));
1327 /* Coprocessor register for mtcN instructions, et al. Note
1328 that FPU (cp1) instructions disassemble this field using
1329 'S' format. Therefore, we only need to worry about cp0,
1331 op
= GET_OP (l
, OP
);
1332 if (op
== OP_OP_COP0
)
1333 infprintf (is
, "%s", mips_cp0_names
[GET_OP (l
, RD
)]);
1335 infprintf (is
, "$%d", GET_OP (l
, RD
));
1339 infprintf (is
, "%s", mips_hwr_names
[GET_OP (l
, RD
)]);
1344 (opp
->pinfo
& (FP_D
| FP_S
)) != 0 ? "$fcc%d" : "$cc%d",
1349 infprintf (is
, "$fcc%d", GET_OP (l
, CCC
));
1353 infprintf (is
, "%d", GET_OP (l
, PERFREG
));
1357 infprintf (is
, "%d", GET_OP (l
, VECBYTE
));
1361 infprintf (is
, "%d", GET_OP (l
, VECALIGN
));
1365 infprintf (is
, "%d", GET_OP (l
, SEL
));
1369 infprintf (is
, "%d", GET_OP (l
, ALN
));
1374 unsigned int vsel
= GET_OP (l
, VSEL
);
1376 if ((vsel
& 0x10) == 0)
1381 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1382 if ((vsel
& 1) == 0)
1384 infprintf (is
, "$v%d[%d]", GET_OP (l
, FT
), vsel
>> 1);
1386 else if ((vsel
& 0x08) == 0)
1388 infprintf (is
, "$v%d", GET_OP (l
, FT
));
1392 infprintf (is
, "0x%x", GET_OP (l
, FT
));
1398 infprintf (is
, "$v%d", GET_OP (l
, FD
));
1402 infprintf (is
, "$v%d", GET_OP (l
, FS
));
1406 infprintf (is
, "$v%d", GET_OP (l
, FT
));
1410 /* xgettext:c-format */
1411 infprintf (is
, _("# internal error, undefined modifier (%c)"), *d
);
1417 /* Print the mips instruction at address MEMADDR in debugged memory,
1418 on using INFO. Returns length of the instruction, in bytes, which is
1419 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1420 this is little-endian code. */
1423 print_insn_mips (bfd_vma memaddr
,
1425 struct disassemble_info
*info
)
1427 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1428 const fprintf_ftype infprintf
= info
->fprintf_func
;
1429 const struct mips_opcode
*op
;
1430 static bfd_boolean init
= 0;
1431 void *is
= info
->stream
;
1433 /* Build a hash table to shorten the search time. */
1438 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1440 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1442 if (op
->pinfo
== INSN_MACRO
1443 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1445 if (i
== GET_OP (op
->match
, OP
))
1456 info
->bytes_per_chunk
= INSNLEN
;
1457 info
->display_endian
= info
->endian
;
1458 info
->insn_info_valid
= 1;
1459 info
->branch_delay_insns
= 0;
1460 info
->data_size
= 0;
1461 info
->insn_type
= dis_nonbranch
;
1465 op
= mips_hash
[GET_OP (word
, OP
)];
1468 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1470 if (op
->pinfo
!= INSN_MACRO
1471 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1472 && (word
& op
->mask
) == op
->match
)
1476 /* We always allow to disassemble the jalx instruction. */
1477 if (!opcode_is_member (op
, mips_isa
, mips_processor
)
1478 && strcmp (op
->name
, "jalx"))
1481 /* Figure out instruction type and branch delay information. */
1482 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1484 if ((op
->pinfo
& (INSN_WRITE_GPR_31
1485 | INSN_WRITE_GPR_D
)) != 0)
1486 info
->insn_type
= dis_jsr
;
1488 info
->insn_type
= dis_branch
;
1489 info
->branch_delay_insns
= 1;
1491 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1492 | INSN_COND_BRANCH_LIKELY
)) != 0)
1494 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1495 info
->insn_type
= dis_condjsr
;
1497 info
->insn_type
= dis_condbranch
;
1498 info
->branch_delay_insns
= 1;
1500 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1501 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1502 info
->insn_type
= dis_dref
;
1504 infprintf (is
, "%s", op
->name
);
1507 if (d
!= NULL
&& *d
!= '\0')
1509 infprintf (is
, "\t");
1510 print_insn_args (d
, word
, memaddr
, info
, op
);
1520 /* Handle undefined instructions. */
1521 info
->insn_type
= dis_noninsn
;
1522 infprintf (is
, "0x%x", word
);
1526 /* Disassemble an operand for a mips16 instruction. */
1529 print_mips16_insn_arg (char type
,
1530 const struct mips_opcode
*op
,
1532 bfd_boolean use_extend
,
1535 struct disassemble_info
*info
)
1537 const fprintf_ftype infprintf
= info
->fprintf_func
;
1538 void *is
= info
->stream
;
1540 #define GET_OP(insn, field) \
1541 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1542 #define GET_OP_S(insn, field) \
1543 ((GET_OP (insn, field) ^ ((MIPS16OP_MASK_##field >> 1) + 1)) \
1544 - ((MIPS16OP_MASK_##field >> 1) + 1))
1550 infprintf (is
, "%c", type
);
1555 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RY
)));
1560 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RX
)));
1564 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RZ
)));
1568 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, MOVE32Z
)));
1572 infprintf (is
, "%s", mips_gpr_names
[0]);
1576 infprintf (is
, "%s", mips_gpr_names
[29]);
1580 infprintf (is
, "$pc");
1584 infprintf (is
, "%s", mips_gpr_names
[31]);
1588 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, REGR32
)]);
1592 infprintf (is
, "%s", mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1618 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1630 immed
= GET_OP (l
, RZ
);
1636 immed
= GET_OP (l
, RX
);
1642 immed
= GET_OP (l
, RZ
);
1648 immed
= GET_OP (l
, RX
);
1654 immed
= GET_OP (l
, IMM4
);
1660 immed
= GET_OP (l
, IMM5
);
1661 info
->insn_type
= dis_dref
;
1662 info
->data_size
= 1;
1667 immed
= GET_OP (l
, IMM5
);
1668 info
->insn_type
= dis_dref
;
1669 info
->data_size
= 2;
1674 immed
= GET_OP (l
, IMM5
);
1675 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1676 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1678 info
->insn_type
= dis_dref
;
1679 info
->data_size
= 4;
1685 immed
= GET_OP (l
, IMM5
);
1686 info
->insn_type
= dis_dref
;
1687 info
->data_size
= 8;
1691 immed
= GET_OP (l
, IMM5
);
1696 immed
= GET_OP (l
, IMM6
);
1700 immed
= GET_OP (l
, IMM8
);
1705 immed
= GET_OP (l
, IMM8
);
1706 /* FIXME: This might be lw, or it might be addiu to $sp or
1707 $pc. We assume it's load. */
1708 info
->insn_type
= dis_dref
;
1709 info
->data_size
= 4;
1714 immed
= GET_OP (l
, IMM8
);
1715 info
->insn_type
= dis_dref
;
1716 info
->data_size
= 8;
1720 immed
= GET_OP (l
, IMM8
);
1725 immed
= GET_OP (l
, IMM8
);
1731 immed
= GET_OP (l
, IMM8
);
1736 immed
= GET_OP (l
, IMM8
);
1743 immed
= GET_OP (l
, IMM11
);
1751 immed
= GET_OP (l
, IMM8
);
1753 /* FIXME: This can be lw or la. We assume it is lw. */
1754 info
->insn_type
= dis_dref
;
1755 info
->data_size
= 4;
1760 immed
= GET_OP (l
, IMM5
);
1762 info
->insn_type
= dis_dref
;
1763 info
->data_size
= 8;
1768 immed
= GET_OP (l
, IMM5
);
1777 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1778 immed
-= 1 << nbits
;
1780 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1787 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1788 else if (extbits
== 15)
1789 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1791 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1792 immed
&= (1 << extbits
) - 1;
1793 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1794 immed
-= 1 << extbits
;
1798 infprintf (is
, "%d", immed
);
1806 baseaddr
= memaddr
+ 2;
1808 else if (use_extend
)
1809 baseaddr
= memaddr
- 2;
1817 /* If this instruction is in the delay slot of a jr
1818 instruction, the base address is the address of the
1819 jr instruction. If it is in the delay slot of jalr
1820 instruction, the base address is the address of the
1821 jalr instruction. This test is unreliable: we have
1822 no way of knowing whether the previous word is
1823 instruction or data. */
1824 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1827 && (((info
->endian
== BFD_ENDIAN_BIG
1828 ? bfd_getb16 (buffer
)
1829 : bfd_getl16 (buffer
))
1830 & 0xf800) == 0x1800))
1831 baseaddr
= memaddr
- 4;
1834 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1837 && (((info
->endian
== BFD_ENDIAN_BIG
1838 ? bfd_getb16 (buffer
)
1839 : bfd_getl16 (buffer
))
1840 & 0xf81f) == 0xe800))
1841 baseaddr
= memaddr
- 2;
1844 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1846 && info
->flavour
== bfd_target_unknown_flavour
)
1847 /* For gdb disassembler, maintain odd address. */
1849 (*info
->print_address_func
) (info
->target
, info
);
1856 int jalx
= l
& 0x400;
1860 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1861 if (!jalx
&& info
->flavour
== bfd_target_unknown_flavour
)
1862 /* For gdb disassembler, maintain odd address. */
1865 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1866 (*info
->print_address_func
) (info
->target
, info
);
1872 int need_comma
, amask
, smask
;
1876 l
= GET_OP (l
, IMM6
);
1878 amask
= (l
>> 3) & 7;
1880 if (amask
> 0 && amask
< 5)
1882 infprintf (is
, "%s", mips_gpr_names
[4]);
1884 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1888 smask
= (l
>> 1) & 3;
1891 infprintf (is
, "%s??", need_comma
? "," : "");
1896 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[16]);
1898 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1904 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[31]);
1908 if (amask
== 5 || amask
== 6)
1910 infprintf (is
, "%s$f0", need_comma
? "," : "");
1912 infprintf (is
, "-$f1");
1919 /* MIPS16e save/restore. */
1922 int amask
, args
, statics
;
1931 amask
= (l
>> 16) & 0xf;
1932 if (amask
== MIPS16_ALL_ARGS
)
1937 else if (amask
== MIPS16_ALL_STATICS
)
1945 statics
= amask
& 3;
1949 infprintf (is
, "%s", mips_gpr_names
[4]);
1951 infprintf (is
, "-%s", mips_gpr_names
[4 + args
- 1]);
1955 framesz
= (((l
>> 16) & 0xf0) | (l
& 0x0f)) * 8;
1956 if (framesz
== 0 && !use_extend
)
1959 infprintf (is
, "%s%d", need_comma
? "," : "", framesz
);
1961 if (l
& 0x40) /* $ra */
1962 infprintf (is
, ",%s", mips_gpr_names
[31]);
1964 nsreg
= (l
>> 24) & 0x7;
1966 if (l
& 0x20) /* $s0 */
1968 if (l
& 0x10) /* $s1 */
1970 if (nsreg
> 0) /* $s2-$s8 */
1971 smask
|= ((1 << nsreg
) - 1) << 2;
1973 /* Find first set static reg bit. */
1974 for (i
= 0; i
< 9; i
++)
1976 if (smask
& (1 << i
))
1978 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1979 /* Skip over string of set bits. */
1980 for (j
= i
; smask
& (2 << j
); j
++)
1983 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1988 /* Statics $ax - $a3. */
1990 infprintf (is
, ",%s", mips_gpr_names
[7]);
1991 else if (statics
> 0)
1992 infprintf (is
, ",%s-%s",
1993 mips_gpr_names
[7 - statics
+ 1],
1999 /* xgettext:c-format */
2001 _("# internal disassembler error, "
2002 "unrecognised modifier (%c)"),
2008 /* Disassemble mips16 instructions. */
2011 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2013 const fprintf_ftype infprintf
= info
->fprintf_func
;
2018 bfd_boolean use_extend
;
2020 const struct mips_opcode
*op
, *opend
;
2021 void *is
= info
->stream
;
2023 info
->bytes_per_chunk
= 2;
2024 info
->display_endian
= info
->endian
;
2025 info
->insn_info_valid
= 1;
2026 info
->branch_delay_insns
= 0;
2027 info
->data_size
= 0;
2028 info
->insn_type
= dis_nonbranch
;
2032 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2035 (*info
->memory_error_func
) (status
, memaddr
, info
);
2041 if (info
->endian
== BFD_ENDIAN_BIG
)
2042 insn
= bfd_getb16 (buffer
);
2044 insn
= bfd_getl16 (buffer
);
2046 /* Handle the extend opcode specially. */
2048 if ((insn
& 0xf800) == 0xf000)
2051 extend
= insn
& 0x7ff;
2055 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2058 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2059 (*info
->memory_error_func
) (status
, memaddr
, info
);
2063 if (info
->endian
== BFD_ENDIAN_BIG
)
2064 insn
= bfd_getb16 (buffer
);
2066 insn
= bfd_getl16 (buffer
);
2068 /* Check for an extend opcode followed by an extend opcode. */
2069 if ((insn
& 0xf800) == 0xf000)
2071 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2072 info
->insn_type
= dis_noninsn
;
2079 /* FIXME: Should probably use a hash table on the major opcode here. */
2081 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2082 for (op
= mips16_opcodes
; op
< opend
; op
++)
2084 if (op
->pinfo
!= INSN_MACRO
2085 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2086 && (insn
& op
->mask
) == op
->match
)
2090 if (strchr (op
->args
, 'a') != NULL
)
2094 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2095 info
->insn_type
= dis_noninsn
;
2103 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2108 if (info
->endian
== BFD_ENDIAN_BIG
)
2109 extend
= bfd_getb16 (buffer
);
2111 extend
= bfd_getl16 (buffer
);
2116 infprintf (is
, "%s", op
->name
);
2117 if (op
->args
[0] != '\0')
2118 infprintf (is
, "\t");
2120 for (s
= op
->args
; *s
!= '\0'; s
++)
2124 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
2126 /* Skip the register and the comma. */
2132 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
2134 /* Skip the register and the comma. */
2138 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
2142 /* Figure out branch instruction type and delay slot information. */
2143 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2144 info
->branch_delay_insns
= 1;
2145 if ((op
->pinfo
& (INSN_UNCOND_BRANCH_DELAY
2146 | MIPS16_INSN_UNCOND_BRANCH
)) != 0)
2148 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2149 info
->insn_type
= dis_jsr
;
2151 info
->insn_type
= dis_branch
;
2153 else if ((op
->pinfo
& MIPS16_INSN_COND_BRANCH
) != 0)
2154 info
->insn_type
= dis_condbranch
;
2163 infprintf (is
, "0x%x", extend
| 0xf000);
2164 infprintf (is
, "0x%x", insn
);
2165 info
->insn_type
= dis_noninsn
;
2170 /* Disassemble microMIPS instructions. */
2173 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2175 const fprintf_ftype infprintf
= info
->fprintf_func
;
2176 const struct mips_opcode
*op
, *opend
;
2177 unsigned int lsb
, msbd
, msb
;
2178 void *is
= info
->stream
;
2191 info
->bytes_per_chunk
= 2;
2192 info
->display_endian
= info
->endian
;
2193 info
->insn_info_valid
= 1;
2194 info
->branch_delay_insns
= 0;
2195 info
->data_size
= 0;
2196 info
->insn_type
= dis_nonbranch
;
2200 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2203 (*info
->memory_error_func
) (status
, memaddr
, info
);
2209 if (info
->endian
== BFD_ENDIAN_BIG
)
2210 insn
= bfd_getb16 (buffer
);
2212 insn
= bfd_getl16 (buffer
);
2214 if ((insn
& 0xfc00) == 0x7c00)
2216 /* This is a 48-bit microMIPS instruction. */
2219 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2222 infprintf (is
, "micromips 0x%x", higher
);
2223 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2226 if (info
->endian
== BFD_ENDIAN_BIG
)
2227 insn
= bfd_getb16 (buffer
);
2229 insn
= bfd_getl16 (buffer
);
2230 higher
= (higher
<< 16) | insn
;
2232 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
2235 infprintf (is
, "micromips 0x%x", higher
);
2236 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2239 if (info
->endian
== BFD_ENDIAN_BIG
)
2240 insn
= bfd_getb16 (buffer
);
2242 insn
= bfd_getl16 (buffer
);
2243 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2245 info
->insn_type
= dis_noninsn
;
2248 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2250 /* This is a 32-bit microMIPS instruction. */
2253 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2256 infprintf (is
, "micromips 0x%x", higher
);
2257 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2261 if (info
->endian
== BFD_ENDIAN_BIG
)
2262 insn
= bfd_getb16 (buffer
);
2264 insn
= bfd_getl16 (buffer
);
2266 insn
= insn
| (higher
<< 16);
2271 /* FIXME: Should probably use a hash table on the major opcode here. */
2273 #define GET_OP(insn, field) \
2274 (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2275 #define GET_OP_S(insn, field) \
2276 ((GET_OP (insn, field) ^ ((MICROMIPSOP_MASK_##field >> 1) + 1)) \
2277 - ((MICROMIPSOP_MASK_##field >> 1) + 1))
2278 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2279 for (op
= micromips_opcodes
; op
< opend
; op
++)
2281 if (op
->pinfo
!= INSN_MACRO
2282 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2283 && (insn
& op
->mask
) == op
->match
2284 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2285 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2289 infprintf (is
, "%s", op
->name
);
2290 if (op
->args
[0] != '\0')
2291 infprintf (is
, "\t");
2293 for (s
= op
->args
; *s
!= '\0'; s
++)
2300 infprintf (is
, "%c", *s
);
2304 infprintf (is
, "%d", GET_OP_S (insn
, OFFSET10
));
2308 infprintf (is
, "0x%x", GET_OP (insn
, STYPE
));
2312 infprintf (is
, "0x%x", GET_OP (insn
, BP
));
2316 infprintf (is
, "0x%x", GET_OP (insn
, SA3
));
2320 infprintf (is
, "0x%x", GET_OP (insn
, SA4
));
2324 infprintf (is
, "0x%x", GET_OP (insn
, IMM8
));
2328 infprintf (is
, "0x%x", GET_OP (insn
, RS
));
2332 infprintf (is
, "$ac%d", GET_OP (insn
, DSPACC
));
2336 infprintf (is
, "0x%x", GET_OP (insn
, WRDSP
));
2339 case '0': /* DSP 6-bit signed immediate in bit 16. */
2340 delta
= (GET_OP (insn
, DSPSFT
) ^ 0x20) - 0x20;
2341 infprintf (is
, "%d", delta
);
2345 infprintf (is
, "0x%x", GET_OP (insn
, SHAMT
));
2349 infprintf (is
, "0x%x", GET_OP (insn
, 3BITPOS
));
2353 infprintf (is
, "0x%x", GET_OP (insn
, RD
));
2357 infprintf (is
, "0x%x", GET_OP (insn
, TRAP
));
2361 infprintf (is
, "%d", GET_OP_S (insn
, OFFSET12
));
2365 if (strcmp (op
->name
, "jalx") == 0)
2366 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff)
2367 | (GET_OP (insn
, TARGET
) << 2));
2369 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x07ffffff)
2370 | (GET_OP (insn
, TARGET
) << 1));
2371 /* For gdb disassembler, force odd address on jalx. */
2372 if (info
->flavour
== bfd_target_unknown_flavour
2373 && strcmp (op
->name
, "jalx") == 0)
2375 (*info
->print_address_func
) (info
->target
, info
);
2382 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS
)]);
2386 infprintf (is
, "0x%x", GET_OP (insn
, CODE
));
2390 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RD
)]);
2394 infprintf (is
, "0x%x", GET_OP (insn
, PREFX
));
2399 infprintf (is
, "0x%x", GET_OP (insn
, IMMEDIATE
));
2402 case 'j': /* Same as i, but sign-extended. */
2404 infprintf (is
, "%d", GET_OP_S (insn
, DELTA
));
2408 infprintf (is
, "0x%x", GET_OP (insn
, CACHE
));
2415 immed
= GET_OP (insn
, RT
);
2416 s_reg_encode
= immed
& 0xf;
2417 if (s_reg_encode
!= 0)
2419 if (s_reg_encode
== 1)
2420 infprintf (is
, "%s", mips_gpr_names
[16]);
2421 else if (s_reg_encode
< 9)
2422 infprintf (is
, "%s-%s",
2424 mips_gpr_names
[15 + s_reg_encode
]);
2425 else if (s_reg_encode
== 9)
2426 infprintf (is
, "%s-%s,%s",
2429 mips_gpr_names
[30]);
2431 infprintf (is
, "UNKNOWN");
2434 if (immed
& 0x10) /* For ra. */
2436 if (s_reg_encode
== 0)
2437 infprintf (is
, "%s", mips_gpr_names
[31]);
2439 infprintf (is
, ",%s", mips_gpr_names
[31]);
2445 /* Sign-extend the displacement. */
2446 delta
= GET_OP_S (insn
, DELTA
);
2447 info
->target
= (delta
<< 1) + memaddr
+ length
;
2448 (*info
->print_address_func
) (info
->target
, info
);
2452 infprintf (is
, "0x%x", GET_OP (insn
, CODE2
));
2457 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RT
)]);
2461 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS3
)]);
2465 infprintf (is
, "%s", mips_gpr_names
[0]);
2468 case '@': /* DSP 10-bit signed immediate in bit 16. */
2469 delta
= (GET_OP (insn
, IMM10
) ^ 0x200) - 0x200;
2470 infprintf (is
, "%d", delta
);
2474 infprintf (is
, "0x%x", GET_OP (insn
, CODE10
));
2478 infprintf (is
, "0x%x", GET_OP (insn
, COPZ
));
2482 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FD
)]);
2486 /* Coprocessor register for lwcN instructions, et al.
2488 Note that there is no load/store cp0 instructions, and
2489 that FPU (cp1) instructions disassemble this field using
2490 'T' format. Therefore, until we gain understanding of
2491 cp2 register names, we can simply print the register
2493 infprintf (is
, "$%d", GET_OP (insn
, RT
));
2497 /* Coprocessor register for mtcN instructions, et al. Note
2498 that FPU (cp1) instructions disassemble this field using
2499 'S' format. Therefore, we only need to worry about cp0,
2501 The microMIPS encoding does not have a coprocessor
2502 identifier field as such, so we must work out the
2503 coprocessor number by looking at the opcode. */
2505 & ~((MICROMIPSOP_MASK_RT
<< MICROMIPSOP_SH_RT
)
2506 | (MICROMIPSOP_MASK_RS
<< MICROMIPSOP_SH_RS
)))
2508 case 0x000000fc: /* mfc0 */
2509 case 0x000002fc: /* mtc0 */
2510 case 0x580000fc: /* dmfc0 */
2511 case 0x580002fc: /* dmtc0 */
2512 infprintf (is
, "%s", mips_cp0_names
[GET_OP (insn
, RS
)]);
2515 infprintf (is
, "$%d", GET_OP (insn
, RS
));
2521 infprintf (is
, "%d", GET_OP (insn
, SEL
));
2525 infprintf (is
, "%s", mips_hwr_names
[GET_OP (insn
, RS
)]);
2529 infprintf (is
, "$fcc%d", GET_OP (insn
, CCC
));
2534 (op
->pinfo
& (FP_D
| FP_S
)) != 0
2535 ? "$fcc%d" : "$cc%d",
2536 GET_OP (insn
, BCC
));
2540 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FR
)]);
2545 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FS
)]);
2549 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FT
)]);
2553 /* Extension character; switch for second char. */
2558 lsb
= GET_OP (insn
, EXTLSB
);
2559 infprintf (is
, "0x%x", lsb
);
2563 msb
= GET_OP (insn
, INSMSB
);
2564 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2569 msbd
= GET_OP (insn
, EXTMSBD
);
2570 infprintf (is
, "0x%x", msbd
+ 1);
2575 const struct mips_cp0sel_name
*n
;
2576 unsigned int cp0reg
, sel
;
2578 cp0reg
= GET_OP (insn
, RS
);
2579 sel
= GET_OP (insn
, SEL
);
2581 /* CP0 register including 'sel' code for mtcN
2582 (et al.), to be printed textually if known.
2583 If not known, print both CP0 register name and
2584 sel numerically since CP0 register with sel 0 may
2585 have a name unrelated to register being printed. */
2586 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2587 mips_cp0sel_names_len
,
2590 infprintf (is
, "%s", n
->name
);
2592 infprintf (is
, "$%d,%d", cp0reg
, sel
);
2597 lsb
= GET_OP (insn
, EXTLSB
) + 32;
2598 infprintf (is
, "0x%x", lsb
);
2602 msb
= GET_OP (insn
, INSMSB
) + 32;
2603 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2607 msbd
= GET_OP (insn
, EXTMSBD
) + 32;
2608 infprintf (is
, "0x%x", msbd
+ 1);
2612 /* xgettext:c-format */
2614 _("# internal disassembler error, "
2615 "unrecognized modifier (+%c)"),
2622 /* Extension character; switch for second char. */
2626 case 'a': /* global pointer. */
2627 infprintf (is
, "%s", mips_gpr_names
[28]);
2631 regno
= micromips_to_32_reg_b_map
[GET_OP (insn
, MB
)];
2632 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2636 regno
= micromips_to_32_reg_c_map
[GET_OP (insn
, MC
)];
2637 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2641 regno
= micromips_to_32_reg_d_map
[GET_OP (insn
, MD
)];
2642 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2646 regno
= micromips_to_32_reg_e_map
[GET_OP (insn
, ME
)];
2647 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2651 /* Save lastregno for "mt" to print out later. */
2652 lastregno
= micromips_to_32_reg_f_map
[GET_OP (insn
, MF
)];
2653 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2657 regno
= micromips_to_32_reg_g_map
[GET_OP (insn
, MG
)];
2658 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2662 regno
= micromips_to_32_reg_h_map
[GET_OP (insn
, MH
)];
2663 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2667 regno
= micromips_to_32_reg_i_map
[GET_OP (insn
, MI
)];
2668 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2672 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, MJ
)]);
2676 regno
= micromips_to_32_reg_l_map
[GET_OP (insn
, ML
)];
2677 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2681 regno
= micromips_to_32_reg_m_map
[GET_OP (insn
, MM
)];
2682 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2686 regno
= micromips_to_32_reg_n_map
[GET_OP (insn
, MN
)];
2687 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2691 /* Save lastregno for "mt" to print out later. */
2692 lastregno
= GET_OP (insn
, MP
);
2693 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2697 regno
= micromips_to_32_reg_q_map
[GET_OP (insn
, MQ
)];
2698 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2701 case 'r': /* program counter. */
2702 infprintf (is
, "$pc");
2705 case 's': /* stack pointer. */
2707 infprintf (is
, "%s", mips_gpr_names
[29]);
2711 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2715 infprintf (is
, "%s", mips_gpr_names
[0]);
2719 /* Sign-extend the immediate. */
2720 immed
= GET_OP_S (insn
, IMMA
) << 2;
2721 infprintf (is
, "%d", immed
);
2725 immed
= micromips_imm_b_map
[GET_OP (insn
, IMMB
)];
2726 infprintf (is
, "%d", immed
);
2730 immed
= micromips_imm_c_map
[GET_OP (insn
, IMMC
)];
2731 infprintf (is
, "0x%x", immed
);
2735 /* Sign-extend the displacement. */
2736 delta
= GET_OP_S (insn
, IMMD
);
2737 info
->target
= (delta
<< 1) + memaddr
+ length
;
2738 (*info
->print_address_func
) (info
->target
, info
);
2742 /* Sign-extend the displacement. */
2743 delta
= GET_OP_S (insn
, IMME
);
2744 info
->target
= (delta
<< 1) + memaddr
+ length
;
2745 (*info
->print_address_func
) (info
->target
, info
);
2749 immed
= GET_OP (insn
, IMMF
);
2750 infprintf (is
, "0x%x", immed
);
2754 immed
= (insn
>> MICROMIPSOP_SH_IMMG
) + 1;
2755 immed
= (immed
& MICROMIPSOP_MASK_IMMG
) - 1;
2756 infprintf (is
, "%d", immed
);
2760 immed
= GET_OP (insn
, IMMH
) << 1;
2761 infprintf (is
, "%d", immed
);
2765 immed
= (insn
>> MICROMIPSOP_SH_IMMI
) + 1;
2766 immed
= (immed
& MICROMIPSOP_MASK_IMMI
) - 1;
2767 infprintf (is
, "%d", immed
);
2771 immed
= GET_OP (insn
, IMMJ
) << 2;
2772 infprintf (is
, "%d", immed
);
2776 immed
= GET_OP (insn
, IMML
);
2777 infprintf (is
, "%d", immed
);
2781 immed
= (insn
>> MICROMIPSOP_SH_IMMM
) - 1;
2782 immed
= (immed
& MICROMIPSOP_MASK_IMMM
) + 1;
2783 infprintf (is
, "%d", immed
);
2787 immed
= GET_OP (insn
, IMMN
);
2789 infprintf (is
, "%s,%s",
2791 mips_gpr_names
[31]);
2793 infprintf (is
, "%s-%s,%s",
2795 mips_gpr_names
[16 + immed
],
2796 mips_gpr_names
[31]);
2800 immed
= GET_OP (insn
, IMMO
);
2801 infprintf (is
, "0x%x", immed
);
2805 immed
= GET_OP (insn
, IMMP
) << 2;
2806 infprintf (is
, "%d", immed
);
2810 /* Sign-extend the immediate. */
2811 immed
= GET_OP_S (insn
, IMMQ
) << 2;
2812 infprintf (is
, "%d", immed
);
2816 immed
= GET_OP (insn
, IMMU
) << 2;
2817 infprintf (is
, "%d", immed
);
2821 immed
= GET_OP (insn
, IMMW
) << 2;
2822 infprintf (is
, "%d", immed
);
2826 /* Sign-extend the immediate. */
2827 immed
= GET_OP_S (insn
, IMMX
);
2828 infprintf (is
, "%d", immed
);
2832 /* Sign-extend the immediate. */
2833 immed
= GET_OP_S (insn
, IMMY
) << 2;
2834 if ((unsigned int) (immed
+ 8) < 16)
2836 infprintf (is
, "%d", immed
);
2840 /* xgettext:c-format */
2842 _("# internal disassembler error, "
2843 "unrecognized modifier (m%c)"),
2850 /* xgettext:c-format */
2852 _("# internal disassembler error, "
2853 "unrecognized modifier (%c)"),
2859 /* Figure out instruction type and branch delay information. */
2861 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2862 info
->branch_delay_insns
= 1;
2863 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2864 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2866 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_GPR_T
)) != 0)
2867 info
->insn_type
= dis_jsr
;
2869 info
->insn_type
= dis_branch
;
2871 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2872 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2874 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2875 info
->insn_type
= dis_condjsr
;
2877 info
->insn_type
= dis_condbranch
;
2880 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY_DELAY
)) != 0)
2881 info
->insn_type
= dis_dref
;
2889 infprintf (is
, "0x%x", insn
);
2890 info
->insn_type
= dis_noninsn
;
2895 /* Return 1 if a symbol associated with the location being disassembled
2896 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2897 all the symbols at the address being considered assuming if at least
2898 one of them indicates code compression, then such code has been
2899 genuinely produced here (other symbols could have been derived from
2900 function symbols defined elsewhere or could define data). Otherwise,
2904 is_compressed_mode_p (struct disassemble_info
*info
)
2906 elf_symbol_type
*symbol
;
2910 for (i
= 0; i
< info
->num_symbols
; i
++)
2912 pos
= info
->symtab_pos
+ i
;
2914 if (bfd_asymbol_flavour (info
->symtab
[pos
]) != bfd_target_elf_flavour
)
2917 symbol
= (elf_symbol_type
*) info
->symtab
[pos
];
2919 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2921 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2928 /* In an environment where we do not know the symbol type of the
2929 instruction we are forced to assume that the low order bit of the
2930 instructions' address may mark it as a mips16 instruction. If we
2931 are single stepping, or the pc is within the disassembled function,
2932 this works. Otherwise, we need a clue. Sometimes. */
2935 _print_insn_mips (bfd_vma memaddr
,
2936 struct disassemble_info
*info
,
2937 enum bfd_endian endianness
)
2939 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
2940 bfd_byte buffer
[INSNLEN
];
2943 set_default_mips_dis_options (info
);
2944 parse_mips_dis_options (info
->disassembler_options
);
2946 if (info
->mach
== bfd_mach_mips16
)
2947 return print_insn_mips16 (memaddr
, info
);
2948 if (info
->mach
== bfd_mach_mips_micromips
)
2949 return print_insn_micromips (memaddr
, info
);
2951 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
2954 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2955 /* Only a few tools will work this way. */
2957 return print_insn_compr (memaddr
, info
);
2960 #if SYMTAB_AVAILABLE
2961 if (is_compressed_mode_p (info
))
2962 return print_insn_compr (memaddr
, info
);
2965 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2970 if (endianness
== BFD_ENDIAN_BIG
)
2971 insn
= bfd_getb32 (buffer
);
2973 insn
= bfd_getl32 (buffer
);
2975 return print_insn_mips (memaddr
, insn
, info
);
2979 (*info
->memory_error_func
) (status
, memaddr
, info
);
2985 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2987 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2991 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2993 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2997 print_mips_disassembler_options (FILE *stream
)
3001 fprintf (stream
, _("\n\
3002 The following MIPS specific disassembler options are supported for use\n\
3003 with the -M switch (multiple options should be separated by commas):\n"));
3005 fprintf (stream
, _("\n\
3006 gpr-names=ABI Print GPR names according to specified ABI.\n\
3007 Default: based on binary being disassembled.\n"));
3009 fprintf (stream
, _("\n\
3010 fpr-names=ABI Print FPR names according to specified ABI.\n\
3011 Default: numeric.\n"));
3013 fprintf (stream
, _("\n\
3014 cp0-names=ARCH Print CP0 register names according to\n\
3015 specified architecture.\n\
3016 Default: based on binary being disassembled.\n"));
3018 fprintf (stream
, _("\n\
3019 hwr-names=ARCH Print HWR names according to specified \n\
3021 Default: based on binary being disassembled.\n"));
3023 fprintf (stream
, _("\n\
3024 reg-names=ABI Print GPR and FPR names according to\n\
3025 specified ABI.\n"));
3027 fprintf (stream
, _("\n\
3028 reg-names=ARCH Print CP0 register and HWR names according to\n\
3029 specified architecture.\n"));
3031 fprintf (stream
, _("\n\
3032 For the options above, the following values are supported for \"ABI\":\n\
3034 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
3035 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
3036 fprintf (stream
, _("\n"));
3038 fprintf (stream
, _("\n\
3039 For the options above, The following values are supported for \"ARCH\":\n\
3041 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
3042 if (*mips_arch_choices
[i
].name
!= '\0')
3043 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
3044 fprintf (stream
, _("\n"));
3046 fprintf (stream
, _("\n"));