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_map1
[] =
81 5, 5, 6, 4, 4, 4, 4, 4
83 static const unsigned int micromips_to_32_reg_h_map2
[] =
85 6, 7, 7, 21, 22, 5, 6, 7
88 /* The microMIPS registers with type j: 32 registers. */
90 /* The microMIPS registers with type l. */
91 #define micromips_to_32_reg_l_map mips16_to_32_reg_map
93 /* The microMIPS registers with type m. */
94 static const unsigned int micromips_to_32_reg_m_map
[] =
96 0, 17, 2, 3, 16, 18, 19, 20
99 /* The microMIPS registers with type n. */
100 #define micromips_to_32_reg_n_map micromips_to_32_reg_m_map
102 /* The microMIPS registers with type p: 32 registers. */
104 /* The microMIPS registers with type q. */
105 static const unsigned int micromips_to_32_reg_q_map
[] =
107 0, 17, 2, 3, 4, 5, 6, 7
110 /* reg type s is $29. */
112 /* reg type t is the same as the last register. */
114 /* reg type y is $31. */
116 /* reg type z is $0. */
118 /* micromips imm B type. */
119 static const int micromips_imm_b_map
[8] =
121 1, 4, 8, 12, 16, 20, 24, -1
124 /* micromips imm C type. */
125 static const int micromips_imm_c_map
[16] =
127 128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 255, 32768, 65535
130 /* micromips imm D type: (-512..511)<<1. */
131 /* micromips imm E type: (-64..63)<<1. */
132 /* micromips imm F type: (0..63). */
133 /* micromips imm G type: (-1..14). */
134 /* micromips imm H type: (0..15)<<1. */
135 /* micromips imm I type: (-1..126). */
136 /* micromips imm J type: (0..15)<<2. */
137 /* micromips imm L type: (0..15). */
138 /* micromips imm M type: (1..8). */
139 /* micromips imm W type: (0..63)<<2. */
140 /* micromips imm X type: (-8..7). */
141 /* micromips imm Y type: (-258..-3, 2..257)<<2. */
143 #define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]]
146 static const char * const mips_gpr_names_numeric
[32] =
148 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
149 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
150 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
151 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
154 static const char * const mips_gpr_names_oldabi
[32] =
156 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
157 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
158 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
159 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
162 static const char * const mips_gpr_names_newabi
[32] =
164 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
165 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
166 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
167 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
170 static const char * const mips_fpr_names_numeric
[32] =
172 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
173 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
174 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
175 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
178 static const char * const mips_fpr_names_32
[32] =
180 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
181 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
182 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
183 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
186 static const char * const mips_fpr_names_n32
[32] =
188 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
189 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
190 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
191 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
194 static const char * const mips_fpr_names_64
[32] =
196 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
197 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
198 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
199 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
202 static const char * const mips_cp0_names_numeric
[32] =
204 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
205 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
206 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
207 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
210 static const char * const mips_cp0_names_r3000
[32] =
212 "c0_index", "c0_random", "c0_entrylo", "$3",
213 "c0_context", "$5", "$6", "$7",
214 "c0_badvaddr", "$9", "c0_entryhi", "$11",
215 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
216 "$16", "$17", "$18", "$19",
217 "$20", "$21", "$22", "$23",
218 "$24", "$25", "$26", "$27",
219 "$28", "$29", "$30", "$31",
222 static const char * const mips_cp0_names_r4000
[32] =
224 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
225 "c0_context", "c0_pagemask", "c0_wired", "$7",
226 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
227 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
228 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
229 "c0_xcontext", "$21", "$22", "$23",
230 "$24", "$25", "c0_ecc", "c0_cacheerr",
231 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
234 static const char * const mips_cp0_names_r5900
[32] =
236 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
237 "c0_context", "c0_pagemask", "c0_wired", "$7",
238 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
239 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
240 "c0_config", "$17", "$18", "$19",
241 "$20", "$21", "$22", "c0_badpaddr",
242 "c0_depc", "c0_perfcnt", "$26", "$27",
243 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
246 static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900
[] =
249 { 24, 3, "c0_iabm" },
251 { 24, 5, "c0_dabm" },
253 { 24, 7, "c0_dvbm" },
254 { 25, 1, "c0_perfcnt,1" },
255 { 25, 2, "c0_perfcnt,2" }
258 static const char * const mips_cp0_names_mips3264
[32] =
260 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
261 "c0_context", "c0_pagemask", "c0_wired", "$7",
262 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
263 "c0_status", "c0_cause", "c0_epc", "c0_prid",
264 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
265 "c0_xcontext", "$21", "$22", "c0_debug",
266 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
267 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
270 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] =
272 { 16, 1, "c0_config1" },
273 { 16, 2, "c0_config2" },
274 { 16, 3, "c0_config3" },
275 { 18, 1, "c0_watchlo,1" },
276 { 18, 2, "c0_watchlo,2" },
277 { 18, 3, "c0_watchlo,3" },
278 { 18, 4, "c0_watchlo,4" },
279 { 18, 5, "c0_watchlo,5" },
280 { 18, 6, "c0_watchlo,6" },
281 { 18, 7, "c0_watchlo,7" },
282 { 19, 1, "c0_watchhi,1" },
283 { 19, 2, "c0_watchhi,2" },
284 { 19, 3, "c0_watchhi,3" },
285 { 19, 4, "c0_watchhi,4" },
286 { 19, 5, "c0_watchhi,5" },
287 { 19, 6, "c0_watchhi,6" },
288 { 19, 7, "c0_watchhi,7" },
289 { 25, 1, "c0_perfcnt,1" },
290 { 25, 2, "c0_perfcnt,2" },
291 { 25, 3, "c0_perfcnt,3" },
292 { 25, 4, "c0_perfcnt,4" },
293 { 25, 5, "c0_perfcnt,5" },
294 { 25, 6, "c0_perfcnt,6" },
295 { 25, 7, "c0_perfcnt,7" },
296 { 27, 1, "c0_cacheerr,1" },
297 { 27, 2, "c0_cacheerr,2" },
298 { 27, 3, "c0_cacheerr,3" },
299 { 28, 1, "c0_datalo" },
300 { 29, 1, "c0_datahi" }
303 static const char * const mips_cp0_names_mips3264r2
[32] =
305 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
306 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
307 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
308 "c0_status", "c0_cause", "c0_epc", "c0_prid",
309 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
310 "c0_xcontext", "$21", "$22", "c0_debug",
311 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
312 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
315 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] =
317 { 4, 1, "c0_contextconfig" },
318 { 0, 1, "c0_mvpcontrol" },
319 { 0, 2, "c0_mvpconf0" },
320 { 0, 3, "c0_mvpconf1" },
321 { 1, 1, "c0_vpecontrol" },
322 { 1, 2, "c0_vpeconf0" },
323 { 1, 3, "c0_vpeconf1" },
324 { 1, 4, "c0_yqmask" },
325 { 1, 5, "c0_vpeschedule" },
326 { 1, 6, "c0_vpeschefback" },
327 { 2, 1, "c0_tcstatus" },
328 { 2, 2, "c0_tcbind" },
329 { 2, 3, "c0_tcrestart" },
330 { 2, 4, "c0_tchalt" },
331 { 2, 5, "c0_tccontext" },
332 { 2, 6, "c0_tcschedule" },
333 { 2, 7, "c0_tcschefback" },
334 { 5, 1, "c0_pagegrain" },
335 { 6, 1, "c0_srsconf0" },
336 { 6, 2, "c0_srsconf1" },
337 { 6, 3, "c0_srsconf2" },
338 { 6, 4, "c0_srsconf3" },
339 { 6, 5, "c0_srsconf4" },
340 { 12, 1, "c0_intctl" },
341 { 12, 2, "c0_srsctl" },
342 { 12, 3, "c0_srsmap" },
343 { 15, 1, "c0_ebase" },
344 { 16, 1, "c0_config1" },
345 { 16, 2, "c0_config2" },
346 { 16, 3, "c0_config3" },
347 { 18, 1, "c0_watchlo,1" },
348 { 18, 2, "c0_watchlo,2" },
349 { 18, 3, "c0_watchlo,3" },
350 { 18, 4, "c0_watchlo,4" },
351 { 18, 5, "c0_watchlo,5" },
352 { 18, 6, "c0_watchlo,6" },
353 { 18, 7, "c0_watchlo,7" },
354 { 19, 1, "c0_watchhi,1" },
355 { 19, 2, "c0_watchhi,2" },
356 { 19, 3, "c0_watchhi,3" },
357 { 19, 4, "c0_watchhi,4" },
358 { 19, 5, "c0_watchhi,5" },
359 { 19, 6, "c0_watchhi,6" },
360 { 19, 7, "c0_watchhi,7" },
361 { 23, 1, "c0_tracecontrol" },
362 { 23, 2, "c0_tracecontrol2" },
363 { 23, 3, "c0_usertracedata" },
364 { 23, 4, "c0_tracebpc" },
365 { 25, 1, "c0_perfcnt,1" },
366 { 25, 2, "c0_perfcnt,2" },
367 { 25, 3, "c0_perfcnt,3" },
368 { 25, 4, "c0_perfcnt,4" },
369 { 25, 5, "c0_perfcnt,5" },
370 { 25, 6, "c0_perfcnt,6" },
371 { 25, 7, "c0_perfcnt,7" },
372 { 27, 1, "c0_cacheerr,1" },
373 { 27, 2, "c0_cacheerr,2" },
374 { 27, 3, "c0_cacheerr,3" },
375 { 28, 1, "c0_datalo" },
376 { 28, 2, "c0_taglo1" },
377 { 28, 3, "c0_datalo1" },
378 { 28, 4, "c0_taglo2" },
379 { 28, 5, "c0_datalo2" },
380 { 28, 6, "c0_taglo3" },
381 { 28, 7, "c0_datalo3" },
382 { 29, 1, "c0_datahi" },
383 { 29, 2, "c0_taghi1" },
384 { 29, 3, "c0_datahi1" },
385 { 29, 4, "c0_taghi2" },
386 { 29, 5, "c0_datahi2" },
387 { 29, 6, "c0_taghi3" },
388 { 29, 7, "c0_datahi3" },
391 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
392 static const char * const mips_cp0_names_sb1
[32] =
394 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
395 "c0_context", "c0_pagemask", "c0_wired", "$7",
396 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
397 "c0_status", "c0_cause", "c0_epc", "c0_prid",
398 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
399 "c0_xcontext", "$21", "$22", "c0_debug",
400 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
401 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
404 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] =
406 { 16, 1, "c0_config1" },
407 { 18, 1, "c0_watchlo,1" },
408 { 19, 1, "c0_watchhi,1" },
409 { 22, 0, "c0_perftrace" },
410 { 23, 3, "c0_edebug" },
411 { 25, 1, "c0_perfcnt,1" },
412 { 25, 2, "c0_perfcnt,2" },
413 { 25, 3, "c0_perfcnt,3" },
414 { 25, 4, "c0_perfcnt,4" },
415 { 25, 5, "c0_perfcnt,5" },
416 { 25, 6, "c0_perfcnt,6" },
417 { 25, 7, "c0_perfcnt,7" },
418 { 26, 1, "c0_buserr_pa" },
419 { 27, 1, "c0_cacheerr_d" },
420 { 27, 3, "c0_cacheerr_d_pa" },
421 { 28, 1, "c0_datalo_i" },
422 { 28, 2, "c0_taglo_d" },
423 { 28, 3, "c0_datalo_d" },
424 { 29, 1, "c0_datahi_i" },
425 { 29, 2, "c0_taghi_d" },
426 { 29, 3, "c0_datahi_d" },
429 /* Xlr cop0 register names. */
430 static const char * const mips_cp0_names_xlr
[32] = {
431 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
432 "c0_context", "c0_pagemask", "c0_wired", "$7",
433 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
434 "c0_status", "c0_cause", "c0_epc", "c0_prid",
435 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
436 "c0_xcontext", "$21", "$22", "c0_debug",
437 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
438 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
441 /* XLR's CP0 Select Registers. */
443 static const struct mips_cp0sel_name mips_cp0sel_names_xlr
[] = {
444 { 9, 6, "c0_extintreq" },
445 { 9, 7, "c0_extintmask" },
446 { 15, 1, "c0_ebase" },
447 { 16, 1, "c0_config1" },
448 { 16, 2, "c0_config2" },
449 { 16, 3, "c0_config3" },
450 { 16, 7, "c0_procid2" },
451 { 18, 1, "c0_watchlo,1" },
452 { 18, 2, "c0_watchlo,2" },
453 { 18, 3, "c0_watchlo,3" },
454 { 18, 4, "c0_watchlo,4" },
455 { 18, 5, "c0_watchlo,5" },
456 { 18, 6, "c0_watchlo,6" },
457 { 18, 7, "c0_watchlo,7" },
458 { 19, 1, "c0_watchhi,1" },
459 { 19, 2, "c0_watchhi,2" },
460 { 19, 3, "c0_watchhi,3" },
461 { 19, 4, "c0_watchhi,4" },
462 { 19, 5, "c0_watchhi,5" },
463 { 19, 6, "c0_watchhi,6" },
464 { 19, 7, "c0_watchhi,7" },
465 { 25, 1, "c0_perfcnt,1" },
466 { 25, 2, "c0_perfcnt,2" },
467 { 25, 3, "c0_perfcnt,3" },
468 { 25, 4, "c0_perfcnt,4" },
469 { 25, 5, "c0_perfcnt,5" },
470 { 25, 6, "c0_perfcnt,6" },
471 { 25, 7, "c0_perfcnt,7" },
472 { 27, 1, "c0_cacheerr,1" },
473 { 27, 2, "c0_cacheerr,2" },
474 { 27, 3, "c0_cacheerr,3" },
475 { 28, 1, "c0_datalo" },
476 { 29, 1, "c0_datahi" }
479 static const char * const mips_hwr_names_numeric
[32] =
481 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
482 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
483 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
484 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
487 static const char * const mips_hwr_names_mips3264r2
[32] =
489 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
490 "$4", "$5", "$6", "$7",
491 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
492 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
493 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
496 struct mips_abi_choice
499 const char * const *gpr_names
;
500 const char * const *fpr_names
;
503 struct mips_abi_choice mips_abi_choices
[] =
505 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
506 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
507 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
508 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
511 struct mips_arch_choice
515 unsigned long bfd_mach
;
519 const char * const *cp0_names
;
520 const struct mips_cp0sel_name
*cp0sel_names
;
521 unsigned int cp0sel_names_len
;
522 const char * const *hwr_names
;
525 const struct mips_arch_choice mips_arch_choices
[] =
527 { "numeric", 0, 0, 0, 0, 0,
528 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
530 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
, 0,
531 mips_cp0_names_r3000
, NULL
, 0, mips_hwr_names_numeric
},
532 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
, 0,
533 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
534 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
, 0,
535 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
536 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
, 0,
537 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
538 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
, 0,
539 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
540 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
, 0,
541 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
542 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
, 0,
543 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
544 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
, 0,
545 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
546 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
, 0,
547 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
548 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
, 0,
549 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
550 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
, 0,
551 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
552 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
, 0,
553 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
554 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
, 0,
555 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
556 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
, 0,
557 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
558 { "r5900", 1, bfd_mach_mips5900
, CPU_R5900
, ISA_MIPS3
, 0,
559 mips_cp0_names_r5900
, NULL
, 0, mips_hwr_names_numeric
},
560 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
, 0,
561 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
562 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
563 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
564 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
565 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
566 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
, 0,
567 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
568 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
, 0,
569 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
570 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
, 0,
571 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
572 { "r14000", 1, bfd_mach_mips14000
, CPU_R14000
, ISA_MIPS4
, 0,
573 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
574 { "r16000", 1, bfd_mach_mips16000
, CPU_R16000
, ISA_MIPS4
, 0,
575 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
576 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
, 0,
577 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
579 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
580 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
581 _MIPS32 Architecture For Programmers Volume I: Introduction to the
582 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
584 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
585 ISA_MIPS32
, ASE_SMARTMIPS
,
586 mips_cp0_names_mips3264
,
587 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
588 mips_hwr_names_numeric
},
590 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
592 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
593 | ASE_MT
| ASE_MCU
| ASE_VIRT
),
594 mips_cp0_names_mips3264r2
,
595 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
596 mips_hwr_names_mips3264r2
},
598 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
599 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
600 ISA_MIPS64
, ASE_MIPS3D
| ASE_MDMX
,
601 mips_cp0_names_mips3264
,
602 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
603 mips_hwr_names_numeric
},
605 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
607 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
608 | ASE_MDMX
| ASE_MCU
| ASE_VIRT
| ASE_VIRT64
),
609 mips_cp0_names_mips3264r2
,
610 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
611 mips_hwr_names_mips3264r2
},
613 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
614 ISA_MIPS64
| INSN_SB1
, ASE_MIPS3D
,
616 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
617 mips_hwr_names_numeric
},
619 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
620 ISA_MIPS3
| INSN_LOONGSON_2E
, 0, mips_cp0_names_numeric
,
621 NULL
, 0, mips_hwr_names_numeric
},
623 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
624 ISA_MIPS3
| INSN_LOONGSON_2F
, 0, mips_cp0_names_numeric
,
625 NULL
, 0, mips_hwr_names_numeric
},
627 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
628 ISA_MIPS64
| INSN_LOONGSON_3A
, 0, mips_cp0_names_numeric
,
629 NULL
, 0, mips_hwr_names_numeric
},
631 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
632 ISA_MIPS64R2
| INSN_OCTEON
, 0, mips_cp0_names_numeric
, NULL
, 0,
633 mips_hwr_names_numeric
},
635 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
636 ISA_MIPS64R2
| INSN_OCTEONP
, 0, mips_cp0_names_numeric
,
637 NULL
, 0, mips_hwr_names_numeric
},
639 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
640 ISA_MIPS64R2
| INSN_OCTEON2
, 0, mips_cp0_names_numeric
,
641 NULL
, 0, mips_hwr_names_numeric
},
643 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
644 ISA_MIPS64
| INSN_XLR
, 0,
646 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
647 mips_hwr_names_numeric
},
649 /* XLP is mostly like XLR, with the prominent exception it is being
651 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
652 ISA_MIPS64R2
| INSN_XLR
, 0,
654 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
655 mips_hwr_names_numeric
},
657 /* This entry, mips16, is here only for ISA/processor selection; do
658 not print its name. */
659 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
, 0,
660 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
663 /* ISA and processor type to disassemble for, and register names to use.
664 set_default_mips_dis_options and parse_mips_dis_options fill in these
666 static int mips_processor
;
669 static int micromips_ase
;
670 static const char * const *mips_gpr_names
;
671 static const char * const *mips_fpr_names
;
672 static const char * const *mips_cp0_names
;
673 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
674 static int mips_cp0sel_names_len
;
675 static const char * const *mips_hwr_names
;
678 static int no_aliases
; /* If set disassemble as most general inst. */
680 static const struct mips_abi_choice
*
681 choose_abi_by_name (const char *name
, unsigned int namelen
)
683 const struct mips_abi_choice
*c
;
686 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
687 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
688 && strlen (mips_abi_choices
[i
].name
) == namelen
)
689 c
= &mips_abi_choices
[i
];
694 static const struct mips_arch_choice
*
695 choose_arch_by_name (const char *name
, unsigned int namelen
)
697 const struct mips_arch_choice
*c
= NULL
;
700 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
701 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
702 && strlen (mips_arch_choices
[i
].name
) == namelen
)
703 c
= &mips_arch_choices
[i
];
708 static const struct mips_arch_choice
*
709 choose_arch_by_number (unsigned long mach
)
711 static unsigned long hint_bfd_mach
;
712 static const struct mips_arch_choice
*hint_arch_choice
;
713 const struct mips_arch_choice
*c
;
716 /* We optimize this because even if the user specifies no
717 flags, this will be done for every instruction! */
718 if (hint_bfd_mach
== mach
719 && hint_arch_choice
!= NULL
720 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
721 return hint_arch_choice
;
723 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
725 if (mips_arch_choices
[i
].bfd_mach_valid
726 && mips_arch_choices
[i
].bfd_mach
== mach
)
728 c
= &mips_arch_choices
[i
];
729 hint_bfd_mach
= mach
;
730 hint_arch_choice
= c
;
736 /* Check if the object uses NewABI conventions. */
739 is_newabi (Elf_Internal_Ehdr
*header
)
741 /* There are no old-style ABIs which use 64-bit ELF. */
742 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
745 /* If a 32-bit ELF file, n32 is a new-style ABI. */
746 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
752 /* Check if the object has microMIPS ASE code. */
755 is_micromips (Elf_Internal_Ehdr
*header
)
757 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
764 set_default_mips_dis_options (struct disassemble_info
*info
)
766 const struct mips_arch_choice
*chosen_arch
;
768 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
769 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
770 CP0 register, and HWR names. */
771 mips_isa
= ISA_MIPS3
;
772 mips_processor
= CPU_R3000
;
775 mips_gpr_names
= mips_gpr_names_oldabi
;
776 mips_fpr_names
= mips_fpr_names_numeric
;
777 mips_cp0_names
= mips_cp0_names_numeric
;
778 mips_cp0sel_names
= NULL
;
779 mips_cp0sel_names_len
= 0;
780 mips_hwr_names
= mips_hwr_names_numeric
;
783 /* Update settings according to the ELF file header flags. */
784 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
786 Elf_Internal_Ehdr
*header
;
788 header
= elf_elfheader (info
->section
->owner
);
789 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
790 if (is_newabi (header
))
791 mips_gpr_names
= mips_gpr_names_newabi
;
792 /* If a microMIPS binary, then don't use MIPS16 bindings. */
793 micromips_ase
= is_micromips (header
);
796 /* Set ISA, architecture, and cp0 register names as best we can. */
797 #if ! SYMTAB_AVAILABLE
798 /* This is running out on a target machine, not in a host tool.
799 FIXME: Where does mips_target_info come from? */
800 target_processor
= mips_target_info
.processor
;
801 mips_isa
= mips_target_info
.isa
;
802 mips_ase
= mips_target_info
.ase
;
804 chosen_arch
= choose_arch_by_number (info
->mach
);
805 if (chosen_arch
!= NULL
)
807 mips_processor
= chosen_arch
->processor
;
808 mips_isa
= chosen_arch
->isa
;
809 mips_ase
= chosen_arch
->ase
;
810 mips_cp0_names
= chosen_arch
->cp0_names
;
811 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
812 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
813 mips_hwr_names
= chosen_arch
->hwr_names
;
819 parse_mips_dis_option (const char *option
, unsigned int len
)
821 unsigned int i
, optionlen
, vallen
;
823 const struct mips_abi_choice
*chosen_abi
;
824 const struct mips_arch_choice
*chosen_arch
;
826 /* Try to match options that are simple flags */
827 if (CONST_STRNEQ (option
, "no-aliases"))
833 if (CONST_STRNEQ (option
, "virt"))
835 mips_ase
|= ASE_VIRT
;
836 if (mips_isa
& ISA_MIPS64R2
)
837 mips_ase
|= ASE_VIRT64
;
841 /* Look for the = that delimits the end of the option name. */
842 for (i
= 0; i
< len
; i
++)
843 if (option
[i
] == '=')
846 if (i
== 0) /* Invalid option: no name before '='. */
848 if (i
== len
) /* Invalid option: no '='. */
850 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
854 val
= option
+ (optionlen
+ 1);
855 vallen
= len
- (optionlen
+ 1);
857 if (strncmp ("gpr-names", option
, optionlen
) == 0
858 && strlen ("gpr-names") == optionlen
)
860 chosen_abi
= choose_abi_by_name (val
, vallen
);
861 if (chosen_abi
!= NULL
)
862 mips_gpr_names
= chosen_abi
->gpr_names
;
866 if (strncmp ("fpr-names", option
, optionlen
) == 0
867 && strlen ("fpr-names") == optionlen
)
869 chosen_abi
= choose_abi_by_name (val
, vallen
);
870 if (chosen_abi
!= NULL
)
871 mips_fpr_names
= chosen_abi
->fpr_names
;
875 if (strncmp ("cp0-names", option
, optionlen
) == 0
876 && strlen ("cp0-names") == optionlen
)
878 chosen_arch
= choose_arch_by_name (val
, vallen
);
879 if (chosen_arch
!= NULL
)
881 mips_cp0_names
= chosen_arch
->cp0_names
;
882 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
883 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
888 if (strncmp ("hwr-names", option
, optionlen
) == 0
889 && strlen ("hwr-names") == optionlen
)
891 chosen_arch
= choose_arch_by_name (val
, vallen
);
892 if (chosen_arch
!= NULL
)
893 mips_hwr_names
= chosen_arch
->hwr_names
;
897 if (strncmp ("reg-names", option
, optionlen
) == 0
898 && strlen ("reg-names") == optionlen
)
900 /* We check both ABI and ARCH here unconditionally, so
901 that "numeric" will do the desirable thing: select
902 numeric register names for all registers. Other than
903 that, a given name probably won't match both. */
904 chosen_abi
= choose_abi_by_name (val
, vallen
);
905 if (chosen_abi
!= NULL
)
907 mips_gpr_names
= chosen_abi
->gpr_names
;
908 mips_fpr_names
= chosen_abi
->fpr_names
;
910 chosen_arch
= choose_arch_by_name (val
, vallen
);
911 if (chosen_arch
!= NULL
)
913 mips_cp0_names
= chosen_arch
->cp0_names
;
914 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
915 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
916 mips_hwr_names
= chosen_arch
->hwr_names
;
921 /* Invalid option. */
925 parse_mips_dis_options (const char *options
)
927 const char *option_end
;
932 while (*options
!= '\0')
934 /* Skip empty options. */
941 /* We know that *options is neither NUL or a comma. */
942 option_end
= options
+ 1;
943 while (*option_end
!= ',' && *option_end
!= '\0')
946 parse_mips_dis_option (options
, option_end
- options
);
948 /* Go on to the next one. If option_end points to a comma, it
949 will be skipped above. */
950 options
= option_end
;
954 static const struct mips_cp0sel_name
*
955 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
962 for (i
= 0; i
< len
; i
++)
963 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
968 /* Print insn arguments for 32/64-bit code. */
971 print_insn_args (const char *d
,
974 struct disassemble_info
*info
,
975 const struct mips_opcode
*opp
)
977 const fprintf_ftype infprintf
= info
->fprintf_func
;
978 unsigned int lsb
, msb
, msbd
, cpreg
;
979 void *is
= info
->stream
;
983 #define GET_OP(insn, field) \
984 (((insn) >> OP_SH_##field) & OP_MASK_##field)
985 #define GET_OP_S(insn, field) \
986 ((GET_OP (insn, field) ^ ((OP_MASK_##field >> 1) + 1)) \
987 - ((OP_MASK_##field >> 1) + 1))
988 for (; *d
!= '\0'; d
++)
995 infprintf (is
, "%c", *d
);
999 /* Extension character; switch for second char. */
1004 /* xgettext:c-format */
1006 _("# internal error, "
1007 "incomplete extension sequence (+)"));
1011 lsb
= GET_OP (l
, SHAMT
);
1012 infprintf (is
, "0x%x", lsb
);
1016 msb
= GET_OP (l
, INSMSB
);
1017 infprintf (is
, "0x%x", msb
- lsb
+ 1);
1021 infprintf (is
, "0x%x", GET_OP (l
, UDI1
));
1025 infprintf (is
, "0x%x", GET_OP (l
, UDI2
));
1029 infprintf (is
, "0x%x", GET_OP (l
, UDI3
));
1033 infprintf (is
, "0x%x", GET_OP (l
, UDI4
));
1038 msbd
= GET_OP (l
, EXTMSBD
);
1039 infprintf (is
, "0x%x", msbd
+ 1);
1043 lsb
= GET_OP (l
, SHAMT
) + 32;
1044 infprintf (is
, "0x%x", lsb
);
1048 msb
= GET_OP (l
, INSMSB
) + 32;
1049 infprintf (is
, "0x%x", msb
- lsb
+ 1);
1053 msbd
= GET_OP (l
, EXTMSBD
) + 32;
1054 infprintf (is
, "0x%x", msbd
+ 1);
1057 case 'J': /* hypcall operand */
1058 infprintf (is
, "0x%x", GET_OP (l
, CODE10
));
1061 case 't': /* Coprocessor 0 reg name */
1062 infprintf (is
, "%s", mips_cp0_names
[GET_OP (l
, RT
)]);
1065 case 'x': /* bbit bit index */
1066 infprintf (is
, "0x%x", GET_OP (l
, BBITIND
));
1069 case 'p': /* cins, cins32, exts and exts32 position */
1070 infprintf (is
, "0x%x", GET_OP (l
, CINSPOS
));
1073 case 's': /* cins32 and exts32 length-minus-one */
1074 case 'S': /* cins and exts length-minus-one field */
1075 infprintf (is
, "0x%x", GET_OP (l
, CINSLM1
));
1078 case 'Q': /* seqi/snei immediate field */
1079 infprintf (is
, "%d", GET_OP_S (l
, SEQI
));
1082 case 'a': /* 8-bit signed offset in bit 6 */
1083 infprintf (is
, "%d", GET_OP_S (l
, OFFSET_A
));
1086 case 'b': /* 8-bit signed offset in bit 3 */
1087 infprintf (is
, "%d", GET_OP_S (l
, OFFSET_B
));
1090 case 'c': /* 9-bit signed offset in bit 6 */
1091 /* Left shift 4 bits to print the real offset. */
1092 infprintf (is
, "%d", GET_OP_S (l
, OFFSET_C
) << 4);
1096 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RZ
)]);
1100 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FZ
)]);
1103 case 'i': /* JALX destination */
1104 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
1105 | (GET_OP (l
, TARGET
) << 2));
1106 /* For gdb disassembler, force odd address on jalx. */
1107 if (info
->flavour
== bfd_target_unknown_flavour
)
1109 (*info
->print_address_func
) (info
->target
, info
);
1112 case 'j': /* 9-bit signed offset in bit 7. */
1113 infprintf (is
, "%d", GET_OP_S (l
, EVAOFFSET
));
1117 /* xgettext:c-format */
1119 _("# internal error, "
1120 "undefined extension sequence (+%c)"),
1127 infprintf (is
, "0x%x", GET_OP (l
, BP
));
1131 infprintf (is
, "0x%x", GET_OP (l
, SA3
));
1135 infprintf (is
, "0x%x", GET_OP (l
, SA4
));
1139 infprintf (is
, "0x%x", GET_OP (l
, IMM8
));
1143 infprintf (is
, "0x%x", GET_OP (l
, RS
));
1147 infprintf (is
, "$ac%d", GET_OP (l
, DSPACC
));
1151 infprintf (is
, "0x%x", GET_OP (l
, WRDSP
));
1155 infprintf (is
, "$ac%d", GET_OP (l
, DSPACC_S
));
1158 case '0': /* dsp 6-bit signed immediate in bit 20 */
1159 infprintf (is
, "%d", GET_OP_S (l
, DSPSFT
));
1162 case ':': /* dsp 7-bit signed immediate in bit 19 */
1163 infprintf (is
, "%d", GET_OP_S (l
, DSPSFT_7
));
1167 infprintf (is
, "%d", GET_OP_S (l
, OFFSET12
));
1171 infprintf (is
, "0x%x", GET_OP (l
, 3BITPOS
));
1175 infprintf (is
, "0x%x", GET_OP (l
, RDDSP
));
1178 case '@': /* dsp 10-bit signed immediate in bit 16 */
1179 infprintf (is
, "%d", GET_OP_S (l
, IMM10
));
1183 infprintf (is
, "%d", GET_OP (l
, MT_U
));
1187 infprintf (is
, "%d", GET_OP (l
, MT_H
));
1191 infprintf (is
, "$ac%d", GET_OP (l
, MTACC_T
));
1195 infprintf (is
, "$ac%d", GET_OP (l
, MTACC_D
));
1199 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
1200 infprintf (is
, "$%d", GET_OP (l
, RD
));
1207 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RS
)]);
1212 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RT
)]);
1217 infprintf (is
, "0x%x", GET_OP (l
, IMMEDIATE
));
1220 case 'j': /* Same as i, but sign-extended. */
1222 infprintf (is
, "%d", GET_OP_S (l
, DELTA
));
1226 infprintf (is
, "0x%x", GET_OP (l
, PREFX
));
1230 infprintf (is
, "0x%x", GET_OP (l
, CACHE
));
1234 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
1235 | (GET_OP (l
, TARGET
) << 2));
1236 (*info
->print_address_func
) (info
->target
, info
);
1240 /* Sign extend the displacement. */
1241 info
->target
= (GET_OP_S (l
, DELTA
) << 2) + pc
+ INSNLEN
;
1242 (*info
->print_address_func
) (info
->target
, info
);
1246 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RD
)]);
1251 /* First check for both rd and rt being equal. */
1254 reg
= GET_OP (l
, RD
);
1255 if (reg
== GET_OP (l
, RT
))
1256 infprintf (is
, "%s", mips_gpr_names
[reg
]);
1259 /* If one is zero use the other. */
1261 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RT
)]);
1262 else if (GET_OP (l
, RT
) == 0)
1263 infprintf (is
, "%s", mips_gpr_names
[reg
]);
1264 else /* Bogus, result depends on processor. */
1265 infprintf (is
, "%s or %s",
1266 mips_gpr_names
[reg
],
1267 mips_gpr_names
[GET_OP (l
, RT
)]);
1273 infprintf (is
, "%s", mips_gpr_names
[0]);
1278 infprintf (is
, "0x%x", GET_OP (l
, SHAMT
));
1282 infprintf (is
, "0x%x", GET_OP (l
, CODE
));
1286 infprintf (is
, "0x%x", GET_OP (l
, CODE2
));
1290 infprintf (is
, "0x%x", GET_OP (l
, COPZ
));
1294 infprintf (is
, "0x%x", GET_OP (l
, CODE20
));
1298 infprintf (is
, "0x%x", GET_OP (l
, CODE19
));
1303 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FS
)]);
1308 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FT
)]);
1312 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FD
)]);
1316 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FR
)]);
1320 cpreg
= GET_OP (l
, RT
);
1324 cpreg
= GET_OP (l
, RD
);
1326 /* Coprocessor register for mtcN instructions, et al. Note
1327 that FPU (cp1) instructions disassemble this field using
1328 'S' format. Therefore, we only need to worry about cp0,
1330 if (opp
->name
[strlen (opp
->name
) - 1] == '0')
1332 if (d
[1] == ',' && d
[2] == 'H')
1334 const struct mips_cp0sel_name
*n
;
1337 sel
= GET_OP (l
, SEL
);
1339 /* CP0 register including 'sel' code for mtcN (et al.), to be
1340 printed textually if known. If not known, print both
1341 CP0 register name and sel numerically since CP0 register
1342 with sel 0 may have a name unrelated to register being
1344 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1345 mips_cp0sel_names_len
,
1348 infprintf (is
, "%s", n
->name
);
1350 infprintf (is
, "$%d,%d", cpreg
, sel
);
1354 infprintf (is
, "%s", mips_cp0_names
[cpreg
]);
1357 infprintf (is
, "$%d", cpreg
);
1361 infprintf (is
, "%s", mips_hwr_names
[GET_OP (l
, RD
)]);
1366 (opp
->pinfo
& (FP_D
| FP_S
)) != 0 ? "$fcc%d" : "$cc%d",
1371 infprintf (is
, "$fcc%d", GET_OP (l
, CCC
));
1375 infprintf (is
, "%d", GET_OP (l
, PERFREG
));
1379 infprintf (is
, "%d", GET_OP (l
, VECBYTE
));
1383 infprintf (is
, "%d", GET_OP (l
, VECALIGN
));
1387 infprintf (is
, "%d", GET_OP (l
, SEL
));
1391 infprintf (is
, "%d", GET_OP (l
, ALN
));
1396 unsigned int vsel
= GET_OP (l
, VSEL
);
1399 prefix
= opp
->membership
& INSN_5400
? 'f' : 'v';
1400 if ((vsel
& 0x10) == 0)
1405 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1406 if ((vsel
& 1) == 0)
1408 infprintf (is
, "$%c%d[%d]", prefix
, GET_OP (l
, FT
), vsel
>> 1);
1410 else if ((vsel
& 0x08) == 0)
1412 infprintf (is
, "$%c%d", prefix
, GET_OP (l
, FT
));
1416 infprintf (is
, "0x%x", GET_OP (l
, FT
));
1422 infprintf (is
, "$v%d", GET_OP (l
, FD
));
1426 infprintf (is
, "$v%d", GET_OP (l
, FS
));
1430 infprintf (is
, "$v%d", GET_OP (l
, FT
));
1434 /* xgettext:c-format */
1435 infprintf (is
, _("# internal error, undefined modifier (%c)"), *d
);
1441 /* Print the mips instruction at address MEMADDR in debugged memory,
1442 on using INFO. Returns length of the instruction, in bytes, which is
1443 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1444 this is little-endian code. */
1447 print_insn_mips (bfd_vma memaddr
,
1449 struct disassemble_info
*info
)
1451 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1452 const fprintf_ftype infprintf
= info
->fprintf_func
;
1453 const struct mips_opcode
*op
;
1454 static bfd_boolean init
= 0;
1455 void *is
= info
->stream
;
1457 /* Build a hash table to shorten the search time. */
1462 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1464 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1466 if (op
->pinfo
== INSN_MACRO
1467 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1469 if (i
== GET_OP (op
->match
, OP
))
1480 info
->bytes_per_chunk
= INSNLEN
;
1481 info
->display_endian
= info
->endian
;
1482 info
->insn_info_valid
= 1;
1483 info
->branch_delay_insns
= 0;
1484 info
->data_size
= 0;
1485 info
->insn_type
= dis_nonbranch
;
1489 op
= mips_hash
[GET_OP (word
, OP
)];
1492 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1494 if (op
->pinfo
!= INSN_MACRO
1495 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1496 && (word
& op
->mask
) == op
->match
)
1500 /* We always allow to disassemble the jalx instruction. */
1501 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1502 && strcmp (op
->name
, "jalx"))
1505 /* Figure out instruction type and branch delay information. */
1506 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1508 if ((op
->pinfo
& (INSN_WRITE_GPR_31
1509 | INSN_WRITE_GPR_D
)) != 0)
1510 info
->insn_type
= dis_jsr
;
1512 info
->insn_type
= dis_branch
;
1513 info
->branch_delay_insns
= 1;
1515 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1516 | INSN_COND_BRANCH_LIKELY
)) != 0)
1518 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1519 info
->insn_type
= dis_condjsr
;
1521 info
->insn_type
= dis_condbranch
;
1522 info
->branch_delay_insns
= 1;
1524 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1525 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1526 info
->insn_type
= dis_dref
;
1528 infprintf (is
, "%s", op
->name
);
1531 if (d
!= NULL
&& *d
!= '\0')
1533 infprintf (is
, "\t");
1534 print_insn_args (d
, word
, memaddr
, info
, op
);
1544 /* Handle undefined instructions. */
1545 info
->insn_type
= dis_noninsn
;
1546 infprintf (is
, "0x%x", word
);
1550 /* Disassemble an operand for a mips16 instruction. */
1553 print_mips16_insn_arg (char type
,
1554 const struct mips_opcode
*op
,
1556 bfd_boolean use_extend
,
1559 struct disassemble_info
*info
)
1561 const fprintf_ftype infprintf
= info
->fprintf_func
;
1562 void *is
= info
->stream
;
1564 #define GET_OP(insn, field) \
1565 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1566 #define GET_OP_S(insn, field) \
1567 ((GET_OP (insn, field) ^ ((MIPS16OP_MASK_##field >> 1) + 1)) \
1568 - ((MIPS16OP_MASK_##field >> 1) + 1))
1574 infprintf (is
, "%c", type
);
1579 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RY
)));
1584 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RX
)));
1588 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RZ
)));
1592 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, MOVE32Z
)));
1596 infprintf (is
, "%s", mips_gpr_names
[0]);
1600 infprintf (is
, "%s", mips_gpr_names
[29]);
1604 infprintf (is
, "$pc");
1608 infprintf (is
, "%s", mips_gpr_names
[31]);
1612 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, REGR32
)]);
1616 infprintf (is
, "%s", mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1642 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1654 immed
= GET_OP (l
, RZ
);
1660 immed
= GET_OP (l
, RX
);
1666 immed
= GET_OP (l
, RZ
);
1672 immed
= GET_OP (l
, RX
);
1678 immed
= GET_OP (l
, IMM4
);
1684 immed
= GET_OP (l
, IMM5
);
1685 info
->insn_type
= dis_dref
;
1686 info
->data_size
= 1;
1691 immed
= GET_OP (l
, IMM5
);
1692 info
->insn_type
= dis_dref
;
1693 info
->data_size
= 2;
1698 immed
= GET_OP (l
, IMM5
);
1699 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1700 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1702 info
->insn_type
= dis_dref
;
1703 info
->data_size
= 4;
1709 immed
= GET_OP (l
, IMM5
);
1710 info
->insn_type
= dis_dref
;
1711 info
->data_size
= 8;
1715 immed
= GET_OP (l
, IMM5
);
1720 immed
= GET_OP (l
, IMM6
);
1724 immed
= GET_OP (l
, IMM8
);
1729 immed
= GET_OP (l
, IMM8
);
1730 /* FIXME: This might be lw, or it might be addiu to $sp or
1731 $pc. We assume it's load. */
1732 info
->insn_type
= dis_dref
;
1733 info
->data_size
= 4;
1738 immed
= GET_OP (l
, IMM8
);
1739 info
->insn_type
= dis_dref
;
1740 info
->data_size
= 8;
1744 immed
= GET_OP (l
, IMM8
);
1749 immed
= GET_OP (l
, IMM8
);
1755 immed
= GET_OP (l
, IMM8
);
1760 immed
= GET_OP (l
, IMM8
);
1767 immed
= GET_OP (l
, IMM11
);
1775 immed
= GET_OP (l
, IMM8
);
1777 /* FIXME: This can be lw or la. We assume it is lw. */
1778 info
->insn_type
= dis_dref
;
1779 info
->data_size
= 4;
1784 immed
= GET_OP (l
, IMM5
);
1786 info
->insn_type
= dis_dref
;
1787 info
->data_size
= 8;
1792 immed
= GET_OP (l
, IMM5
);
1801 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1802 immed
-= 1 << nbits
;
1804 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1811 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1812 else if (extbits
== 15)
1813 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1815 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1816 immed
&= (1 << extbits
) - 1;
1817 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1818 immed
-= 1 << extbits
;
1822 infprintf (is
, "%d", immed
);
1830 baseaddr
= memaddr
+ 2;
1832 else if (use_extend
)
1833 baseaddr
= memaddr
- 2;
1841 /* If this instruction is in the delay slot of a jr
1842 instruction, the base address is the address of the
1843 jr instruction. If it is in the delay slot of jalr
1844 instruction, the base address is the address of the
1845 jalr instruction. This test is unreliable: we have
1846 no way of knowing whether the previous word is
1847 instruction or data. */
1848 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1851 && (((info
->endian
== BFD_ENDIAN_BIG
1852 ? bfd_getb16 (buffer
)
1853 : bfd_getl16 (buffer
))
1854 & 0xf800) == 0x1800))
1855 baseaddr
= memaddr
- 4;
1858 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1861 && (((info
->endian
== BFD_ENDIAN_BIG
1862 ? bfd_getb16 (buffer
)
1863 : bfd_getl16 (buffer
))
1864 & 0xf81f) == 0xe800))
1865 baseaddr
= memaddr
- 2;
1868 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1870 && info
->flavour
== bfd_target_unknown_flavour
)
1871 /* For gdb disassembler, maintain odd address. */
1873 (*info
->print_address_func
) (info
->target
, info
);
1883 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1884 if (type
== 'a' && info
->flavour
== bfd_target_unknown_flavour
)
1885 /* For gdb disassembler, maintain odd address. */
1888 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1889 (*info
->print_address_func
) (info
->target
, info
);
1895 int need_comma
, amask
, smask
;
1899 l
= GET_OP (l
, IMM6
);
1901 amask
= (l
>> 3) & 7;
1903 if (amask
> 0 && amask
< 5)
1905 infprintf (is
, "%s", mips_gpr_names
[4]);
1907 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1911 smask
= (l
>> 1) & 3;
1914 infprintf (is
, "%s??", need_comma
? "," : "");
1919 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[16]);
1921 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1927 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[31]);
1931 if (amask
== 5 || amask
== 6)
1933 infprintf (is
, "%s$f0", need_comma
? "," : "");
1935 infprintf (is
, "-$f1");
1942 /* MIPS16e save/restore. */
1945 int amask
, args
, statics
;
1954 amask
= (l
>> 16) & 0xf;
1955 if (amask
== MIPS16_ALL_ARGS
)
1960 else if (amask
== MIPS16_ALL_STATICS
)
1968 statics
= amask
& 3;
1972 infprintf (is
, "%s", mips_gpr_names
[4]);
1974 infprintf (is
, "-%s", mips_gpr_names
[4 + args
- 1]);
1978 framesz
= (((l
>> 16) & 0xf0) | (l
& 0x0f)) * 8;
1979 if (framesz
== 0 && !use_extend
)
1982 infprintf (is
, "%s%d", need_comma
? "," : "", framesz
);
1984 if (l
& 0x40) /* $ra */
1985 infprintf (is
, ",%s", mips_gpr_names
[31]);
1987 nsreg
= (l
>> 24) & 0x7;
1989 if (l
& 0x20) /* $s0 */
1991 if (l
& 0x10) /* $s1 */
1993 if (nsreg
> 0) /* $s2-$s8 */
1994 smask
|= ((1 << nsreg
) - 1) << 2;
1996 /* Find first set static reg bit. */
1997 for (i
= 0; i
< 9; i
++)
1999 if (smask
& (1 << i
))
2001 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
2002 /* Skip over string of set bits. */
2003 for (j
= i
; smask
& (2 << j
); j
++)
2006 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
2011 /* Statics $ax - $a3. */
2013 infprintf (is
, ",%s", mips_gpr_names
[7]);
2014 else if (statics
> 0)
2015 infprintf (is
, ",%s-%s",
2016 mips_gpr_names
[7 - statics
+ 1],
2022 /* xgettext:c-format */
2024 _("# internal disassembler error, "
2025 "unrecognised modifier (%c)"),
2032 /* Check if the given address is the last word of a MIPS16 PLT entry.
2033 This word is data and depending on the value it may interfere with
2034 disassembly of further PLT entries. We make use of the fact PLT
2035 symbols are marked BSF_SYNTHETIC. */
2037 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2041 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2042 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2048 /* Disassemble mips16 instructions. */
2051 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2053 const fprintf_ftype infprintf
= info
->fprintf_func
;
2058 bfd_boolean use_extend
;
2060 const struct mips_opcode
*op
, *opend
;
2061 void *is
= info
->stream
;
2063 info
->bytes_per_chunk
= 2;
2064 info
->display_endian
= info
->endian
;
2065 info
->insn_info_valid
= 1;
2066 info
->branch_delay_insns
= 0;
2067 info
->data_size
= 0;
2071 /* Decode PLT entry's GOT slot address word. */
2072 if (is_mips16_plt_tail (info
, memaddr
))
2074 info
->insn_type
= dis_noninsn
;
2075 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2078 unsigned int gotslot
;
2080 if (info
->endian
== BFD_ENDIAN_BIG
)
2081 gotslot
= bfd_getb32 (buffer
);
2083 gotslot
= bfd_getl32 (buffer
);
2084 infprintf (is
, ".word\t0x%x", gotslot
);
2091 info
->insn_type
= dis_nonbranch
;
2092 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2096 (*info
->memory_error_func
) (status
, memaddr
, info
);
2102 if (info
->endian
== BFD_ENDIAN_BIG
)
2103 insn
= bfd_getb16 (buffer
);
2105 insn
= bfd_getl16 (buffer
);
2107 /* Handle the extend opcode specially. */
2109 if ((insn
& 0xf800) == 0xf000)
2112 extend
= insn
& 0x7ff;
2116 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2119 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2120 (*info
->memory_error_func
) (status
, memaddr
, info
);
2124 if (info
->endian
== BFD_ENDIAN_BIG
)
2125 insn
= bfd_getb16 (buffer
);
2127 insn
= bfd_getl16 (buffer
);
2129 /* Check for an extend opcode followed by an extend opcode. */
2130 if ((insn
& 0xf800) == 0xf000)
2132 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2133 info
->insn_type
= dis_noninsn
;
2140 /* FIXME: Should probably use a hash table on the major opcode here. */
2142 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2143 for (op
= mips16_opcodes
; op
< opend
; op
++)
2145 if (op
->pinfo
!= INSN_MACRO
2146 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2147 && (insn
& op
->mask
) == op
->match
)
2151 if (op
->args
[0] == 'a' || op
->args
[0] == 'i')
2155 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2156 info
->insn_type
= dis_noninsn
;
2164 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2169 if (info
->endian
== BFD_ENDIAN_BIG
)
2170 extend
= bfd_getb16 (buffer
);
2172 extend
= bfd_getl16 (buffer
);
2177 infprintf (is
, "%s", op
->name
);
2178 if (op
->args
[0] != '\0')
2179 infprintf (is
, "\t");
2181 for (s
= op
->args
; *s
!= '\0'; s
++)
2185 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
2187 /* Skip the register and the comma. */
2193 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
2195 /* Skip the register and the comma. */
2199 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
2203 /* Figure out branch instruction type and delay slot information. */
2204 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2205 info
->branch_delay_insns
= 1;
2206 if ((op
->pinfo
& (INSN_UNCOND_BRANCH_DELAY
2207 | MIPS16_INSN_UNCOND_BRANCH
)) != 0)
2209 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2210 info
->insn_type
= dis_jsr
;
2212 info
->insn_type
= dis_branch
;
2214 else if ((op
->pinfo
& MIPS16_INSN_COND_BRANCH
) != 0)
2215 info
->insn_type
= dis_condbranch
;
2224 infprintf (is
, "0x%x", extend
| 0xf000);
2225 infprintf (is
, "0x%x", insn
);
2226 info
->insn_type
= dis_noninsn
;
2231 /* Disassemble microMIPS instructions. */
2234 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2236 const fprintf_ftype infprintf
= info
->fprintf_func
;
2237 const struct mips_opcode
*op
, *opend
;
2238 unsigned int lsb
, msbd
, msb
;
2239 void *is
= info
->stream
;
2252 info
->bytes_per_chunk
= 2;
2253 info
->display_endian
= info
->endian
;
2254 info
->insn_info_valid
= 1;
2255 info
->branch_delay_insns
= 0;
2256 info
->data_size
= 0;
2257 info
->insn_type
= dis_nonbranch
;
2261 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2264 (*info
->memory_error_func
) (status
, memaddr
, info
);
2270 if (info
->endian
== BFD_ENDIAN_BIG
)
2271 insn
= bfd_getb16 (buffer
);
2273 insn
= bfd_getl16 (buffer
);
2275 if ((insn
& 0xfc00) == 0x7c00)
2277 /* This is a 48-bit microMIPS instruction. */
2280 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2283 infprintf (is
, "micromips 0x%x", higher
);
2284 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2287 if (info
->endian
== BFD_ENDIAN_BIG
)
2288 insn
= bfd_getb16 (buffer
);
2290 insn
= bfd_getl16 (buffer
);
2291 higher
= (higher
<< 16) | insn
;
2293 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
2296 infprintf (is
, "micromips 0x%x", higher
);
2297 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2300 if (info
->endian
== BFD_ENDIAN_BIG
)
2301 insn
= bfd_getb16 (buffer
);
2303 insn
= bfd_getl16 (buffer
);
2304 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2306 info
->insn_type
= dis_noninsn
;
2309 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2311 /* This is a 32-bit microMIPS instruction. */
2314 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2317 infprintf (is
, "micromips 0x%x", higher
);
2318 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2322 if (info
->endian
== BFD_ENDIAN_BIG
)
2323 insn
= bfd_getb16 (buffer
);
2325 insn
= bfd_getl16 (buffer
);
2327 insn
= insn
| (higher
<< 16);
2332 /* FIXME: Should probably use a hash table on the major opcode here. */
2334 #define GET_OP(insn, field) \
2335 (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2336 #define GET_OP_S(insn, field) \
2337 ((GET_OP (insn, field) ^ ((MICROMIPSOP_MASK_##field >> 1) + 1)) \
2338 - ((MICROMIPSOP_MASK_##field >> 1) + 1))
2339 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2340 for (op
= micromips_opcodes
; op
< opend
; op
++)
2342 if (op
->pinfo
!= INSN_MACRO
2343 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2344 && (insn
& op
->mask
) == op
->match
2345 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2346 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2350 infprintf (is
, "%s", op
->name
);
2351 if (op
->args
[0] != '\0')
2352 infprintf (is
, "\t");
2354 for (s
= op
->args
; *s
!= '\0'; s
++)
2361 infprintf (is
, "%c", *s
);
2365 infprintf (is
, "%d", GET_OP_S (insn
, OFFSET10
));
2369 infprintf (is
, "0x%x", GET_OP (insn
, STYPE
));
2373 infprintf (is
, "0x%x", GET_OP (insn
, BP
));
2377 infprintf (is
, "0x%x", GET_OP (insn
, SA3
));
2381 infprintf (is
, "0x%x", GET_OP (insn
, SA4
));
2385 infprintf (is
, "0x%x", GET_OP (insn
, IMM8
));
2389 infprintf (is
, "0x%x", GET_OP (insn
, RS
));
2393 infprintf (is
, "$ac%d", GET_OP (insn
, DSPACC
));
2397 infprintf (is
, "0x%x", GET_OP (insn
, WRDSP
));
2400 case '0': /* DSP 6-bit signed immediate in bit 16. */
2401 delta
= (GET_OP (insn
, DSPSFT
) ^ 0x20) - 0x20;
2402 infprintf (is
, "%d", delta
);
2406 infprintf (is
, "0x%x", GET_OP (insn
, SHAMT
));
2410 infprintf (is
, "0x%x", GET_OP (insn
, 3BITPOS
));
2414 infprintf (is
, "0x%x", GET_OP (insn
, RD
));
2418 infprintf (is
, "0x%x", GET_OP (insn
, TRAP
));
2422 infprintf (is
, "%d", GET_OP_S (insn
, OFFSET12
));
2426 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x07ffffff)
2427 | (GET_OP (insn
, TARGET
) << 1));
2428 /* For gdb disassembler, maintain odd address. */
2429 if (info
->flavour
== bfd_target_unknown_flavour
)
2431 (*info
->print_address_func
) (info
->target
, info
);
2438 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS
)]);
2442 infprintf (is
, "0x%x", GET_OP (insn
, CODE
));
2446 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RD
)]);
2450 infprintf (is
, "0x%x", GET_OP (insn
, PREFX
));
2455 infprintf (is
, "0x%x", GET_OP (insn
, IMMEDIATE
));
2458 case 'j': /* Same as i, but sign-extended. */
2460 infprintf (is
, "%d", GET_OP_S (insn
, DELTA
));
2464 infprintf (is
, "0x%x", GET_OP (insn
, CACHE
));
2471 immed
= GET_OP (insn
, RT
);
2472 s_reg_encode
= immed
& 0xf;
2473 if (s_reg_encode
!= 0)
2475 if (s_reg_encode
== 1)
2476 infprintf (is
, "%s", mips_gpr_names
[16]);
2477 else if (s_reg_encode
< 9)
2478 infprintf (is
, "%s-%s",
2480 mips_gpr_names
[15 + s_reg_encode
]);
2481 else if (s_reg_encode
== 9)
2482 infprintf (is
, "%s-%s,%s",
2485 mips_gpr_names
[30]);
2487 infprintf (is
, "UNKNOWN");
2490 if (immed
& 0x10) /* For ra. */
2492 if (s_reg_encode
== 0)
2493 infprintf (is
, "%s", mips_gpr_names
[31]);
2495 infprintf (is
, ",%s", mips_gpr_names
[31]);
2501 /* Sign-extend the displacement. */
2502 delta
= GET_OP_S (insn
, DELTA
);
2503 info
->target
= (delta
<< 1) + memaddr
+ length
;
2504 (*info
->print_address_func
) (info
->target
, info
);
2508 infprintf (is
, "0x%x", GET_OP (insn
, CODE2
));
2513 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RT
)]);
2517 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS3
)]);
2521 infprintf (is
, "%s", mips_gpr_names
[0]);
2524 case '@': /* DSP 10-bit signed immediate in bit 16. */
2525 delta
= (GET_OP (insn
, IMM10
) ^ 0x200) - 0x200;
2526 infprintf (is
, "%d", delta
);
2530 infprintf (is
, "0x%x", GET_OP (insn
, CODE10
));
2534 infprintf (is
, "0x%x", GET_OP (insn
, COPZ
));
2538 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FD
)]);
2542 /* Coprocessor register for lwcN instructions, et al.
2544 Note that there is no load/store cp0 instructions, and
2545 that FPU (cp1) instructions disassemble this field using
2546 'T' format. Therefore, until we gain understanding of
2547 cp2 register names, we can simply print the register
2549 infprintf (is
, "$%d", GET_OP (insn
, RT
));
2553 /* Coprocessor register for mtcN instructions, et al. Note
2554 that FPU (cp1) instructions disassemble this field using
2555 'S' format. Therefore, we only need to worry about cp0,
2557 if (op
->name
[strlen (op
->name
) - 1] == '0')
2559 if (s
[1] == ',' && s
[2] == 'H')
2561 const struct mips_cp0sel_name
*n
;
2562 unsigned int cp0reg
, sel
;
2564 cp0reg
= GET_OP (insn
, RS
);
2565 sel
= GET_OP (insn
, SEL
);
2567 /* CP0 register including 'sel' code for mtcN
2568 (et al.), to be printed textually if known.
2569 If not known, print both CP0 register name and
2570 sel numerically since CP0 register with sel 0 may
2571 have a name unrelated to register being
2573 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2574 mips_cp0sel_names_len
,
2577 infprintf (is
, "%s", n
->name
);
2579 infprintf (is
, "$%d,%d", cp0reg
, sel
);
2583 infprintf (is
, "%s", mips_cp0_names
[GET_OP (insn
, RS
)]);
2586 infprintf (is
, "$%d", GET_OP (insn
, RS
));
2590 infprintf (is
, "%d", GET_OP (insn
, SEL
));
2594 infprintf (is
, "%s", mips_hwr_names
[GET_OP (insn
, RS
)]);
2598 infprintf (is
, "$fcc%d", GET_OP (insn
, CCC
));
2603 (op
->pinfo
& (FP_D
| FP_S
)) != 0
2604 ? "$fcc%d" : "$cc%d",
2605 GET_OP (insn
, BCC
));
2609 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FR
)]);
2614 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FS
)]);
2618 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FT
)]);
2622 /* Extension character; switch for second char. */
2627 lsb
= GET_OP (insn
, EXTLSB
);
2628 infprintf (is
, "0x%x", lsb
);
2632 msb
= GET_OP (insn
, INSMSB
);
2633 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2638 msbd
= GET_OP (insn
, EXTMSBD
);
2639 infprintf (is
, "0x%x", msbd
+ 1);
2643 lsb
= GET_OP (insn
, EXTLSB
) + 32;
2644 infprintf (is
, "0x%x", lsb
);
2648 msb
= GET_OP (insn
, INSMSB
) + 32;
2649 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2653 msbd
= GET_OP (insn
, EXTMSBD
) + 32;
2654 infprintf (is
, "0x%x", msbd
+ 1);
2658 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff)
2659 | (GET_OP (insn
, TARGET
) << 2));
2660 (*info
->print_address_func
) (info
->target
, info
);
2663 case 'j': /* 9-bit signed offset in bit 0. */
2664 delta
= GET_OP_S (insn
, EVAOFFSET
);
2665 infprintf (is
, "%d", delta
);
2669 /* xgettext:c-format */
2671 _("# internal disassembler error, "
2672 "unrecognized modifier (+%c)"),
2679 /* Extension character; switch for second char. */
2683 case 'a': /* global pointer. */
2684 infprintf (is
, "%s", mips_gpr_names
[28]);
2688 regno
= micromips_to_32_reg_b_map
[GET_OP (insn
, MB
)];
2689 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2693 regno
= micromips_to_32_reg_c_map
[GET_OP (insn
, MC
)];
2694 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2698 regno
= micromips_to_32_reg_d_map
[GET_OP (insn
, MD
)];
2699 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2703 regno
= micromips_to_32_reg_e_map
[GET_OP (insn
, ME
)];
2704 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2708 /* Save lastregno for "mt" to print out later. */
2709 lastregno
= micromips_to_32_reg_f_map
[GET_OP (insn
, MF
)];
2710 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2714 regno
= micromips_to_32_reg_g_map
[GET_OP (insn
, MG
)];
2715 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2719 regno
= micromips_to_32_reg_h_map1
[GET_OP (insn
, MH
)];
2720 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2721 regno
= micromips_to_32_reg_h_map2
[GET_OP (insn
, MH
)];
2722 infprintf (is
, ",%s", mips_gpr_names
[regno
]);
2726 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, MJ
)]);
2730 regno
= micromips_to_32_reg_l_map
[GET_OP (insn
, ML
)];
2731 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2735 regno
= micromips_to_32_reg_m_map
[GET_OP (insn
, MM
)];
2736 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2740 regno
= micromips_to_32_reg_n_map
[GET_OP (insn
, MN
)];
2741 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2745 /* Save lastregno for "mt" to print out later. */
2746 lastregno
= GET_OP (insn
, MP
);
2747 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2751 regno
= micromips_to_32_reg_q_map
[GET_OP (insn
, MQ
)];
2752 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2755 case 'r': /* program counter. */
2756 infprintf (is
, "$pc");
2759 case 's': /* stack pointer. */
2761 infprintf (is
, "%s", mips_gpr_names
[29]);
2765 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2769 infprintf (is
, "%s", mips_gpr_names
[0]);
2773 /* Sign-extend the immediate. */
2774 immed
= GET_OP_S (insn
, IMMA
) << 2;
2775 infprintf (is
, "%d", immed
);
2779 immed
= micromips_imm_b_map
[GET_OP (insn
, IMMB
)];
2780 infprintf (is
, "%d", immed
);
2784 immed
= micromips_imm_c_map
[GET_OP (insn
, IMMC
)];
2785 infprintf (is
, "0x%x", immed
);
2789 /* Sign-extend the displacement. */
2790 delta
= GET_OP_S (insn
, IMMD
);
2791 info
->target
= (delta
<< 1) + memaddr
+ length
;
2792 (*info
->print_address_func
) (info
->target
, info
);
2796 /* Sign-extend the displacement. */
2797 delta
= GET_OP_S (insn
, IMME
);
2798 info
->target
= (delta
<< 1) + memaddr
+ length
;
2799 (*info
->print_address_func
) (info
->target
, info
);
2803 immed
= GET_OP (insn
, IMMF
);
2804 infprintf (is
, "0x%x", immed
);
2808 immed
= (insn
>> MICROMIPSOP_SH_IMMG
) + 1;
2809 immed
= (immed
& MICROMIPSOP_MASK_IMMG
) - 1;
2810 infprintf (is
, "%d", immed
);
2814 immed
= GET_OP (insn
, IMMH
) << 1;
2815 infprintf (is
, "%d", immed
);
2819 immed
= (insn
>> MICROMIPSOP_SH_IMMI
) + 1;
2820 immed
= (immed
& MICROMIPSOP_MASK_IMMI
) - 1;
2821 infprintf (is
, "%d", immed
);
2825 immed
= GET_OP (insn
, IMMJ
) << 2;
2826 infprintf (is
, "%d", immed
);
2830 immed
= GET_OP (insn
, IMML
);
2831 infprintf (is
, "%d", immed
);
2835 immed
= (insn
>> MICROMIPSOP_SH_IMMM
) - 1;
2836 immed
= (immed
& MICROMIPSOP_MASK_IMMM
) + 1;
2837 infprintf (is
, "%d", immed
);
2841 immed
= GET_OP (insn
, IMMN
);
2843 infprintf (is
, "%s,%s",
2845 mips_gpr_names
[31]);
2847 infprintf (is
, "%s-%s,%s",
2849 mips_gpr_names
[16 + immed
],
2850 mips_gpr_names
[31]);
2854 immed
= GET_OP (insn
, IMMO
);
2855 infprintf (is
, "0x%x", immed
);
2859 immed
= GET_OP (insn
, IMMP
) << 2;
2860 infprintf (is
, "%d", immed
);
2864 /* Sign-extend the immediate. */
2865 immed
= GET_OP_S (insn
, IMMQ
) << 2;
2866 infprintf (is
, "%d", immed
);
2870 immed
= GET_OP (insn
, IMMU
) << 2;
2871 infprintf (is
, "%d", immed
);
2875 immed
= GET_OP (insn
, IMMW
) << 2;
2876 infprintf (is
, "%d", immed
);
2880 /* Sign-extend the immediate. */
2881 immed
= GET_OP_S (insn
, IMMX
);
2882 infprintf (is
, "%d", immed
);
2886 /* Sign-extend the immediate. */
2887 immed
= GET_OP_S (insn
, IMMY
) << 2;
2888 if ((unsigned int) (immed
+ 8) < 16)
2890 infprintf (is
, "%d", immed
);
2894 /* xgettext:c-format */
2896 _("# internal disassembler error, "
2897 "unrecognized modifier (m%c)"),
2904 /* xgettext:c-format */
2906 _("# internal disassembler error, "
2907 "unrecognized modifier (%c)"),
2913 /* Figure out instruction type and branch delay information. */
2915 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2916 info
->branch_delay_insns
= 1;
2917 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2918 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2920 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_GPR_T
)) != 0)
2921 info
->insn_type
= dis_jsr
;
2923 info
->insn_type
= dis_branch
;
2925 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2926 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2928 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2929 info
->insn_type
= dis_condjsr
;
2931 info
->insn_type
= dis_condbranch
;
2934 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY_DELAY
)) != 0)
2935 info
->insn_type
= dis_dref
;
2943 infprintf (is
, "0x%x", insn
);
2944 info
->insn_type
= dis_noninsn
;
2949 /* Return 1 if a symbol associated with the location being disassembled
2950 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2951 all the symbols at the address being considered assuming if at least
2952 one of them indicates code compression, then such code has been
2953 genuinely produced here (other symbols could have been derived from
2954 function symbols defined elsewhere or could define data). Otherwise,
2958 is_compressed_mode_p (struct disassemble_info
*info
)
2963 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2964 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2966 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2968 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2970 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2971 && info
->symtab
[i
]->section
== info
->section
)
2973 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2975 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2977 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2984 /* In an environment where we do not know the symbol type of the
2985 instruction we are forced to assume that the low order bit of the
2986 instructions' address may mark it as a mips16 instruction. If we
2987 are single stepping, or the pc is within the disassembled function,
2988 this works. Otherwise, we need a clue. Sometimes. */
2991 _print_insn_mips (bfd_vma memaddr
,
2992 struct disassemble_info
*info
,
2993 enum bfd_endian endianness
)
2995 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
2996 bfd_byte buffer
[INSNLEN
];
2999 set_default_mips_dis_options (info
);
3000 parse_mips_dis_options (info
->disassembler_options
);
3002 if (info
->mach
== bfd_mach_mips16
)
3003 return print_insn_mips16 (memaddr
, info
);
3004 if (info
->mach
== bfd_mach_mips_micromips
)
3005 return print_insn_micromips (memaddr
, info
);
3007 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
3010 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
3011 /* Only a few tools will work this way. */
3013 return print_insn_compr (memaddr
, info
);
3016 #if SYMTAB_AVAILABLE
3017 if (is_compressed_mode_p (info
))
3018 return print_insn_compr (memaddr
, info
);
3021 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
3026 if (endianness
== BFD_ENDIAN_BIG
)
3027 insn
= bfd_getb32 (buffer
);
3029 insn
= bfd_getl32 (buffer
);
3031 return print_insn_mips (memaddr
, insn
, info
);
3035 (*info
->memory_error_func
) (status
, memaddr
, info
);
3041 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3043 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
3047 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3049 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
3053 print_mips_disassembler_options (FILE *stream
)
3057 fprintf (stream
, _("\n\
3058 The following MIPS specific disassembler options are supported for use\n\
3059 with the -M switch (multiple options should be separated by commas):\n"));
3061 fprintf (stream
, _("\n\
3062 virt Recognize the virtualization ASE instructions.\n"));
3064 fprintf (stream
, _("\n\
3065 gpr-names=ABI Print GPR names according to specified ABI.\n\
3066 Default: based on binary being disassembled.\n"));
3068 fprintf (stream
, _("\n\
3069 fpr-names=ABI Print FPR names according to specified ABI.\n\
3070 Default: numeric.\n"));
3072 fprintf (stream
, _("\n\
3073 cp0-names=ARCH Print CP0 register names according to\n\
3074 specified architecture.\n\
3075 Default: based on binary being disassembled.\n"));
3077 fprintf (stream
, _("\n\
3078 hwr-names=ARCH Print HWR names according to specified \n\
3080 Default: based on binary being disassembled.\n"));
3082 fprintf (stream
, _("\n\
3083 reg-names=ABI Print GPR and FPR names according to\n\
3084 specified ABI.\n"));
3086 fprintf (stream
, _("\n\
3087 reg-names=ARCH Print CP0 register and HWR names according to\n\
3088 specified architecture.\n"));
3090 fprintf (stream
, _("\n\
3091 For the options above, the following values are supported for \"ABI\":\n\
3093 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
3094 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
3095 fprintf (stream
, _("\n"));
3097 fprintf (stream
, _("\n\
3098 For the options above, The following values are supported for \"ARCH\":\n\
3100 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
3101 if (*mips_arch_choices
[i
].name
!= '\0')
3102 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
3103 fprintf (stream
, _("\n"));
3105 fprintf (stream
, _("\n"));