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_r5900[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_sr", "c0_cause", "c0_epc", "c0_prid",
242 "c0_config", "$17", "$18", "$19",
243 "$20", "$21", "$22", "c0_badpaddr",
244 "c0_depc", "c0_perfcnt", "$26", "$27",
245 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
248 static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900[] =
251 { 24, 3, "c0_iabm" },
253 { 24, 5, "c0_dabm" },
255 { 24, 7, "c0_dvbm" },
256 { 25, 1, "c0_perfcnt,1" },
257 { 25, 2, "c0_perfcnt,2" }
260 static const char * const mips_cp0_names_mips3264[32] =
262 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
263 "c0_context", "c0_pagemask", "c0_wired", "$7",
264 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
265 "c0_status", "c0_cause", "c0_epc", "c0_prid",
266 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
267 "c0_xcontext", "$21", "$22", "c0_debug",
268 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
269 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
272 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
274 { 16, 1, "c0_config1" },
275 { 16, 2, "c0_config2" },
276 { 16, 3, "c0_config3" },
277 { 18, 1, "c0_watchlo,1" },
278 { 18, 2, "c0_watchlo,2" },
279 { 18, 3, "c0_watchlo,3" },
280 { 18, 4, "c0_watchlo,4" },
281 { 18, 5, "c0_watchlo,5" },
282 { 18, 6, "c0_watchlo,6" },
283 { 18, 7, "c0_watchlo,7" },
284 { 19, 1, "c0_watchhi,1" },
285 { 19, 2, "c0_watchhi,2" },
286 { 19, 3, "c0_watchhi,3" },
287 { 19, 4, "c0_watchhi,4" },
288 { 19, 5, "c0_watchhi,5" },
289 { 19, 6, "c0_watchhi,6" },
290 { 19, 7, "c0_watchhi,7" },
291 { 25, 1, "c0_perfcnt,1" },
292 { 25, 2, "c0_perfcnt,2" },
293 { 25, 3, "c0_perfcnt,3" },
294 { 25, 4, "c0_perfcnt,4" },
295 { 25, 5, "c0_perfcnt,5" },
296 { 25, 6, "c0_perfcnt,6" },
297 { 25, 7, "c0_perfcnt,7" },
298 { 27, 1, "c0_cacheerr,1" },
299 { 27, 2, "c0_cacheerr,2" },
300 { 27, 3, "c0_cacheerr,3" },
301 { 28, 1, "c0_datalo" },
302 { 29, 1, "c0_datahi" }
305 static const char * const mips_cp0_names_mips3264r2[32] =
307 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
308 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
309 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
310 "c0_status", "c0_cause", "c0_epc", "c0_prid",
311 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
312 "c0_xcontext", "$21", "$22", "c0_debug",
313 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
314 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
317 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
319 { 4, 1, "c0_contextconfig" },
320 { 0, 1, "c0_mvpcontrol" },
321 { 0, 2, "c0_mvpconf0" },
322 { 0, 3, "c0_mvpconf1" },
323 { 1, 1, "c0_vpecontrol" },
324 { 1, 2, "c0_vpeconf0" },
325 { 1, 3, "c0_vpeconf1" },
326 { 1, 4, "c0_yqmask" },
327 { 1, 5, "c0_vpeschedule" },
328 { 1, 6, "c0_vpeschefback" },
329 { 2, 1, "c0_tcstatus" },
330 { 2, 2, "c0_tcbind" },
331 { 2, 3, "c0_tcrestart" },
332 { 2, 4, "c0_tchalt" },
333 { 2, 5, "c0_tccontext" },
334 { 2, 6, "c0_tcschedule" },
335 { 2, 7, "c0_tcschefback" },
336 { 5, 1, "c0_pagegrain" },
337 { 6, 1, "c0_srsconf0" },
338 { 6, 2, "c0_srsconf1" },
339 { 6, 3, "c0_srsconf2" },
340 { 6, 4, "c0_srsconf3" },
341 { 6, 5, "c0_srsconf4" },
342 { 12, 1, "c0_intctl" },
343 { 12, 2, "c0_srsctl" },
344 { 12, 3, "c0_srsmap" },
345 { 15, 1, "c0_ebase" },
346 { 16, 1, "c0_config1" },
347 { 16, 2, "c0_config2" },
348 { 16, 3, "c0_config3" },
349 { 18, 1, "c0_watchlo,1" },
350 { 18, 2, "c0_watchlo,2" },
351 { 18, 3, "c0_watchlo,3" },
352 { 18, 4, "c0_watchlo,4" },
353 { 18, 5, "c0_watchlo,5" },
354 { 18, 6, "c0_watchlo,6" },
355 { 18, 7, "c0_watchlo,7" },
356 { 19, 1, "c0_watchhi,1" },
357 { 19, 2, "c0_watchhi,2" },
358 { 19, 3, "c0_watchhi,3" },
359 { 19, 4, "c0_watchhi,4" },
360 { 19, 5, "c0_watchhi,5" },
361 { 19, 6, "c0_watchhi,6" },
362 { 19, 7, "c0_watchhi,7" },
363 { 23, 1, "c0_tracecontrol" },
364 { 23, 2, "c0_tracecontrol2" },
365 { 23, 3, "c0_usertracedata" },
366 { 23, 4, "c0_tracebpc" },
367 { 25, 1, "c0_perfcnt,1" },
368 { 25, 2, "c0_perfcnt,2" },
369 { 25, 3, "c0_perfcnt,3" },
370 { 25, 4, "c0_perfcnt,4" },
371 { 25, 5, "c0_perfcnt,5" },
372 { 25, 6, "c0_perfcnt,6" },
373 { 25, 7, "c0_perfcnt,7" },
374 { 27, 1, "c0_cacheerr,1" },
375 { 27, 2, "c0_cacheerr,2" },
376 { 27, 3, "c0_cacheerr,3" },
377 { 28, 1, "c0_datalo" },
378 { 28, 2, "c0_taglo1" },
379 { 28, 3, "c0_datalo1" },
380 { 28, 4, "c0_taglo2" },
381 { 28, 5, "c0_datalo2" },
382 { 28, 6, "c0_taglo3" },
383 { 28, 7, "c0_datalo3" },
384 { 29, 1, "c0_datahi" },
385 { 29, 2, "c0_taghi1" },
386 { 29, 3, "c0_datahi1" },
387 { 29, 4, "c0_taghi2" },
388 { 29, 5, "c0_datahi2" },
389 { 29, 6, "c0_taghi3" },
390 { 29, 7, "c0_datahi3" },
393 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
394 static const char * const mips_cp0_names_sb1[32] =
396 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
397 "c0_context", "c0_pagemask", "c0_wired", "$7",
398 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
399 "c0_status", "c0_cause", "c0_epc", "c0_prid",
400 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
401 "c0_xcontext", "$21", "$22", "c0_debug",
402 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
403 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
406 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
408 { 16, 1, "c0_config1" },
409 { 18, 1, "c0_watchlo,1" },
410 { 19, 1, "c0_watchhi,1" },
411 { 22, 0, "c0_perftrace" },
412 { 23, 3, "c0_edebug" },
413 { 25, 1, "c0_perfcnt,1" },
414 { 25, 2, "c0_perfcnt,2" },
415 { 25, 3, "c0_perfcnt,3" },
416 { 25, 4, "c0_perfcnt,4" },
417 { 25, 5, "c0_perfcnt,5" },
418 { 25, 6, "c0_perfcnt,6" },
419 { 25, 7, "c0_perfcnt,7" },
420 { 26, 1, "c0_buserr_pa" },
421 { 27, 1, "c0_cacheerr_d" },
422 { 27, 3, "c0_cacheerr_d_pa" },
423 { 28, 1, "c0_datalo_i" },
424 { 28, 2, "c0_taglo_d" },
425 { 28, 3, "c0_datalo_d" },
426 { 29, 1, "c0_datahi_i" },
427 { 29, 2, "c0_taghi_d" },
428 { 29, 3, "c0_datahi_d" },
431 /* Xlr cop0 register names. */
432 static const char * const mips_cp0_names_xlr[32] = {
433 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
434 "c0_context", "c0_pagemask", "c0_wired", "$7",
435 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
436 "c0_status", "c0_cause", "c0_epc", "c0_prid",
437 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
438 "c0_xcontext", "$21", "$22", "c0_debug",
439 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
440 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
443 /* XLR's CP0 Select Registers. */
445 static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
446 { 9, 6, "c0_extintreq" },
447 { 9, 7, "c0_extintmask" },
448 { 15, 1, "c0_ebase" },
449 { 16, 1, "c0_config1" },
450 { 16, 2, "c0_config2" },
451 { 16, 3, "c0_config3" },
452 { 16, 7, "c0_procid2" },
453 { 18, 1, "c0_watchlo,1" },
454 { 18, 2, "c0_watchlo,2" },
455 { 18, 3, "c0_watchlo,3" },
456 { 18, 4, "c0_watchlo,4" },
457 { 18, 5, "c0_watchlo,5" },
458 { 18, 6, "c0_watchlo,6" },
459 { 18, 7, "c0_watchlo,7" },
460 { 19, 1, "c0_watchhi,1" },
461 { 19, 2, "c0_watchhi,2" },
462 { 19, 3, "c0_watchhi,3" },
463 { 19, 4, "c0_watchhi,4" },
464 { 19, 5, "c0_watchhi,5" },
465 { 19, 6, "c0_watchhi,6" },
466 { 19, 7, "c0_watchhi,7" },
467 { 25, 1, "c0_perfcnt,1" },
468 { 25, 2, "c0_perfcnt,2" },
469 { 25, 3, "c0_perfcnt,3" },
470 { 25, 4, "c0_perfcnt,4" },
471 { 25, 5, "c0_perfcnt,5" },
472 { 25, 6, "c0_perfcnt,6" },
473 { 25, 7, "c0_perfcnt,7" },
474 { 27, 1, "c0_cacheerr,1" },
475 { 27, 2, "c0_cacheerr,2" },
476 { 27, 3, "c0_cacheerr,3" },
477 { 28, 1, "c0_datalo" },
478 { 29, 1, "c0_datahi" }
481 static const char * const mips_hwr_names_numeric[32] =
483 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
484 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
485 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
486 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
489 static const char * const mips_hwr_names_mips3264r2[32] =
491 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
492 "$4", "$5", "$6", "$7",
493 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
494 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
495 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
498 struct mips_abi_choice
501 const char * const *gpr_names;
502 const char * const *fpr_names;
505 struct mips_abi_choice mips_abi_choices[] =
507 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
508 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
509 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
510 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
513 struct mips_arch_choice
517 unsigned long bfd_mach;
521 const char * const *cp0_names;
522 const struct mips_cp0sel_name *cp0sel_names;
523 unsigned int cp0sel_names_len;
524 const char * const *hwr_names;
527 const struct mips_arch_choice mips_arch_choices[] =
529 { "numeric", 0, 0, 0, 0, 0,
530 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
532 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
533 mips_cp0_names_r3000, NULL, 0, mips_hwr_names_numeric },
534 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
535 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
536 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
537 mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
538 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
539 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
540 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
541 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
542 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
543 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
544 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
545 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
546 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
547 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
548 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
549 mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
550 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
551 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
552 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
553 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
554 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
555 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
556 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
557 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
558 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
559 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
560 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
561 mips_cp0_names_r5900, NULL, 0, mips_hwr_names_numeric },
562 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
563 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
564 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
565 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
566 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
567 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
568 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
569 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
570 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
571 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
572 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
573 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
574 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
575 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
576 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
577 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
578 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
579 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
581 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
582 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
583 _MIPS32 Architecture For Programmers Volume I: Introduction to the
584 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
586 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
587 ISA_MIPS32, ASE_SMARTMIPS,
588 mips_cp0_names_mips3264,
589 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
590 mips_hwr_names_numeric },
592 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
594 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_MIPS3D | ASE_MT
595 | ASE_MCU | ASE_VIRT),
596 mips_cp0_names_mips3264r2,
597 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
598 mips_hwr_names_mips3264r2 },
600 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
601 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
602 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
603 mips_cp0_names_mips3264,
604 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
605 mips_hwr_names_numeric },
607 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
609 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_MT | ASE_MDMX
610 | ASE_MCU | ASE_VIRT | ASE_VIRT64),
611 mips_cp0_names_mips3264r2,
612 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
613 mips_hwr_names_mips3264r2 },
615 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
616 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
618 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
619 mips_hwr_names_numeric },
621 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
622 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
623 NULL, 0, mips_hwr_names_numeric },
625 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
626 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
627 NULL, 0, mips_hwr_names_numeric },
629 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
630 ISA_MIPS64 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
631 NULL, 0, mips_hwr_names_numeric },
633 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
634 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
635 mips_hwr_names_numeric },
637 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
638 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
639 NULL, 0, mips_hwr_names_numeric },
641 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
642 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
643 NULL, 0, mips_hwr_names_numeric },
645 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
646 ISA_MIPS64 | INSN_XLR, 0,
648 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
649 mips_hwr_names_numeric },
651 /* XLP is mostly like XLR, with the prominent exception it is being
653 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
654 ISA_MIPS64R2 | INSN_XLR, 0,
656 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
657 mips_hwr_names_numeric },
659 /* This entry, mips16, is here only for ISA/processor selection; do
660 not print its name. */
661 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0,
662 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
665 /* ISA and processor type to disassemble for, and register names to use.
666 set_default_mips_dis_options and parse_mips_dis_options fill in these
668 static int mips_processor;
671 static int micromips_ase;
672 static const char * const *mips_gpr_names;
673 static const char * const *mips_fpr_names;
674 static const char * const *mips_cp0_names;
675 static const struct mips_cp0sel_name *mips_cp0sel_names;
676 static int mips_cp0sel_names_len;
677 static const char * const *mips_hwr_names;
680 static int no_aliases; /* If set disassemble as most general inst. */
682 static const struct mips_abi_choice *
683 choose_abi_by_name (const char *name, unsigned int namelen)
685 const struct mips_abi_choice *c;
688 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
689 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
690 && strlen (mips_abi_choices[i].name) == namelen)
691 c = &mips_abi_choices[i];
696 static const struct mips_arch_choice *
697 choose_arch_by_name (const char *name, unsigned int namelen)
699 const struct mips_arch_choice *c = NULL;
702 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
703 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
704 && strlen (mips_arch_choices[i].name) == namelen)
705 c = &mips_arch_choices[i];
710 static const struct mips_arch_choice *
711 choose_arch_by_number (unsigned long mach)
713 static unsigned long hint_bfd_mach;
714 static const struct mips_arch_choice *hint_arch_choice;
715 const struct mips_arch_choice *c;
718 /* We optimize this because even if the user specifies no
719 flags, this will be done for every instruction! */
720 if (hint_bfd_mach == mach
721 && hint_arch_choice != NULL
722 && hint_arch_choice->bfd_mach == hint_bfd_mach)
723 return hint_arch_choice;
725 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
727 if (mips_arch_choices[i].bfd_mach_valid
728 && mips_arch_choices[i].bfd_mach == mach)
730 c = &mips_arch_choices[i];
731 hint_bfd_mach = mach;
732 hint_arch_choice = c;
738 /* Check if the object uses NewABI conventions. */
741 is_newabi (Elf_Internal_Ehdr *header)
743 /* There are no old-style ABIs which use 64-bit ELF. */
744 if (header->e_ident[EI_CLASS] == ELFCLASS64)
747 /* If a 32-bit ELF file, n32 is a new-style ABI. */
748 if ((header->e_flags & EF_MIPS_ABI2) != 0)
754 /* Check if the object has microMIPS ASE code. */
757 is_micromips (Elf_Internal_Ehdr *header)
759 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
766 set_default_mips_dis_options (struct disassemble_info *info)
768 const struct mips_arch_choice *chosen_arch;
770 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
771 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
772 CP0 register, and HWR names. */
773 mips_isa = ISA_MIPS3;
774 mips_processor = CPU_R3000;
777 mips_gpr_names = mips_gpr_names_oldabi;
778 mips_fpr_names = mips_fpr_names_numeric;
779 mips_cp0_names = mips_cp0_names_numeric;
780 mips_cp0sel_names = NULL;
781 mips_cp0sel_names_len = 0;
782 mips_hwr_names = mips_hwr_names_numeric;
785 /* Update settings according to the ELF file header flags. */
786 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
788 Elf_Internal_Ehdr *header;
790 header = elf_elfheader (info->section->owner);
791 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
792 if (is_newabi (header))
793 mips_gpr_names = mips_gpr_names_newabi;
794 /* If a microMIPS binary, then don't use MIPS16 bindings. */
795 micromips_ase = is_micromips (header);
798 /* Set ISA, architecture, and cp0 register names as best we can. */
799 #if ! SYMTAB_AVAILABLE
800 /* This is running out on a target machine, not in a host tool.
801 FIXME: Where does mips_target_info come from? */
802 target_processor = mips_target_info.processor;
803 mips_isa = mips_target_info.isa;
804 mips_ase = mips_target_info.ase;
806 chosen_arch = choose_arch_by_number (info->mach);
807 if (chosen_arch != NULL)
809 mips_processor = chosen_arch->processor;
810 mips_isa = chosen_arch->isa;
811 mips_ase = chosen_arch->ase;
812 mips_cp0_names = chosen_arch->cp0_names;
813 mips_cp0sel_names = chosen_arch->cp0sel_names;
814 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
815 mips_hwr_names = chosen_arch->hwr_names;
821 parse_mips_dis_option (const char *option, unsigned int len)
823 unsigned int i, optionlen, vallen;
825 const struct mips_abi_choice *chosen_abi;
826 const struct mips_arch_choice *chosen_arch;
828 /* Try to match options that are simple flags */
829 if (CONST_STRNEQ (option, "no-aliases"))
835 if (CONST_STRNEQ (option, "virt"))
837 mips_ase |= ASE_VIRT;
838 if (mips_isa & ISA_MIPS64R2)
839 mips_ase |= ASE_VIRT64;
843 /* Look for the = that delimits the end of the option name. */
844 for (i = 0; i < len; i++)
845 if (option[i] == '=')
848 if (i == 0) /* Invalid option: no name before '='. */
850 if (i == len) /* Invalid option: no '='. */
852 if (i == (len - 1)) /* Invalid option: no value after '='. */
856 val = option + (optionlen + 1);
857 vallen = len - (optionlen + 1);
859 if (strncmp ("gpr-names", option, optionlen) == 0
860 && strlen ("gpr-names") == optionlen)
862 chosen_abi = choose_abi_by_name (val, vallen);
863 if (chosen_abi != NULL)
864 mips_gpr_names = chosen_abi->gpr_names;
868 if (strncmp ("fpr-names", option, optionlen) == 0
869 && strlen ("fpr-names") == optionlen)
871 chosen_abi = choose_abi_by_name (val, vallen);
872 if (chosen_abi != NULL)
873 mips_fpr_names = chosen_abi->fpr_names;
877 if (strncmp ("cp0-names", option, optionlen) == 0
878 && strlen ("cp0-names") == optionlen)
880 chosen_arch = choose_arch_by_name (val, vallen);
881 if (chosen_arch != NULL)
883 mips_cp0_names = chosen_arch->cp0_names;
884 mips_cp0sel_names = chosen_arch->cp0sel_names;
885 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
890 if (strncmp ("hwr-names", option, optionlen) == 0
891 && strlen ("hwr-names") == optionlen)
893 chosen_arch = choose_arch_by_name (val, vallen);
894 if (chosen_arch != NULL)
895 mips_hwr_names = chosen_arch->hwr_names;
899 if (strncmp ("reg-names", option, optionlen) == 0
900 && strlen ("reg-names") == optionlen)
902 /* We check both ABI and ARCH here unconditionally, so
903 that "numeric" will do the desirable thing: select
904 numeric register names for all registers. Other than
905 that, a given name probably won't match both. */
906 chosen_abi = choose_abi_by_name (val, vallen);
907 if (chosen_abi != NULL)
909 mips_gpr_names = chosen_abi->gpr_names;
910 mips_fpr_names = chosen_abi->fpr_names;
912 chosen_arch = choose_arch_by_name (val, vallen);
913 if (chosen_arch != NULL)
915 mips_cp0_names = chosen_arch->cp0_names;
916 mips_cp0sel_names = chosen_arch->cp0sel_names;
917 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
918 mips_hwr_names = chosen_arch->hwr_names;
923 /* Invalid option. */
927 parse_mips_dis_options (const char *options)
929 const char *option_end;
934 while (*options != '\0')
936 /* Skip empty options. */
943 /* We know that *options is neither NUL or a comma. */
944 option_end = options + 1;
945 while (*option_end != ',' && *option_end != '\0')
948 parse_mips_dis_option (options, option_end - options);
950 /* Go on to the next one. If option_end points to a comma, it
951 will be skipped above. */
952 options = option_end;
956 static const struct mips_cp0sel_name *
957 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
964 for (i = 0; i < len; i++)
965 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
970 /* Print insn arguments for 32/64-bit code. */
973 print_insn_args (const char *d,
976 struct disassemble_info *info,
977 const struct mips_opcode *opp)
979 const fprintf_ftype infprintf = info->fprintf_func;
980 unsigned int lsb, msb, msbd;
981 void *is = info->stream;
986 #define GET_OP(insn, field) \
987 (((insn) >> OP_SH_##field) & OP_MASK_##field)
988 #define GET_OP_S(insn, field) \
989 ((GET_OP (insn, field) ^ ((OP_MASK_##field >> 1) + 1)) \
990 - ((OP_MASK_##field >> 1) + 1))
991 for (; *d != '\0'; d++)
1000 infprintf (is, "%c", *d);
1004 /* Extension character; switch for second char. */
1009 /* xgettext:c-format */
1011 _("# internal error, "
1012 "incomplete extension sequence (+)"));
1016 lsb = GET_OP (l, SHAMT);
1017 infprintf (is, "0x%x", lsb);
1021 msb = GET_OP (l, INSMSB);
1022 infprintf (is, "0x%x", msb - lsb + 1);
1026 infprintf (is, "0x%x", GET_OP (l, UDI1));
1030 infprintf (is, "0x%x", GET_OP (l, UDI2));
1034 infprintf (is, "0x%x", GET_OP (l, UDI3));
1038 infprintf (is, "0x%x", GET_OP (l, UDI4));
1043 msbd = GET_OP (l, EXTMSBD);
1044 infprintf (is, "0x%x", msbd + 1);
1049 const struct mips_cp0sel_name *n;
1050 unsigned int cp0reg, sel;
1052 cp0reg = GET_OP (l, RD);
1053 sel = GET_OP (l, SEL);
1055 /* CP0 register including 'sel' code for mtcN (et al.), 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);
1070 lsb = GET_OP (l, SHAMT) + 32;
1071 infprintf (is, "0x%x", lsb);
1075 msb = GET_OP (l, INSMSB) + 32;
1076 infprintf (is, "0x%x", msb - lsb + 1);
1080 msbd = GET_OP (l, EXTMSBD) + 32;
1081 infprintf (is, "0x%x", msbd + 1);
1084 case 'J': /* hypcall operand */
1085 infprintf (is, "0x%x", GET_OP (l, CODE10));
1088 case 't': /* Coprocessor 0 reg name */
1089 infprintf (is, "%s", mips_cp0_names[GET_OP (l, RT)]);
1092 case 'T': /* Coprocessor 0 reg name */
1094 const struct mips_cp0sel_name *n;
1095 unsigned int cp0reg, sel;
1097 cp0reg = GET_OP (l, RT);
1098 sel = GET_OP (l, SEL);
1100 /* CP0 register including 'sel' code for mftc0, to be
1101 printed textually if known. If not known, print both
1102 CP0 register name and sel numerically since CP0 register
1103 with sel 0 may have a name unrelated to register being
1105 n = lookup_mips_cp0sel_name(mips_cp0sel_names,
1106 mips_cp0sel_names_len, cp0reg, sel);
1108 infprintf (is, "%s", n->name);
1110 infprintf (is, "$%d,%d", cp0reg, sel);
1114 case 'x': /* bbit bit index */
1115 infprintf (is, "0x%x", GET_OP (l, BBITIND));
1118 case 'p': /* cins, cins32, exts and exts32 position */
1119 infprintf (is, "0x%x", GET_OP (l, CINSPOS));
1122 case 's': /* cins and exts length-minus-one */
1123 infprintf (is, "0x%x", GET_OP (l, CINSLM1));
1126 case 'S': /* cins32 and exts32 length-minus-one field */
1127 infprintf (is, "0x%x", GET_OP (l, CINSLM1));
1130 case 'Q': /* seqi/snei immediate field */
1131 infprintf (is, "%d", GET_OP_S (l, SEQI));
1134 case 'a': /* 8-bit signed offset in bit 6 */
1135 infprintf (is, "%d", GET_OP_S (l, OFFSET_A));
1138 case 'b': /* 8-bit signed offset in bit 3 */
1139 infprintf (is, "%d", GET_OP_S (l, OFFSET_B));
1142 case 'c': /* 9-bit signed offset in bit 6 */
1143 /* Left shift 4 bits to print the real offset. */
1144 infprintf (is, "%d", GET_OP_S (l, OFFSET_C) << 4);
1148 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RZ)]);
1152 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FZ)]);
1156 /* xgettext:c-format */
1158 _("# internal error, "
1159 "undefined extension sequence (+%c)"),
1166 infprintf (is, "0x%x", GET_OP (l, BP));
1170 infprintf (is, "0x%x", GET_OP (l, SA3));
1174 infprintf (is, "0x%x", GET_OP (l, SA4));
1178 infprintf (is, "0x%x", GET_OP (l, IMM8));
1182 infprintf (is, "0x%x", GET_OP (l, RS));
1186 infprintf (is, "$ac%d", GET_OP (l, DSPACC));
1190 infprintf (is, "0x%x", GET_OP (l, WRDSP));
1194 infprintf (is, "$ac%d", GET_OP (l, DSPACC_S));
1197 case '0': /* dsp 6-bit signed immediate in bit 20 */
1198 infprintf (is, "%d", GET_OP_S (l, DSPSFT));
1201 case ':': /* dsp 7-bit signed immediate in bit 19 */
1202 infprintf (is, "%d", GET_OP_S (l, DSPSFT_7));
1206 infprintf (is, "%d", GET_OP_S (l, OFFSET12));
1210 infprintf (is, "0x%x", GET_OP (l, 3BITPOS));
1214 infprintf (is, "0x%x", GET_OP (l, RDDSP));
1217 case '@': /* dsp 10-bit signed immediate in bit 16 */
1218 infprintf (is, "%d", GET_OP_S (l, IMM10));
1222 infprintf (is, "%d", GET_OP (l, MT_U));
1226 infprintf (is, "%d", GET_OP (l, MT_H));
1230 infprintf (is, "$ac%d", GET_OP (l, MTACC_T));
1234 infprintf (is, "$ac%d", GET_OP (l, MTACC_D));
1238 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
1239 infprintf (is, "$%d", GET_OP (l, RD));
1246 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RS)]);
1251 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RT)]);
1256 infprintf (is, "0x%x", GET_OP (l, IMMEDIATE));
1259 case 'j': /* Same as i, but sign-extended. */
1261 infprintf (is, "%d", GET_OP_S (l, DELTA));
1265 infprintf (is, "0x%x", GET_OP (l, PREFX));
1269 infprintf (is, "0x%x", GET_OP (l, CACHE));
1273 info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
1274 | (GET_OP (l, 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 info->target = (GET_OP_S (l, DELTA) << 2) + pc + INSNLEN;
1285 (*info->print_address_func) (info->target, info);
1289 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RD)]);
1294 /* First check for both rd and rt being equal. */
1297 reg = GET_OP (l, RD);
1298 if (reg == GET_OP (l, RT))
1299 infprintf (is, "%s", mips_gpr_names[reg]);
1302 /* If one is zero use the other. */
1304 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RT)]);
1305 else if (GET_OP (l, RT) == 0)
1306 infprintf (is, "%s", mips_gpr_names[reg]);
1307 else /* Bogus, result depends on processor. */
1308 infprintf (is, "%s or %s",
1309 mips_gpr_names[reg],
1310 mips_gpr_names[GET_OP (l, RT)]);
1316 infprintf (is, "%s", mips_gpr_names[0]);
1321 infprintf (is, "0x%x", GET_OP (l, SHAMT));
1325 infprintf (is, "0x%x", GET_OP (l, CODE));
1329 infprintf (is, "0x%x", GET_OP (l, CODE2));
1333 infprintf (is, "0x%x", GET_OP (l, COPZ));
1337 infprintf (is, "0x%x", GET_OP (l, CODE20));
1341 infprintf (is, "0x%x", GET_OP (l, CODE19));
1346 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FS)]);
1351 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FT)]);
1355 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FD)]);
1359 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FR)]);
1363 /* Coprocessor register for lwcN instructions, et al.
1365 Note that there is no load/store cp0 instructions, and
1366 that FPU (cp1) instructions disassemble this field using
1367 'T' format. Therefore, until we gain understanding of
1368 cp2 register names, we can simply print the register
1370 infprintf (is, "$%d", GET_OP (l, RT));
1374 /* Coprocessor register for mtcN instructions, et al. Note
1375 that FPU (cp1) instructions disassemble this field using
1376 'S' format. Therefore, we only need to worry about cp0,
1378 op = GET_OP (l, OP);
1379 if (op == OP_OP_COP0)
1380 infprintf (is, "%s", mips_cp0_names[GET_OP (l, RD)]);
1382 infprintf (is, "$%d", GET_OP (l, RD));
1386 infprintf (is, "%s", mips_hwr_names[GET_OP (l, RD)]);
1391 (opp->pinfo & (FP_D | FP_S)) != 0 ? "$fcc%d" : "$cc%d",
1396 infprintf (is, "$fcc%d", GET_OP (l, CCC));
1400 infprintf (is, "%d", GET_OP (l, PERFREG));
1404 infprintf (is, "%d", GET_OP (l, VECBYTE));
1408 infprintf (is, "%d", GET_OP (l, VECALIGN));
1412 infprintf (is, "%d", GET_OP (l, SEL));
1416 infprintf (is, "%d", GET_OP (l, ALN));
1421 unsigned int vsel = GET_OP (l, VSEL);
1423 if ((vsel & 0x10) == 0)
1428 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1429 if ((vsel & 1) == 0)
1431 infprintf (is, "$v%d[%d]", GET_OP (l, FT), vsel >> 1);
1433 else if ((vsel & 0x08) == 0)
1435 infprintf (is, "$v%d", GET_OP (l, FT));
1439 infprintf (is, "0x%x", GET_OP (l, FT));
1445 infprintf (is, "$v%d", GET_OP (l, FD));
1449 infprintf (is, "$v%d", GET_OP (l, FS));
1453 infprintf (is, "$v%d", GET_OP (l, FT));
1457 /* xgettext:c-format */
1458 infprintf (is, _("# internal error, undefined modifier (%c)"), *d);
1464 /* Print the mips instruction at address MEMADDR in debugged memory,
1465 on using INFO. Returns length of the instruction, in bytes, which is
1466 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1467 this is little-endian code. */
1470 print_insn_mips (bfd_vma memaddr,
1472 struct disassemble_info *info)
1474 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1475 const fprintf_ftype infprintf = info->fprintf_func;
1476 const struct mips_opcode *op;
1477 static bfd_boolean init = 0;
1478 void *is = info->stream;
1480 /* Build a hash table to shorten the search time. */
1485 for (i = 0; i <= OP_MASK_OP; i++)
1487 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1489 if (op->pinfo == INSN_MACRO
1490 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1492 if (i == GET_OP (op->match, OP))
1503 info->bytes_per_chunk = INSNLEN;
1504 info->display_endian = info->endian;
1505 info->insn_info_valid = 1;
1506 info->branch_delay_insns = 0;
1507 info->data_size = 0;
1508 info->insn_type = dis_nonbranch;
1512 op = mips_hash[GET_OP (word, OP)];
1515 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1517 if (op->pinfo != INSN_MACRO
1518 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1519 && (word & op->mask) == op->match)
1523 /* We always allow to disassemble the jalx instruction. */
1524 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1525 && strcmp (op->name, "jalx"))
1528 /* Figure out instruction type and branch delay information. */
1529 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1531 if ((op->pinfo & (INSN_WRITE_GPR_31
1532 | INSN_WRITE_GPR_D)) != 0)
1533 info->insn_type = dis_jsr;
1535 info->insn_type = dis_branch;
1536 info->branch_delay_insns = 1;
1538 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1539 | INSN_COND_BRANCH_LIKELY)) != 0)
1541 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1542 info->insn_type = dis_condjsr;
1544 info->insn_type = dis_condbranch;
1545 info->branch_delay_insns = 1;
1547 else if ((op->pinfo & (INSN_STORE_MEMORY
1548 | INSN_LOAD_MEMORY_DELAY)) != 0)
1549 info->insn_type = dis_dref;
1551 infprintf (is, "%s", op->name);
1554 if (d != NULL && *d != '\0')
1556 infprintf (is, "\t");
1557 print_insn_args (d, word, memaddr, info, op);
1567 /* Handle undefined instructions. */
1568 info->insn_type = dis_noninsn;
1569 infprintf (is, "0x%x", word);
1573 /* Disassemble an operand for a mips16 instruction. */
1576 print_mips16_insn_arg (char type,
1577 const struct mips_opcode *op,
1579 bfd_boolean use_extend,
1582 struct disassemble_info *info)
1584 const fprintf_ftype infprintf = info->fprintf_func;
1585 void *is = info->stream;
1587 #define GET_OP(insn, field) \
1588 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1589 #define GET_OP_S(insn, field) \
1590 ((GET_OP (insn, field) ^ ((MIPS16OP_MASK_##field >> 1) + 1)) \
1591 - ((MIPS16OP_MASK_##field >> 1) + 1))
1597 infprintf (is, "%c", type);
1602 infprintf (is, "%s", mips16_reg_names (GET_OP (l, RY)));
1607 infprintf (is, "%s", mips16_reg_names (GET_OP (l, RX)));
1611 infprintf (is, "%s", mips16_reg_names (GET_OP (l, RZ)));
1615 infprintf (is, "%s", mips16_reg_names (GET_OP (l, MOVE32Z)));
1619 infprintf (is, "%s", mips_gpr_names[0]);
1623 infprintf (is, "%s", mips_gpr_names[29]);
1627 infprintf (is, "$pc");
1631 infprintf (is, "%s", mips_gpr_names[31]);
1635 infprintf (is, "%s", mips_gpr_names[GET_OP (l, REGR32)]);
1639 infprintf (is, "%s", mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
1665 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
1677 immed = GET_OP (l, RZ);
1683 immed = GET_OP (l, RX);
1689 immed = GET_OP (l, RZ);
1695 immed = GET_OP (l, RX);
1701 immed = GET_OP (l, IMM4);
1707 immed = GET_OP (l, IMM5);
1708 info->insn_type = dis_dref;
1709 info->data_size = 1;
1714 immed = GET_OP (l, IMM5);
1715 info->insn_type = dis_dref;
1716 info->data_size = 2;
1721 immed = GET_OP (l, IMM5);
1722 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1723 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1725 info->insn_type = dis_dref;
1726 info->data_size = 4;
1732 immed = GET_OP (l, IMM5);
1733 info->insn_type = dis_dref;
1734 info->data_size = 8;
1738 immed = GET_OP (l, IMM5);
1743 immed = GET_OP (l, IMM6);
1747 immed = GET_OP (l, IMM8);
1752 immed = GET_OP (l, IMM8);
1753 /* FIXME: This might be lw, or it might be addiu to $sp or
1754 $pc. We assume it's load. */
1755 info->insn_type = dis_dref;
1756 info->data_size = 4;
1761 immed = GET_OP (l, IMM8);
1762 info->insn_type = dis_dref;
1763 info->data_size = 8;
1767 immed = GET_OP (l, IMM8);
1772 immed = GET_OP (l, IMM8);
1778 immed = GET_OP (l, IMM8);
1783 immed = GET_OP (l, IMM8);
1790 immed = GET_OP (l, IMM11);
1798 immed = GET_OP (l, IMM8);
1800 /* FIXME: This can be lw or la. We assume it is lw. */
1801 info->insn_type = dis_dref;
1802 info->data_size = 4;
1807 immed = GET_OP (l, IMM5);
1809 info->insn_type = dis_dref;
1810 info->data_size = 8;
1815 immed = GET_OP (l, IMM5);
1824 if (signedp && immed >= (1 << (nbits - 1)))
1825 immed -= 1 << nbits;
1827 if ((type == '<' || type == '>' || type == '[' || type == ']')
1834 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1835 else if (extbits == 15)
1836 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1838 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1839 immed &= (1 << extbits) - 1;
1840 if (! extu && immed >= (1 << (extbits - 1)))
1841 immed -= 1 << extbits;
1845 infprintf (is, "%d", immed);
1853 baseaddr = memaddr + 2;
1855 else if (use_extend)
1856 baseaddr = memaddr - 2;
1864 /* If this instruction is in the delay slot of a jr
1865 instruction, the base address is the address of the
1866 jr instruction. If it is in the delay slot of jalr
1867 instruction, the base address is the address of the
1868 jalr instruction. This test is unreliable: we have
1869 no way of knowing whether the previous word is
1870 instruction or data. */
1871 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1874 && (((info->endian == BFD_ENDIAN_BIG
1875 ? bfd_getb16 (buffer)
1876 : bfd_getl16 (buffer))
1877 & 0xf800) == 0x1800))
1878 baseaddr = memaddr - 4;
1881 status = (*info->read_memory_func) (memaddr - 2, buffer,
1884 && (((info->endian == BFD_ENDIAN_BIG
1885 ? bfd_getb16 (buffer)
1886 : bfd_getl16 (buffer))
1887 & 0xf81f) == 0xe800))
1888 baseaddr = memaddr - 2;
1891 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1893 && info->flavour == bfd_target_unknown_flavour)
1894 /* For gdb disassembler, maintain odd address. */
1896 (*info->print_address_func) (info->target, info);
1903 int jalx = l & 0x400;
1907 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1908 if (!jalx && info->flavour == bfd_target_unknown_flavour)
1909 /* For gdb disassembler, maintain odd address. */
1912 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1913 (*info->print_address_func) (info->target, info);
1919 int need_comma, amask, smask;
1923 l = GET_OP (l, IMM6);
1925 amask = (l >> 3) & 7;
1927 if (amask > 0 && amask < 5)
1929 infprintf (is, "%s", mips_gpr_names[4]);
1931 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1935 smask = (l >> 1) & 3;
1938 infprintf (is, "%s??", need_comma ? "," : "");
1943 infprintf (is, "%s%s", need_comma ? "," : "", mips_gpr_names[16]);
1945 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1951 infprintf (is, "%s%s", need_comma ? "," : "", mips_gpr_names[31]);
1955 if (amask == 5 || amask == 6)
1957 infprintf (is, "%s$f0", need_comma ? "," : "");
1959 infprintf (is, "-$f1");
1966 /* MIPS16e save/restore. */
1969 int amask, args, statics;
1978 amask = (l >> 16) & 0xf;
1979 if (amask == MIPS16_ALL_ARGS)
1984 else if (amask == MIPS16_ALL_STATICS)
1992 statics = amask & 3;
1996 infprintf (is, "%s", mips_gpr_names[4]);
1998 infprintf (is, "-%s", mips_gpr_names[4 + args - 1]);
2002 framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
2003 if (framesz == 0 && !use_extend)
2006 infprintf (is, "%s%d", need_comma ? "," : "", framesz);
2008 if (l & 0x40) /* $ra */
2009 infprintf (is, ",%s", mips_gpr_names[31]);
2011 nsreg = (l >> 24) & 0x7;
2013 if (l & 0x20) /* $s0 */
2015 if (l & 0x10) /* $s1 */
2017 if (nsreg > 0) /* $s2-$s8 */
2018 smask |= ((1 << nsreg) - 1) << 2;
2020 /* Find first set static reg bit. */
2021 for (i = 0; i < 9; i++)
2023 if (smask & (1 << i))
2025 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
2026 /* Skip over string of set bits. */
2027 for (j = i; smask & (2 << j); j++)
2030 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
2035 /* Statics $ax - $a3. */
2037 infprintf (is, ",%s", mips_gpr_names[7]);
2038 else if (statics > 0)
2039 infprintf (is, ",%s-%s",
2040 mips_gpr_names[7 - statics + 1],
2046 /* xgettext:c-format */
2048 _("# internal disassembler error, "
2049 "unrecognised modifier (%c)"),
2055 /* Disassemble mips16 instructions. */
2058 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2060 const fprintf_ftype infprintf = info->fprintf_func;
2065 bfd_boolean use_extend;
2067 const struct mips_opcode *op, *opend;
2068 void *is = info->stream;
2070 info->bytes_per_chunk = 2;
2071 info->display_endian = info->endian;
2072 info->insn_info_valid = 1;
2073 info->branch_delay_insns = 0;
2074 info->data_size = 0;
2075 info->insn_type = dis_nonbranch;
2079 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2082 (*info->memory_error_func) (status, memaddr, info);
2088 if (info->endian == BFD_ENDIAN_BIG)
2089 insn = bfd_getb16 (buffer);
2091 insn = bfd_getl16 (buffer);
2093 /* Handle the extend opcode specially. */
2095 if ((insn & 0xf800) == 0xf000)
2098 extend = insn & 0x7ff;
2102 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2105 infprintf (is, "extend 0x%x", (unsigned int) extend);
2106 (*info->memory_error_func) (status, memaddr, info);
2110 if (info->endian == BFD_ENDIAN_BIG)
2111 insn = bfd_getb16 (buffer);
2113 insn = bfd_getl16 (buffer);
2115 /* Check for an extend opcode followed by an extend opcode. */
2116 if ((insn & 0xf800) == 0xf000)
2118 infprintf (is, "extend 0x%x", (unsigned int) extend);
2119 info->insn_type = dis_noninsn;
2126 /* FIXME: Should probably use a hash table on the major opcode here. */
2128 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2129 for (op = mips16_opcodes; op < opend; op++)
2131 if (op->pinfo != INSN_MACRO
2132 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2133 && (insn & op->mask) == op->match)
2137 if (strchr (op->args, 'a') != NULL)
2141 infprintf (is, "extend 0x%x", (unsigned int) extend);
2142 info->insn_type = dis_noninsn;
2150 status = (*info->read_memory_func) (memaddr, buffer, 2,
2155 if (info->endian == BFD_ENDIAN_BIG)
2156 extend = bfd_getb16 (buffer);
2158 extend = bfd_getl16 (buffer);
2163 infprintf (is, "%s", op->name);
2164 if (op->args[0] != '\0')
2165 infprintf (is, "\t");
2167 for (s = op->args; *s != '\0'; s++)
2171 && GET_OP (insn, RX) == GET_OP (insn, RY))
2173 /* Skip the register and the comma. */
2179 && GET_OP (insn, RZ) == GET_OP (insn, RX))
2181 /* Skip the register and the comma. */
2185 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
2189 /* Figure out branch instruction type and delay slot information. */
2190 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2191 info->branch_delay_insns = 1;
2192 if ((op->pinfo & (INSN_UNCOND_BRANCH_DELAY
2193 | MIPS16_INSN_UNCOND_BRANCH)) != 0)
2195 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2196 info->insn_type = dis_jsr;
2198 info->insn_type = dis_branch;
2200 else if ((op->pinfo & MIPS16_INSN_COND_BRANCH) != 0)
2201 info->insn_type = dis_condbranch;
2210 infprintf (is, "0x%x", extend | 0xf000);
2211 infprintf (is, "0x%x", insn);
2212 info->insn_type = dis_noninsn;
2217 /* Disassemble microMIPS instructions. */
2220 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2222 const fprintf_ftype infprintf = info->fprintf_func;
2223 const struct mips_opcode *op, *opend;
2224 unsigned int lsb, msbd, msb;
2225 void *is = info->stream;
2238 info->bytes_per_chunk = 2;
2239 info->display_endian = info->endian;
2240 info->insn_info_valid = 1;
2241 info->branch_delay_insns = 0;
2242 info->data_size = 0;
2243 info->insn_type = dis_nonbranch;
2247 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2250 (*info->memory_error_func) (status, memaddr, info);
2256 if (info->endian == BFD_ENDIAN_BIG)
2257 insn = bfd_getb16 (buffer);
2259 insn = bfd_getl16 (buffer);
2261 if ((insn & 0xfc00) == 0x7c00)
2263 /* This is a 48-bit microMIPS instruction. */
2266 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2269 infprintf (is, "micromips 0x%x", higher);
2270 (*info->memory_error_func) (status, memaddr + 2, info);
2273 if (info->endian == BFD_ENDIAN_BIG)
2274 insn = bfd_getb16 (buffer);
2276 insn = bfd_getl16 (buffer);
2277 higher = (higher << 16) | insn;
2279 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
2282 infprintf (is, "micromips 0x%x", higher);
2283 (*info->memory_error_func) (status, memaddr + 4, info);
2286 if (info->endian == BFD_ENDIAN_BIG)
2287 insn = bfd_getb16 (buffer);
2289 insn = bfd_getl16 (buffer);
2290 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
2292 info->insn_type = dis_noninsn;
2295 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2297 /* This is a 32-bit microMIPS instruction. */
2300 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2303 infprintf (is, "micromips 0x%x", higher);
2304 (*info->memory_error_func) (status, memaddr + 2, info);
2308 if (info->endian == BFD_ENDIAN_BIG)
2309 insn = bfd_getb16 (buffer);
2311 insn = bfd_getl16 (buffer);
2313 insn = insn | (higher << 16);
2318 /* FIXME: Should probably use a hash table on the major opcode here. */
2320 #define GET_OP(insn, field) \
2321 (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2322 #define GET_OP_S(insn, field) \
2323 ((GET_OP (insn, field) ^ ((MICROMIPSOP_MASK_##field >> 1) + 1)) \
2324 - ((MICROMIPSOP_MASK_##field >> 1) + 1))
2325 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2326 for (op = micromips_opcodes; op < opend; op++)
2328 if (op->pinfo != INSN_MACRO
2329 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2330 && (insn & op->mask) == op->match
2331 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2332 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2336 infprintf (is, "%s", op->name);
2337 if (op->args[0] != '\0')
2338 infprintf (is, "\t");
2340 for (s = op->args; *s != '\0'; s++)
2347 infprintf (is, "%c", *s);
2351 infprintf (is, "%d", GET_OP_S (insn, OFFSET10));
2355 infprintf (is, "0x%x", GET_OP (insn, STYPE));
2359 infprintf (is, "0x%x", GET_OP (insn, BP));
2363 infprintf (is, "0x%x", GET_OP (insn, SA3));
2367 infprintf (is, "0x%x", GET_OP (insn, SA4));
2371 infprintf (is, "0x%x", GET_OP (insn, IMM8));
2375 infprintf (is, "0x%x", GET_OP (insn, RS));
2379 infprintf (is, "$ac%d", GET_OP (insn, DSPACC));
2383 infprintf (is, "0x%x", GET_OP (insn, WRDSP));
2386 case '0': /* DSP 6-bit signed immediate in bit 16. */
2387 delta = (GET_OP (insn, DSPSFT) ^ 0x20) - 0x20;
2388 infprintf (is, "%d", delta);
2392 infprintf (is, "0x%x", GET_OP (insn, SHAMT));
2396 infprintf (is, "0x%x", GET_OP (insn, 3BITPOS));
2400 infprintf (is, "0x%x", GET_OP (insn, RD));
2404 infprintf (is, "0x%x", GET_OP (insn, TRAP));
2408 infprintf (is, "%d", GET_OP_S (insn, OFFSET12));
2412 if (strcmp (op->name, "jalx") == 0)
2413 info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff)
2414 | (GET_OP (insn, TARGET) << 2));
2416 info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff)
2417 | (GET_OP (insn, TARGET) << 1));
2418 /* For gdb disassembler, force odd address on jalx. */
2419 if (info->flavour == bfd_target_unknown_flavour
2420 && strcmp (op->name, "jalx") == 0)
2422 (*info->print_address_func) (info->target, info);
2429 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]);
2433 infprintf (is, "0x%x", GET_OP (insn, CODE));
2437 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]);
2441 infprintf (is, "0x%x", GET_OP (insn, PREFX));
2446 infprintf (is, "0x%x", GET_OP (insn, IMMEDIATE));
2449 case 'j': /* Same as i, but sign-extended. */
2451 infprintf (is, "%d", GET_OP_S (insn, DELTA));
2455 infprintf (is, "0x%x", GET_OP (insn, CACHE));
2462 immed = GET_OP (insn, RT);
2463 s_reg_encode = immed & 0xf;
2464 if (s_reg_encode != 0)
2466 if (s_reg_encode == 1)
2467 infprintf (is, "%s", mips_gpr_names[16]);
2468 else if (s_reg_encode < 9)
2469 infprintf (is, "%s-%s",
2471 mips_gpr_names[15 + s_reg_encode]);
2472 else if (s_reg_encode == 9)
2473 infprintf (is, "%s-%s,%s",
2476 mips_gpr_names[30]);
2478 infprintf (is, "UNKNOWN");
2481 if (immed & 0x10) /* For ra. */
2483 if (s_reg_encode == 0)
2484 infprintf (is, "%s", mips_gpr_names[31]);
2486 infprintf (is, ",%s", mips_gpr_names[31]);
2492 /* Sign-extend the displacement. */
2493 delta = GET_OP_S (insn, DELTA);
2494 info->target = (delta << 1) + memaddr + length;
2495 (*info->print_address_func) (info->target, info);
2499 infprintf (is, "0x%x", GET_OP (insn, CODE2));
2504 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]);
2508 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]);
2512 infprintf (is, "%s", mips_gpr_names[0]);
2515 case '@': /* DSP 10-bit signed immediate in bit 16. */
2516 delta = (GET_OP (insn, IMM10) ^ 0x200) - 0x200;
2517 infprintf (is, "%d", delta);
2521 infprintf (is, "0x%x", GET_OP (insn, CODE10));
2525 infprintf (is, "0x%x", GET_OP (insn, COPZ));
2529 infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]);
2533 /* Coprocessor register for lwcN instructions, et al.
2535 Note that there is no load/store cp0 instructions, and
2536 that FPU (cp1) instructions disassemble this field using
2537 'T' format. Therefore, until we gain understanding of
2538 cp2 register names, we can simply print the register
2540 infprintf (is, "$%d", GET_OP (insn, RT));
2544 /* Coprocessor register for mtcN instructions, et al. Note
2545 that FPU (cp1) instructions disassemble this field using
2546 'S' format. Therefore, we only need to worry about cp0,
2548 The microMIPS encoding does not have a coprocessor
2549 identifier field as such, so we must work out the
2550 coprocessor number by looking at the opcode. */
2552 & ~((MICROMIPSOP_MASK_RT << MICROMIPSOP_SH_RT)
2553 | (MICROMIPSOP_MASK_RS << MICROMIPSOP_SH_RS)))
2555 case 0x000000fc: /* mfc0 */
2556 case 0x000002fc: /* mtc0 */
2557 case 0x000004fc: /* mfgc0 */
2558 case 0x000006fc: /* mtgc0 */
2559 case 0x580000fc: /* dmfc0 */
2560 case 0x580002fc: /* dmtc0 */
2561 case 0x580000e7: /* dmfgc0 */
2562 case 0x580002e7: /* dmtgc0 */
2563 infprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]);
2566 infprintf (is, "$%d", GET_OP (insn, RS));
2572 infprintf (is, "%d", GET_OP (insn, SEL));
2576 infprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]);
2580 infprintf (is, "$fcc%d", GET_OP (insn, CCC));
2585 (op->pinfo & (FP_D | FP_S)) != 0
2586 ? "$fcc%d" : "$cc%d",
2587 GET_OP (insn, BCC));
2591 infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]);
2596 infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]);
2600 infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]);
2604 /* Extension character; switch for second char. */
2609 lsb = GET_OP (insn, EXTLSB);
2610 infprintf (is, "0x%x", lsb);
2614 msb = GET_OP (insn, INSMSB);
2615 infprintf (is, "0x%x", msb - lsb + 1);
2620 msbd = GET_OP (insn, EXTMSBD);
2621 infprintf (is, "0x%x", msbd + 1);
2626 const struct mips_cp0sel_name *n;
2627 unsigned int cp0reg, sel;
2629 cp0reg = GET_OP (insn, RS);
2630 sel = GET_OP (insn, SEL);
2632 /* CP0 register including 'sel' code for mtcN
2633 (et al.), to be printed textually if known.
2634 If not known, print both CP0 register name and
2635 sel numerically since CP0 register with sel 0 may
2636 have a name unrelated to register being printed. */
2637 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2638 mips_cp0sel_names_len,
2641 infprintf (is, "%s", n->name);
2643 infprintf (is, "$%d,%d", cp0reg, sel);
2648 lsb = GET_OP (insn, EXTLSB) + 32;
2649 infprintf (is, "0x%x", lsb);
2653 msb = GET_OP (insn, INSMSB) + 32;
2654 infprintf (is, "0x%x", msb - lsb + 1);
2658 msbd = GET_OP (insn, EXTMSBD) + 32;
2659 infprintf (is, "0x%x", msbd + 1);
2663 /* xgettext:c-format */
2665 _("# internal disassembler error, "
2666 "unrecognized modifier (+%c)"),
2673 /* Extension character; switch for second char. */
2677 case 'a': /* global pointer. */
2678 infprintf (is, "%s", mips_gpr_names[28]);
2682 regno = micromips_to_32_reg_b_map[GET_OP (insn, MB)];
2683 infprintf (is, "%s", mips_gpr_names[regno]);
2687 regno = micromips_to_32_reg_c_map[GET_OP (insn, MC)];
2688 infprintf (is, "%s", mips_gpr_names[regno]);
2692 regno = micromips_to_32_reg_d_map[GET_OP (insn, MD)];
2693 infprintf (is, "%s", mips_gpr_names[regno]);
2697 regno = micromips_to_32_reg_e_map[GET_OP (insn, ME)];
2698 infprintf (is, "%s", mips_gpr_names[regno]);
2702 /* Save lastregno for "mt" to print out later. */
2703 lastregno = micromips_to_32_reg_f_map[GET_OP (insn, MF)];
2704 infprintf (is, "%s", mips_gpr_names[lastregno]);
2708 regno = micromips_to_32_reg_g_map[GET_OP (insn, MG)];
2709 infprintf (is, "%s", mips_gpr_names[regno]);
2713 regno = micromips_to_32_reg_h_map[GET_OP (insn, MH)];
2714 infprintf (is, "%s", mips_gpr_names[regno]);
2718 regno = micromips_to_32_reg_i_map[GET_OP (insn, MI)];
2719 infprintf (is, "%s", mips_gpr_names[regno]);
2723 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]);
2727 regno = micromips_to_32_reg_l_map[GET_OP (insn, ML)];
2728 infprintf (is, "%s", mips_gpr_names[regno]);
2732 regno = micromips_to_32_reg_m_map[GET_OP (insn, MM)];
2733 infprintf (is, "%s", mips_gpr_names[regno]);
2737 regno = micromips_to_32_reg_n_map[GET_OP (insn, MN)];
2738 infprintf (is, "%s", mips_gpr_names[regno]);
2742 /* Save lastregno for "mt" to print out later. */
2743 lastregno = GET_OP (insn, MP);
2744 infprintf (is, "%s", mips_gpr_names[lastregno]);
2748 regno = micromips_to_32_reg_q_map[GET_OP (insn, MQ)];
2749 infprintf (is, "%s", mips_gpr_names[regno]);
2752 case 'r': /* program counter. */
2753 infprintf (is, "$pc");
2756 case 's': /* stack pointer. */
2758 infprintf (is, "%s", mips_gpr_names[29]);
2762 infprintf (is, "%s", mips_gpr_names[lastregno]);
2766 infprintf (is, "%s", mips_gpr_names[0]);
2770 /* Sign-extend the immediate. */
2771 immed = GET_OP_S (insn, IMMA) << 2;
2772 infprintf (is, "%d", immed);
2776 immed = micromips_imm_b_map[GET_OP (insn, IMMB)];
2777 infprintf (is, "%d", immed);
2781 immed = micromips_imm_c_map[GET_OP (insn, IMMC)];
2782 infprintf (is, "0x%x", immed);
2786 /* Sign-extend the displacement. */
2787 delta = GET_OP_S (insn, IMMD);
2788 info->target = (delta << 1) + memaddr + length;
2789 (*info->print_address_func) (info->target, info);
2793 /* Sign-extend the displacement. */
2794 delta = GET_OP_S (insn, IMME);
2795 info->target = (delta << 1) + memaddr + length;
2796 (*info->print_address_func) (info->target, info);
2800 immed = GET_OP (insn, IMMF);
2801 infprintf (is, "0x%x", immed);
2805 immed = (insn >> MICROMIPSOP_SH_IMMG) + 1;
2806 immed = (immed & MICROMIPSOP_MASK_IMMG) - 1;
2807 infprintf (is, "%d", immed);
2811 immed = GET_OP (insn, IMMH) << 1;
2812 infprintf (is, "%d", immed);
2816 immed = (insn >> MICROMIPSOP_SH_IMMI) + 1;
2817 immed = (immed & MICROMIPSOP_MASK_IMMI) - 1;
2818 infprintf (is, "%d", immed);
2822 immed = GET_OP (insn, IMMJ) << 2;
2823 infprintf (is, "%d", immed);
2827 immed = GET_OP (insn, IMML);
2828 infprintf (is, "%d", immed);
2832 immed = (insn >> MICROMIPSOP_SH_IMMM) - 1;
2833 immed = (immed & MICROMIPSOP_MASK_IMMM) + 1;
2834 infprintf (is, "%d", immed);
2838 immed = GET_OP (insn, IMMN);
2840 infprintf (is, "%s,%s",
2842 mips_gpr_names[31]);
2844 infprintf (is, "%s-%s,%s",
2846 mips_gpr_names[16 + immed],
2847 mips_gpr_names[31]);
2851 immed = GET_OP (insn, IMMO);
2852 infprintf (is, "0x%x", immed);
2856 immed = GET_OP (insn, IMMP) << 2;
2857 infprintf (is, "%d", immed);
2861 /* Sign-extend the immediate. */
2862 immed = GET_OP_S (insn, IMMQ) << 2;
2863 infprintf (is, "%d", immed);
2867 immed = GET_OP (insn, IMMU) << 2;
2868 infprintf (is, "%d", immed);
2872 immed = GET_OP (insn, IMMW) << 2;
2873 infprintf (is, "%d", immed);
2877 /* Sign-extend the immediate. */
2878 immed = GET_OP_S (insn, IMMX);
2879 infprintf (is, "%d", immed);
2883 /* Sign-extend the immediate. */
2884 immed = GET_OP_S (insn, IMMY) << 2;
2885 if ((unsigned int) (immed + 8) < 16)
2887 infprintf (is, "%d", immed);
2891 /* xgettext:c-format */
2893 _("# internal disassembler error, "
2894 "unrecognized modifier (m%c)"),
2901 /* xgettext:c-format */
2903 _("# internal disassembler error, "
2904 "unrecognized modifier (%c)"),
2910 /* Figure out instruction type and branch delay information. */
2912 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2913 info->branch_delay_insns = 1;
2914 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2915 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2917 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_GPR_T)) != 0)
2918 info->insn_type = dis_jsr;
2920 info->insn_type = dis_branch;
2922 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2923 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2925 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2926 info->insn_type = dis_condjsr;
2928 info->insn_type = dis_condbranch;
2931 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY_DELAY)) != 0)
2932 info->insn_type = dis_dref;
2940 infprintf (is, "0x%x", insn);
2941 info->insn_type = dis_noninsn;
2946 /* Return 1 if a symbol associated with the location being disassembled
2947 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2948 all the symbols at the address being considered assuming if at least
2949 one of them indicates code compression, then such code has been
2950 genuinely produced here (other symbols could have been derived from
2951 function symbols defined elsewhere or could define data). Otherwise,
2955 is_compressed_mode_p (struct disassemble_info *info)
2957 elf_symbol_type *symbol;
2961 for (i = 0; i < info->num_symbols; i++)
2963 pos = info->symtab_pos + i;
2965 if (bfd_asymbol_flavour (info->symtab[pos]) != bfd_target_elf_flavour)
2968 if (info->symtab[pos]->section != info->section)
2971 symbol = (elf_symbol_type *) info->symtab[pos];
2973 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2975 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2982 /* In an environment where we do not know the symbol type of the
2983 instruction we are forced to assume that the low order bit of the
2984 instructions' address may mark it as a mips16 instruction. If we
2985 are single stepping, or the pc is within the disassembled function,
2986 this works. Otherwise, we need a clue. Sometimes. */
2989 _print_insn_mips (bfd_vma memaddr,
2990 struct disassemble_info *info,
2991 enum bfd_endian endianness)
2993 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
2994 bfd_byte buffer[INSNLEN];
2997 set_default_mips_dis_options (info);
2998 parse_mips_dis_options (info->disassembler_options);
3000 if (info->mach == bfd_mach_mips16)
3001 return print_insn_mips16 (memaddr, info);
3002 if (info->mach == bfd_mach_mips_micromips)
3003 return print_insn_micromips (memaddr, info);
3005 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
3008 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
3009 /* Only a few tools will work this way. */
3011 return print_insn_compr (memaddr, info);
3014 #if SYMTAB_AVAILABLE
3015 if (is_compressed_mode_p (info))
3016 return print_insn_compr (memaddr, info);
3019 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
3024 if (endianness == BFD_ENDIAN_BIG)
3025 insn = bfd_getb32 (buffer);
3027 insn = bfd_getl32 (buffer);
3029 return print_insn_mips (memaddr, insn, info);
3033 (*info->memory_error_func) (status, memaddr, info);
3039 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
3041 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
3045 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
3047 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
3051 print_mips_disassembler_options (FILE *stream)
3055 fprintf (stream, _("\n\
3056 The following MIPS specific disassembler options are supported for use\n\
3057 with the -M switch (multiple options should be separated by commas):\n"));
3059 fprintf (stream, _("\n\
3060 virt Recognize the virtualization ASE instructions.\n"));
3062 fprintf (stream, _("\n\
3063 gpr-names=ABI Print GPR names according to specified ABI.\n\
3064 Default: based on binary being disassembled.\n"));
3066 fprintf (stream, _("\n\
3067 fpr-names=ABI Print FPR names according to specified ABI.\n\
3068 Default: numeric.\n"));
3070 fprintf (stream, _("\n\
3071 cp0-names=ARCH Print CP0 register names according to\n\
3072 specified architecture.\n\
3073 Default: based on binary being disassembled.\n"));
3075 fprintf (stream, _("\n\
3076 hwr-names=ARCH Print HWR names according to specified \n\
3078 Default: based on binary being disassembled.\n"));
3080 fprintf (stream, _("\n\
3081 reg-names=ABI Print GPR and FPR names according to\n\
3082 specified ABI.\n"));
3084 fprintf (stream, _("\n\
3085 reg-names=ARCH Print CP0 register and HWR names according to\n\
3086 specified architecture.\n"));
3088 fprintf (stream, _("\n\
3089 For the options above, the following values are supported for \"ABI\":\n\
3091 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
3092 fprintf (stream, " %s", mips_abi_choices[i].name);
3093 fprintf (stream, _("\n"));
3095 fprintf (stream, _("\n\
3096 For the options above, The following values are supported for \"ARCH\":\n\
3098 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
3099 if (*mips_arch_choices[i].name != '\0')
3100 fprintf (stream, " %s", mips_arch_choices[i].name);
3101 fprintf (stream, _("\n"));
3103 fprintf (stream, _("\n"));