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_EVA
| ASE_MIPS3D
595 | ASE_MT
| 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_EVA
| ASE_MT
610 | ASE_MDMX
| 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
)]);
1155 case 'j': /* 9-bit signed offset in bit 7. */
1156 infprintf (is
, "%d", GET_OP_S (l
, EVAOFFSET
));
1160 /* xgettext:c-format */
1162 _("# internal error, "
1163 "undefined extension sequence (+%c)"),
1170 infprintf (is
, "0x%x", GET_OP (l
, BP
));
1174 infprintf (is
, "0x%x", GET_OP (l
, SA3
));
1178 infprintf (is
, "0x%x", GET_OP (l
, SA4
));
1182 infprintf (is
, "0x%x", GET_OP (l
, IMM8
));
1186 infprintf (is
, "0x%x", GET_OP (l
, RS
));
1190 infprintf (is
, "$ac%d", GET_OP (l
, DSPACC
));
1194 infprintf (is
, "0x%x", GET_OP (l
, WRDSP
));
1198 infprintf (is
, "$ac%d", GET_OP (l
, DSPACC_S
));
1201 case '0': /* dsp 6-bit signed immediate in bit 20 */
1202 infprintf (is
, "%d", GET_OP_S (l
, DSPSFT
));
1205 case ':': /* dsp 7-bit signed immediate in bit 19 */
1206 infprintf (is
, "%d", GET_OP_S (l
, DSPSFT_7
));
1210 infprintf (is
, "%d", GET_OP_S (l
, OFFSET12
));
1214 infprintf (is
, "0x%x", GET_OP (l
, 3BITPOS
));
1218 infprintf (is
, "0x%x", GET_OP (l
, RDDSP
));
1221 case '@': /* dsp 10-bit signed immediate in bit 16 */
1222 infprintf (is
, "%d", GET_OP_S (l
, IMM10
));
1226 infprintf (is
, "%d", GET_OP (l
, MT_U
));
1230 infprintf (is
, "%d", GET_OP (l
, MT_H
));
1234 infprintf (is
, "$ac%d", GET_OP (l
, MTACC_T
));
1238 infprintf (is
, "$ac%d", GET_OP (l
, MTACC_D
));
1242 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
1243 infprintf (is
, "$%d", GET_OP (l
, RD
));
1250 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RS
)]);
1255 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RT
)]);
1260 infprintf (is
, "0x%x", GET_OP (l
, IMMEDIATE
));
1263 case 'j': /* Same as i, but sign-extended. */
1265 infprintf (is
, "%d", GET_OP_S (l
, DELTA
));
1269 infprintf (is
, "0x%x", GET_OP (l
, PREFX
));
1273 infprintf (is
, "0x%x", GET_OP (l
, CACHE
));
1277 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
1278 | (GET_OP (l
, TARGET
) << 2));
1279 /* For gdb disassembler, force odd address on jalx. */
1280 if (info
->flavour
== bfd_target_unknown_flavour
1281 && strcmp (opp
->name
, "jalx") == 0)
1283 (*info
->print_address_func
) (info
->target
, info
);
1287 /* Sign extend the displacement. */
1288 info
->target
= (GET_OP_S (l
, DELTA
) << 2) + pc
+ INSNLEN
;
1289 (*info
->print_address_func
) (info
->target
, info
);
1293 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RD
)]);
1298 /* First check for both rd and rt being equal. */
1301 reg
= GET_OP (l
, RD
);
1302 if (reg
== GET_OP (l
, RT
))
1303 infprintf (is
, "%s", mips_gpr_names
[reg
]);
1306 /* If one is zero use the other. */
1308 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RT
)]);
1309 else if (GET_OP (l
, RT
) == 0)
1310 infprintf (is
, "%s", mips_gpr_names
[reg
]);
1311 else /* Bogus, result depends on processor. */
1312 infprintf (is
, "%s or %s",
1313 mips_gpr_names
[reg
],
1314 mips_gpr_names
[GET_OP (l
, RT
)]);
1320 infprintf (is
, "%s", mips_gpr_names
[0]);
1325 infprintf (is
, "0x%x", GET_OP (l
, SHAMT
));
1329 infprintf (is
, "0x%x", GET_OP (l
, CODE
));
1333 infprintf (is
, "0x%x", GET_OP (l
, CODE2
));
1337 infprintf (is
, "0x%x", GET_OP (l
, COPZ
));
1341 infprintf (is
, "0x%x", GET_OP (l
, CODE20
));
1345 infprintf (is
, "0x%x", GET_OP (l
, CODE19
));
1350 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FS
)]);
1355 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FT
)]);
1359 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FD
)]);
1363 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FR
)]);
1367 /* Coprocessor register for lwcN instructions, et al.
1369 Note that there is no load/store cp0 instructions, and
1370 that FPU (cp1) instructions disassemble this field using
1371 'T' format. Therefore, until we gain understanding of
1372 cp2 register names, we can simply print the register
1374 infprintf (is
, "$%d", GET_OP (l
, RT
));
1378 /* Coprocessor register for mtcN instructions, et al. Note
1379 that FPU (cp1) instructions disassemble this field using
1380 'S' format. Therefore, we only need to worry about cp0,
1382 op
= GET_OP (l
, OP
);
1383 if (op
== OP_OP_COP0
)
1384 infprintf (is
, "%s", mips_cp0_names
[GET_OP (l
, RD
)]);
1386 infprintf (is
, "$%d", GET_OP (l
, RD
));
1390 infprintf (is
, "%s", mips_hwr_names
[GET_OP (l
, RD
)]);
1395 (opp
->pinfo
& (FP_D
| FP_S
)) != 0 ? "$fcc%d" : "$cc%d",
1400 infprintf (is
, "$fcc%d", GET_OP (l
, CCC
));
1404 infprintf (is
, "%d", GET_OP (l
, PERFREG
));
1408 infprintf (is
, "%d", GET_OP (l
, VECBYTE
));
1412 infprintf (is
, "%d", GET_OP (l
, VECALIGN
));
1416 infprintf (is
, "%d", GET_OP (l
, SEL
));
1420 infprintf (is
, "%d", GET_OP (l
, ALN
));
1425 unsigned int vsel
= GET_OP (l
, VSEL
);
1427 if ((vsel
& 0x10) == 0)
1432 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1433 if ((vsel
& 1) == 0)
1435 infprintf (is
, "$v%d[%d]", GET_OP (l
, FT
), vsel
>> 1);
1437 else if ((vsel
& 0x08) == 0)
1439 infprintf (is
, "$v%d", GET_OP (l
, FT
));
1443 infprintf (is
, "0x%x", GET_OP (l
, FT
));
1449 infprintf (is
, "$v%d", GET_OP (l
, FD
));
1453 infprintf (is
, "$v%d", GET_OP (l
, FS
));
1457 infprintf (is
, "$v%d", GET_OP (l
, FT
));
1461 /* xgettext:c-format */
1462 infprintf (is
, _("# internal error, undefined modifier (%c)"), *d
);
1468 /* Print the mips instruction at address MEMADDR in debugged memory,
1469 on using INFO. Returns length of the instruction, in bytes, which is
1470 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1471 this is little-endian code. */
1474 print_insn_mips (bfd_vma memaddr
,
1476 struct disassemble_info
*info
)
1478 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1479 const fprintf_ftype infprintf
= info
->fprintf_func
;
1480 const struct mips_opcode
*op
;
1481 static bfd_boolean init
= 0;
1482 void *is
= info
->stream
;
1484 /* Build a hash table to shorten the search time. */
1489 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1491 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1493 if (op
->pinfo
== INSN_MACRO
1494 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1496 if (i
== GET_OP (op
->match
, OP
))
1507 info
->bytes_per_chunk
= INSNLEN
;
1508 info
->display_endian
= info
->endian
;
1509 info
->insn_info_valid
= 1;
1510 info
->branch_delay_insns
= 0;
1511 info
->data_size
= 0;
1512 info
->insn_type
= dis_nonbranch
;
1516 op
= mips_hash
[GET_OP (word
, OP
)];
1519 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1521 if (op
->pinfo
!= INSN_MACRO
1522 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1523 && (word
& op
->mask
) == op
->match
)
1527 /* We always allow to disassemble the jalx instruction. */
1528 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1529 && strcmp (op
->name
, "jalx"))
1532 /* Figure out instruction type and branch delay information. */
1533 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1535 if ((op
->pinfo
& (INSN_WRITE_GPR_31
1536 | INSN_WRITE_GPR_D
)) != 0)
1537 info
->insn_type
= dis_jsr
;
1539 info
->insn_type
= dis_branch
;
1540 info
->branch_delay_insns
= 1;
1542 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1543 | INSN_COND_BRANCH_LIKELY
)) != 0)
1545 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1546 info
->insn_type
= dis_condjsr
;
1548 info
->insn_type
= dis_condbranch
;
1549 info
->branch_delay_insns
= 1;
1551 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1552 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1553 info
->insn_type
= dis_dref
;
1555 infprintf (is
, "%s", op
->name
);
1558 if (d
!= NULL
&& *d
!= '\0')
1560 infprintf (is
, "\t");
1561 print_insn_args (d
, word
, memaddr
, info
, op
);
1571 /* Handle undefined instructions. */
1572 info
->insn_type
= dis_noninsn
;
1573 infprintf (is
, "0x%x", word
);
1577 /* Disassemble an operand for a mips16 instruction. */
1580 print_mips16_insn_arg (char type
,
1581 const struct mips_opcode
*op
,
1583 bfd_boolean use_extend
,
1586 struct disassemble_info
*info
)
1588 const fprintf_ftype infprintf
= info
->fprintf_func
;
1589 void *is
= info
->stream
;
1591 #define GET_OP(insn, field) \
1592 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1593 #define GET_OP_S(insn, field) \
1594 ((GET_OP (insn, field) ^ ((MIPS16OP_MASK_##field >> 1) + 1)) \
1595 - ((MIPS16OP_MASK_##field >> 1) + 1))
1601 infprintf (is
, "%c", type
);
1606 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RY
)));
1611 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RX
)));
1615 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RZ
)));
1619 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, MOVE32Z
)));
1623 infprintf (is
, "%s", mips_gpr_names
[0]);
1627 infprintf (is
, "%s", mips_gpr_names
[29]);
1631 infprintf (is
, "$pc");
1635 infprintf (is
, "%s", mips_gpr_names
[31]);
1639 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, REGR32
)]);
1643 infprintf (is
, "%s", mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1669 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1681 immed
= GET_OP (l
, RZ
);
1687 immed
= GET_OP (l
, RX
);
1693 immed
= GET_OP (l
, RZ
);
1699 immed
= GET_OP (l
, RX
);
1705 immed
= GET_OP (l
, IMM4
);
1711 immed
= GET_OP (l
, IMM5
);
1712 info
->insn_type
= dis_dref
;
1713 info
->data_size
= 1;
1718 immed
= GET_OP (l
, IMM5
);
1719 info
->insn_type
= dis_dref
;
1720 info
->data_size
= 2;
1725 immed
= GET_OP (l
, IMM5
);
1726 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1727 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1729 info
->insn_type
= dis_dref
;
1730 info
->data_size
= 4;
1736 immed
= GET_OP (l
, IMM5
);
1737 info
->insn_type
= dis_dref
;
1738 info
->data_size
= 8;
1742 immed
= GET_OP (l
, IMM5
);
1747 immed
= GET_OP (l
, IMM6
);
1751 immed
= GET_OP (l
, IMM8
);
1756 immed
= GET_OP (l
, IMM8
);
1757 /* FIXME: This might be lw, or it might be addiu to $sp or
1758 $pc. We assume it's load. */
1759 info
->insn_type
= dis_dref
;
1760 info
->data_size
= 4;
1765 immed
= GET_OP (l
, IMM8
);
1766 info
->insn_type
= dis_dref
;
1767 info
->data_size
= 8;
1771 immed
= GET_OP (l
, IMM8
);
1776 immed
= GET_OP (l
, IMM8
);
1782 immed
= GET_OP (l
, IMM8
);
1787 immed
= GET_OP (l
, IMM8
);
1794 immed
= GET_OP (l
, IMM11
);
1802 immed
= GET_OP (l
, IMM8
);
1804 /* FIXME: This can be lw or la. We assume it is lw. */
1805 info
->insn_type
= dis_dref
;
1806 info
->data_size
= 4;
1811 immed
= GET_OP (l
, IMM5
);
1813 info
->insn_type
= dis_dref
;
1814 info
->data_size
= 8;
1819 immed
= GET_OP (l
, IMM5
);
1828 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1829 immed
-= 1 << nbits
;
1831 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1838 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1839 else if (extbits
== 15)
1840 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1842 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1843 immed
&= (1 << extbits
) - 1;
1844 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1845 immed
-= 1 << extbits
;
1849 infprintf (is
, "%d", immed
);
1857 baseaddr
= memaddr
+ 2;
1859 else if (use_extend
)
1860 baseaddr
= memaddr
- 2;
1868 /* If this instruction is in the delay slot of a jr
1869 instruction, the base address is the address of the
1870 jr instruction. If it is in the delay slot of jalr
1871 instruction, the base address is the address of the
1872 jalr instruction. This test is unreliable: we have
1873 no way of knowing whether the previous word is
1874 instruction or data. */
1875 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1878 && (((info
->endian
== BFD_ENDIAN_BIG
1879 ? bfd_getb16 (buffer
)
1880 : bfd_getl16 (buffer
))
1881 & 0xf800) == 0x1800))
1882 baseaddr
= memaddr
- 4;
1885 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1888 && (((info
->endian
== BFD_ENDIAN_BIG
1889 ? bfd_getb16 (buffer
)
1890 : bfd_getl16 (buffer
))
1891 & 0xf81f) == 0xe800))
1892 baseaddr
= memaddr
- 2;
1895 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1897 && info
->flavour
== bfd_target_unknown_flavour
)
1898 /* For gdb disassembler, maintain odd address. */
1900 (*info
->print_address_func
) (info
->target
, info
);
1907 int jalx
= l
& 0x400;
1911 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1912 if (!jalx
&& info
->flavour
== bfd_target_unknown_flavour
)
1913 /* For gdb disassembler, maintain odd address. */
1916 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1917 (*info
->print_address_func
) (info
->target
, info
);
1923 int need_comma
, amask
, smask
;
1927 l
= GET_OP (l
, IMM6
);
1929 amask
= (l
>> 3) & 7;
1931 if (amask
> 0 && amask
< 5)
1933 infprintf (is
, "%s", mips_gpr_names
[4]);
1935 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1939 smask
= (l
>> 1) & 3;
1942 infprintf (is
, "%s??", need_comma
? "," : "");
1947 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[16]);
1949 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1955 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[31]);
1959 if (amask
== 5 || amask
== 6)
1961 infprintf (is
, "%s$f0", need_comma
? "," : "");
1963 infprintf (is
, "-$f1");
1970 /* MIPS16e save/restore. */
1973 int amask
, args
, statics
;
1982 amask
= (l
>> 16) & 0xf;
1983 if (amask
== MIPS16_ALL_ARGS
)
1988 else if (amask
== MIPS16_ALL_STATICS
)
1996 statics
= amask
& 3;
2000 infprintf (is
, "%s", mips_gpr_names
[4]);
2002 infprintf (is
, "-%s", mips_gpr_names
[4 + args
- 1]);
2006 framesz
= (((l
>> 16) & 0xf0) | (l
& 0x0f)) * 8;
2007 if (framesz
== 0 && !use_extend
)
2010 infprintf (is
, "%s%d", need_comma
? "," : "", framesz
);
2012 if (l
& 0x40) /* $ra */
2013 infprintf (is
, ",%s", mips_gpr_names
[31]);
2015 nsreg
= (l
>> 24) & 0x7;
2017 if (l
& 0x20) /* $s0 */
2019 if (l
& 0x10) /* $s1 */
2021 if (nsreg
> 0) /* $s2-$s8 */
2022 smask
|= ((1 << nsreg
) - 1) << 2;
2024 /* Find first set static reg bit. */
2025 for (i
= 0; i
< 9; i
++)
2027 if (smask
& (1 << i
))
2029 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
2030 /* Skip over string of set bits. */
2031 for (j
= i
; smask
& (2 << j
); j
++)
2034 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
2039 /* Statics $ax - $a3. */
2041 infprintf (is
, ",%s", mips_gpr_names
[7]);
2042 else if (statics
> 0)
2043 infprintf (is
, ",%s-%s",
2044 mips_gpr_names
[7 - statics
+ 1],
2050 /* xgettext:c-format */
2052 _("# internal disassembler error, "
2053 "unrecognised modifier (%c)"),
2060 /* Check if the given address is the last word of a MIPS16 PLT entry.
2061 This word is data and depending on the value it may interfere with
2062 disassembly of further PLT entries. We make use of the fact PLT
2063 symbols are marked BSF_SYNTHETIC. */
2065 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2069 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2070 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2076 /* Disassemble mips16 instructions. */
2079 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2081 const fprintf_ftype infprintf
= info
->fprintf_func
;
2086 bfd_boolean use_extend
;
2088 const struct mips_opcode
*op
, *opend
;
2089 void *is
= info
->stream
;
2091 info
->bytes_per_chunk
= 2;
2092 info
->display_endian
= info
->endian
;
2093 info
->insn_info_valid
= 1;
2094 info
->branch_delay_insns
= 0;
2095 info
->data_size
= 0;
2099 /* Decode PLT entry's GOT slot address word. */
2100 if (is_mips16_plt_tail (info
, memaddr
))
2102 info
->insn_type
= dis_noninsn
;
2103 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2106 unsigned int gotslot
;
2108 if (info
->endian
== BFD_ENDIAN_BIG
)
2109 gotslot
= bfd_getb32 (buffer
);
2111 gotslot
= bfd_getl32 (buffer
);
2112 infprintf (is
, ".word\t0x%x", gotslot
);
2119 info
->insn_type
= dis_nonbranch
;
2120 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2124 (*info
->memory_error_func
) (status
, memaddr
, info
);
2130 if (info
->endian
== BFD_ENDIAN_BIG
)
2131 insn
= bfd_getb16 (buffer
);
2133 insn
= bfd_getl16 (buffer
);
2135 /* Handle the extend opcode specially. */
2137 if ((insn
& 0xf800) == 0xf000)
2140 extend
= insn
& 0x7ff;
2144 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2147 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2148 (*info
->memory_error_func
) (status
, memaddr
, info
);
2152 if (info
->endian
== BFD_ENDIAN_BIG
)
2153 insn
= bfd_getb16 (buffer
);
2155 insn
= bfd_getl16 (buffer
);
2157 /* Check for an extend opcode followed by an extend opcode. */
2158 if ((insn
& 0xf800) == 0xf000)
2160 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2161 info
->insn_type
= dis_noninsn
;
2168 /* FIXME: Should probably use a hash table on the major opcode here. */
2170 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2171 for (op
= mips16_opcodes
; op
< opend
; op
++)
2173 if (op
->pinfo
!= INSN_MACRO
2174 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2175 && (insn
& op
->mask
) == op
->match
)
2179 if (strchr (op
->args
, 'a') != NULL
)
2183 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2184 info
->insn_type
= dis_noninsn
;
2192 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2197 if (info
->endian
== BFD_ENDIAN_BIG
)
2198 extend
= bfd_getb16 (buffer
);
2200 extend
= bfd_getl16 (buffer
);
2205 infprintf (is
, "%s", op
->name
);
2206 if (op
->args
[0] != '\0')
2207 infprintf (is
, "\t");
2209 for (s
= op
->args
; *s
!= '\0'; s
++)
2213 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
2215 /* Skip the register and the comma. */
2221 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
2223 /* Skip the register and the comma. */
2227 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
2231 /* Figure out branch instruction type and delay slot information. */
2232 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2233 info
->branch_delay_insns
= 1;
2234 if ((op
->pinfo
& (INSN_UNCOND_BRANCH_DELAY
2235 | MIPS16_INSN_UNCOND_BRANCH
)) != 0)
2237 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2238 info
->insn_type
= dis_jsr
;
2240 info
->insn_type
= dis_branch
;
2242 else if ((op
->pinfo
& MIPS16_INSN_COND_BRANCH
) != 0)
2243 info
->insn_type
= dis_condbranch
;
2252 infprintf (is
, "0x%x", extend
| 0xf000);
2253 infprintf (is
, "0x%x", insn
);
2254 info
->insn_type
= dis_noninsn
;
2259 /* Disassemble microMIPS instructions. */
2262 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2264 const fprintf_ftype infprintf
= info
->fprintf_func
;
2265 const struct mips_opcode
*op
, *opend
;
2266 unsigned int lsb
, msbd
, msb
;
2267 void *is
= info
->stream
;
2280 info
->bytes_per_chunk
= 2;
2281 info
->display_endian
= info
->endian
;
2282 info
->insn_info_valid
= 1;
2283 info
->branch_delay_insns
= 0;
2284 info
->data_size
= 0;
2285 info
->insn_type
= dis_nonbranch
;
2289 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2292 (*info
->memory_error_func
) (status
, memaddr
, info
);
2298 if (info
->endian
== BFD_ENDIAN_BIG
)
2299 insn
= bfd_getb16 (buffer
);
2301 insn
= bfd_getl16 (buffer
);
2303 if ((insn
& 0xfc00) == 0x7c00)
2305 /* This is a 48-bit microMIPS instruction. */
2308 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2311 infprintf (is
, "micromips 0x%x", higher
);
2312 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2315 if (info
->endian
== BFD_ENDIAN_BIG
)
2316 insn
= bfd_getb16 (buffer
);
2318 insn
= bfd_getl16 (buffer
);
2319 higher
= (higher
<< 16) | insn
;
2321 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
2324 infprintf (is
, "micromips 0x%x", higher
);
2325 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2328 if (info
->endian
== BFD_ENDIAN_BIG
)
2329 insn
= bfd_getb16 (buffer
);
2331 insn
= bfd_getl16 (buffer
);
2332 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2334 info
->insn_type
= dis_noninsn
;
2337 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2339 /* This is a 32-bit microMIPS instruction. */
2342 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2345 infprintf (is
, "micromips 0x%x", higher
);
2346 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2350 if (info
->endian
== BFD_ENDIAN_BIG
)
2351 insn
= bfd_getb16 (buffer
);
2353 insn
= bfd_getl16 (buffer
);
2355 insn
= insn
| (higher
<< 16);
2360 /* FIXME: Should probably use a hash table on the major opcode here. */
2362 #define GET_OP(insn, field) \
2363 (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2364 #define GET_OP_S(insn, field) \
2365 ((GET_OP (insn, field) ^ ((MICROMIPSOP_MASK_##field >> 1) + 1)) \
2366 - ((MICROMIPSOP_MASK_##field >> 1) + 1))
2367 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2368 for (op
= micromips_opcodes
; op
< opend
; op
++)
2370 if (op
->pinfo
!= INSN_MACRO
2371 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2372 && (insn
& op
->mask
) == op
->match
2373 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2374 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2378 infprintf (is
, "%s", op
->name
);
2379 if (op
->args
[0] != '\0')
2380 infprintf (is
, "\t");
2382 for (s
= op
->args
; *s
!= '\0'; s
++)
2389 infprintf (is
, "%c", *s
);
2393 infprintf (is
, "%d", GET_OP_S (insn
, OFFSET10
));
2397 infprintf (is
, "0x%x", GET_OP (insn
, STYPE
));
2401 infprintf (is
, "0x%x", GET_OP (insn
, BP
));
2405 infprintf (is
, "0x%x", GET_OP (insn
, SA3
));
2409 infprintf (is
, "0x%x", GET_OP (insn
, SA4
));
2413 infprintf (is
, "0x%x", GET_OP (insn
, IMM8
));
2417 infprintf (is
, "0x%x", GET_OP (insn
, RS
));
2421 infprintf (is
, "$ac%d", GET_OP (insn
, DSPACC
));
2425 infprintf (is
, "0x%x", GET_OP (insn
, WRDSP
));
2428 case '0': /* DSP 6-bit signed immediate in bit 16. */
2429 delta
= (GET_OP (insn
, DSPSFT
) ^ 0x20) - 0x20;
2430 infprintf (is
, "%d", delta
);
2434 infprintf (is
, "0x%x", GET_OP (insn
, SHAMT
));
2438 infprintf (is
, "0x%x", GET_OP (insn
, 3BITPOS
));
2442 infprintf (is
, "0x%x", GET_OP (insn
, RD
));
2446 infprintf (is
, "0x%x", GET_OP (insn
, TRAP
));
2450 infprintf (is
, "%d", GET_OP_S (insn
, OFFSET12
));
2454 if (strcmp (op
->name
, "jalx") == 0)
2455 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff)
2456 | (GET_OP (insn
, TARGET
) << 2));
2458 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x07ffffff)
2459 | (GET_OP (insn
, TARGET
) << 1));
2460 /* For gdb disassembler, force odd address on jalx. */
2461 if (info
->flavour
== bfd_target_unknown_flavour
2462 && strcmp (op
->name
, "jalx") == 0)
2464 (*info
->print_address_func
) (info
->target
, info
);
2471 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS
)]);
2475 infprintf (is
, "0x%x", GET_OP (insn
, CODE
));
2479 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RD
)]);
2483 infprintf (is
, "0x%x", GET_OP (insn
, PREFX
));
2488 infprintf (is
, "0x%x", GET_OP (insn
, IMMEDIATE
));
2491 case 'j': /* Same as i, but sign-extended. */
2493 infprintf (is
, "%d", GET_OP_S (insn
, DELTA
));
2497 infprintf (is
, "0x%x", GET_OP (insn
, CACHE
));
2504 immed
= GET_OP (insn
, RT
);
2505 s_reg_encode
= immed
& 0xf;
2506 if (s_reg_encode
!= 0)
2508 if (s_reg_encode
== 1)
2509 infprintf (is
, "%s", mips_gpr_names
[16]);
2510 else if (s_reg_encode
< 9)
2511 infprintf (is
, "%s-%s",
2513 mips_gpr_names
[15 + s_reg_encode
]);
2514 else if (s_reg_encode
== 9)
2515 infprintf (is
, "%s-%s,%s",
2518 mips_gpr_names
[30]);
2520 infprintf (is
, "UNKNOWN");
2523 if (immed
& 0x10) /* For ra. */
2525 if (s_reg_encode
== 0)
2526 infprintf (is
, "%s", mips_gpr_names
[31]);
2528 infprintf (is
, ",%s", mips_gpr_names
[31]);
2534 /* Sign-extend the displacement. */
2535 delta
= GET_OP_S (insn
, DELTA
);
2536 info
->target
= (delta
<< 1) + memaddr
+ length
;
2537 (*info
->print_address_func
) (info
->target
, info
);
2541 infprintf (is
, "0x%x", GET_OP (insn
, CODE2
));
2546 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RT
)]);
2550 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS3
)]);
2554 infprintf (is
, "%s", mips_gpr_names
[0]);
2557 case '@': /* DSP 10-bit signed immediate in bit 16. */
2558 delta
= (GET_OP (insn
, IMM10
) ^ 0x200) - 0x200;
2559 infprintf (is
, "%d", delta
);
2563 infprintf (is
, "0x%x", GET_OP (insn
, CODE10
));
2567 infprintf (is
, "0x%x", GET_OP (insn
, COPZ
));
2571 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FD
)]);
2575 /* Coprocessor register for lwcN instructions, et al.
2577 Note that there is no load/store cp0 instructions, and
2578 that FPU (cp1) instructions disassemble this field using
2579 'T' format. Therefore, until we gain understanding of
2580 cp2 register names, we can simply print the register
2582 infprintf (is
, "$%d", GET_OP (insn
, RT
));
2586 /* Coprocessor register for mtcN instructions, et al. Note
2587 that FPU (cp1) instructions disassemble this field using
2588 'S' format. Therefore, we only need to worry about cp0,
2590 The microMIPS encoding does not have a coprocessor
2591 identifier field as such, so we must work out the
2592 coprocessor number by looking at the opcode. */
2594 & ~((MICROMIPSOP_MASK_RT
<< MICROMIPSOP_SH_RT
)
2595 | (MICROMIPSOP_MASK_RS
<< MICROMIPSOP_SH_RS
)))
2597 case 0x000000fc: /* mfc0 */
2598 case 0x000002fc: /* mtc0 */
2599 case 0x000004fc: /* mfgc0 */
2600 case 0x000006fc: /* mtgc0 */
2601 case 0x580000fc: /* dmfc0 */
2602 case 0x580002fc: /* dmtc0 */
2603 case 0x580000e7: /* dmfgc0 */
2604 case 0x580002e7: /* dmtgc0 */
2605 infprintf (is
, "%s", mips_cp0_names
[GET_OP (insn
, RS
)]);
2608 infprintf (is
, "$%d", GET_OP (insn
, RS
));
2614 infprintf (is
, "%d", GET_OP (insn
, SEL
));
2618 infprintf (is
, "%s", mips_hwr_names
[GET_OP (insn
, RS
)]);
2622 infprintf (is
, "$fcc%d", GET_OP (insn
, CCC
));
2627 (op
->pinfo
& (FP_D
| FP_S
)) != 0
2628 ? "$fcc%d" : "$cc%d",
2629 GET_OP (insn
, BCC
));
2633 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FR
)]);
2638 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FS
)]);
2642 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FT
)]);
2646 /* Extension character; switch for second char. */
2651 lsb
= GET_OP (insn
, EXTLSB
);
2652 infprintf (is
, "0x%x", lsb
);
2656 msb
= GET_OP (insn
, INSMSB
);
2657 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2662 msbd
= GET_OP (insn
, EXTMSBD
);
2663 infprintf (is
, "0x%x", msbd
+ 1);
2668 const struct mips_cp0sel_name
*n
;
2669 unsigned int cp0reg
, sel
;
2671 cp0reg
= GET_OP (insn
, RS
);
2672 sel
= GET_OP (insn
, SEL
);
2674 /* CP0 register including 'sel' code for mtcN
2675 (et al.), to be printed textually if known.
2676 If not known, print both CP0 register name and
2677 sel numerically since CP0 register with sel 0 may
2678 have a name unrelated to register being printed. */
2679 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2680 mips_cp0sel_names_len
,
2683 infprintf (is
, "%s", n
->name
);
2685 infprintf (is
, "$%d,%d", cp0reg
, sel
);
2690 lsb
= GET_OP (insn
, EXTLSB
) + 32;
2691 infprintf (is
, "0x%x", lsb
);
2695 msb
= GET_OP (insn
, INSMSB
) + 32;
2696 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2700 msbd
= GET_OP (insn
, EXTMSBD
) + 32;
2701 infprintf (is
, "0x%x", msbd
+ 1);
2704 case 'j': /* 9-bit signed offset in bit 0. */
2705 delta
= GET_OP_S (insn
, EVAOFFSET
);
2706 infprintf (is
, "%d", delta
);
2710 /* xgettext:c-format */
2712 _("# internal disassembler error, "
2713 "unrecognized modifier (+%c)"),
2720 /* Extension character; switch for second char. */
2724 case 'a': /* global pointer. */
2725 infprintf (is
, "%s", mips_gpr_names
[28]);
2729 regno
= micromips_to_32_reg_b_map
[GET_OP (insn
, MB
)];
2730 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2734 regno
= micromips_to_32_reg_c_map
[GET_OP (insn
, MC
)];
2735 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2739 regno
= micromips_to_32_reg_d_map
[GET_OP (insn
, MD
)];
2740 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2744 regno
= micromips_to_32_reg_e_map
[GET_OP (insn
, ME
)];
2745 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2749 /* Save lastregno for "mt" to print out later. */
2750 lastregno
= micromips_to_32_reg_f_map
[GET_OP (insn
, MF
)];
2751 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2755 regno
= micromips_to_32_reg_g_map
[GET_OP (insn
, MG
)];
2756 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2760 regno
= micromips_to_32_reg_h_map
[GET_OP (insn
, MH
)];
2761 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2765 regno
= micromips_to_32_reg_i_map
[GET_OP (insn
, MI
)];
2766 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2770 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, MJ
)]);
2774 regno
= micromips_to_32_reg_l_map
[GET_OP (insn
, ML
)];
2775 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2779 regno
= micromips_to_32_reg_m_map
[GET_OP (insn
, MM
)];
2780 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2784 regno
= micromips_to_32_reg_n_map
[GET_OP (insn
, MN
)];
2785 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2789 /* Save lastregno for "mt" to print out later. */
2790 lastregno
= GET_OP (insn
, MP
);
2791 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2795 regno
= micromips_to_32_reg_q_map
[GET_OP (insn
, MQ
)];
2796 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2799 case 'r': /* program counter. */
2800 infprintf (is
, "$pc");
2803 case 's': /* stack pointer. */
2805 infprintf (is
, "%s", mips_gpr_names
[29]);
2809 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2813 infprintf (is
, "%s", mips_gpr_names
[0]);
2817 /* Sign-extend the immediate. */
2818 immed
= GET_OP_S (insn
, IMMA
) << 2;
2819 infprintf (is
, "%d", immed
);
2823 immed
= micromips_imm_b_map
[GET_OP (insn
, IMMB
)];
2824 infprintf (is
, "%d", immed
);
2828 immed
= micromips_imm_c_map
[GET_OP (insn
, IMMC
)];
2829 infprintf (is
, "0x%x", immed
);
2833 /* Sign-extend the displacement. */
2834 delta
= GET_OP_S (insn
, IMMD
);
2835 info
->target
= (delta
<< 1) + memaddr
+ length
;
2836 (*info
->print_address_func
) (info
->target
, info
);
2840 /* Sign-extend the displacement. */
2841 delta
= GET_OP_S (insn
, IMME
);
2842 info
->target
= (delta
<< 1) + memaddr
+ length
;
2843 (*info
->print_address_func
) (info
->target
, info
);
2847 immed
= GET_OP (insn
, IMMF
);
2848 infprintf (is
, "0x%x", immed
);
2852 immed
= (insn
>> MICROMIPSOP_SH_IMMG
) + 1;
2853 immed
= (immed
& MICROMIPSOP_MASK_IMMG
) - 1;
2854 infprintf (is
, "%d", immed
);
2858 immed
= GET_OP (insn
, IMMH
) << 1;
2859 infprintf (is
, "%d", immed
);
2863 immed
= (insn
>> MICROMIPSOP_SH_IMMI
) + 1;
2864 immed
= (immed
& MICROMIPSOP_MASK_IMMI
) - 1;
2865 infprintf (is
, "%d", immed
);
2869 immed
= GET_OP (insn
, IMMJ
) << 2;
2870 infprintf (is
, "%d", immed
);
2874 immed
= GET_OP (insn
, IMML
);
2875 infprintf (is
, "%d", immed
);
2879 immed
= (insn
>> MICROMIPSOP_SH_IMMM
) - 1;
2880 immed
= (immed
& MICROMIPSOP_MASK_IMMM
) + 1;
2881 infprintf (is
, "%d", immed
);
2885 immed
= GET_OP (insn
, IMMN
);
2887 infprintf (is
, "%s,%s",
2889 mips_gpr_names
[31]);
2891 infprintf (is
, "%s-%s,%s",
2893 mips_gpr_names
[16 + immed
],
2894 mips_gpr_names
[31]);
2898 immed
= GET_OP (insn
, IMMO
);
2899 infprintf (is
, "0x%x", immed
);
2903 immed
= GET_OP (insn
, IMMP
) << 2;
2904 infprintf (is
, "%d", immed
);
2908 /* Sign-extend the immediate. */
2909 immed
= GET_OP_S (insn
, IMMQ
) << 2;
2910 infprintf (is
, "%d", immed
);
2914 immed
= GET_OP (insn
, IMMU
) << 2;
2915 infprintf (is
, "%d", immed
);
2919 immed
= GET_OP (insn
, IMMW
) << 2;
2920 infprintf (is
, "%d", immed
);
2924 /* Sign-extend the immediate. */
2925 immed
= GET_OP_S (insn
, IMMX
);
2926 infprintf (is
, "%d", immed
);
2930 /* Sign-extend the immediate. */
2931 immed
= GET_OP_S (insn
, IMMY
) << 2;
2932 if ((unsigned int) (immed
+ 8) < 16)
2934 infprintf (is
, "%d", immed
);
2938 /* xgettext:c-format */
2940 _("# internal disassembler error, "
2941 "unrecognized modifier (m%c)"),
2948 /* xgettext:c-format */
2950 _("# internal disassembler error, "
2951 "unrecognized modifier (%c)"),
2957 /* Figure out instruction type and branch delay information. */
2959 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2960 info
->branch_delay_insns
= 1;
2961 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2962 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2964 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_GPR_T
)) != 0)
2965 info
->insn_type
= dis_jsr
;
2967 info
->insn_type
= dis_branch
;
2969 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2970 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2972 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2973 info
->insn_type
= dis_condjsr
;
2975 info
->insn_type
= dis_condbranch
;
2978 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY_DELAY
)) != 0)
2979 info
->insn_type
= dis_dref
;
2987 infprintf (is
, "0x%x", insn
);
2988 info
->insn_type
= dis_noninsn
;
2993 /* Return 1 if a symbol associated with the location being disassembled
2994 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2995 all the symbols at the address being considered assuming if at least
2996 one of them indicates code compression, then such code has been
2997 genuinely produced here (other symbols could have been derived from
2998 function symbols defined elsewhere or could define data). Otherwise,
3002 is_compressed_mode_p (struct disassemble_info
*info
)
3007 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
3008 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
3010 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
3012 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
3014 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
3015 && info
->symtab
[i
]->section
== info
->section
)
3017 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
3019 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
3021 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
3028 /* In an environment where we do not know the symbol type of the
3029 instruction we are forced to assume that the low order bit of the
3030 instructions' address may mark it as a mips16 instruction. If we
3031 are single stepping, or the pc is within the disassembled function,
3032 this works. Otherwise, we need a clue. Sometimes. */
3035 _print_insn_mips (bfd_vma memaddr
,
3036 struct disassemble_info
*info
,
3037 enum bfd_endian endianness
)
3039 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
3040 bfd_byte buffer
[INSNLEN
];
3043 set_default_mips_dis_options (info
);
3044 parse_mips_dis_options (info
->disassembler_options
);
3046 if (info
->mach
== bfd_mach_mips16
)
3047 return print_insn_mips16 (memaddr
, info
);
3048 if (info
->mach
== bfd_mach_mips_micromips
)
3049 return print_insn_micromips (memaddr
, info
);
3051 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
3054 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
3055 /* Only a few tools will work this way. */
3057 return print_insn_compr (memaddr
, info
);
3060 #if SYMTAB_AVAILABLE
3061 if (is_compressed_mode_p (info
))
3062 return print_insn_compr (memaddr
, info
);
3065 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
3070 if (endianness
== BFD_ENDIAN_BIG
)
3071 insn
= bfd_getb32 (buffer
);
3073 insn
= bfd_getl32 (buffer
);
3075 return print_insn_mips (memaddr
, insn
, info
);
3079 (*info
->memory_error_func
) (status
, memaddr
, info
);
3085 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3087 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
3091 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3093 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
3097 print_mips_disassembler_options (FILE *stream
)
3101 fprintf (stream
, _("\n\
3102 The following MIPS specific disassembler options are supported for use\n\
3103 with the -M switch (multiple options should be separated by commas):\n"));
3105 fprintf (stream
, _("\n\
3106 virt Recognize the virtualization ASE instructions.\n"));
3108 fprintf (stream
, _("\n\
3109 gpr-names=ABI Print GPR names according to specified ABI.\n\
3110 Default: based on binary being disassembled.\n"));
3112 fprintf (stream
, _("\n\
3113 fpr-names=ABI Print FPR names according to specified ABI.\n\
3114 Default: numeric.\n"));
3116 fprintf (stream
, _("\n\
3117 cp0-names=ARCH Print CP0 register names according to\n\
3118 specified architecture.\n\
3119 Default: based on binary being disassembled.\n"));
3121 fprintf (stream
, _("\n\
3122 hwr-names=ARCH Print HWR names according to specified \n\
3124 Default: based on binary being disassembled.\n"));
3126 fprintf (stream
, _("\n\
3127 reg-names=ABI Print GPR and FPR names according to\n\
3128 specified ABI.\n"));
3130 fprintf (stream
, _("\n\
3131 reg-names=ARCH Print CP0 register and HWR names according to\n\
3132 specified architecture.\n"));
3134 fprintf (stream
, _("\n\
3135 For the options above, the following values are supported for \"ABI\":\n\
3137 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
3138 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
3139 fprintf (stream
, _("\n"));
3141 fprintf (stream
, _("\n\
3142 For the options above, The following values are supported for \"ARCH\":\n\
3144 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
3145 if (*mips_arch_choices
[i
].name
!= '\0')
3146 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
3147 fprintf (stream
, _("\n"));
3149 fprintf (stream
, _("\n"));