1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 Free Software Foundation, Inc.
5 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
7 This file is part of GDB, GAS, and the GNU binutils.
9 This program 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 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #include "libiberty.h"
26 #include "opcode/mips.h"
29 /* FIXME: These are needed to figure out if the code is mips16 or
30 not. The low bit of the address is often a good indicator. No
31 symbol table is available when this code runs out in an embedded
32 system as when it is used for disassembler support in a monitor. */
34 #if !defined(EMBEDDED_ENV)
35 #define SYMTAB_AVAILABLE 1
40 /* Mips instructions are at maximum this many bytes long. */
43 static void set_default_mips_dis_options
44 PARAMS ((struct disassemble_info
*));
45 static void parse_mips_dis_option
46 PARAMS ((const char *, unsigned int));
47 static void parse_mips_dis_options
48 PARAMS ((const char *));
49 static int _print_insn_mips
50 PARAMS ((bfd_vma
, struct disassemble_info
*, enum bfd_endian
));
51 static int print_insn_mips
52 PARAMS ((bfd_vma
, unsigned long int, struct disassemble_info
*));
53 static int print_insn_arg
54 PARAMS ((const char *, unsigned long, bfd_vma
, struct disassemble_info
*));
55 static int print_insn_mips16
56 PARAMS ((bfd_vma
, struct disassemble_info
*));
58 PARAMS ((Elf_Internal_Ehdr
*));
59 static void print_mips16_insn_arg
60 PARAMS ((int, const struct mips_opcode
*, int, bfd_boolean
, int, bfd_vma
,
61 struct disassemble_info
*));
63 /* FIXME: These should be shared with gdb somehow. */
65 struct mips_cp0sel_name
{
68 const char * const name
;
71 /* The mips16 register names. */
72 static const char * const mips16_reg_names
[] = {
73 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
76 static const char * const mips_gpr_names_numeric
[32] = {
77 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
78 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
79 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
80 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
83 static const char * const mips_gpr_names_oldabi
[32] = {
84 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
85 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
86 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
87 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
90 static const char * const mips_gpr_names_newabi
[32] = {
91 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
92 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
93 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
94 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
97 static const char * const mips_fpr_names_numeric
[32] = {
98 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
99 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
100 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
101 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
104 static const char * const mips_fpr_names_32
[32] = {
105 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
106 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
107 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
108 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
111 static const char * const mips_fpr_names_n32
[32] = {
112 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
113 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
114 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
115 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
118 static const char * const mips_fpr_names_64
[32] = {
119 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
120 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
121 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
122 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
125 static const char * const mips_cp0_names_numeric
[32] = {
126 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
127 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
128 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
129 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
132 static const char * const mips_cp0_names_mips3264
[32] = {
133 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
134 "c0_context", "c0_pagemask", "c0_wired", "$7",
135 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
136 "c0_status", "c0_cause", "c0_epc", "c0_prid",
137 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
138 "c0_xcontext", "$21", "$22", "c0_debug",
139 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
140 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
143 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] = {
144 { 16, 1, "c0_config1" },
145 { 16, 2, "c0_config2" },
146 { 16, 3, "c0_config3" },
147 { 18, 1, "c0_watchlo,1" },
148 { 18, 2, "c0_watchlo,2" },
149 { 18, 3, "c0_watchlo,3" },
150 { 18, 4, "c0_watchlo,4" },
151 { 18, 5, "c0_watchlo,5" },
152 { 18, 6, "c0_watchlo,6" },
153 { 18, 7, "c0_watchlo,7" },
154 { 19, 1, "c0_watchhi,1" },
155 { 19, 2, "c0_watchhi,2" },
156 { 19, 3, "c0_watchhi,3" },
157 { 19, 4, "c0_watchhi,4" },
158 { 19, 5, "c0_watchhi,5" },
159 { 19, 6, "c0_watchhi,6" },
160 { 19, 7, "c0_watchhi,7" },
161 { 25, 1, "c0_perfcnt,1" },
162 { 25, 2, "c0_perfcnt,2" },
163 { 25, 3, "c0_perfcnt,3" },
164 { 25, 4, "c0_perfcnt,4" },
165 { 25, 5, "c0_perfcnt,5" },
166 { 25, 6, "c0_perfcnt,6" },
167 { 25, 7, "c0_perfcnt,7" },
168 { 27, 1, "c0_cacheerr,1" },
169 { 27, 2, "c0_cacheerr,2" },
170 { 27, 3, "c0_cacheerr,3" },
171 { 28, 1, "c0_datalo" },
172 { 29, 1, "c0_datahi" }
175 static const char * const mips_cp0_names_mips3264r2
[32] = {
176 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
177 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
178 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
179 "c0_status", "c0_cause", "c0_epc", "c0_prid",
180 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
181 "c0_xcontext", "$21", "$22", "c0_debug",
182 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
183 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
186 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] = {
187 { 4, 1, "c0_contextconfig" },
188 { 5, 1, "c0_pagegrain" },
189 { 12, 1, "c0_intctl" },
190 { 12, 2, "c0_srsctl" },
191 { 12, 3, "c0_srsmap" },
192 { 15, 1, "c0_ebase" },
193 { 16, 1, "c0_config1" },
194 { 16, 2, "c0_config2" },
195 { 16, 3, "c0_config3" },
196 { 18, 1, "c0_watchlo,1" },
197 { 18, 2, "c0_watchlo,2" },
198 { 18, 3, "c0_watchlo,3" },
199 { 18, 4, "c0_watchlo,4" },
200 { 18, 5, "c0_watchlo,5" },
201 { 18, 6, "c0_watchlo,6" },
202 { 18, 7, "c0_watchlo,7" },
203 { 19, 1, "c0_watchhi,1" },
204 { 19, 2, "c0_watchhi,2" },
205 { 19, 3, "c0_watchhi,3" },
206 { 19, 4, "c0_watchhi,4" },
207 { 19, 5, "c0_watchhi,5" },
208 { 19, 6, "c0_watchhi,6" },
209 { 19, 7, "c0_watchhi,7" },
210 { 23, 1, "c0_tracecontrol" },
211 { 23, 2, "c0_tracecontrol2" },
212 { 23, 3, "c0_usertracedata" },
213 { 23, 4, "c0_tracebpc" },
214 { 25, 1, "c0_perfcnt,1" },
215 { 25, 2, "c0_perfcnt,2" },
216 { 25, 3, "c0_perfcnt,3" },
217 { 25, 4, "c0_perfcnt,4" },
218 { 25, 5, "c0_perfcnt,5" },
219 { 25, 6, "c0_perfcnt,6" },
220 { 25, 7, "c0_perfcnt,7" },
221 { 27, 1, "c0_cacheerr,1" },
222 { 27, 2, "c0_cacheerr,2" },
223 { 27, 3, "c0_cacheerr,3" },
224 { 28, 1, "c0_datalo" },
225 { 28, 2, "c0_taglo1" },
226 { 28, 3, "c0_datalo1" },
227 { 28, 4, "c0_taglo2" },
228 { 28, 5, "c0_datalo2" },
229 { 28, 6, "c0_taglo3" },
230 { 28, 7, "c0_datalo3" },
231 { 29, 1, "c0_datahi" },
232 { 29, 2, "c0_taghi1" },
233 { 29, 3, "c0_datahi1" },
234 { 29, 4, "c0_taghi2" },
235 { 29, 5, "c0_datahi2" },
236 { 29, 6, "c0_taghi3" },
237 { 29, 7, "c0_datahi3" },
240 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
241 static const char * const mips_cp0_names_sb1
[32] = {
242 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
243 "c0_context", "c0_pagemask", "c0_wired", "$7",
244 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
245 "c0_status", "c0_cause", "c0_epc", "c0_prid",
246 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
247 "c0_xcontext", "$21", "$22", "c0_debug",
248 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
249 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
252 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] = {
253 { 16, 1, "c0_config1" },
254 { 18, 1, "c0_watchlo,1" },
255 { 19, 1, "c0_watchhi,1" },
256 { 22, 0, "c0_perftrace" },
257 { 23, 3, "c0_edebug" },
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 { 26, 1, "c0_buserr_pa" },
266 { 27, 1, "c0_cacheerr_d" },
267 { 27, 3, "c0_cacheerr_d_pa" },
268 { 28, 1, "c0_datalo_i" },
269 { 28, 2, "c0_taglo_d" },
270 { 28, 3, "c0_datalo_d" },
271 { 29, 1, "c0_datahi_i" },
272 { 29, 2, "c0_taghi_d" },
273 { 29, 3, "c0_datahi_d" },
276 static const char * const mips_hwr_names_numeric
[32] = {
277 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
278 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
279 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
280 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
283 static const char * const mips_hwr_names_mips3264r2
[32] = {
284 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
285 "$4", "$5", "$6", "$7",
286 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
287 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
288 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
291 struct mips_abi_choice
{
293 const char * const *gpr_names
;
294 const char * const *fpr_names
;
297 struct mips_abi_choice mips_abi_choices
[] = {
298 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
299 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
300 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
301 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
304 struct mips_arch_choice
{
307 unsigned long bfd_mach
;
310 const char * const *cp0_names
;
311 const struct mips_cp0sel_name
*cp0sel_names
;
312 unsigned int cp0sel_names_len
;
313 const char * const *hwr_names
;
316 const struct mips_arch_choice mips_arch_choices
[] = {
317 { "numeric", 0, 0, 0, 0,
318 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
320 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
,
321 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
322 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
,
323 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
324 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
,
325 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
326 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
,
327 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
328 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
,
329 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
330 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
,
331 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
332 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
,
333 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
334 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
,
335 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
336 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
,
337 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
338 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
,
339 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
340 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
,
341 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
342 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
,
343 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
344 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
,
345 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
346 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
,
347 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
348 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
,
349 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
350 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
,
351 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
352 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
,
353 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
354 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
,
355 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
356 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
,
357 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
359 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
360 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
361 _MIPS32 Architecture For Programmers Volume I: Introduction to the
362 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
364 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
365 ISA_MIPS32
| INSN_MIPS16
,
366 mips_cp0_names_mips3264
,
367 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
368 mips_hwr_names_numeric
},
370 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
371 ISA_MIPS32R2
| INSN_MIPS16
,
372 mips_cp0_names_mips3264r2
,
373 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
374 mips_hwr_names_mips3264r2
},
376 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
377 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
378 ISA_MIPS64
| INSN_MIPS16
| INSN_MIPS3D
| INSN_MDMX
,
379 mips_cp0_names_mips3264
,
380 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
381 mips_hwr_names_numeric
},
383 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
384 ISA_MIPS64
| INSN_MIPS3D
| INSN_SB1
,
386 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
387 mips_hwr_names_numeric
},
389 /* This entry, mips16, is here only for ISA/processor selection; do
390 not print its name. */
391 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
| INSN_MIPS16
,
392 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
395 /* ISA and processor type to disassemble for, and register names to use.
396 set_default_mips_dis_options and parse_mips_dis_options fill in these
398 static int mips_processor
;
400 static const char * const *mips_gpr_names
;
401 static const char * const *mips_fpr_names
;
402 static const char * const *mips_cp0_names
;
403 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
404 static int mips_cp0sel_names_len
;
405 static const char * const *mips_hwr_names
;
407 static const struct mips_abi_choice
*choose_abi_by_name
408 PARAMS ((const char *, unsigned int));
409 static const struct mips_arch_choice
*choose_arch_by_name
410 PARAMS ((const char *, unsigned int));
411 static const struct mips_arch_choice
*choose_arch_by_number
412 PARAMS ((unsigned long));
413 static const struct mips_cp0sel_name
*lookup_mips_cp0sel_name
414 PARAMS ((const struct mips_cp0sel_name
*, unsigned int, unsigned int,
417 static const struct mips_abi_choice
*
418 choose_abi_by_name (name
, namelen
)
420 unsigned int namelen
;
422 const struct mips_abi_choice
*c
;
425 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
427 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
428 && strlen (mips_abi_choices
[i
].name
) == namelen
)
429 c
= &mips_abi_choices
[i
];
434 static const struct mips_arch_choice
*
435 choose_arch_by_name (name
, namelen
)
437 unsigned int namelen
;
439 const struct mips_arch_choice
*c
= NULL
;
442 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
444 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
445 && strlen (mips_arch_choices
[i
].name
) == namelen
)
446 c
= &mips_arch_choices
[i
];
451 static const struct mips_arch_choice
*
452 choose_arch_by_number (mach
)
455 static unsigned long hint_bfd_mach
;
456 static const struct mips_arch_choice
*hint_arch_choice
;
457 const struct mips_arch_choice
*c
;
460 /* We optimize this because even if the user specifies no
461 flags, this will be done for every instruction! */
462 if (hint_bfd_mach
== mach
463 && hint_arch_choice
!= NULL
464 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
465 return hint_arch_choice
;
467 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
469 if (mips_arch_choices
[i
].bfd_mach_valid
470 && mips_arch_choices
[i
].bfd_mach
== mach
)
472 c
= &mips_arch_choices
[i
];
473 hint_bfd_mach
= mach
;
474 hint_arch_choice
= c
;
481 set_default_mips_dis_options (info
)
482 struct disassemble_info
*info
;
484 const struct mips_arch_choice
*chosen_arch
;
486 /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names,
487 and numeric FPR, CP0 register, and HWR names. */
488 mips_isa
= ISA_MIPS3
;
489 mips_processor
= CPU_R3000
;
490 mips_gpr_names
= mips_gpr_names_oldabi
;
491 mips_fpr_names
= mips_fpr_names_numeric
;
492 mips_cp0_names
= mips_cp0_names_numeric
;
493 mips_cp0sel_names
= NULL
;
494 mips_cp0sel_names_len
= 0;
495 mips_hwr_names
= mips_hwr_names_numeric
;
497 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
498 if (info
->flavour
== bfd_target_elf_flavour
&& info
->symbols
!= NULL
)
500 Elf_Internal_Ehdr
*header
;
502 header
= elf_elfheader (bfd_asymbol_bfd (*(info
->symbols
)));
503 if (is_newabi (header
))
504 mips_gpr_names
= mips_gpr_names_newabi
;
507 /* Set ISA, architecture, and cp0 register names as best we can. */
508 #if ! SYMTAB_AVAILABLE
509 /* This is running out on a target machine, not in a host tool.
510 FIXME: Where does mips_target_info come from? */
511 target_processor
= mips_target_info
.processor
;
512 mips_isa
= mips_target_info
.isa
;
514 chosen_arch
= choose_arch_by_number (info
->mach
);
515 if (chosen_arch
!= NULL
)
517 mips_processor
= chosen_arch
->processor
;
518 mips_isa
= chosen_arch
->isa
;
519 mips_cp0_names
= chosen_arch
->cp0_names
;
520 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
521 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
522 mips_hwr_names
= chosen_arch
->hwr_names
;
528 parse_mips_dis_option (option
, len
)
532 unsigned int i
, optionlen
, vallen
;
534 const struct mips_abi_choice
*chosen_abi
;
535 const struct mips_arch_choice
*chosen_arch
;
537 /* Look for the = that delimits the end of the option name. */
538 for (i
= 0; i
< len
; i
++)
540 if (option
[i
] == '=')
543 if (i
== 0) /* Invalid option: no name before '='. */
545 if (i
== len
) /* Invalid option: no '='. */
547 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
551 val
= option
+ (optionlen
+ 1);
552 vallen
= len
- (optionlen
+ 1);
554 if (strncmp("gpr-names", option
, optionlen
) == 0
555 && strlen("gpr-names") == optionlen
)
557 chosen_abi
= choose_abi_by_name (val
, vallen
);
558 if (chosen_abi
!= NULL
)
559 mips_gpr_names
= chosen_abi
->gpr_names
;
563 if (strncmp("fpr-names", option
, optionlen
) == 0
564 && strlen("fpr-names") == optionlen
)
566 chosen_abi
= choose_abi_by_name (val
, vallen
);
567 if (chosen_abi
!= NULL
)
568 mips_fpr_names
= chosen_abi
->fpr_names
;
572 if (strncmp("cp0-names", option
, optionlen
) == 0
573 && strlen("cp0-names") == optionlen
)
575 chosen_arch
= choose_arch_by_name (val
, vallen
);
576 if (chosen_arch
!= NULL
)
578 mips_cp0_names
= chosen_arch
->cp0_names
;
579 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
580 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
585 if (strncmp("hwr-names", option
, optionlen
) == 0
586 && strlen("hwr-names") == optionlen
)
588 chosen_arch
= choose_arch_by_name (val
, vallen
);
589 if (chosen_arch
!= NULL
)
590 mips_hwr_names
= chosen_arch
->hwr_names
;
594 if (strncmp("reg-names", option
, optionlen
) == 0
595 && strlen("reg-names") == optionlen
)
597 /* We check both ABI and ARCH here unconditionally, so
598 that "numeric" will do the desirable thing: select
599 numeric register names for all registers. Other than
600 that, a given name probably won't match both. */
601 chosen_abi
= choose_abi_by_name (val
, vallen
);
602 if (chosen_abi
!= NULL
)
604 mips_gpr_names
= chosen_abi
->gpr_names
;
605 mips_fpr_names
= chosen_abi
->fpr_names
;
607 chosen_arch
= choose_arch_by_name (val
, vallen
);
608 if (chosen_arch
!= NULL
)
610 mips_cp0_names
= chosen_arch
->cp0_names
;
611 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
612 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
613 mips_hwr_names
= chosen_arch
->hwr_names
;
618 /* Invalid option. */
622 parse_mips_dis_options (options
)
625 const char *option_end
;
630 while (*options
!= '\0')
632 /* Skip empty options. */
639 /* We know that *options is neither NUL or a comma. */
640 option_end
= options
+ 1;
641 while (*option_end
!= ',' && *option_end
!= '\0')
644 parse_mips_dis_option (options
, option_end
- options
);
646 /* Go on to the next one. If option_end points to a comma, it
647 will be skipped above. */
648 options
= option_end
;
652 static const struct mips_cp0sel_name
*
653 lookup_mips_cp0sel_name(names
, len
, cp0reg
, sel
)
654 const struct mips_cp0sel_name
*names
;
655 unsigned int len
, cp0reg
, sel
;
659 for (i
= 0; i
< len
; i
++)
660 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
665 /* Print insn arguments for 32/64-bit code. */
668 print_insn_arg (d
, l
, pc
, info
)
670 register unsigned long int l
;
672 struct disassemble_info
*info
;
674 int op
, delta
, consumed
;
684 (*info
->fprintf_func
) (info
->stream
, "%c", *d
);
688 /* Extension character; switch for second char. */
694 (*info
->fprintf_func
) (info
->stream
, "0x%x",
695 (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
);
699 (*info
->fprintf_func
) (info
->stream
, "0x%x",
700 (((l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
)
701 - ((l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
)
706 (*info
->fprintf_func
) (info
->stream
, "0x%x",
707 (((l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
)
713 const struct mips_cp0sel_name
*n
;
714 unsigned int cp0reg
, sel
;
716 cp0reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
717 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
719 /* CP0 register including 'sel' code for mtcN (et al.), to be
720 printed textually if known. If not known, print both
721 CP0 register name and sel numerically since CP0 register
722 with sel 0 may have a name unrelated to register being
724 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
725 mips_cp0sel_names_len
, cp0reg
, sel
);
727 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
729 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
734 /* xgettext:c-format */
735 (*info
->fprintf_func
) (info
->stream
,
736 _("# internal error, undefined extension sequence (+%c)"),
738 /* Do not eat the trailing newline. */
749 (*info
->fprintf_func
) (info
->stream
, "%s",
750 mips_gpr_names
[(l
>> OP_SH_RS
) & OP_MASK_RS
]);
755 (*info
->fprintf_func
) (info
->stream
, "%s",
756 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
761 (*info
->fprintf_func
) (info
->stream
, "0x%x",
762 (l
>> OP_SH_IMMEDIATE
) & OP_MASK_IMMEDIATE
);
765 case 'j': /* Same as i, but sign-extended. */
767 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
770 (*info
->fprintf_func
) (info
->stream
, "%d",
775 (*info
->fprintf_func
) (info
->stream
, "0x%x",
776 (unsigned int) ((l
>> OP_SH_PREFX
)
781 (*info
->fprintf_func
) (info
->stream
, "0x%x",
782 (unsigned int) ((l
>> OP_SH_CACHE
)
787 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
788 | (((l
>> OP_SH_TARGET
) & OP_MASK_TARGET
) << 2));
789 (*info
->print_address_func
) (info
->target
, info
);
793 /* Sign extend the displacement. */
794 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
797 info
->target
= (delta
<< 2) + pc
+ INSNLEN
;
798 (*info
->print_address_func
) (info
->target
, info
);
802 (*info
->fprintf_func
) (info
->stream
, "%s",
803 mips_gpr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
808 /* First check for both rd and rt being equal. */
809 unsigned int reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
810 if (reg
== ((l
>> OP_SH_RT
) & OP_MASK_RT
))
811 (*info
->fprintf_func
) (info
->stream
, "%s",
812 mips_gpr_names
[reg
]);
815 /* If one is zero use the other. */
817 (*info
->fprintf_func
) (info
->stream
, "%s",
818 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
819 else if (((l
>> OP_SH_RT
) & OP_MASK_RT
) == 0)
820 (*info
->fprintf_func
) (info
->stream
, "%s",
821 mips_gpr_names
[reg
]);
822 else /* Bogus, result depends on processor. */
823 (*info
->fprintf_func
) (info
->stream
, "%s or %s",
825 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
831 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
835 (*info
->fprintf_func
) (info
->stream
, "0x%x",
836 (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
);
840 (*info
->fprintf_func
) (info
->stream
, "0x%x",
841 (l
>> OP_SH_CODE
) & OP_MASK_CODE
);
845 (*info
->fprintf_func
) (info
->stream
, "0x%x",
846 (l
>> OP_SH_CODE2
) & OP_MASK_CODE2
);
850 (*info
->fprintf_func
) (info
->stream
, "0x%x",
851 (l
>> OP_SH_COPZ
) & OP_MASK_COPZ
);
855 (*info
->fprintf_func
) (info
->stream
, "0x%x",
856 (l
>> OP_SH_CODE20
) & OP_MASK_CODE20
);
860 (*info
->fprintf_func
) (info
->stream
, "0x%x",
861 (l
>> OP_SH_CODE19
) & OP_MASK_CODE19
);
866 (*info
->fprintf_func
) (info
->stream
, "%s",
867 mips_fpr_names
[(l
>> OP_SH_FS
) & OP_MASK_FS
]);
872 (*info
->fprintf_func
) (info
->stream
, "%s",
873 mips_fpr_names
[(l
>> OP_SH_FT
) & OP_MASK_FT
]);
877 (*info
->fprintf_func
) (info
->stream
, "%s",
878 mips_fpr_names
[(l
>> OP_SH_FD
) & OP_MASK_FD
]);
882 (*info
->fprintf_func
) (info
->stream
, "%s",
883 mips_fpr_names
[(l
>> OP_SH_FR
) & OP_MASK_FR
]);
887 /* Coprocessor register for lwcN instructions, et al.
889 Note that there is no load/store cp0 instructions, and
890 that FPU (cp1) instructions disassemble this field using
891 'T' format. Therefore, until we gain understanding of
893 we can simply print the register numbers. */
894 (*info
->fprintf_func
) (info
->stream
, "$%d",
895 (l
>> OP_SH_RT
) & OP_MASK_RT
);
899 /* Coprocessor register for mtcN instructions, et al.
900 Note that FPU (cp1) instructions disassemble this field using
901 'S' format. Therefore, we only need to worry about cp0, cp2,
903 op
= (l
>> OP_SH_OP
) & OP_MASK_OP
;
904 if (op
== OP_OP_COP0
)
905 (*info
->fprintf_func
) (info
->stream
, "%s",
906 mips_cp0_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
908 (*info
->fprintf_func
) (info
->stream
, "$%d",
909 (l
>> OP_SH_RD
) & OP_MASK_RD
);
913 (*info
->fprintf_func
) (info
->stream
, "%s",
914 mips_hwr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
918 (*info
->fprintf_func
) (info
->stream
, "$fcc%d",
919 (l
>> OP_SH_BCC
) & OP_MASK_BCC
);
923 (*info
->fprintf_func
) (info
->stream
, "$fcc%d",
924 (l
>> OP_SH_CCC
) & OP_MASK_CCC
);
928 (*info
->fprintf_func
) (info
->stream
, "%d",
929 (l
>> OP_SH_PERFREG
) & OP_MASK_PERFREG
);
933 (*info
->fprintf_func
) (info
->stream
, "%d",
934 (l
>> OP_SH_VECBYTE
) & OP_MASK_VECBYTE
);
938 (*info
->fprintf_func
) (info
->stream
, "%d",
939 (l
>> OP_SH_VECALIGN
) & OP_MASK_VECALIGN
);
943 (*info
->fprintf_func
) (info
->stream
, "%d",
944 (l
>> OP_SH_SEL
) & OP_MASK_SEL
);
948 (*info
->fprintf_func
) (info
->stream
, "%d",
949 (l
>> OP_SH_ALN
) & OP_MASK_ALN
);
954 unsigned int vsel
= (l
>> OP_SH_VSEL
) & OP_MASK_VSEL
;
955 if ((vsel
& 0x10) == 0)
959 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
962 (*info
->fprintf_func
) (info
->stream
, "$v%d[%d]",
963 (l
>> OP_SH_FT
) & OP_MASK_FT
,
966 else if ((vsel
& 0x08) == 0)
968 (*info
->fprintf_func
) (info
->stream
, "$v%d",
969 (l
>> OP_SH_FT
) & OP_MASK_FT
);
973 (*info
->fprintf_func
) (info
->stream
, "0x%x",
974 (l
>> OP_SH_FT
) & OP_MASK_FT
);
980 (*info
->fprintf_func
) (info
->stream
, "$v%d",
981 (l
>> OP_SH_FD
) & OP_MASK_FD
);
985 (*info
->fprintf_func
) (info
->stream
, "$v%d",
986 (l
>> OP_SH_FS
) & OP_MASK_FS
);
990 (*info
->fprintf_func
) (info
->stream
, "$v%d",
991 (l
>> OP_SH_FT
) & OP_MASK_FT
);
995 /* xgettext:c-format */
996 (*info
->fprintf_func
) (info
->stream
,
997 _("# internal error, undefined modifier(%c)"),
1005 /* Check if the object uses NewABI conventions. */
1009 Elf_Internal_Ehdr
*header
;
1011 /* There are no old-style ABIs which use 64-bit ELF. */
1012 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
1015 /* If a 32-bit ELF file, n32 is a new-style ABI. */
1016 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
1022 /* Print the mips instruction at address MEMADDR in debugged memory,
1023 on using INFO. Returns length of the instruction, in bytes, which is
1024 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1025 this is little-endian code. */
1028 print_insn_mips (memaddr
, word
, info
)
1030 unsigned long int word
;
1031 struct disassemble_info
*info
;
1033 register const struct mips_opcode
*op
;
1034 static bfd_boolean init
= 0;
1035 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1037 /* Build a hash table to shorten the search time. */
1042 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1044 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1046 if (op
->pinfo
== INSN_MACRO
)
1048 if (i
== ((op
->match
>> OP_SH_OP
) & OP_MASK_OP
))
1059 info
->bytes_per_chunk
= INSNLEN
;
1060 info
->display_endian
= info
->endian
;
1061 info
->insn_info_valid
= 1;
1062 info
->branch_delay_insns
= 0;
1063 info
->data_size
= 0;
1064 info
->insn_type
= dis_nonbranch
;
1068 op
= mips_hash
[(word
>> OP_SH_OP
) & OP_MASK_OP
];
1071 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1073 if (op
->pinfo
!= INSN_MACRO
&& (word
& op
->mask
) == op
->match
)
1075 register const char *d
;
1077 /* We always allow to disassemble the jalx instruction. */
1078 if (! OPCODE_IS_MEMBER (op
, mips_isa
, mips_processor
)
1079 && strcmp (op
->name
, "jalx"))
1082 /* Figure out instruction type and branch delay information. */
1083 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1085 if ((info
->insn_type
& INSN_WRITE_GPR_31
) != 0)
1086 info
->insn_type
= dis_jsr
;
1088 info
->insn_type
= dis_branch
;
1089 info
->branch_delay_insns
= 1;
1091 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1092 | INSN_COND_BRANCH_LIKELY
)) != 0)
1094 if ((info
->insn_type
& INSN_WRITE_GPR_31
) != 0)
1095 info
->insn_type
= dis_condjsr
;
1097 info
->insn_type
= dis_condbranch
;
1098 info
->branch_delay_insns
= 1;
1100 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1101 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1102 info
->insn_type
= dis_dref
;
1104 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
1107 if (d
!= NULL
&& *d
!= '\0')
1111 (*info
->fprintf_func
) (info
->stream
, "\t");
1114 /* print_insn_arg will not eat the trailing NUL
1115 of (erroneous) multi-character strings. */
1116 consumed
= print_insn_arg (d
, word
, memaddr
, info
);
1126 /* Handle undefined instructions. */
1127 info
->insn_type
= dis_noninsn
;
1128 (*info
->fprintf_func
) (info
->stream
, "0x%x", word
);
1132 /* In an environment where we do not know the symbol type of the
1133 instruction we are forced to assume that the low order bit of the
1134 instructions' address may mark it as a mips16 instruction. If we
1135 are single stepping, or the pc is within the disassembled function,
1136 this works. Otherwise, we need a clue. Sometimes. */
1139 _print_insn_mips (memaddr
, info
, endianness
)
1141 struct disassemble_info
*info
;
1142 enum bfd_endian endianness
;
1144 bfd_byte buffer
[INSNLEN
];
1147 set_default_mips_dis_options (info
);
1148 parse_mips_dis_options (info
->disassembler_options
);
1151 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
1152 /* Only a few tools will work this way. */
1154 return print_insn_mips16 (memaddr
, info
);
1157 #if SYMTAB_AVAILABLE
1158 if (info
->mach
== bfd_mach_mips16
1159 || (info
->flavour
== bfd_target_elf_flavour
1160 && info
->symbols
!= NULL
1161 && ((*(elf_symbol_type
**) info
->symbols
)->internal_elf_sym
.st_other
1163 return print_insn_mips16 (memaddr
, info
);
1166 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
1171 if (endianness
== BFD_ENDIAN_BIG
)
1172 insn
= (unsigned long) bfd_getb32 (buffer
);
1174 insn
= (unsigned long) bfd_getl32 (buffer
);
1176 return print_insn_mips (memaddr
, insn
, info
);
1180 (*info
->memory_error_func
) (status
, memaddr
, info
);
1186 print_insn_big_mips (memaddr
, info
)
1188 struct disassemble_info
*info
;
1190 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
1194 print_insn_little_mips (memaddr
, info
)
1196 struct disassemble_info
*info
;
1198 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
1201 /* Disassemble mips16 instructions. */
1204 print_insn_mips16 (memaddr
, info
)
1206 struct disassemble_info
*info
;
1212 bfd_boolean use_extend
;
1214 const struct mips_opcode
*op
, *opend
;
1216 info
->bytes_per_chunk
= 2;
1217 info
->display_endian
= info
->endian
;
1218 info
->insn_info_valid
= 1;
1219 info
->branch_delay_insns
= 0;
1220 info
->data_size
= 0;
1221 info
->insn_type
= dis_nonbranch
;
1225 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1228 (*info
->memory_error_func
) (status
, memaddr
, info
);
1234 if (info
->endian
== BFD_ENDIAN_BIG
)
1235 insn
= bfd_getb16 (buffer
);
1237 insn
= bfd_getl16 (buffer
);
1239 /* Handle the extend opcode specially. */
1241 if ((insn
& 0xf800) == 0xf000)
1244 extend
= insn
& 0x7ff;
1248 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1251 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
1252 (unsigned int) extend
);
1253 (*info
->memory_error_func
) (status
, memaddr
, info
);
1257 if (info
->endian
== BFD_ENDIAN_BIG
)
1258 insn
= bfd_getb16 (buffer
);
1260 insn
= bfd_getl16 (buffer
);
1262 /* Check for an extend opcode followed by an extend opcode. */
1263 if ((insn
& 0xf800) == 0xf000)
1265 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
1266 (unsigned int) extend
);
1267 info
->insn_type
= dis_noninsn
;
1274 /* FIXME: Should probably use a hash table on the major opcode here. */
1276 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
1277 for (op
= mips16_opcodes
; op
< opend
; op
++)
1279 if (op
->pinfo
!= INSN_MACRO
&& (insn
& op
->mask
) == op
->match
)
1283 if (strchr (op
->args
, 'a') != NULL
)
1287 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
1288 (unsigned int) extend
);
1289 info
->insn_type
= dis_noninsn
;
1297 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
1302 if (info
->endian
== BFD_ENDIAN_BIG
)
1303 extend
= bfd_getb16 (buffer
);
1305 extend
= bfd_getl16 (buffer
);
1310 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
1311 if (op
->args
[0] != '\0')
1312 (*info
->fprintf_func
) (info
->stream
, "\t");
1314 for (s
= op
->args
; *s
!= '\0'; s
++)
1318 && (((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)
1319 == ((insn
>> MIPS16OP_SH_RY
) & MIPS16OP_MASK_RY
)))
1321 /* Skip the register and the comma. */
1327 && (((insn
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
)
1328 == ((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)))
1330 /* Skip the register and the comma. */
1334 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
1338 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1340 info
->branch_delay_insns
= 1;
1341 if (info
->insn_type
!= dis_jsr
)
1342 info
->insn_type
= dis_branch
;
1350 (*info
->fprintf_func
) (info
->stream
, "0x%x", extend
| 0xf000);
1351 (*info
->fprintf_func
) (info
->stream
, "0x%x", insn
);
1352 info
->insn_type
= dis_noninsn
;
1357 /* Disassemble an operand for a mips16 instruction. */
1360 print_mips16_insn_arg (type
, op
, l
, use_extend
, extend
, memaddr
, info
)
1362 const struct mips_opcode
*op
;
1364 bfd_boolean use_extend
;
1367 struct disassemble_info
*info
;
1374 (*info
->fprintf_func
) (info
->stream
, "%c", type
);
1379 (*info
->fprintf_func
) (info
->stream
, "%s",
1380 mips16_reg_names
[((l
>> MIPS16OP_SH_RY
)
1381 & MIPS16OP_MASK_RY
)]);
1386 (*info
->fprintf_func
) (info
->stream
, "%s",
1387 mips16_reg_names
[((l
>> MIPS16OP_SH_RX
)
1388 & MIPS16OP_MASK_RX
)]);
1392 (*info
->fprintf_func
) (info
->stream
, "%s",
1393 mips16_reg_names
[((l
>> MIPS16OP_SH_RZ
)
1394 & MIPS16OP_MASK_RZ
)]);
1398 (*info
->fprintf_func
) (info
->stream
, "%s",
1399 mips16_reg_names
[((l
>> MIPS16OP_SH_MOVE32Z
)
1400 & MIPS16OP_MASK_MOVE32Z
)]);
1404 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1408 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[29]);
1412 (*info
->fprintf_func
) (info
->stream
, "$pc");
1416 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[31]);
1420 (*info
->fprintf_func
) (info
->stream
, "%s",
1421 mips_gpr_names
[((l
>> MIPS16OP_SH_REGR32
)
1422 & MIPS16OP_MASK_REGR32
)]);
1426 (*info
->fprintf_func
) (info
->stream
, "%s",
1427 mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1453 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1465 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1471 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1477 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1483 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1489 immed
= (l
>> MIPS16OP_SH_IMM4
) & MIPS16OP_MASK_IMM4
;
1495 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1496 info
->insn_type
= dis_dref
;
1497 info
->data_size
= 1;
1502 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1503 info
->insn_type
= dis_dref
;
1504 info
->data_size
= 2;
1509 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1510 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1511 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1513 info
->insn_type
= dis_dref
;
1514 info
->data_size
= 4;
1520 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1521 info
->insn_type
= dis_dref
;
1522 info
->data_size
= 8;
1526 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1531 immed
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1535 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1540 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1541 /* FIXME: This might be lw, or it might be addiu to $sp or
1542 $pc. We assume it's load. */
1543 info
->insn_type
= dis_dref
;
1544 info
->data_size
= 4;
1549 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1550 info
->insn_type
= dis_dref
;
1551 info
->data_size
= 8;
1555 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1560 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1566 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1571 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1575 info
->insn_type
= dis_condbranch
;
1579 immed
= (l
>> MIPS16OP_SH_IMM11
) & MIPS16OP_MASK_IMM11
;
1583 info
->insn_type
= dis_branch
;
1588 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1590 /* FIXME: This can be lw or la. We assume it is lw. */
1591 info
->insn_type
= dis_dref
;
1592 info
->data_size
= 4;
1597 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1599 info
->insn_type
= dis_dref
;
1600 info
->data_size
= 8;
1605 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1614 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1615 immed
-= 1 << nbits
;
1617 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1624 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1625 else if (extbits
== 15)
1626 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1628 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1629 immed
&= (1 << extbits
) - 1;
1630 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1631 immed
-= 1 << extbits
;
1635 (*info
->fprintf_func
) (info
->stream
, "%d", immed
);
1643 baseaddr
= memaddr
+ 2;
1645 else if (use_extend
)
1646 baseaddr
= memaddr
- 2;
1654 /* If this instruction is in the delay slot of a jr
1655 instruction, the base address is the address of the
1656 jr instruction. If it is in the delay slot of jalr
1657 instruction, the base address is the address of the
1658 jalr instruction. This test is unreliable: we have
1659 no way of knowing whether the previous word is
1660 instruction or data. */
1661 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1664 && (((info
->endian
== BFD_ENDIAN_BIG
1665 ? bfd_getb16 (buffer
)
1666 : bfd_getl16 (buffer
))
1667 & 0xf800) == 0x1800))
1668 baseaddr
= memaddr
- 4;
1671 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1674 && (((info
->endian
== BFD_ENDIAN_BIG
1675 ? bfd_getb16 (buffer
)
1676 : bfd_getl16 (buffer
))
1677 & 0xf81f) == 0xe800))
1678 baseaddr
= memaddr
- 2;
1681 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1682 (*info
->print_address_func
) (info
->target
, info
);
1690 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1691 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1692 (*info
->print_address_func
) (info
->target
, info
);
1693 info
->insn_type
= dis_jsr
;
1694 info
->branch_delay_insns
= 1;
1700 int need_comma
, amask
, smask
;
1704 l
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1706 amask
= (l
>> 3) & 7;
1708 if (amask
> 0 && amask
< 5)
1710 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
1712 (*info
->fprintf_func
) (info
->stream
, "-%s",
1713 mips_gpr_names
[amask
+ 3]);
1717 smask
= (l
>> 1) & 3;
1720 (*info
->fprintf_func
) (info
->stream
, "%s??",
1721 need_comma
? "," : "");
1726 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1727 need_comma
? "," : "",
1728 mips_gpr_names
[16]);
1730 (*info
->fprintf_func
) (info
->stream
, "-%s",
1731 mips_gpr_names
[smask
+ 15]);
1737 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1738 need_comma
? "," : "",
1739 mips_gpr_names
[31]);
1743 if (amask
== 5 || amask
== 6)
1745 (*info
->fprintf_func
) (info
->stream
, "%s$f0",
1746 need_comma
? "," : "");
1748 (*info
->fprintf_func
) (info
->stream
, "-$f1");
1754 /* xgettext:c-format */
1755 (*info
->fprintf_func
)
1757 _("# internal disassembler error, unrecognised modifier (%c)"),
1764 print_mips_disassembler_options (stream
)
1769 fprintf (stream
, _("\n\
1770 The following MIPS specific disassembler options are supported for use\n\
1771 with the -M switch (multiple options should be separated by commas):\n"));
1773 fprintf (stream
, _("\n\
1774 gpr-names=ABI Print GPR names according to specified ABI.\n\
1775 Default: based on binary being disassembled.\n"));
1777 fprintf (stream
, _("\n\
1778 fpr-names=ABI Print FPR names according to specified ABI.\n\
1779 Default: numeric.\n"));
1781 fprintf (stream
, _("\n\
1782 cp0-names=ARCH Print CP0 register names according to\n\
1783 specified architecture.\n\
1784 Default: based on binary being disassembled.\n"));
1786 fprintf (stream
, _("\n\
1787 hwr-names=ARCH Print HWR names according to specified \n\
1789 Default: based on binary being disassembled.\n"));
1791 fprintf (stream
, _("\n\
1792 reg-names=ABI Print GPR and FPR names according to\n\
1793 specified ABI.\n"));
1795 fprintf (stream
, _("\n\
1796 reg-names=ARCH Print CP0 register and HWR names according to\n\
1797 specified architecture.\n"));
1799 fprintf (stream
, _("\n\
1800 For the options above, the following values are supported for \"ABI\":\n\
1802 for (i
= 0; mips_abi_choices
[i
].name
!= NULL
; i
++)
1803 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
1804 fprintf (stream
, _("\n"));
1806 fprintf (stream
, _("\n\
1807 For the options above, The following values are supported for \"ARCH\":\n\
1809 for (i
= 0; mips_arch_choices
[i
].name
!= NULL
; i
++)
1810 if (*mips_arch_choices
[i
].name
!= '\0')
1811 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
1812 fprintf (stream
, _("\n"));
1814 fprintf (stream
, _("\n"));