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
++)
997 infprintf (is
, "%c", *d
);
1001 /* Extension character; switch for second char. */
1006 /* xgettext:c-format */
1008 _("# internal error, "
1009 "incomplete extension sequence (+)"));
1013 lsb
= GET_OP (l
, SHAMT
);
1014 infprintf (is
, "0x%x", lsb
);
1018 msb
= GET_OP (l
, INSMSB
);
1019 infprintf (is
, "0x%x", msb
- lsb
+ 1);
1023 infprintf (is
, "0x%x", GET_OP (l
, UDI1
));
1027 infprintf (is
, "0x%x", GET_OP (l
, UDI2
));
1031 infprintf (is
, "0x%x", GET_OP (l
, UDI3
));
1035 infprintf (is
, "0x%x", GET_OP (l
, UDI4
));
1040 msbd
= GET_OP (l
, EXTMSBD
);
1041 infprintf (is
, "0x%x", msbd
+ 1);
1045 lsb
= GET_OP (l
, SHAMT
) + 32;
1046 infprintf (is
, "0x%x", lsb
);
1050 msb
= GET_OP (l
, INSMSB
) + 32;
1051 infprintf (is
, "0x%x", msb
- lsb
+ 1);
1055 msbd
= GET_OP (l
, EXTMSBD
) + 32;
1056 infprintf (is
, "0x%x", msbd
+ 1);
1059 case 'J': /* hypcall operand */
1060 infprintf (is
, "0x%x", GET_OP (l
, CODE10
));
1063 case 't': /* Coprocessor 0 reg name */
1064 infprintf (is
, "%s", mips_cp0_names
[GET_OP (l
, RT
)]);
1067 case 'x': /* bbit bit index */
1068 infprintf (is
, "0x%x", GET_OP (l
, BBITIND
));
1071 case 'p': /* cins, cins32, exts and exts32 position */
1072 infprintf (is
, "0x%x", GET_OP (l
, CINSPOS
));
1075 case 's': /* cins and exts length-minus-one */
1076 infprintf (is
, "0x%x", GET_OP (l
, CINSLM1
));
1079 case 'S': /* cins32 and exts32 length-minus-one field */
1080 infprintf (is
, "0x%x", GET_OP (l
, CINSLM1
));
1083 case 'Q': /* seqi/snei immediate field */
1084 infprintf (is
, "%d", GET_OP_S (l
, SEQI
));
1087 case 'a': /* 8-bit signed offset in bit 6 */
1088 infprintf (is
, "%d", GET_OP_S (l
, OFFSET_A
));
1091 case 'b': /* 8-bit signed offset in bit 3 */
1092 infprintf (is
, "%d", GET_OP_S (l
, OFFSET_B
));
1095 case 'c': /* 9-bit signed offset in bit 6 */
1096 /* Left shift 4 bits to print the real offset. */
1097 infprintf (is
, "%d", GET_OP_S (l
, OFFSET_C
) << 4);
1101 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RZ
)]);
1105 infprintf (is
, "%s", mips_fpr_names
[GET_OP (l
, FZ
)]);
1108 case 'j': /* 9-bit signed offset in bit 7. */
1109 infprintf (is
, "%d", GET_OP_S (l
, EVAOFFSET
));
1113 /* xgettext:c-format */
1115 _("# internal error, "
1116 "undefined extension sequence (+%c)"),
1123 infprintf (is
, "0x%x", GET_OP (l
, BP
));
1127 infprintf (is
, "0x%x", GET_OP (l
, SA3
));
1131 infprintf (is
, "0x%x", GET_OP (l
, SA4
));
1135 infprintf (is
, "0x%x", GET_OP (l
, IMM8
));
1139 infprintf (is
, "0x%x", GET_OP (l
, RS
));
1143 infprintf (is
, "$ac%d", GET_OP (l
, DSPACC
));
1147 infprintf (is
, "0x%x", GET_OP (l
, WRDSP
));
1151 infprintf (is
, "$ac%d", GET_OP (l
, DSPACC_S
));
1154 case '0': /* dsp 6-bit signed immediate in bit 20 */
1155 infprintf (is
, "%d", GET_OP_S (l
, DSPSFT
));
1158 case ':': /* dsp 7-bit signed immediate in bit 19 */
1159 infprintf (is
, "%d", GET_OP_S (l
, DSPSFT_7
));
1163 infprintf (is
, "%d", GET_OP_S (l
, OFFSET12
));
1167 infprintf (is
, "0x%x", GET_OP (l
, 3BITPOS
));
1171 infprintf (is
, "0x%x", GET_OP (l
, RDDSP
));
1174 case '@': /* dsp 10-bit signed immediate in bit 16 */
1175 infprintf (is
, "%d", GET_OP_S (l
, IMM10
));
1179 infprintf (is
, "%d", GET_OP (l
, MT_U
));
1183 infprintf (is
, "%d", GET_OP (l
, MT_H
));
1187 infprintf (is
, "$ac%d", GET_OP (l
, MTACC_T
));
1191 infprintf (is
, "$ac%d", GET_OP (l
, MTACC_D
));
1195 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
1196 infprintf (is
, "$%d", GET_OP (l
, RD
));
1203 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RS
)]);
1208 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, RT
)]);
1213 infprintf (is
, "0x%x", GET_OP (l
, IMMEDIATE
));
1216 case 'j': /* Same as i, but sign-extended. */
1218 infprintf (is
, "%d", GET_OP_S (l
, DELTA
));
1222 infprintf (is
, "0x%x", GET_OP (l
, PREFX
));
1226 infprintf (is
, "0x%x", GET_OP (l
, CACHE
));
1230 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
1231 | (GET_OP (l
, TARGET
) << 2));
1232 /* For gdb disassembler, force odd address on jalx. */
1233 if (info
->flavour
== bfd_target_unknown_flavour
1234 && strcmp (opp
->name
, "jalx") == 0)
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
);
1398 if ((vsel
& 0x10) == 0)
1403 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1404 if ((vsel
& 1) == 0)
1406 infprintf (is
, "$v%d[%d]", GET_OP (l
, FT
), vsel
>> 1);
1408 else if ((vsel
& 0x08) == 0)
1410 infprintf (is
, "$v%d", GET_OP (l
, FT
));
1414 infprintf (is
, "0x%x", GET_OP (l
, FT
));
1420 infprintf (is
, "$v%d", GET_OP (l
, FD
));
1424 infprintf (is
, "$v%d", GET_OP (l
, FS
));
1428 infprintf (is
, "$v%d", GET_OP (l
, FT
));
1432 /* xgettext:c-format */
1433 infprintf (is
, _("# internal error, undefined modifier (%c)"), *d
);
1439 /* Print the mips instruction at address MEMADDR in debugged memory,
1440 on using INFO. Returns length of the instruction, in bytes, which is
1441 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1442 this is little-endian code. */
1445 print_insn_mips (bfd_vma memaddr
,
1447 struct disassemble_info
*info
)
1449 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1450 const fprintf_ftype infprintf
= info
->fprintf_func
;
1451 const struct mips_opcode
*op
;
1452 static bfd_boolean init
= 0;
1453 void *is
= info
->stream
;
1455 /* Build a hash table to shorten the search time. */
1460 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1462 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1464 if (op
->pinfo
== INSN_MACRO
1465 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1467 if (i
== GET_OP (op
->match
, OP
))
1478 info
->bytes_per_chunk
= INSNLEN
;
1479 info
->display_endian
= info
->endian
;
1480 info
->insn_info_valid
= 1;
1481 info
->branch_delay_insns
= 0;
1482 info
->data_size
= 0;
1483 info
->insn_type
= dis_nonbranch
;
1487 op
= mips_hash
[GET_OP (word
, OP
)];
1490 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1492 if (op
->pinfo
!= INSN_MACRO
1493 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1494 && (word
& op
->mask
) == op
->match
)
1498 /* We always allow to disassemble the jalx instruction. */
1499 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1500 && strcmp (op
->name
, "jalx"))
1503 /* Figure out instruction type and branch delay information. */
1504 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1506 if ((op
->pinfo
& (INSN_WRITE_GPR_31
1507 | INSN_WRITE_GPR_D
)) != 0)
1508 info
->insn_type
= dis_jsr
;
1510 info
->insn_type
= dis_branch
;
1511 info
->branch_delay_insns
= 1;
1513 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1514 | INSN_COND_BRANCH_LIKELY
)) != 0)
1516 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1517 info
->insn_type
= dis_condjsr
;
1519 info
->insn_type
= dis_condbranch
;
1520 info
->branch_delay_insns
= 1;
1522 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1523 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1524 info
->insn_type
= dis_dref
;
1526 infprintf (is
, "%s", op
->name
);
1529 if (d
!= NULL
&& *d
!= '\0')
1531 infprintf (is
, "\t");
1532 print_insn_args (d
, word
, memaddr
, info
, op
);
1542 /* Handle undefined instructions. */
1543 info
->insn_type
= dis_noninsn
;
1544 infprintf (is
, "0x%x", word
);
1548 /* Disassemble an operand for a mips16 instruction. */
1551 print_mips16_insn_arg (char type
,
1552 const struct mips_opcode
*op
,
1554 bfd_boolean use_extend
,
1557 struct disassemble_info
*info
)
1559 const fprintf_ftype infprintf
= info
->fprintf_func
;
1560 void *is
= info
->stream
;
1562 #define GET_OP(insn, field) \
1563 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1564 #define GET_OP_S(insn, field) \
1565 ((GET_OP (insn, field) ^ ((MIPS16OP_MASK_##field >> 1) + 1)) \
1566 - ((MIPS16OP_MASK_##field >> 1) + 1))
1572 infprintf (is
, "%c", type
);
1577 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RY
)));
1582 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RX
)));
1586 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, RZ
)));
1590 infprintf (is
, "%s", mips16_reg_names (GET_OP (l
, MOVE32Z
)));
1594 infprintf (is
, "%s", mips_gpr_names
[0]);
1598 infprintf (is
, "%s", mips_gpr_names
[29]);
1602 infprintf (is
, "$pc");
1606 infprintf (is
, "%s", mips_gpr_names
[31]);
1610 infprintf (is
, "%s", mips_gpr_names
[GET_OP (l
, REGR32
)]);
1614 infprintf (is
, "%s", mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1640 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1652 immed
= GET_OP (l
, RZ
);
1658 immed
= GET_OP (l
, RX
);
1664 immed
= GET_OP (l
, RZ
);
1670 immed
= GET_OP (l
, RX
);
1676 immed
= GET_OP (l
, IMM4
);
1682 immed
= GET_OP (l
, IMM5
);
1683 info
->insn_type
= dis_dref
;
1684 info
->data_size
= 1;
1689 immed
= GET_OP (l
, IMM5
);
1690 info
->insn_type
= dis_dref
;
1691 info
->data_size
= 2;
1696 immed
= GET_OP (l
, IMM5
);
1697 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1698 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1700 info
->insn_type
= dis_dref
;
1701 info
->data_size
= 4;
1707 immed
= GET_OP (l
, IMM5
);
1708 info
->insn_type
= dis_dref
;
1709 info
->data_size
= 8;
1713 immed
= GET_OP (l
, IMM5
);
1718 immed
= GET_OP (l
, IMM6
);
1722 immed
= GET_OP (l
, IMM8
);
1727 immed
= GET_OP (l
, IMM8
);
1728 /* FIXME: This might be lw, or it might be addiu to $sp or
1729 $pc. We assume it's load. */
1730 info
->insn_type
= dis_dref
;
1731 info
->data_size
= 4;
1736 immed
= GET_OP (l
, IMM8
);
1737 info
->insn_type
= dis_dref
;
1738 info
->data_size
= 8;
1742 immed
= GET_OP (l
, IMM8
);
1747 immed
= GET_OP (l
, IMM8
);
1753 immed
= GET_OP (l
, IMM8
);
1758 immed
= GET_OP (l
, IMM8
);
1765 immed
= GET_OP (l
, IMM11
);
1773 immed
= GET_OP (l
, IMM8
);
1775 /* FIXME: This can be lw or la. We assume it is lw. */
1776 info
->insn_type
= dis_dref
;
1777 info
->data_size
= 4;
1782 immed
= GET_OP (l
, IMM5
);
1784 info
->insn_type
= dis_dref
;
1785 info
->data_size
= 8;
1790 immed
= GET_OP (l
, IMM5
);
1799 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1800 immed
-= 1 << nbits
;
1802 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1809 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1810 else if (extbits
== 15)
1811 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1813 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1814 immed
&= (1 << extbits
) - 1;
1815 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1816 immed
-= 1 << extbits
;
1820 infprintf (is
, "%d", immed
);
1828 baseaddr
= memaddr
+ 2;
1830 else if (use_extend
)
1831 baseaddr
= memaddr
- 2;
1839 /* If this instruction is in the delay slot of a jr
1840 instruction, the base address is the address of the
1841 jr instruction. If it is in the delay slot of jalr
1842 instruction, the base address is the address of the
1843 jalr instruction. This test is unreliable: we have
1844 no way of knowing whether the previous word is
1845 instruction or data. */
1846 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1849 && (((info
->endian
== BFD_ENDIAN_BIG
1850 ? bfd_getb16 (buffer
)
1851 : bfd_getl16 (buffer
))
1852 & 0xf800) == 0x1800))
1853 baseaddr
= memaddr
- 4;
1856 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1859 && (((info
->endian
== BFD_ENDIAN_BIG
1860 ? bfd_getb16 (buffer
)
1861 : bfd_getl16 (buffer
))
1862 & 0xf81f) == 0xe800))
1863 baseaddr
= memaddr
- 2;
1866 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1868 && info
->flavour
== bfd_target_unknown_flavour
)
1869 /* For gdb disassembler, maintain odd address. */
1871 (*info
->print_address_func
) (info
->target
, info
);
1878 int jalx
= l
& 0x400;
1882 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1883 if (!jalx
&& info
->flavour
== bfd_target_unknown_flavour
)
1884 /* For gdb disassembler, maintain odd address. */
1887 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1888 (*info
->print_address_func
) (info
->target
, info
);
1894 int need_comma
, amask
, smask
;
1898 l
= GET_OP (l
, IMM6
);
1900 amask
= (l
>> 3) & 7;
1902 if (amask
> 0 && amask
< 5)
1904 infprintf (is
, "%s", mips_gpr_names
[4]);
1906 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1910 smask
= (l
>> 1) & 3;
1913 infprintf (is
, "%s??", need_comma
? "," : "");
1918 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[16]);
1920 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1926 infprintf (is
, "%s%s", need_comma
? "," : "", mips_gpr_names
[31]);
1930 if (amask
== 5 || amask
== 6)
1932 infprintf (is
, "%s$f0", need_comma
? "," : "");
1934 infprintf (is
, "-$f1");
1941 /* MIPS16e save/restore. */
1944 int amask
, args
, statics
;
1953 amask
= (l
>> 16) & 0xf;
1954 if (amask
== MIPS16_ALL_ARGS
)
1959 else if (amask
== MIPS16_ALL_STATICS
)
1967 statics
= amask
& 3;
1971 infprintf (is
, "%s", mips_gpr_names
[4]);
1973 infprintf (is
, "-%s", mips_gpr_names
[4 + args
- 1]);
1977 framesz
= (((l
>> 16) & 0xf0) | (l
& 0x0f)) * 8;
1978 if (framesz
== 0 && !use_extend
)
1981 infprintf (is
, "%s%d", need_comma
? "," : "", framesz
);
1983 if (l
& 0x40) /* $ra */
1984 infprintf (is
, ",%s", mips_gpr_names
[31]);
1986 nsreg
= (l
>> 24) & 0x7;
1988 if (l
& 0x20) /* $s0 */
1990 if (l
& 0x10) /* $s1 */
1992 if (nsreg
> 0) /* $s2-$s8 */
1993 smask
|= ((1 << nsreg
) - 1) << 2;
1995 /* Find first set static reg bit. */
1996 for (i
= 0; i
< 9; i
++)
1998 if (smask
& (1 << i
))
2000 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
2001 /* Skip over string of set bits. */
2002 for (j
= i
; smask
& (2 << j
); j
++)
2005 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
2010 /* Statics $ax - $a3. */
2012 infprintf (is
, ",%s", mips_gpr_names
[7]);
2013 else if (statics
> 0)
2014 infprintf (is
, ",%s-%s",
2015 mips_gpr_names
[7 - statics
+ 1],
2021 /* xgettext:c-format */
2023 _("# internal disassembler error, "
2024 "unrecognised modifier (%c)"),
2031 /* Check if the given address is the last word of a MIPS16 PLT entry.
2032 This word is data and depending on the value it may interfere with
2033 disassembly of further PLT entries. We make use of the fact PLT
2034 symbols are marked BSF_SYNTHETIC. */
2036 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2040 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2041 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2047 /* Disassemble mips16 instructions. */
2050 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2052 const fprintf_ftype infprintf
= info
->fprintf_func
;
2057 bfd_boolean use_extend
;
2059 const struct mips_opcode
*op
, *opend
;
2060 void *is
= info
->stream
;
2062 info
->bytes_per_chunk
= 2;
2063 info
->display_endian
= info
->endian
;
2064 info
->insn_info_valid
= 1;
2065 info
->branch_delay_insns
= 0;
2066 info
->data_size
= 0;
2070 /* Decode PLT entry's GOT slot address word. */
2071 if (is_mips16_plt_tail (info
, memaddr
))
2073 info
->insn_type
= dis_noninsn
;
2074 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2077 unsigned int gotslot
;
2079 if (info
->endian
== BFD_ENDIAN_BIG
)
2080 gotslot
= bfd_getb32 (buffer
);
2082 gotslot
= bfd_getl32 (buffer
);
2083 infprintf (is
, ".word\t0x%x", gotslot
);
2090 info
->insn_type
= dis_nonbranch
;
2091 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2095 (*info
->memory_error_func
) (status
, memaddr
, info
);
2101 if (info
->endian
== BFD_ENDIAN_BIG
)
2102 insn
= bfd_getb16 (buffer
);
2104 insn
= bfd_getl16 (buffer
);
2106 /* Handle the extend opcode specially. */
2108 if ((insn
& 0xf800) == 0xf000)
2111 extend
= insn
& 0x7ff;
2115 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2118 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2119 (*info
->memory_error_func
) (status
, memaddr
, info
);
2123 if (info
->endian
== BFD_ENDIAN_BIG
)
2124 insn
= bfd_getb16 (buffer
);
2126 insn
= bfd_getl16 (buffer
);
2128 /* Check for an extend opcode followed by an extend opcode. */
2129 if ((insn
& 0xf800) == 0xf000)
2131 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2132 info
->insn_type
= dis_noninsn
;
2139 /* FIXME: Should probably use a hash table on the major opcode here. */
2141 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2142 for (op
= mips16_opcodes
; op
< opend
; op
++)
2144 if (op
->pinfo
!= INSN_MACRO
2145 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2146 && (insn
& op
->mask
) == op
->match
)
2150 if (strchr (op
->args
, 'a') != NULL
)
2154 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2155 info
->insn_type
= dis_noninsn
;
2163 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2168 if (info
->endian
== BFD_ENDIAN_BIG
)
2169 extend
= bfd_getb16 (buffer
);
2171 extend
= bfd_getl16 (buffer
);
2176 infprintf (is
, "%s", op
->name
);
2177 if (op
->args
[0] != '\0')
2178 infprintf (is
, "\t");
2180 for (s
= op
->args
; *s
!= '\0'; s
++)
2184 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
2186 /* Skip the register and the comma. */
2192 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
2194 /* Skip the register and the comma. */
2198 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
2202 /* Figure out branch instruction type and delay slot information. */
2203 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2204 info
->branch_delay_insns
= 1;
2205 if ((op
->pinfo
& (INSN_UNCOND_BRANCH_DELAY
2206 | MIPS16_INSN_UNCOND_BRANCH
)) != 0)
2208 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2209 info
->insn_type
= dis_jsr
;
2211 info
->insn_type
= dis_branch
;
2213 else if ((op
->pinfo
& MIPS16_INSN_COND_BRANCH
) != 0)
2214 info
->insn_type
= dis_condbranch
;
2223 infprintf (is
, "0x%x", extend
| 0xf000);
2224 infprintf (is
, "0x%x", insn
);
2225 info
->insn_type
= dis_noninsn
;
2230 /* Disassemble microMIPS instructions. */
2233 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2235 const fprintf_ftype infprintf
= info
->fprintf_func
;
2236 const struct mips_opcode
*op
, *opend
;
2237 unsigned int lsb
, msbd
, msb
;
2238 void *is
= info
->stream
;
2251 info
->bytes_per_chunk
= 2;
2252 info
->display_endian
= info
->endian
;
2253 info
->insn_info_valid
= 1;
2254 info
->branch_delay_insns
= 0;
2255 info
->data_size
= 0;
2256 info
->insn_type
= dis_nonbranch
;
2260 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2263 (*info
->memory_error_func
) (status
, memaddr
, info
);
2269 if (info
->endian
== BFD_ENDIAN_BIG
)
2270 insn
= bfd_getb16 (buffer
);
2272 insn
= bfd_getl16 (buffer
);
2274 if ((insn
& 0xfc00) == 0x7c00)
2276 /* This is a 48-bit microMIPS instruction. */
2279 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2282 infprintf (is
, "micromips 0x%x", higher
);
2283 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2286 if (info
->endian
== BFD_ENDIAN_BIG
)
2287 insn
= bfd_getb16 (buffer
);
2289 insn
= bfd_getl16 (buffer
);
2290 higher
= (higher
<< 16) | insn
;
2292 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
2295 infprintf (is
, "micromips 0x%x", higher
);
2296 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2299 if (info
->endian
== BFD_ENDIAN_BIG
)
2300 insn
= bfd_getb16 (buffer
);
2302 insn
= bfd_getl16 (buffer
);
2303 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2305 info
->insn_type
= dis_noninsn
;
2308 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2310 /* This is a 32-bit microMIPS instruction. */
2313 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2316 infprintf (is
, "micromips 0x%x", higher
);
2317 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2321 if (info
->endian
== BFD_ENDIAN_BIG
)
2322 insn
= bfd_getb16 (buffer
);
2324 insn
= bfd_getl16 (buffer
);
2326 insn
= insn
| (higher
<< 16);
2331 /* FIXME: Should probably use a hash table on the major opcode here. */
2333 #define GET_OP(insn, field) \
2334 (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2335 #define GET_OP_S(insn, field) \
2336 ((GET_OP (insn, field) ^ ((MICROMIPSOP_MASK_##field >> 1) + 1)) \
2337 - ((MICROMIPSOP_MASK_##field >> 1) + 1))
2338 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2339 for (op
= micromips_opcodes
; op
< opend
; op
++)
2341 if (op
->pinfo
!= INSN_MACRO
2342 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2343 && (insn
& op
->mask
) == op
->match
2344 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2345 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2349 infprintf (is
, "%s", op
->name
);
2350 if (op
->args
[0] != '\0')
2351 infprintf (is
, "\t");
2353 for (s
= op
->args
; *s
!= '\0'; s
++)
2360 infprintf (is
, "%c", *s
);
2364 infprintf (is
, "%d", GET_OP_S (insn
, OFFSET10
));
2368 infprintf (is
, "0x%x", GET_OP (insn
, STYPE
));
2372 infprintf (is
, "0x%x", GET_OP (insn
, BP
));
2376 infprintf (is
, "0x%x", GET_OP (insn
, SA3
));
2380 infprintf (is
, "0x%x", GET_OP (insn
, SA4
));
2384 infprintf (is
, "0x%x", GET_OP (insn
, IMM8
));
2388 infprintf (is
, "0x%x", GET_OP (insn
, RS
));
2392 infprintf (is
, "$ac%d", GET_OP (insn
, DSPACC
));
2396 infprintf (is
, "0x%x", GET_OP (insn
, WRDSP
));
2399 case '0': /* DSP 6-bit signed immediate in bit 16. */
2400 delta
= (GET_OP (insn
, DSPSFT
) ^ 0x20) - 0x20;
2401 infprintf (is
, "%d", delta
);
2405 infprintf (is
, "0x%x", GET_OP (insn
, SHAMT
));
2409 infprintf (is
, "0x%x", GET_OP (insn
, 3BITPOS
));
2413 infprintf (is
, "0x%x", GET_OP (insn
, RD
));
2417 infprintf (is
, "0x%x", GET_OP (insn
, TRAP
));
2421 infprintf (is
, "%d", GET_OP_S (insn
, OFFSET12
));
2425 if (strcmp (op
->name
, "jalx") == 0)
2426 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff)
2427 | (GET_OP (insn
, TARGET
) << 2));
2429 info
->target
= (((memaddr
+ 4) & ~(bfd_vma
) 0x07ffffff)
2430 | (GET_OP (insn
, TARGET
) << 1));
2431 /* For gdb disassembler, force odd address on jalx. */
2432 if (info
->flavour
== bfd_target_unknown_flavour
2433 && strcmp (op
->name
, "jalx") == 0)
2435 (*info
->print_address_func
) (info
->target
, info
);
2442 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS
)]);
2446 infprintf (is
, "0x%x", GET_OP (insn
, CODE
));
2450 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RD
)]);
2454 infprintf (is
, "0x%x", GET_OP (insn
, PREFX
));
2459 infprintf (is
, "0x%x", GET_OP (insn
, IMMEDIATE
));
2462 case 'j': /* Same as i, but sign-extended. */
2464 infprintf (is
, "%d", GET_OP_S (insn
, DELTA
));
2468 infprintf (is
, "0x%x", GET_OP (insn
, CACHE
));
2475 immed
= GET_OP (insn
, RT
);
2476 s_reg_encode
= immed
& 0xf;
2477 if (s_reg_encode
!= 0)
2479 if (s_reg_encode
== 1)
2480 infprintf (is
, "%s", mips_gpr_names
[16]);
2481 else if (s_reg_encode
< 9)
2482 infprintf (is
, "%s-%s",
2484 mips_gpr_names
[15 + s_reg_encode
]);
2485 else if (s_reg_encode
== 9)
2486 infprintf (is
, "%s-%s,%s",
2489 mips_gpr_names
[30]);
2491 infprintf (is
, "UNKNOWN");
2494 if (immed
& 0x10) /* For ra. */
2496 if (s_reg_encode
== 0)
2497 infprintf (is
, "%s", mips_gpr_names
[31]);
2499 infprintf (is
, ",%s", mips_gpr_names
[31]);
2505 /* Sign-extend the displacement. */
2506 delta
= GET_OP_S (insn
, DELTA
);
2507 info
->target
= (delta
<< 1) + memaddr
+ length
;
2508 (*info
->print_address_func
) (info
->target
, info
);
2512 infprintf (is
, "0x%x", GET_OP (insn
, CODE2
));
2517 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RT
)]);
2521 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, RS3
)]);
2525 infprintf (is
, "%s", mips_gpr_names
[0]);
2528 case '@': /* DSP 10-bit signed immediate in bit 16. */
2529 delta
= (GET_OP (insn
, IMM10
) ^ 0x200) - 0x200;
2530 infprintf (is
, "%d", delta
);
2534 infprintf (is
, "0x%x", GET_OP (insn
, CODE10
));
2538 infprintf (is
, "0x%x", GET_OP (insn
, COPZ
));
2542 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FD
)]);
2546 /* Coprocessor register for lwcN instructions, et al.
2548 Note that there is no load/store cp0 instructions, and
2549 that FPU (cp1) instructions disassemble this field using
2550 'T' format. Therefore, until we gain understanding of
2551 cp2 register names, we can simply print the register
2553 infprintf (is
, "$%d", GET_OP (insn
, RT
));
2557 /* Coprocessor register for mtcN instructions, et al. Note
2558 that FPU (cp1) instructions disassemble this field using
2559 'S' format. Therefore, we only need to worry about cp0,
2561 if (op
->name
[strlen (op
->name
) - 1] == '0')
2563 if (s
[1] == ',' && s
[2] == 'H')
2565 const struct mips_cp0sel_name
*n
;
2566 unsigned int cp0reg
, sel
;
2568 cp0reg
= GET_OP (insn
, RS
);
2569 sel
= GET_OP (insn
, SEL
);
2571 /* CP0 register including 'sel' code for mtcN
2572 (et al.), to be printed textually if known.
2573 If not known, print both CP0 register name and
2574 sel numerically since CP0 register with sel 0 may
2575 have a name unrelated to register being
2577 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2578 mips_cp0sel_names_len
,
2581 infprintf (is
, "%s", n
->name
);
2583 infprintf (is
, "$%d,%d", cp0reg
, sel
);
2587 infprintf (is
, "%s", mips_cp0_names
[GET_OP (insn
, RS
)]);
2590 infprintf (is
, "$%d", GET_OP (insn
, RS
));
2594 infprintf (is
, "%d", GET_OP (insn
, SEL
));
2598 infprintf (is
, "%s", mips_hwr_names
[GET_OP (insn
, RS
)]);
2602 infprintf (is
, "$fcc%d", GET_OP (insn
, CCC
));
2607 (op
->pinfo
& (FP_D
| FP_S
)) != 0
2608 ? "$fcc%d" : "$cc%d",
2609 GET_OP (insn
, BCC
));
2613 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FR
)]);
2618 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FS
)]);
2622 infprintf (is
, "%s", mips_fpr_names
[GET_OP (insn
, FT
)]);
2626 /* Extension character; switch for second char. */
2631 lsb
= GET_OP (insn
, EXTLSB
);
2632 infprintf (is
, "0x%x", lsb
);
2636 msb
= GET_OP (insn
, INSMSB
);
2637 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2642 msbd
= GET_OP (insn
, EXTMSBD
);
2643 infprintf (is
, "0x%x", msbd
+ 1);
2647 lsb
= GET_OP (insn
, EXTLSB
) + 32;
2648 infprintf (is
, "0x%x", lsb
);
2652 msb
= GET_OP (insn
, INSMSB
) + 32;
2653 infprintf (is
, "0x%x", msb
- lsb
+ 1);
2657 msbd
= GET_OP (insn
, EXTMSBD
) + 32;
2658 infprintf (is
, "0x%x", msbd
+ 1);
2661 case 'j': /* 9-bit signed offset in bit 0. */
2662 delta
= GET_OP_S (insn
, EVAOFFSET
);
2663 infprintf (is
, "%d", delta
);
2667 /* xgettext:c-format */
2669 _("# internal disassembler error, "
2670 "unrecognized modifier (+%c)"),
2677 /* Extension character; switch for second char. */
2681 case 'a': /* global pointer. */
2682 infprintf (is
, "%s", mips_gpr_names
[28]);
2686 regno
= micromips_to_32_reg_b_map
[GET_OP (insn
, MB
)];
2687 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2691 regno
= micromips_to_32_reg_c_map
[GET_OP (insn
, MC
)];
2692 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2696 regno
= micromips_to_32_reg_d_map
[GET_OP (insn
, MD
)];
2697 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2701 regno
= micromips_to_32_reg_e_map
[GET_OP (insn
, ME
)];
2702 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2706 /* Save lastregno for "mt" to print out later. */
2707 lastregno
= micromips_to_32_reg_f_map
[GET_OP (insn
, MF
)];
2708 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2712 regno
= micromips_to_32_reg_g_map
[GET_OP (insn
, MG
)];
2713 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2717 regno
= micromips_to_32_reg_h_map1
[GET_OP (insn
, MH
)];
2718 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2719 regno
= micromips_to_32_reg_h_map2
[GET_OP (insn
, MH
)];
2720 infprintf (is
, ",%s", mips_gpr_names
[regno
]);
2724 infprintf (is
, "%s", mips_gpr_names
[GET_OP (insn
, MJ
)]);
2728 regno
= micromips_to_32_reg_l_map
[GET_OP (insn
, ML
)];
2729 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2733 regno
= micromips_to_32_reg_m_map
[GET_OP (insn
, MM
)];
2734 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2738 regno
= micromips_to_32_reg_n_map
[GET_OP (insn
, MN
)];
2739 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2743 /* Save lastregno for "mt" to print out later. */
2744 lastregno
= GET_OP (insn
, MP
);
2745 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2749 regno
= micromips_to_32_reg_q_map
[GET_OP (insn
, MQ
)];
2750 infprintf (is
, "%s", mips_gpr_names
[regno
]);
2753 case 'r': /* program counter. */
2754 infprintf (is
, "$pc");
2757 case 's': /* stack pointer. */
2759 infprintf (is
, "%s", mips_gpr_names
[29]);
2763 infprintf (is
, "%s", mips_gpr_names
[lastregno
]);
2767 infprintf (is
, "%s", mips_gpr_names
[0]);
2771 /* Sign-extend the immediate. */
2772 immed
= GET_OP_S (insn
, IMMA
) << 2;
2773 infprintf (is
, "%d", immed
);
2777 immed
= micromips_imm_b_map
[GET_OP (insn
, IMMB
)];
2778 infprintf (is
, "%d", immed
);
2782 immed
= micromips_imm_c_map
[GET_OP (insn
, IMMC
)];
2783 infprintf (is
, "0x%x", immed
);
2787 /* Sign-extend the displacement. */
2788 delta
= GET_OP_S (insn
, IMMD
);
2789 info
->target
= (delta
<< 1) + memaddr
+ length
;
2790 (*info
->print_address_func
) (info
->target
, info
);
2794 /* Sign-extend the displacement. */
2795 delta
= GET_OP_S (insn
, IMME
);
2796 info
->target
= (delta
<< 1) + memaddr
+ length
;
2797 (*info
->print_address_func
) (info
->target
, info
);
2801 immed
= GET_OP (insn
, IMMF
);
2802 infprintf (is
, "0x%x", immed
);
2806 immed
= (insn
>> MICROMIPSOP_SH_IMMG
) + 1;
2807 immed
= (immed
& MICROMIPSOP_MASK_IMMG
) - 1;
2808 infprintf (is
, "%d", immed
);
2812 immed
= GET_OP (insn
, IMMH
) << 1;
2813 infprintf (is
, "%d", immed
);
2817 immed
= (insn
>> MICROMIPSOP_SH_IMMI
) + 1;
2818 immed
= (immed
& MICROMIPSOP_MASK_IMMI
) - 1;
2819 infprintf (is
, "%d", immed
);
2823 immed
= GET_OP (insn
, IMMJ
) << 2;
2824 infprintf (is
, "%d", immed
);
2828 immed
= GET_OP (insn
, IMML
);
2829 infprintf (is
, "%d", immed
);
2833 immed
= (insn
>> MICROMIPSOP_SH_IMMM
) - 1;
2834 immed
= (immed
& MICROMIPSOP_MASK_IMMM
) + 1;
2835 infprintf (is
, "%d", immed
);
2839 immed
= GET_OP (insn
, IMMN
);
2841 infprintf (is
, "%s,%s",
2843 mips_gpr_names
[31]);
2845 infprintf (is
, "%s-%s,%s",
2847 mips_gpr_names
[16 + immed
],
2848 mips_gpr_names
[31]);
2852 immed
= GET_OP (insn
, IMMO
);
2853 infprintf (is
, "0x%x", immed
);
2857 immed
= GET_OP (insn
, IMMP
) << 2;
2858 infprintf (is
, "%d", immed
);
2862 /* Sign-extend the immediate. */
2863 immed
= GET_OP_S (insn
, IMMQ
) << 2;
2864 infprintf (is
, "%d", immed
);
2868 immed
= GET_OP (insn
, IMMU
) << 2;
2869 infprintf (is
, "%d", immed
);
2873 immed
= GET_OP (insn
, IMMW
) << 2;
2874 infprintf (is
, "%d", immed
);
2878 /* Sign-extend the immediate. */
2879 immed
= GET_OP_S (insn
, IMMX
);
2880 infprintf (is
, "%d", immed
);
2884 /* Sign-extend the immediate. */
2885 immed
= GET_OP_S (insn
, IMMY
) << 2;
2886 if ((unsigned int) (immed
+ 8) < 16)
2888 infprintf (is
, "%d", immed
);
2892 /* xgettext:c-format */
2894 _("# internal disassembler error, "
2895 "unrecognized modifier (m%c)"),
2902 /* xgettext:c-format */
2904 _("# internal disassembler error, "
2905 "unrecognized modifier (%c)"),
2911 /* Figure out instruction type and branch delay information. */
2913 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2914 info
->branch_delay_insns
= 1;
2915 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2916 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2918 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_GPR_T
)) != 0)
2919 info
->insn_type
= dis_jsr
;
2921 info
->insn_type
= dis_branch
;
2923 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2924 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2926 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2927 info
->insn_type
= dis_condjsr
;
2929 info
->insn_type
= dis_condbranch
;
2932 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY_DELAY
)) != 0)
2933 info
->insn_type
= dis_dref
;
2941 infprintf (is
, "0x%x", insn
);
2942 info
->insn_type
= dis_noninsn
;
2947 /* Return 1 if a symbol associated with the location being disassembled
2948 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2949 all the symbols at the address being considered assuming if at least
2950 one of them indicates code compression, then such code has been
2951 genuinely produced here (other symbols could have been derived from
2952 function symbols defined elsewhere or could define data). Otherwise,
2956 is_compressed_mode_p (struct disassemble_info
*info
)
2961 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2962 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2964 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2966 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2968 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2969 && info
->symtab
[i
]->section
== info
->section
)
2971 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2973 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2975 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2982 /* In an environment where we do not know the symbol type of the
2983 instruction we are forced to assume that the low order bit of the
2984 instructions' address may mark it as a mips16 instruction. If we
2985 are single stepping, or the pc is within the disassembled function,
2986 this works. Otherwise, we need a clue. Sometimes. */
2989 _print_insn_mips (bfd_vma memaddr
,
2990 struct disassemble_info
*info
,
2991 enum bfd_endian endianness
)
2993 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
2994 bfd_byte buffer
[INSNLEN
];
2997 set_default_mips_dis_options (info
);
2998 parse_mips_dis_options (info
->disassembler_options
);
3000 if (info
->mach
== bfd_mach_mips16
)
3001 return print_insn_mips16 (memaddr
, info
);
3002 if (info
->mach
== bfd_mach_mips_micromips
)
3003 return print_insn_micromips (memaddr
, info
);
3005 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
3008 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
3009 /* Only a few tools will work this way. */
3011 return print_insn_compr (memaddr
, info
);
3014 #if SYMTAB_AVAILABLE
3015 if (is_compressed_mode_p (info
))
3016 return print_insn_compr (memaddr
, info
);
3019 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
3024 if (endianness
== BFD_ENDIAN_BIG
)
3025 insn
= bfd_getb32 (buffer
);
3027 insn
= bfd_getl32 (buffer
);
3029 return print_insn_mips (memaddr
, insn
, info
);
3033 (*info
->memory_error_func
) (status
, memaddr
, info
);
3039 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3041 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
3045 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
3047 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
3051 print_mips_disassembler_options (FILE *stream
)
3055 fprintf (stream
, _("\n\
3056 The following MIPS specific disassembler options are supported for use\n\
3057 with the -M switch (multiple options should be separated by commas):\n"));
3059 fprintf (stream
, _("\n\
3060 virt Recognize the virtualization ASE instructions.\n"));
3062 fprintf (stream
, _("\n\
3063 gpr-names=ABI Print GPR names according to specified ABI.\n\
3064 Default: based on binary being disassembled.\n"));
3066 fprintf (stream
, _("\n\
3067 fpr-names=ABI Print FPR names according to specified ABI.\n\
3068 Default: numeric.\n"));
3070 fprintf (stream
, _("\n\
3071 cp0-names=ARCH Print CP0 register names according to\n\
3072 specified architecture.\n\
3073 Default: based on binary being disassembled.\n"));
3075 fprintf (stream
, _("\n\
3076 hwr-names=ARCH Print HWR names according to specified \n\
3078 Default: based on binary being disassembled.\n"));
3080 fprintf (stream
, _("\n\
3081 reg-names=ABI Print GPR and FPR names according to\n\
3082 specified ABI.\n"));
3084 fprintf (stream
, _("\n\
3085 reg-names=ARCH Print CP0 register and HWR names according to\n\
3086 specified architecture.\n"));
3088 fprintf (stream
, _("\n\
3089 For the options above, the following values are supported for \"ABI\":\n\
3091 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
3092 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
3093 fprintf (stream
, _("\n"));
3095 fprintf (stream
, _("\n\
3096 For the options above, The following values are supported for \"ARCH\":\n\
3098 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
3099 if (*mips_arch_choices
[i
].name
!= '\0')
3100 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
3101 fprintf (stream
, _("\n"));
3103 fprintf (stream
, _("\n"));