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, 2007
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 #define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]]
63 static const char * const mips_gpr_names_numeric
[32] =
65 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
66 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
67 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
68 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
71 static const char * const mips_gpr_names_oldabi
[32] =
73 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
74 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
75 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
76 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
79 static const char * const mips_gpr_names_newabi
[32] =
81 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
82 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
83 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
84 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
87 static const char * const mips_fpr_names_numeric
[32] =
89 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
90 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
91 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
92 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
95 static const char * const mips_fpr_names_32
[32] =
97 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
98 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
99 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
100 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
103 static const char * const mips_fpr_names_n32
[32] =
105 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
106 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
107 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
108 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
111 static const char * const mips_fpr_names_64
[32] =
113 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
114 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
115 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
116 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
119 static const char * const mips_cp0_names_numeric
[32] =
121 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
122 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
123 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
124 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
127 static const char * const mips_cp0_names_r3000
[32] =
129 "c0_index", "c0_random", "c0_entrylo", "$3",
130 "c0_context", "$5", "$6", "$7",
131 "c0_badvaddr", "$9", "c0_entryhi", "$11",
132 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
133 "$16", "$17", "$18", "$19",
134 "$20", "$21", "$22", "$23",
135 "$24", "$25", "$26", "$27",
136 "$28", "$29", "$30", "$31",
139 static const char * const mips_cp0_names_r4000
[32] =
141 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
142 "c0_context", "c0_pagemask", "c0_wired", "$7",
143 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
144 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
145 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
146 "c0_xcontext", "$21", "$22", "$23",
147 "$24", "$25", "c0_ecc", "c0_cacheerr",
148 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
151 static const char * const mips_cp0_names_mips3264
[32] =
153 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
154 "c0_context", "c0_pagemask", "c0_wired", "$7",
155 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
156 "c0_status", "c0_cause", "c0_epc", "c0_prid",
157 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
158 "c0_xcontext", "$21", "$22", "c0_debug",
159 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
160 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
163 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] =
165 { 16, 1, "c0_config1" },
166 { 16, 2, "c0_config2" },
167 { 16, 3, "c0_config3" },
168 { 18, 1, "c0_watchlo,1" },
169 { 18, 2, "c0_watchlo,2" },
170 { 18, 3, "c0_watchlo,3" },
171 { 18, 4, "c0_watchlo,4" },
172 { 18, 5, "c0_watchlo,5" },
173 { 18, 6, "c0_watchlo,6" },
174 { 18, 7, "c0_watchlo,7" },
175 { 19, 1, "c0_watchhi,1" },
176 { 19, 2, "c0_watchhi,2" },
177 { 19, 3, "c0_watchhi,3" },
178 { 19, 4, "c0_watchhi,4" },
179 { 19, 5, "c0_watchhi,5" },
180 { 19, 6, "c0_watchhi,6" },
181 { 19, 7, "c0_watchhi,7" },
182 { 25, 1, "c0_perfcnt,1" },
183 { 25, 2, "c0_perfcnt,2" },
184 { 25, 3, "c0_perfcnt,3" },
185 { 25, 4, "c0_perfcnt,4" },
186 { 25, 5, "c0_perfcnt,5" },
187 { 25, 6, "c0_perfcnt,6" },
188 { 25, 7, "c0_perfcnt,7" },
189 { 27, 1, "c0_cacheerr,1" },
190 { 27, 2, "c0_cacheerr,2" },
191 { 27, 3, "c0_cacheerr,3" },
192 { 28, 1, "c0_datalo" },
193 { 29, 1, "c0_datahi" }
196 static const char * const mips_cp0_names_mips3264r2
[32] =
198 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
199 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
200 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
201 "c0_status", "c0_cause", "c0_epc", "c0_prid",
202 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
203 "c0_xcontext", "$21", "$22", "c0_debug",
204 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
205 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
208 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] =
210 { 4, 1, "c0_contextconfig" },
211 { 0, 1, "c0_mvpcontrol" },
212 { 0, 2, "c0_mvpconf0" },
213 { 0, 3, "c0_mvpconf1" },
214 { 1, 1, "c0_vpecontrol" },
215 { 1, 2, "c0_vpeconf0" },
216 { 1, 3, "c0_vpeconf1" },
217 { 1, 4, "c0_yqmask" },
218 { 1, 5, "c0_vpeschedule" },
219 { 1, 6, "c0_vpeschefback" },
220 { 2, 1, "c0_tcstatus" },
221 { 2, 2, "c0_tcbind" },
222 { 2, 3, "c0_tcrestart" },
223 { 2, 4, "c0_tchalt" },
224 { 2, 5, "c0_tccontext" },
225 { 2, 6, "c0_tcschedule" },
226 { 2, 7, "c0_tcschefback" },
227 { 5, 1, "c0_pagegrain" },
228 { 6, 1, "c0_srsconf0" },
229 { 6, 2, "c0_srsconf1" },
230 { 6, 3, "c0_srsconf2" },
231 { 6, 4, "c0_srsconf3" },
232 { 6, 5, "c0_srsconf4" },
233 { 12, 1, "c0_intctl" },
234 { 12, 2, "c0_srsctl" },
235 { 12, 3, "c0_srsmap" },
236 { 15, 1, "c0_ebase" },
237 { 16, 1, "c0_config1" },
238 { 16, 2, "c0_config2" },
239 { 16, 3, "c0_config3" },
240 { 18, 1, "c0_watchlo,1" },
241 { 18, 2, "c0_watchlo,2" },
242 { 18, 3, "c0_watchlo,3" },
243 { 18, 4, "c0_watchlo,4" },
244 { 18, 5, "c0_watchlo,5" },
245 { 18, 6, "c0_watchlo,6" },
246 { 18, 7, "c0_watchlo,7" },
247 { 19, 1, "c0_watchhi,1" },
248 { 19, 2, "c0_watchhi,2" },
249 { 19, 3, "c0_watchhi,3" },
250 { 19, 4, "c0_watchhi,4" },
251 { 19, 5, "c0_watchhi,5" },
252 { 19, 6, "c0_watchhi,6" },
253 { 19, 7, "c0_watchhi,7" },
254 { 23, 1, "c0_tracecontrol" },
255 { 23, 2, "c0_tracecontrol2" },
256 { 23, 3, "c0_usertracedata" },
257 { 23, 4, "c0_tracebpc" },
258 { 25, 1, "c0_perfcnt,1" },
259 { 25, 2, "c0_perfcnt,2" },
260 { 25, 3, "c0_perfcnt,3" },
261 { 25, 4, "c0_perfcnt,4" },
262 { 25, 5, "c0_perfcnt,5" },
263 { 25, 6, "c0_perfcnt,6" },
264 { 25, 7, "c0_perfcnt,7" },
265 { 27, 1, "c0_cacheerr,1" },
266 { 27, 2, "c0_cacheerr,2" },
267 { 27, 3, "c0_cacheerr,3" },
268 { 28, 1, "c0_datalo" },
269 { 28, 2, "c0_taglo1" },
270 { 28, 3, "c0_datalo1" },
271 { 28, 4, "c0_taglo2" },
272 { 28, 5, "c0_datalo2" },
273 { 28, 6, "c0_taglo3" },
274 { 28, 7, "c0_datalo3" },
275 { 29, 1, "c0_datahi" },
276 { 29, 2, "c0_taghi1" },
277 { 29, 3, "c0_datahi1" },
278 { 29, 4, "c0_taghi2" },
279 { 29, 5, "c0_datahi2" },
280 { 29, 6, "c0_taghi3" },
281 { 29, 7, "c0_datahi3" },
284 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
285 static const char * const mips_cp0_names_sb1
[32] =
287 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
288 "c0_context", "c0_pagemask", "c0_wired", "$7",
289 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
290 "c0_status", "c0_cause", "c0_epc", "c0_prid",
291 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
292 "c0_xcontext", "$21", "$22", "c0_debug",
293 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
294 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
297 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] =
299 { 16, 1, "c0_config1" },
300 { 18, 1, "c0_watchlo,1" },
301 { 19, 1, "c0_watchhi,1" },
302 { 22, 0, "c0_perftrace" },
303 { 23, 3, "c0_edebug" },
304 { 25, 1, "c0_perfcnt,1" },
305 { 25, 2, "c0_perfcnt,2" },
306 { 25, 3, "c0_perfcnt,3" },
307 { 25, 4, "c0_perfcnt,4" },
308 { 25, 5, "c0_perfcnt,5" },
309 { 25, 6, "c0_perfcnt,6" },
310 { 25, 7, "c0_perfcnt,7" },
311 { 26, 1, "c0_buserr_pa" },
312 { 27, 1, "c0_cacheerr_d" },
313 { 27, 3, "c0_cacheerr_d_pa" },
314 { 28, 1, "c0_datalo_i" },
315 { 28, 2, "c0_taglo_d" },
316 { 28, 3, "c0_datalo_d" },
317 { 29, 1, "c0_datahi_i" },
318 { 29, 2, "c0_taghi_d" },
319 { 29, 3, "c0_datahi_d" },
322 static const char * const mips_hwr_names_numeric
[32] =
324 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
325 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
326 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
327 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
330 static const char * const mips_hwr_names_mips3264r2
[32] =
332 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
333 "$4", "$5", "$6", "$7",
334 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
335 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
336 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
339 struct mips_abi_choice
342 const char * const *gpr_names
;
343 const char * const *fpr_names
;
346 struct mips_abi_choice mips_abi_choices
[] =
348 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
349 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
350 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
351 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
354 struct mips_arch_choice
358 unsigned long bfd_mach
;
361 const char * const *cp0_names
;
362 const struct mips_cp0sel_name
*cp0sel_names
;
363 unsigned int cp0sel_names_len
;
364 const char * const *hwr_names
;
367 const struct mips_arch_choice mips_arch_choices
[] =
369 { "numeric", 0, 0, 0, 0,
370 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
372 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
,
373 mips_cp0_names_r3000
, NULL
, 0, mips_hwr_names_numeric
},
374 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
,
375 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
376 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
,
377 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
378 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
,
379 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
380 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
,
381 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
382 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
,
383 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
384 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
,
385 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
386 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
,
387 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
388 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
,
389 mips_cp0_names_r4000
, NULL
, 0, mips_hwr_names_numeric
},
390 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
,
391 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
392 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
,
393 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
394 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
,
395 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
396 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
,
397 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
398 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
,
399 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
400 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
,
401 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
402 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
,
403 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
404 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
,
405 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
406 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
,
407 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
408 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
,
409 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
410 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
,
411 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
412 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
,
413 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
415 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
416 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
417 _MIPS32 Architecture For Programmers Volume I: Introduction to the
418 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
420 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
421 ISA_MIPS32
| INSN_MIPS16
| INSN_SMARTMIPS
,
422 mips_cp0_names_mips3264
,
423 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
424 mips_hwr_names_numeric
},
426 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
427 (ISA_MIPS32R2
| INSN_MIPS16
| INSN_SMARTMIPS
| INSN_DSP
| INSN_DSPR2
428 | INSN_MIPS3D
| INSN_MT
),
429 mips_cp0_names_mips3264r2
,
430 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
431 mips_hwr_names_mips3264r2
},
433 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
434 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
435 ISA_MIPS64
| INSN_MIPS16
| INSN_MIPS3D
| INSN_MDMX
,
436 mips_cp0_names_mips3264
,
437 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
438 mips_hwr_names_numeric
},
440 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
441 (ISA_MIPS64R2
| INSN_MIPS16
| INSN_MIPS3D
| INSN_DSP
| INSN_DSPR2
442 | INSN_DSP64
| INSN_MT
| INSN_MDMX
),
443 mips_cp0_names_mips3264r2
,
444 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
445 mips_hwr_names_mips3264r2
},
447 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
448 ISA_MIPS64
| INSN_MIPS3D
| INSN_SB1
,
450 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
451 mips_hwr_names_numeric
},
453 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
454 ISA_MIPS3
| INSN_LOONGSON_2E
, mips_cp0_names_numeric
,
455 NULL
, 0, mips_hwr_names_numeric
},
457 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
458 ISA_MIPS3
| INSN_LOONGSON_2F
, mips_cp0_names_numeric
,
459 NULL
, 0, mips_hwr_names_numeric
},
461 /* This entry, mips16, is here only for ISA/processor selection; do
462 not print its name. */
463 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
| INSN_MIPS16
,
464 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
467 /* ISA and processor type to disassemble for, and register names to use.
468 set_default_mips_dis_options and parse_mips_dis_options fill in these
470 static int mips_processor
;
472 static const char * const *mips_gpr_names
;
473 static const char * const *mips_fpr_names
;
474 static const char * const *mips_cp0_names
;
475 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
476 static int mips_cp0sel_names_len
;
477 static const char * const *mips_hwr_names
;
480 static int no_aliases
; /* If set disassemble as most general inst. */
482 static const struct mips_abi_choice
*
483 choose_abi_by_name (const char *name
, unsigned int namelen
)
485 const struct mips_abi_choice
*c
;
488 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
489 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
490 && strlen (mips_abi_choices
[i
].name
) == namelen
)
491 c
= &mips_abi_choices
[i
];
496 static const struct mips_arch_choice
*
497 choose_arch_by_name (const char *name
, unsigned int namelen
)
499 const struct mips_arch_choice
*c
= NULL
;
502 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
503 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
504 && strlen (mips_arch_choices
[i
].name
) == namelen
)
505 c
= &mips_arch_choices
[i
];
510 static const struct mips_arch_choice
*
511 choose_arch_by_number (unsigned long mach
)
513 static unsigned long hint_bfd_mach
;
514 static const struct mips_arch_choice
*hint_arch_choice
;
515 const struct mips_arch_choice
*c
;
518 /* We optimize this because even if the user specifies no
519 flags, this will be done for every instruction! */
520 if (hint_bfd_mach
== mach
521 && hint_arch_choice
!= NULL
522 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
523 return hint_arch_choice
;
525 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
527 if (mips_arch_choices
[i
].bfd_mach_valid
528 && mips_arch_choices
[i
].bfd_mach
== mach
)
530 c
= &mips_arch_choices
[i
];
531 hint_bfd_mach
= mach
;
532 hint_arch_choice
= c
;
538 /* Check if the object uses NewABI conventions. */
541 is_newabi (Elf_Internal_Ehdr
*header
)
543 /* There are no old-style ABIs which use 64-bit ELF. */
544 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
547 /* If a 32-bit ELF file, n32 is a new-style ABI. */
548 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
555 set_default_mips_dis_options (struct disassemble_info
*info
)
557 const struct mips_arch_choice
*chosen_arch
;
559 /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names,
560 and numeric FPR, CP0 register, and HWR names. */
561 mips_isa
= ISA_MIPS3
;
562 mips_processor
= CPU_R3000
;
563 mips_gpr_names
= mips_gpr_names_oldabi
;
564 mips_fpr_names
= mips_fpr_names_numeric
;
565 mips_cp0_names
= mips_cp0_names_numeric
;
566 mips_cp0sel_names
= NULL
;
567 mips_cp0sel_names_len
= 0;
568 mips_hwr_names
= mips_hwr_names_numeric
;
571 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
572 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
574 Elf_Internal_Ehdr
*header
;
576 header
= elf_elfheader (info
->section
->owner
);
577 if (is_newabi (header
))
578 mips_gpr_names
= mips_gpr_names_newabi
;
581 /* Set ISA, architecture, and cp0 register names as best we can. */
582 #if ! SYMTAB_AVAILABLE
583 /* This is running out on a target machine, not in a host tool.
584 FIXME: Where does mips_target_info come from? */
585 target_processor
= mips_target_info
.processor
;
586 mips_isa
= mips_target_info
.isa
;
588 chosen_arch
= choose_arch_by_number (info
->mach
);
589 if (chosen_arch
!= NULL
)
591 mips_processor
= chosen_arch
->processor
;
592 mips_isa
= chosen_arch
->isa
;
593 mips_cp0_names
= chosen_arch
->cp0_names
;
594 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
595 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
596 mips_hwr_names
= chosen_arch
->hwr_names
;
602 parse_mips_dis_option (const char *option
, unsigned int len
)
604 unsigned int i
, optionlen
, vallen
;
606 const struct mips_abi_choice
*chosen_abi
;
607 const struct mips_arch_choice
*chosen_arch
;
609 /* Try to match options that are simple flags */
610 if (CONST_STRNEQ (option
, "no-aliases"))
616 /* Look for the = that delimits the end of the option name. */
617 for (i
= 0; i
< len
; i
++)
618 if (option
[i
] == '=')
621 if (i
== 0) /* Invalid option: no name before '='. */
623 if (i
== len
) /* Invalid option: no '='. */
625 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
629 val
= option
+ (optionlen
+ 1);
630 vallen
= len
- (optionlen
+ 1);
632 if (strncmp ("gpr-names", option
, optionlen
) == 0
633 && strlen ("gpr-names") == optionlen
)
635 chosen_abi
= choose_abi_by_name (val
, vallen
);
636 if (chosen_abi
!= NULL
)
637 mips_gpr_names
= chosen_abi
->gpr_names
;
641 if (strncmp ("fpr-names", option
, optionlen
) == 0
642 && strlen ("fpr-names") == optionlen
)
644 chosen_abi
= choose_abi_by_name (val
, vallen
);
645 if (chosen_abi
!= NULL
)
646 mips_fpr_names
= chosen_abi
->fpr_names
;
650 if (strncmp ("cp0-names", option
, optionlen
) == 0
651 && strlen ("cp0-names") == optionlen
)
653 chosen_arch
= choose_arch_by_name (val
, vallen
);
654 if (chosen_arch
!= NULL
)
656 mips_cp0_names
= chosen_arch
->cp0_names
;
657 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
658 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
663 if (strncmp ("hwr-names", option
, optionlen
) == 0
664 && strlen ("hwr-names") == optionlen
)
666 chosen_arch
= choose_arch_by_name (val
, vallen
);
667 if (chosen_arch
!= NULL
)
668 mips_hwr_names
= chosen_arch
->hwr_names
;
672 if (strncmp ("reg-names", option
, optionlen
) == 0
673 && strlen ("reg-names") == optionlen
)
675 /* We check both ABI and ARCH here unconditionally, so
676 that "numeric" will do the desirable thing: select
677 numeric register names for all registers. Other than
678 that, a given name probably won't match both. */
679 chosen_abi
= choose_abi_by_name (val
, vallen
);
680 if (chosen_abi
!= NULL
)
682 mips_gpr_names
= chosen_abi
->gpr_names
;
683 mips_fpr_names
= chosen_abi
->fpr_names
;
685 chosen_arch
= choose_arch_by_name (val
, vallen
);
686 if (chosen_arch
!= NULL
)
688 mips_cp0_names
= chosen_arch
->cp0_names
;
689 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
690 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
691 mips_hwr_names
= chosen_arch
->hwr_names
;
696 /* Invalid option. */
700 parse_mips_dis_options (const char *options
)
702 const char *option_end
;
707 while (*options
!= '\0')
709 /* Skip empty options. */
716 /* We know that *options is neither NUL or a comma. */
717 option_end
= options
+ 1;
718 while (*option_end
!= ',' && *option_end
!= '\0')
721 parse_mips_dis_option (options
, option_end
- options
);
723 /* Go on to the next one. If option_end points to a comma, it
724 will be skipped above. */
725 options
= option_end
;
729 static const struct mips_cp0sel_name
*
730 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
737 for (i
= 0; i
< len
; i
++)
738 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
743 /* Print insn arguments for 32/64-bit code. */
746 print_insn_args (const char *d
,
747 register unsigned long int l
,
749 struct disassemble_info
*info
,
750 const struct mips_opcode
*opp
)
753 unsigned int lsb
, msb
, msbd
;
757 for (; *d
!= '\0'; d
++)
766 (*info
->fprintf_func
) (info
->stream
, "%c", *d
);
770 /* Extension character; switch for second char. */
775 /* xgettext:c-format */
776 (*info
->fprintf_func
) (info
->stream
,
777 _("# internal error, incomplete extension sequence (+)"));
781 lsb
= (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
;
782 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
786 msb
= (l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
;
787 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
791 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
792 (l
>> OP_SH_UDI1
) & OP_MASK_UDI1
);
796 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
797 (l
>> OP_SH_UDI2
) & OP_MASK_UDI2
);
801 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
802 (l
>> OP_SH_UDI3
) & OP_MASK_UDI3
);
806 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
807 (l
>> OP_SH_UDI4
) & OP_MASK_UDI4
);
812 msbd
= (l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
;
813 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
818 const struct mips_cp0sel_name
*n
;
819 unsigned int cp0reg
, sel
;
821 cp0reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
822 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
824 /* CP0 register including 'sel' code for mtcN (et al.), to be
825 printed textually if known. If not known, print both
826 CP0 register name and sel numerically since CP0 register
827 with sel 0 may have a name unrelated to register being
829 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
830 mips_cp0sel_names_len
, cp0reg
, sel
);
832 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
834 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
839 lsb
= ((l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
) + 32;
840 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
844 msb
= ((l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
) + 32;
845 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
849 msbd
= ((l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
) + 32;
850 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
853 case 't': /* Coprocessor 0 reg name */
854 (*info
->fprintf_func
) (info
->stream
, "%s",
855 mips_cp0_names
[(l
>> OP_SH_RT
) &
859 case 'T': /* Coprocessor 0 reg name */
861 const struct mips_cp0sel_name
*n
;
862 unsigned int cp0reg
, sel
;
864 cp0reg
= (l
>> OP_SH_RT
) & OP_MASK_RT
;
865 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
867 /* CP0 register including 'sel' code for mftc0, to be
868 printed textually if known. If not known, print both
869 CP0 register name and sel numerically since CP0 register
870 with sel 0 may have a name unrelated to register being
872 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
873 mips_cp0sel_names_len
, cp0reg
, sel
);
875 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
877 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
882 /* xgettext:c-format */
883 (*info
->fprintf_func
) (info
->stream
,
884 _("# internal error, undefined extension sequence (+%c)"),
891 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
892 (l
>> OP_SH_BP
) & OP_MASK_BP
);
896 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
897 (l
>> OP_SH_SA3
) & OP_MASK_SA3
);
901 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
902 (l
>> OP_SH_SA4
) & OP_MASK_SA4
);
906 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
907 (l
>> OP_SH_IMM8
) & OP_MASK_IMM8
);
911 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
912 (l
>> OP_SH_RS
) & OP_MASK_RS
);
916 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
917 (l
>> OP_SH_DSPACC
) & OP_MASK_DSPACC
);
921 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
922 (l
>> OP_SH_WRDSP
) & OP_MASK_WRDSP
);
926 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
927 (l
>> OP_SH_DSPACC_S
) & OP_MASK_DSPACC_S
);
930 case '0': /* dsp 6-bit signed immediate in bit 20 */
931 delta
= ((l
>> OP_SH_DSPSFT
) & OP_MASK_DSPSFT
);
932 if (delta
& 0x20) /* test sign bit */
933 delta
|= ~OP_MASK_DSPSFT
;
934 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
937 case ':': /* dsp 7-bit signed immediate in bit 19 */
938 delta
= ((l
>> OP_SH_DSPSFT_7
) & OP_MASK_DSPSFT_7
);
939 if (delta
& 0x40) /* test sign bit */
940 delta
|= ~OP_MASK_DSPSFT_7
;
941 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
945 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
946 (l
>> OP_SH_RDDSP
) & OP_MASK_RDDSP
);
949 case '@': /* dsp 10-bit signed immediate in bit 16 */
950 delta
= ((l
>> OP_SH_IMM10
) & OP_MASK_IMM10
);
951 if (delta
& 0x200) /* test sign bit */
952 delta
|= ~OP_MASK_IMM10
;
953 (*info
->fprintf_func
) (info
->stream
, "%d", delta
);
957 (*info
->fprintf_func
) (info
->stream
, "%ld",
958 (l
>> OP_SH_MT_U
) & OP_MASK_MT_U
);
962 (*info
->fprintf_func
) (info
->stream
, "%ld",
963 (l
>> OP_SH_MT_H
) & OP_MASK_MT_H
);
967 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
968 (l
>> OP_SH_MTACC_T
) & OP_MASK_MTACC_T
);
972 (*info
->fprintf_func
) (info
->stream
, "$ac%ld",
973 (l
>> OP_SH_MTACC_D
) & OP_MASK_MTACC_D
);
977 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
978 (*info
->fprintf_func
) (info
->stream
, "$%ld",
979 (l
>> OP_SH_RD
) & OP_MASK_RD
);
986 (*info
->fprintf_func
) (info
->stream
, "%s",
987 mips_gpr_names
[(l
>> OP_SH_RS
) & OP_MASK_RS
]);
992 (*info
->fprintf_func
) (info
->stream
, "%s",
993 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
998 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
999 (l
>> OP_SH_IMMEDIATE
) & OP_MASK_IMMEDIATE
);
1002 case 'j': /* Same as i, but sign-extended. */
1004 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
1007 (*info
->fprintf_func
) (info
->stream
, "%d",
1012 (*info
->fprintf_func
) (info
->stream
, "0x%x",
1013 (unsigned int) ((l
>> OP_SH_PREFX
)
1018 (*info
->fprintf_func
) (info
->stream
, "0x%x",
1019 (unsigned int) ((l
>> OP_SH_CACHE
)
1024 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
1025 | (((l
>> OP_SH_TARGET
) & OP_MASK_TARGET
) << 2));
1026 /* For gdb disassembler, force odd address on jalx. */
1027 if (info
->flavour
== bfd_target_unknown_flavour
1028 && strcmp (opp
->name
, "jalx") == 0)
1030 (*info
->print_address_func
) (info
->target
, info
);
1034 /* Sign extend the displacement. */
1035 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
1038 info
->target
= (delta
<< 2) + pc
+ INSNLEN
;
1039 (*info
->print_address_func
) (info
->target
, info
);
1043 (*info
->fprintf_func
) (info
->stream
, "%s",
1044 mips_gpr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1049 /* First check for both rd and rt being equal. */
1050 unsigned int reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
1051 if (reg
== ((l
>> OP_SH_RT
) & OP_MASK_RT
))
1052 (*info
->fprintf_func
) (info
->stream
, "%s",
1053 mips_gpr_names
[reg
]);
1056 /* If one is zero use the other. */
1058 (*info
->fprintf_func
) (info
->stream
, "%s",
1059 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1060 else if (((l
>> OP_SH_RT
) & OP_MASK_RT
) == 0)
1061 (*info
->fprintf_func
) (info
->stream
, "%s",
1062 mips_gpr_names
[reg
]);
1063 else /* Bogus, result depends on processor. */
1064 (*info
->fprintf_func
) (info
->stream
, "%s or %s",
1065 mips_gpr_names
[reg
],
1066 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
1072 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1076 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1077 (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
);
1081 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1082 (l
>> OP_SH_CODE
) & OP_MASK_CODE
);
1086 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1087 (l
>> OP_SH_CODE2
) & OP_MASK_CODE2
);
1091 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1092 (l
>> OP_SH_COPZ
) & OP_MASK_COPZ
);
1096 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1098 (l
>> OP_SH_CODE20
) & OP_MASK_CODE20
);
1102 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1103 (l
>> OP_SH_CODE19
) & OP_MASK_CODE19
);
1108 (*info
->fprintf_func
) (info
->stream
, "%s",
1109 mips_fpr_names
[(l
>> OP_SH_FS
) & OP_MASK_FS
]);
1114 (*info
->fprintf_func
) (info
->stream
, "%s",
1115 mips_fpr_names
[(l
>> OP_SH_FT
) & OP_MASK_FT
]);
1119 (*info
->fprintf_func
) (info
->stream
, "%s",
1120 mips_fpr_names
[(l
>> OP_SH_FD
) & OP_MASK_FD
]);
1124 (*info
->fprintf_func
) (info
->stream
, "%s",
1125 mips_fpr_names
[(l
>> OP_SH_FR
) & OP_MASK_FR
]);
1129 /* Coprocessor register for lwcN instructions, et al.
1131 Note that there is no load/store cp0 instructions, and
1132 that FPU (cp1) instructions disassemble this field using
1133 'T' format. Therefore, until we gain understanding of
1134 cp2 register names, we can simply print the register
1136 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1137 (l
>> OP_SH_RT
) & OP_MASK_RT
);
1141 /* Coprocessor register for mtcN instructions, et al. Note
1142 that FPU (cp1) instructions disassemble this field using
1143 'S' format. Therefore, we only need to worry about cp0,
1145 op
= (l
>> OP_SH_OP
) & OP_MASK_OP
;
1146 if (op
== OP_OP_COP0
)
1147 (*info
->fprintf_func
) (info
->stream
, "%s",
1148 mips_cp0_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1150 (*info
->fprintf_func
) (info
->stream
, "$%ld",
1151 (l
>> OP_SH_RD
) & OP_MASK_RD
);
1155 (*info
->fprintf_func
) (info
->stream
, "%s",
1156 mips_hwr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
1160 (*info
->fprintf_func
) (info
->stream
,
1161 ((opp
->pinfo
& (FP_D
| FP_S
)) != 0
1162 ? "$fcc%ld" : "$cc%ld"),
1163 (l
>> OP_SH_BCC
) & OP_MASK_BCC
);
1167 (*info
->fprintf_func
) (info
->stream
, "$fcc%ld",
1168 (l
>> OP_SH_CCC
) & OP_MASK_CCC
);
1172 (*info
->fprintf_func
) (info
->stream
, "%ld",
1173 (l
>> OP_SH_PERFREG
) & OP_MASK_PERFREG
);
1177 (*info
->fprintf_func
) (info
->stream
, "%ld",
1178 (l
>> OP_SH_VECBYTE
) & OP_MASK_VECBYTE
);
1182 (*info
->fprintf_func
) (info
->stream
, "%ld",
1183 (l
>> OP_SH_VECALIGN
) & OP_MASK_VECALIGN
);
1187 (*info
->fprintf_func
) (info
->stream
, "%ld",
1188 (l
>> OP_SH_SEL
) & OP_MASK_SEL
);
1192 (*info
->fprintf_func
) (info
->stream
, "%ld",
1193 (l
>> OP_SH_ALN
) & OP_MASK_ALN
);
1198 unsigned int vsel
= (l
>> OP_SH_VSEL
) & OP_MASK_VSEL
;
1200 if ((vsel
& 0x10) == 0)
1205 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1206 if ((vsel
& 1) == 0)
1208 (*info
->fprintf_func
) (info
->stream
, "$v%ld[%d]",
1209 (l
>> OP_SH_FT
) & OP_MASK_FT
,
1212 else if ((vsel
& 0x08) == 0)
1214 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1215 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1219 (*info
->fprintf_func
) (info
->stream
, "0x%lx",
1220 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1226 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1227 (l
>> OP_SH_FD
) & OP_MASK_FD
);
1231 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1232 (l
>> OP_SH_FS
) & OP_MASK_FS
);
1236 (*info
->fprintf_func
) (info
->stream
, "$v%ld",
1237 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1241 /* xgettext:c-format */
1242 (*info
->fprintf_func
) (info
->stream
,
1243 _("# internal error, undefined modifier (%c)"),
1250 /* Print the mips instruction at address MEMADDR in debugged memory,
1251 on using INFO. Returns length of the instruction, in bytes, which is
1252 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1253 this is little-endian code. */
1256 print_insn_mips (bfd_vma memaddr
,
1257 unsigned long int word
,
1258 struct disassemble_info
*info
)
1260 const struct mips_opcode
*op
;
1261 static bfd_boolean init
= 0;
1262 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1264 /* Build a hash table to shorten the search time. */
1269 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1271 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1273 if (op
->pinfo
== INSN_MACRO
1274 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1276 if (i
== ((op
->match
>> OP_SH_OP
) & OP_MASK_OP
))
1287 info
->bytes_per_chunk
= INSNLEN
;
1288 info
->display_endian
= info
->endian
;
1289 info
->insn_info_valid
= 1;
1290 info
->branch_delay_insns
= 0;
1291 info
->data_size
= 0;
1292 info
->insn_type
= dis_nonbranch
;
1296 op
= mips_hash
[(word
>> OP_SH_OP
) & OP_MASK_OP
];
1299 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1301 if (op
->pinfo
!= INSN_MACRO
1302 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1303 && (word
& op
->mask
) == op
->match
)
1307 /* We always allow to disassemble the jalx instruction. */
1308 if (! OPCODE_IS_MEMBER (op
, mips_isa
, mips_processor
)
1309 && strcmp (op
->name
, "jalx"))
1312 /* Figure out instruction type and branch delay information. */
1313 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1315 if ((info
->insn_type
& INSN_WRITE_GPR_31
) != 0)
1316 info
->insn_type
= dis_jsr
;
1318 info
->insn_type
= dis_branch
;
1319 info
->branch_delay_insns
= 1;
1321 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1322 | INSN_COND_BRANCH_LIKELY
)) != 0)
1324 if ((info
->insn_type
& INSN_WRITE_GPR_31
) != 0)
1325 info
->insn_type
= dis_condjsr
;
1327 info
->insn_type
= dis_condbranch
;
1328 info
->branch_delay_insns
= 1;
1330 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1331 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1332 info
->insn_type
= dis_dref
;
1334 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
1337 if (d
!= NULL
&& *d
!= '\0')
1339 (*info
->fprintf_func
) (info
->stream
, "\t");
1340 print_insn_args (d
, word
, memaddr
, info
, op
);
1348 /* Handle undefined instructions. */
1349 info
->insn_type
= dis_noninsn
;
1350 (*info
->fprintf_func
) (info
->stream
, "0x%lx", word
);
1354 /* Disassemble an operand for a mips16 instruction. */
1357 print_mips16_insn_arg (char type
,
1358 const struct mips_opcode
*op
,
1360 bfd_boolean use_extend
,
1363 struct disassemble_info
*info
)
1370 (*info
->fprintf_func
) (info
->stream
, "%c", type
);
1375 (*info
->fprintf_func
) (info
->stream
, "%s",
1376 mips16_reg_names(((l
>> MIPS16OP_SH_RY
)
1377 & MIPS16OP_MASK_RY
)));
1382 (*info
->fprintf_func
) (info
->stream
, "%s",
1383 mips16_reg_names(((l
>> MIPS16OP_SH_RX
)
1384 & MIPS16OP_MASK_RX
)));
1388 (*info
->fprintf_func
) (info
->stream
, "%s",
1389 mips16_reg_names(((l
>> MIPS16OP_SH_RZ
)
1390 & MIPS16OP_MASK_RZ
)));
1394 (*info
->fprintf_func
) (info
->stream
, "%s",
1395 mips16_reg_names(((l
>> MIPS16OP_SH_MOVE32Z
)
1396 & MIPS16OP_MASK_MOVE32Z
)));
1400 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1404 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[29]);
1408 (*info
->fprintf_func
) (info
->stream
, "$pc");
1412 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[31]);
1416 (*info
->fprintf_func
) (info
->stream
, "%s",
1417 mips_gpr_names
[((l
>> MIPS16OP_SH_REGR32
)
1418 & MIPS16OP_MASK_REGR32
)]);
1422 (*info
->fprintf_func
) (info
->stream
, "%s",
1423 mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1449 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1461 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1467 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1473 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1479 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1485 immed
= (l
>> MIPS16OP_SH_IMM4
) & MIPS16OP_MASK_IMM4
;
1491 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1492 info
->insn_type
= dis_dref
;
1493 info
->data_size
= 1;
1498 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1499 info
->insn_type
= dis_dref
;
1500 info
->data_size
= 2;
1505 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1506 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1507 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1509 info
->insn_type
= dis_dref
;
1510 info
->data_size
= 4;
1516 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1517 info
->insn_type
= dis_dref
;
1518 info
->data_size
= 8;
1522 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1527 immed
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1531 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1536 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1537 /* FIXME: This might be lw, or it might be addiu to $sp or
1538 $pc. We assume it's load. */
1539 info
->insn_type
= dis_dref
;
1540 info
->data_size
= 4;
1545 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1546 info
->insn_type
= dis_dref
;
1547 info
->data_size
= 8;
1551 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1556 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1562 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1567 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1571 info
->insn_type
= dis_condbranch
;
1575 immed
= (l
>> MIPS16OP_SH_IMM11
) & MIPS16OP_MASK_IMM11
;
1579 info
->insn_type
= dis_branch
;
1584 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1586 /* FIXME: This can be lw or la. We assume it is lw. */
1587 info
->insn_type
= dis_dref
;
1588 info
->data_size
= 4;
1593 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1595 info
->insn_type
= dis_dref
;
1596 info
->data_size
= 8;
1601 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1610 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1611 immed
-= 1 << nbits
;
1613 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1620 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1621 else if (extbits
== 15)
1622 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1624 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1625 immed
&= (1 << extbits
) - 1;
1626 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1627 immed
-= 1 << extbits
;
1631 (*info
->fprintf_func
) (info
->stream
, "%d", immed
);
1639 baseaddr
= memaddr
+ 2;
1641 else if (use_extend
)
1642 baseaddr
= memaddr
- 2;
1650 /* If this instruction is in the delay slot of a jr
1651 instruction, the base address is the address of the
1652 jr instruction. If it is in the delay slot of jalr
1653 instruction, the base address is the address of the
1654 jalr instruction. This test is unreliable: we have
1655 no way of knowing whether the previous word is
1656 instruction or data. */
1657 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1660 && (((info
->endian
== BFD_ENDIAN_BIG
1661 ? bfd_getb16 (buffer
)
1662 : bfd_getl16 (buffer
))
1663 & 0xf800) == 0x1800))
1664 baseaddr
= memaddr
- 4;
1667 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1670 && (((info
->endian
== BFD_ENDIAN_BIG
1671 ? bfd_getb16 (buffer
)
1672 : bfd_getl16 (buffer
))
1673 & 0xf81f) == 0xe800))
1674 baseaddr
= memaddr
- 2;
1677 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1679 && info
->flavour
== bfd_target_unknown_flavour
)
1680 /* For gdb disassembler, maintain odd address. */
1682 (*info
->print_address_func
) (info
->target
, info
);
1689 int jalx
= l
& 0x400;
1693 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1694 if (!jalx
&& info
->flavour
== bfd_target_unknown_flavour
)
1695 /* For gdb disassembler, maintain odd address. */
1698 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1699 (*info
->print_address_func
) (info
->target
, info
);
1700 info
->insn_type
= dis_jsr
;
1701 info
->branch_delay_insns
= 1;
1707 int need_comma
, amask
, smask
;
1711 l
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1713 amask
= (l
>> 3) & 7;
1715 if (amask
> 0 && amask
< 5)
1717 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
1719 (*info
->fprintf_func
) (info
->stream
, "-%s",
1720 mips_gpr_names
[amask
+ 3]);
1724 smask
= (l
>> 1) & 3;
1727 (*info
->fprintf_func
) (info
->stream
, "%s??",
1728 need_comma
? "," : "");
1733 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1734 need_comma
? "," : "",
1735 mips_gpr_names
[16]);
1737 (*info
->fprintf_func
) (info
->stream
, "-%s",
1738 mips_gpr_names
[smask
+ 15]);
1744 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1745 need_comma
? "," : "",
1746 mips_gpr_names
[31]);
1750 if (amask
== 5 || amask
== 6)
1752 (*info
->fprintf_func
) (info
->stream
, "%s$f0",
1753 need_comma
? "," : "");
1755 (*info
->fprintf_func
) (info
->stream
, "-$f1");
1762 /* MIPS16e save/restore. */
1765 int amask
, args
, statics
;
1774 amask
= (l
>> 16) & 0xf;
1775 if (amask
== MIPS16_ALL_ARGS
)
1780 else if (amask
== MIPS16_ALL_STATICS
)
1788 statics
= amask
& 3;
1792 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
1794 (*info
->fprintf_func
) (info
->stream
, "-%s",
1795 mips_gpr_names
[4 + args
- 1]);
1799 framesz
= (((l
>> 16) & 0xf0) | (l
& 0x0f)) * 8;
1800 if (framesz
== 0 && !use_extend
)
1803 (*info
->fprintf_func
) (info
->stream
, "%s%d",
1804 need_comma
? "," : "",
1807 if (l
& 0x40) /* $ra */
1808 (*info
->fprintf_func
) (info
->stream
, ",%s", mips_gpr_names
[31]);
1810 nsreg
= (l
>> 24) & 0x7;
1812 if (l
& 0x20) /* $s0 */
1814 if (l
& 0x10) /* $s1 */
1816 if (nsreg
> 0) /* $s2-$s8 */
1817 smask
|= ((1 << nsreg
) - 1) << 2;
1819 /* Find first set static reg bit. */
1820 for (i
= 0; i
< 9; i
++)
1822 if (smask
& (1 << i
))
1824 (*info
->fprintf_func
) (info
->stream
, ",%s",
1825 mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1826 /* Skip over string of set bits. */
1827 for (j
= i
; smask
& (2 << j
); j
++)
1830 (*info
->fprintf_func
) (info
->stream
, "-%s",
1831 mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1836 /* Statics $ax - $a3. */
1838 (*info
->fprintf_func
) (info
->stream
, ",%s", mips_gpr_names
[7]);
1839 else if (statics
> 0)
1840 (*info
->fprintf_func
) (info
->stream
, ",%s-%s",
1841 mips_gpr_names
[7 - statics
+ 1],
1847 /* xgettext:c-format */
1848 (*info
->fprintf_func
)
1850 _("# internal disassembler error, unrecognised modifier (%c)"),
1856 /* Disassemble mips16 instructions. */
1859 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
1865 bfd_boolean use_extend
;
1867 const struct mips_opcode
*op
, *opend
;
1869 info
->bytes_per_chunk
= 2;
1870 info
->display_endian
= info
->endian
;
1871 info
->insn_info_valid
= 1;
1872 info
->branch_delay_insns
= 0;
1873 info
->data_size
= 0;
1874 info
->insn_type
= dis_nonbranch
;
1878 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1881 (*info
->memory_error_func
) (status
, memaddr
, info
);
1887 if (info
->endian
== BFD_ENDIAN_BIG
)
1888 insn
= bfd_getb16 (buffer
);
1890 insn
= bfd_getl16 (buffer
);
1892 /* Handle the extend opcode specially. */
1894 if ((insn
& 0xf800) == 0xf000)
1897 extend
= insn
& 0x7ff;
1901 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1904 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
1905 (unsigned int) extend
);
1906 (*info
->memory_error_func
) (status
, memaddr
, info
);
1910 if (info
->endian
== BFD_ENDIAN_BIG
)
1911 insn
= bfd_getb16 (buffer
);
1913 insn
= bfd_getl16 (buffer
);
1915 /* Check for an extend opcode followed by an extend opcode. */
1916 if ((insn
& 0xf800) == 0xf000)
1918 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
1919 (unsigned int) extend
);
1920 info
->insn_type
= dis_noninsn
;
1927 /* FIXME: Should probably use a hash table on the major opcode here. */
1929 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
1930 for (op
= mips16_opcodes
; op
< opend
; op
++)
1932 if (op
->pinfo
!= INSN_MACRO
1933 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1934 && (insn
& op
->mask
) == op
->match
)
1938 if (strchr (op
->args
, 'a') != NULL
)
1942 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
1943 (unsigned int) extend
);
1944 info
->insn_type
= dis_noninsn
;
1952 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
1957 if (info
->endian
== BFD_ENDIAN_BIG
)
1958 extend
= bfd_getb16 (buffer
);
1960 extend
= bfd_getl16 (buffer
);
1965 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
1966 if (op
->args
[0] != '\0')
1967 (*info
->fprintf_func
) (info
->stream
, "\t");
1969 for (s
= op
->args
; *s
!= '\0'; s
++)
1973 && (((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)
1974 == ((insn
>> MIPS16OP_SH_RY
) & MIPS16OP_MASK_RY
)))
1976 /* Skip the register and the comma. */
1982 && (((insn
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
)
1983 == ((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)))
1985 /* Skip the register and the comma. */
1989 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
1993 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1995 info
->branch_delay_insns
= 1;
1996 if (info
->insn_type
!= dis_jsr
)
1997 info
->insn_type
= dis_branch
;
2005 (*info
->fprintf_func
) (info
->stream
, "0x%x", extend
| 0xf000);
2006 (*info
->fprintf_func
) (info
->stream
, "0x%x", insn
);
2007 info
->insn_type
= dis_noninsn
;
2012 /* In an environment where we do not know the symbol type of the
2013 instruction we are forced to assume that the low order bit of the
2014 instructions' address may mark it as a mips16 instruction. If we
2015 are single stepping, or the pc is within the disassembled function,
2016 this works. Otherwise, we need a clue. Sometimes. */
2019 _print_insn_mips (bfd_vma memaddr
,
2020 struct disassemble_info
*info
,
2021 enum bfd_endian endianness
)
2023 bfd_byte buffer
[INSNLEN
];
2026 set_default_mips_dis_options (info
);
2027 parse_mips_dis_options (info
->disassembler_options
);
2030 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
2031 /* Only a few tools will work this way. */
2033 return print_insn_mips16 (memaddr
, info
);
2036 #if SYMTAB_AVAILABLE
2037 if (info
->mach
== bfd_mach_mips16
2038 || (info
->flavour
== bfd_target_elf_flavour
2039 && info
->symbols
!= NULL
2040 && ((*(elf_symbol_type
**) info
->symbols
)->internal_elf_sym
.st_other
2042 return print_insn_mips16 (memaddr
, info
);
2045 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2050 if (endianness
== BFD_ENDIAN_BIG
)
2051 insn
= (unsigned long) bfd_getb32 (buffer
);
2053 insn
= (unsigned long) bfd_getl32 (buffer
);
2055 return print_insn_mips (memaddr
, insn
, info
);
2059 (*info
->memory_error_func
) (status
, memaddr
, info
);
2065 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2067 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2071 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2073 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2077 print_mips_disassembler_options (FILE *stream
)
2081 fprintf (stream
, _("\n\
2082 The following MIPS specific disassembler options are supported for use\n\
2083 with the -M switch (multiple options should be separated by commas):\n"));
2085 fprintf (stream
, _("\n\
2086 gpr-names=ABI Print GPR names according to specified ABI.\n\
2087 Default: based on binary being disassembled.\n"));
2089 fprintf (stream
, _("\n\
2090 fpr-names=ABI Print FPR names according to specified ABI.\n\
2091 Default: numeric.\n"));
2093 fprintf (stream
, _("\n\
2094 cp0-names=ARCH Print CP0 register names according to\n\
2095 specified architecture.\n\
2096 Default: based on binary being disassembled.\n"));
2098 fprintf (stream
, _("\n\
2099 hwr-names=ARCH Print HWR names according to specified \n\
2101 Default: based on binary being disassembled.\n"));
2103 fprintf (stream
, _("\n\
2104 reg-names=ABI Print GPR and FPR names according to\n\
2105 specified ABI.\n"));
2107 fprintf (stream
, _("\n\
2108 reg-names=ARCH Print CP0 register and HWR names according to\n\
2109 specified architecture.\n"));
2111 fprintf (stream
, _("\n\
2112 For the options above, the following values are supported for \"ABI\":\n\
2114 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2115 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2116 fprintf (stream
, _("\n"));
2118 fprintf (stream
, _("\n\
2119 For the options above, The following values are supported for \"ARCH\":\n\
2121 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2122 if (*mips_arch_choices
[i
].name
!= '\0')
2123 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2124 fprintf (stream
, _("\n"));
2126 fprintf (stream
, _("\n"));