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 void print_insn_args
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 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
,
351 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
352 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
,
353 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
354 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
,
355 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
356 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
,
357 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
358 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
,
359 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
360 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
,
361 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
363 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
364 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
365 _MIPS32 Architecture For Programmers Volume I: Introduction to the
366 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
368 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
369 ISA_MIPS32
| INSN_MIPS16
,
370 mips_cp0_names_mips3264
,
371 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
372 mips_hwr_names_numeric
},
374 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
375 ISA_MIPS32R2
| INSN_MIPS16
,
376 mips_cp0_names_mips3264r2
,
377 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
378 mips_hwr_names_mips3264r2
},
380 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
381 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
382 ISA_MIPS64
| INSN_MIPS16
| INSN_MIPS3D
| INSN_MDMX
,
383 mips_cp0_names_mips3264
,
384 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
385 mips_hwr_names_numeric
},
387 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
388 ISA_MIPS64R2
| INSN_MIPS16
| INSN_MIPS3D
| INSN_MDMX
,
389 mips_cp0_names_mips3264r2
,
390 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
391 mips_hwr_names_mips3264r2
},
393 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
394 ISA_MIPS64
| INSN_MIPS3D
| INSN_SB1
,
396 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
397 mips_hwr_names_numeric
},
399 /* This entry, mips16, is here only for ISA/processor selection; do
400 not print its name. */
401 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
| INSN_MIPS16
,
402 mips_cp0_names_numeric
, NULL
, 0, mips_hwr_names_numeric
},
405 /* ISA and processor type to disassemble for, and register names to use.
406 set_default_mips_dis_options and parse_mips_dis_options fill in these
408 static int mips_processor
;
410 static const char * const *mips_gpr_names
;
411 static const char * const *mips_fpr_names
;
412 static const char * const *mips_cp0_names
;
413 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
414 static int mips_cp0sel_names_len
;
415 static const char * const *mips_hwr_names
;
417 static const struct mips_abi_choice
*choose_abi_by_name
418 PARAMS ((const char *, unsigned int));
419 static const struct mips_arch_choice
*choose_arch_by_name
420 PARAMS ((const char *, unsigned int));
421 static const struct mips_arch_choice
*choose_arch_by_number
422 PARAMS ((unsigned long));
423 static const struct mips_cp0sel_name
*lookup_mips_cp0sel_name
424 PARAMS ((const struct mips_cp0sel_name
*, unsigned int, unsigned int,
427 static const struct mips_abi_choice
*
428 choose_abi_by_name (name
, namelen
)
430 unsigned int namelen
;
432 const struct mips_abi_choice
*c
;
435 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
437 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
438 && strlen (mips_abi_choices
[i
].name
) == namelen
)
439 c
= &mips_abi_choices
[i
];
444 static const struct mips_arch_choice
*
445 choose_arch_by_name (name
, namelen
)
447 unsigned int namelen
;
449 const struct mips_arch_choice
*c
= NULL
;
452 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
454 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
455 && strlen (mips_arch_choices
[i
].name
) == namelen
)
456 c
= &mips_arch_choices
[i
];
461 static const struct mips_arch_choice
*
462 choose_arch_by_number (mach
)
465 static unsigned long hint_bfd_mach
;
466 static const struct mips_arch_choice
*hint_arch_choice
;
467 const struct mips_arch_choice
*c
;
470 /* We optimize this because even if the user specifies no
471 flags, this will be done for every instruction! */
472 if (hint_bfd_mach
== mach
473 && hint_arch_choice
!= NULL
474 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
475 return hint_arch_choice
;
477 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
479 if (mips_arch_choices
[i
].bfd_mach_valid
480 && mips_arch_choices
[i
].bfd_mach
== mach
)
482 c
= &mips_arch_choices
[i
];
483 hint_bfd_mach
= mach
;
484 hint_arch_choice
= c
;
491 set_default_mips_dis_options (info
)
492 struct disassemble_info
*info
;
494 const struct mips_arch_choice
*chosen_arch
;
496 /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names,
497 and numeric FPR, CP0 register, and HWR names. */
498 mips_isa
= ISA_MIPS3
;
499 mips_processor
= CPU_R3000
;
500 mips_gpr_names
= mips_gpr_names_oldabi
;
501 mips_fpr_names
= mips_fpr_names_numeric
;
502 mips_cp0_names
= mips_cp0_names_numeric
;
503 mips_cp0sel_names
= NULL
;
504 mips_cp0sel_names_len
= 0;
505 mips_hwr_names
= mips_hwr_names_numeric
;
507 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
508 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
510 Elf_Internal_Ehdr
*header
;
512 header
= elf_elfheader (info
->section
->owner
);
513 if (is_newabi (header
))
514 mips_gpr_names
= mips_gpr_names_newabi
;
517 /* Set ISA, architecture, and cp0 register names as best we can. */
518 #if ! SYMTAB_AVAILABLE
519 /* This is running out on a target machine, not in a host tool.
520 FIXME: Where does mips_target_info come from? */
521 target_processor
= mips_target_info
.processor
;
522 mips_isa
= mips_target_info
.isa
;
524 chosen_arch
= choose_arch_by_number (info
->mach
);
525 if (chosen_arch
!= NULL
)
527 mips_processor
= chosen_arch
->processor
;
528 mips_isa
= chosen_arch
->isa
;
529 mips_cp0_names
= chosen_arch
->cp0_names
;
530 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
531 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
532 mips_hwr_names
= chosen_arch
->hwr_names
;
538 parse_mips_dis_option (option
, len
)
542 unsigned int i
, optionlen
, vallen
;
544 const struct mips_abi_choice
*chosen_abi
;
545 const struct mips_arch_choice
*chosen_arch
;
547 /* Look for the = that delimits the end of the option name. */
548 for (i
= 0; i
< len
; i
++)
550 if (option
[i
] == '=')
553 if (i
== 0) /* Invalid option: no name before '='. */
555 if (i
== len
) /* Invalid option: no '='. */
557 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
561 val
= option
+ (optionlen
+ 1);
562 vallen
= len
- (optionlen
+ 1);
564 if (strncmp("gpr-names", option
, optionlen
) == 0
565 && strlen("gpr-names") == optionlen
)
567 chosen_abi
= choose_abi_by_name (val
, vallen
);
568 if (chosen_abi
!= NULL
)
569 mips_gpr_names
= chosen_abi
->gpr_names
;
573 if (strncmp("fpr-names", option
, optionlen
) == 0
574 && strlen("fpr-names") == optionlen
)
576 chosen_abi
= choose_abi_by_name (val
, vallen
);
577 if (chosen_abi
!= NULL
)
578 mips_fpr_names
= chosen_abi
->fpr_names
;
582 if (strncmp("cp0-names", option
, optionlen
) == 0
583 && strlen("cp0-names") == optionlen
)
585 chosen_arch
= choose_arch_by_name (val
, vallen
);
586 if (chosen_arch
!= NULL
)
588 mips_cp0_names
= chosen_arch
->cp0_names
;
589 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
590 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
595 if (strncmp("hwr-names", option
, optionlen
) == 0
596 && strlen("hwr-names") == optionlen
)
598 chosen_arch
= choose_arch_by_name (val
, vallen
);
599 if (chosen_arch
!= NULL
)
600 mips_hwr_names
= chosen_arch
->hwr_names
;
604 if (strncmp("reg-names", option
, optionlen
) == 0
605 && strlen("reg-names") == optionlen
)
607 /* We check both ABI and ARCH here unconditionally, so
608 that "numeric" will do the desirable thing: select
609 numeric register names for all registers. Other than
610 that, a given name probably won't match both. */
611 chosen_abi
= choose_abi_by_name (val
, vallen
);
612 if (chosen_abi
!= NULL
)
614 mips_gpr_names
= chosen_abi
->gpr_names
;
615 mips_fpr_names
= chosen_abi
->fpr_names
;
617 chosen_arch
= choose_arch_by_name (val
, vallen
);
618 if (chosen_arch
!= NULL
)
620 mips_cp0_names
= chosen_arch
->cp0_names
;
621 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
622 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
623 mips_hwr_names
= chosen_arch
->hwr_names
;
628 /* Invalid option. */
632 parse_mips_dis_options (options
)
635 const char *option_end
;
640 while (*options
!= '\0')
642 /* Skip empty options. */
649 /* We know that *options is neither NUL or a comma. */
650 option_end
= options
+ 1;
651 while (*option_end
!= ',' && *option_end
!= '\0')
654 parse_mips_dis_option (options
, option_end
- options
);
656 /* Go on to the next one. If option_end points to a comma, it
657 will be skipped above. */
658 options
= option_end
;
662 static const struct mips_cp0sel_name
*
663 lookup_mips_cp0sel_name(names
, len
, cp0reg
, sel
)
664 const struct mips_cp0sel_name
*names
;
665 unsigned int len
, cp0reg
, sel
;
669 for (i
= 0; i
< len
; i
++)
670 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
675 /* Print insn arguments for 32/64-bit code. */
678 print_insn_args (d
, l
, pc
, info
)
680 register unsigned long int l
;
682 struct disassemble_info
*info
;
685 unsigned int lsb
, msb
, msbd
;
689 for (; *d
!= '\0'; d
++)
698 (*info
->fprintf_func
) (info
->stream
, "%c", *d
);
702 /* Extension character; switch for second char. */
707 /* xgettext:c-format */
708 (*info
->fprintf_func
) (info
->stream
,
709 _("# internal error, incomplete extension sequence (+)"));
713 lsb
= (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
;
714 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
718 msb
= (l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
;
719 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
724 msbd
= (l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
;
725 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
730 const struct mips_cp0sel_name
*n
;
731 unsigned int cp0reg
, sel
;
733 cp0reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
734 sel
= (l
>> OP_SH_SEL
) & OP_MASK_SEL
;
736 /* CP0 register including 'sel' code for mtcN (et al.), to be
737 printed textually if known. If not known, print both
738 CP0 register name and sel numerically since CP0 register
739 with sel 0 may have a name unrelated to register being
741 n
= lookup_mips_cp0sel_name(mips_cp0sel_names
,
742 mips_cp0sel_names_len
, cp0reg
, sel
);
744 (*info
->fprintf_func
) (info
->stream
, "%s", n
->name
);
746 (*info
->fprintf_func
) (info
->stream
, "$%d,%d", cp0reg
, sel
);
751 lsb
= ((l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
) + 32;
752 (*info
->fprintf_func
) (info
->stream
, "0x%x", lsb
);
756 msb
= ((l
>> OP_SH_INSMSB
) & OP_MASK_INSMSB
) + 32;
757 (*info
->fprintf_func
) (info
->stream
, "0x%x", msb
- lsb
+ 1);
761 msbd
= ((l
>> OP_SH_EXTMSBD
) & OP_MASK_EXTMSBD
) + 32;
762 (*info
->fprintf_func
) (info
->stream
, "0x%x", msbd
+ 1);
766 /* xgettext:c-format */
767 (*info
->fprintf_func
) (info
->stream
,
768 _("# internal error, undefined extension sequence (+%c)"),
778 (*info
->fprintf_func
) (info
->stream
, "%s",
779 mips_gpr_names
[(l
>> OP_SH_RS
) & OP_MASK_RS
]);
784 (*info
->fprintf_func
) (info
->stream
, "%s",
785 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
790 (*info
->fprintf_func
) (info
->stream
, "0x%x",
791 (l
>> OP_SH_IMMEDIATE
) & OP_MASK_IMMEDIATE
);
794 case 'j': /* Same as i, but sign-extended. */
796 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
799 (*info
->fprintf_func
) (info
->stream
, "%d",
804 (*info
->fprintf_func
) (info
->stream
, "0x%x",
805 (unsigned int) ((l
>> OP_SH_PREFX
)
810 (*info
->fprintf_func
) (info
->stream
, "0x%x",
811 (unsigned int) ((l
>> OP_SH_CACHE
)
816 info
->target
= (((pc
+ 4) & ~(bfd_vma
) 0x0fffffff)
817 | (((l
>> OP_SH_TARGET
) & OP_MASK_TARGET
) << 2));
818 (*info
->print_address_func
) (info
->target
, info
);
822 /* Sign extend the displacement. */
823 delta
= (l
>> OP_SH_DELTA
) & OP_MASK_DELTA
;
826 info
->target
= (delta
<< 2) + pc
+ INSNLEN
;
827 (*info
->print_address_func
) (info
->target
, info
);
831 (*info
->fprintf_func
) (info
->stream
, "%s",
832 mips_gpr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
837 /* First check for both rd and rt being equal. */
838 unsigned int reg
= (l
>> OP_SH_RD
) & OP_MASK_RD
;
839 if (reg
== ((l
>> OP_SH_RT
) & OP_MASK_RT
))
840 (*info
->fprintf_func
) (info
->stream
, "%s",
841 mips_gpr_names
[reg
]);
844 /* If one is zero use the other. */
846 (*info
->fprintf_func
) (info
->stream
, "%s",
847 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
848 else if (((l
>> OP_SH_RT
) & OP_MASK_RT
) == 0)
849 (*info
->fprintf_func
) (info
->stream
, "%s",
850 mips_gpr_names
[reg
]);
851 else /* Bogus, result depends on processor. */
852 (*info
->fprintf_func
) (info
->stream
, "%s or %s",
854 mips_gpr_names
[(l
>> OP_SH_RT
) & OP_MASK_RT
]);
860 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
864 (*info
->fprintf_func
) (info
->stream
, "0x%x",
865 (l
>> OP_SH_SHAMT
) & OP_MASK_SHAMT
);
869 (*info
->fprintf_func
) (info
->stream
, "0x%x",
870 (l
>> OP_SH_CODE
) & OP_MASK_CODE
);
874 (*info
->fprintf_func
) (info
->stream
, "0x%x",
875 (l
>> OP_SH_CODE2
) & OP_MASK_CODE2
);
879 (*info
->fprintf_func
) (info
->stream
, "0x%x",
880 (l
>> OP_SH_COPZ
) & OP_MASK_COPZ
);
884 (*info
->fprintf_func
) (info
->stream
, "0x%x",
885 (l
>> OP_SH_CODE20
) & OP_MASK_CODE20
);
889 (*info
->fprintf_func
) (info
->stream
, "0x%x",
890 (l
>> OP_SH_CODE19
) & OP_MASK_CODE19
);
895 (*info
->fprintf_func
) (info
->stream
, "%s",
896 mips_fpr_names
[(l
>> OP_SH_FS
) & OP_MASK_FS
]);
901 (*info
->fprintf_func
) (info
->stream
, "%s",
902 mips_fpr_names
[(l
>> OP_SH_FT
) & OP_MASK_FT
]);
906 (*info
->fprintf_func
) (info
->stream
, "%s",
907 mips_fpr_names
[(l
>> OP_SH_FD
) & OP_MASK_FD
]);
911 (*info
->fprintf_func
) (info
->stream
, "%s",
912 mips_fpr_names
[(l
>> OP_SH_FR
) & OP_MASK_FR
]);
916 /* Coprocessor register for lwcN instructions, et al.
918 Note that there is no load/store cp0 instructions, and
919 that FPU (cp1) instructions disassemble this field using
920 'T' format. Therefore, until we gain understanding of
921 cp2 register names, we can simply print the register
923 (*info
->fprintf_func
) (info
->stream
, "$%d",
924 (l
>> OP_SH_RT
) & OP_MASK_RT
);
928 /* Coprocessor register for mtcN instructions, et al. Note
929 that FPU (cp1) instructions disassemble this field using
930 'S' format. Therefore, we only need to worry about cp0,
932 op
= (l
>> OP_SH_OP
) & OP_MASK_OP
;
933 if (op
== OP_OP_COP0
)
934 (*info
->fprintf_func
) (info
->stream
, "%s",
935 mips_cp0_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
937 (*info
->fprintf_func
) (info
->stream
, "$%d",
938 (l
>> OP_SH_RD
) & OP_MASK_RD
);
942 (*info
->fprintf_func
) (info
->stream
, "%s",
943 mips_hwr_names
[(l
>> OP_SH_RD
) & OP_MASK_RD
]);
947 (*info
->fprintf_func
) (info
->stream
, "$fcc%d",
948 (l
>> OP_SH_BCC
) & OP_MASK_BCC
);
952 (*info
->fprintf_func
) (info
->stream
, "$fcc%d",
953 (l
>> OP_SH_CCC
) & OP_MASK_CCC
);
957 (*info
->fprintf_func
) (info
->stream
, "%d",
958 (l
>> OP_SH_PERFREG
) & OP_MASK_PERFREG
);
962 (*info
->fprintf_func
) (info
->stream
, "%d",
963 (l
>> OP_SH_VECBYTE
) & OP_MASK_VECBYTE
);
967 (*info
->fprintf_func
) (info
->stream
, "%d",
968 (l
>> OP_SH_VECALIGN
) & OP_MASK_VECALIGN
);
972 (*info
->fprintf_func
) (info
->stream
, "%d",
973 (l
>> OP_SH_SEL
) & OP_MASK_SEL
);
977 (*info
->fprintf_func
) (info
->stream
, "%d",
978 (l
>> OP_SH_ALN
) & OP_MASK_ALN
);
983 unsigned int vsel
= (l
>> OP_SH_VSEL
) & OP_MASK_VSEL
;
984 if ((vsel
& 0x10) == 0)
988 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
991 (*info
->fprintf_func
) (info
->stream
, "$v%d[%d]",
992 (l
>> OP_SH_FT
) & OP_MASK_FT
,
995 else if ((vsel
& 0x08) == 0)
997 (*info
->fprintf_func
) (info
->stream
, "$v%d",
998 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1002 (*info
->fprintf_func
) (info
->stream
, "0x%x",
1003 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1009 (*info
->fprintf_func
) (info
->stream
, "$v%d",
1010 (l
>> OP_SH_FD
) & OP_MASK_FD
);
1014 (*info
->fprintf_func
) (info
->stream
, "$v%d",
1015 (l
>> OP_SH_FS
) & OP_MASK_FS
);
1019 (*info
->fprintf_func
) (info
->stream
, "$v%d",
1020 (l
>> OP_SH_FT
) & OP_MASK_FT
);
1024 /* xgettext:c-format */
1025 (*info
->fprintf_func
) (info
->stream
,
1026 _("# internal error, undefined modifier(%c)"),
1033 /* Check if the object uses NewABI conventions. */
1037 Elf_Internal_Ehdr
*header
;
1039 /* There are no old-style ABIs which use 64-bit ELF. */
1040 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
1043 /* If a 32-bit ELF file, n32 is a new-style ABI. */
1044 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
1050 /* Print the mips instruction at address MEMADDR in debugged memory,
1051 on using INFO. Returns length of the instruction, in bytes, which is
1052 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1053 this is little-endian code. */
1056 print_insn_mips (memaddr
, word
, info
)
1058 unsigned long int word
;
1059 struct disassemble_info
*info
;
1061 register const struct mips_opcode
*op
;
1062 static bfd_boolean init
= 0;
1063 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1065 /* Build a hash table to shorten the search time. */
1070 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1072 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1074 if (op
->pinfo
== INSN_MACRO
)
1076 if (i
== ((op
->match
>> OP_SH_OP
) & OP_MASK_OP
))
1087 info
->bytes_per_chunk
= INSNLEN
;
1088 info
->display_endian
= info
->endian
;
1089 info
->insn_info_valid
= 1;
1090 info
->branch_delay_insns
= 0;
1091 info
->data_size
= 0;
1092 info
->insn_type
= dis_nonbranch
;
1096 op
= mips_hash
[(word
>> OP_SH_OP
) & OP_MASK_OP
];
1099 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1101 if (op
->pinfo
!= INSN_MACRO
&& (word
& op
->mask
) == op
->match
)
1103 register const char *d
;
1105 /* We always allow to disassemble the jalx instruction. */
1106 if (! OPCODE_IS_MEMBER (op
, mips_isa
, mips_processor
)
1107 && strcmp (op
->name
, "jalx"))
1110 /* Figure out instruction type and branch delay information. */
1111 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1113 if ((info
->insn_type
& INSN_WRITE_GPR_31
) != 0)
1114 info
->insn_type
= dis_jsr
;
1116 info
->insn_type
= dis_branch
;
1117 info
->branch_delay_insns
= 1;
1119 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1120 | INSN_COND_BRANCH_LIKELY
)) != 0)
1122 if ((info
->insn_type
& INSN_WRITE_GPR_31
) != 0)
1123 info
->insn_type
= dis_condjsr
;
1125 info
->insn_type
= dis_condbranch
;
1126 info
->branch_delay_insns
= 1;
1128 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1129 | INSN_LOAD_MEMORY_DELAY
)) != 0)
1130 info
->insn_type
= dis_dref
;
1132 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
1135 if (d
!= NULL
&& *d
!= '\0')
1137 (*info
->fprintf_func
) (info
->stream
, "\t");
1138 print_insn_args (d
, word
, memaddr
, info
);
1146 /* Handle undefined instructions. */
1147 info
->insn_type
= dis_noninsn
;
1148 (*info
->fprintf_func
) (info
->stream
, "0x%x", word
);
1152 /* In an environment where we do not know the symbol type of the
1153 instruction we are forced to assume that the low order bit of the
1154 instructions' address may mark it as a mips16 instruction. If we
1155 are single stepping, or the pc is within the disassembled function,
1156 this works. Otherwise, we need a clue. Sometimes. */
1159 _print_insn_mips (memaddr
, info
, endianness
)
1161 struct disassemble_info
*info
;
1162 enum bfd_endian endianness
;
1164 bfd_byte buffer
[INSNLEN
];
1167 set_default_mips_dis_options (info
);
1168 parse_mips_dis_options (info
->disassembler_options
);
1171 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
1172 /* Only a few tools will work this way. */
1174 return print_insn_mips16 (memaddr
, info
);
1177 #if SYMTAB_AVAILABLE
1178 if (info
->mach
== bfd_mach_mips16
1179 || (info
->flavour
== bfd_target_elf_flavour
1180 && info
->symbols
!= NULL
1181 && ((*(elf_symbol_type
**) info
->symbols
)->internal_elf_sym
.st_other
1183 return print_insn_mips16 (memaddr
, info
);
1186 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
1191 if (endianness
== BFD_ENDIAN_BIG
)
1192 insn
= (unsigned long) bfd_getb32 (buffer
);
1194 insn
= (unsigned long) bfd_getl32 (buffer
);
1196 return print_insn_mips (memaddr
, insn
, info
);
1200 (*info
->memory_error_func
) (status
, memaddr
, info
);
1206 print_insn_big_mips (memaddr
, info
)
1208 struct disassemble_info
*info
;
1210 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
1214 print_insn_little_mips (memaddr
, info
)
1216 struct disassemble_info
*info
;
1218 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
1221 /* Disassemble mips16 instructions. */
1224 print_insn_mips16 (memaddr
, info
)
1226 struct disassemble_info
*info
;
1232 bfd_boolean use_extend
;
1234 const struct mips_opcode
*op
, *opend
;
1236 info
->bytes_per_chunk
= 2;
1237 info
->display_endian
= info
->endian
;
1238 info
->insn_info_valid
= 1;
1239 info
->branch_delay_insns
= 0;
1240 info
->data_size
= 0;
1241 info
->insn_type
= dis_nonbranch
;
1245 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1248 (*info
->memory_error_func
) (status
, memaddr
, info
);
1254 if (info
->endian
== BFD_ENDIAN_BIG
)
1255 insn
= bfd_getb16 (buffer
);
1257 insn
= bfd_getl16 (buffer
);
1259 /* Handle the extend opcode specially. */
1261 if ((insn
& 0xf800) == 0xf000)
1264 extend
= insn
& 0x7ff;
1268 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1271 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
1272 (unsigned int) extend
);
1273 (*info
->memory_error_func
) (status
, memaddr
, info
);
1277 if (info
->endian
== BFD_ENDIAN_BIG
)
1278 insn
= bfd_getb16 (buffer
);
1280 insn
= bfd_getl16 (buffer
);
1282 /* Check for an extend opcode followed by an extend opcode. */
1283 if ((insn
& 0xf800) == 0xf000)
1285 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
1286 (unsigned int) extend
);
1287 info
->insn_type
= dis_noninsn
;
1294 /* FIXME: Should probably use a hash table on the major opcode here. */
1296 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
1297 for (op
= mips16_opcodes
; op
< opend
; op
++)
1299 if (op
->pinfo
!= INSN_MACRO
&& (insn
& op
->mask
) == op
->match
)
1303 if (strchr (op
->args
, 'a') != NULL
)
1307 (*info
->fprintf_func
) (info
->stream
, "extend 0x%x",
1308 (unsigned int) extend
);
1309 info
->insn_type
= dis_noninsn
;
1317 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
1322 if (info
->endian
== BFD_ENDIAN_BIG
)
1323 extend
= bfd_getb16 (buffer
);
1325 extend
= bfd_getl16 (buffer
);
1330 (*info
->fprintf_func
) (info
->stream
, "%s", op
->name
);
1331 if (op
->args
[0] != '\0')
1332 (*info
->fprintf_func
) (info
->stream
, "\t");
1334 for (s
= op
->args
; *s
!= '\0'; s
++)
1338 && (((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)
1339 == ((insn
>> MIPS16OP_SH_RY
) & MIPS16OP_MASK_RY
)))
1341 /* Skip the register and the comma. */
1347 && (((insn
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
)
1348 == ((insn
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
)))
1350 /* Skip the register and the comma. */
1354 print_mips16_insn_arg (*s
, op
, insn
, use_extend
, extend
, memaddr
,
1358 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1360 info
->branch_delay_insns
= 1;
1361 if (info
->insn_type
!= dis_jsr
)
1362 info
->insn_type
= dis_branch
;
1370 (*info
->fprintf_func
) (info
->stream
, "0x%x", extend
| 0xf000);
1371 (*info
->fprintf_func
) (info
->stream
, "0x%x", insn
);
1372 info
->insn_type
= dis_noninsn
;
1377 /* Disassemble an operand for a mips16 instruction. */
1380 print_mips16_insn_arg (type
, op
, l
, use_extend
, extend
, memaddr
, info
)
1382 const struct mips_opcode
*op
;
1384 bfd_boolean use_extend
;
1387 struct disassemble_info
*info
;
1394 (*info
->fprintf_func
) (info
->stream
, "%c", type
);
1399 (*info
->fprintf_func
) (info
->stream
, "%s",
1400 mips16_reg_names
[((l
>> MIPS16OP_SH_RY
)
1401 & MIPS16OP_MASK_RY
)]);
1406 (*info
->fprintf_func
) (info
->stream
, "%s",
1407 mips16_reg_names
[((l
>> MIPS16OP_SH_RX
)
1408 & MIPS16OP_MASK_RX
)]);
1412 (*info
->fprintf_func
) (info
->stream
, "%s",
1413 mips16_reg_names
[((l
>> MIPS16OP_SH_RZ
)
1414 & MIPS16OP_MASK_RZ
)]);
1418 (*info
->fprintf_func
) (info
->stream
, "%s",
1419 mips16_reg_names
[((l
>> MIPS16OP_SH_MOVE32Z
)
1420 & MIPS16OP_MASK_MOVE32Z
)]);
1424 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[0]);
1428 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[29]);
1432 (*info
->fprintf_func
) (info
->stream
, "$pc");
1436 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[31]);
1440 (*info
->fprintf_func
) (info
->stream
, "%s",
1441 mips_gpr_names
[((l
>> MIPS16OP_SH_REGR32
)
1442 & MIPS16OP_MASK_REGR32
)]);
1446 (*info
->fprintf_func
) (info
->stream
, "%s",
1447 mips_gpr_names
[MIPS16OP_EXTRACT_REG32R (l
)]);
1473 int immed
, nbits
, shift
, signedp
, extbits
, pcrel
, extu
, branch
;
1485 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1491 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1497 immed
= (l
>> MIPS16OP_SH_RZ
) & MIPS16OP_MASK_RZ
;
1503 immed
= (l
>> MIPS16OP_SH_RX
) & MIPS16OP_MASK_RX
;
1509 immed
= (l
>> MIPS16OP_SH_IMM4
) & MIPS16OP_MASK_IMM4
;
1515 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1516 info
->insn_type
= dis_dref
;
1517 info
->data_size
= 1;
1522 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1523 info
->insn_type
= dis_dref
;
1524 info
->data_size
= 2;
1529 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1530 if ((op
->pinfo
& MIPS16_INSN_READ_PC
) == 0
1531 && (op
->pinfo
& MIPS16_INSN_READ_SP
) == 0)
1533 info
->insn_type
= dis_dref
;
1534 info
->data_size
= 4;
1540 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1541 info
->insn_type
= dis_dref
;
1542 info
->data_size
= 8;
1546 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1551 immed
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1555 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1560 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1561 /* FIXME: This might be lw, or it might be addiu to $sp or
1562 $pc. We assume it's load. */
1563 info
->insn_type
= dis_dref
;
1564 info
->data_size
= 4;
1569 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1570 info
->insn_type
= dis_dref
;
1571 info
->data_size
= 8;
1575 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1580 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1586 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1591 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1595 info
->insn_type
= dis_condbranch
;
1599 immed
= (l
>> MIPS16OP_SH_IMM11
) & MIPS16OP_MASK_IMM11
;
1603 info
->insn_type
= dis_branch
;
1608 immed
= (l
>> MIPS16OP_SH_IMM8
) & MIPS16OP_MASK_IMM8
;
1610 /* FIXME: This can be lw or la. We assume it is lw. */
1611 info
->insn_type
= dis_dref
;
1612 info
->data_size
= 4;
1617 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1619 info
->insn_type
= dis_dref
;
1620 info
->data_size
= 8;
1625 immed
= (l
>> MIPS16OP_SH_IMM5
) & MIPS16OP_MASK_IMM5
;
1634 if (signedp
&& immed
>= (1 << (nbits
- 1)))
1635 immed
-= 1 << nbits
;
1637 if ((type
== '<' || type
== '>' || type
== '[' || type
== ']')
1644 immed
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1645 else if (extbits
== 15)
1646 immed
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1648 immed
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1649 immed
&= (1 << extbits
) - 1;
1650 if (! extu
&& immed
>= (1 << (extbits
- 1)))
1651 immed
-= 1 << extbits
;
1655 (*info
->fprintf_func
) (info
->stream
, "%d", immed
);
1663 baseaddr
= memaddr
+ 2;
1665 else if (use_extend
)
1666 baseaddr
= memaddr
- 2;
1674 /* If this instruction is in the delay slot of a jr
1675 instruction, the base address is the address of the
1676 jr instruction. If it is in the delay slot of jalr
1677 instruction, the base address is the address of the
1678 jalr instruction. This test is unreliable: we have
1679 no way of knowing whether the previous word is
1680 instruction or data. */
1681 status
= (*info
->read_memory_func
) (memaddr
- 4, buffer
, 2,
1684 && (((info
->endian
== BFD_ENDIAN_BIG
1685 ? bfd_getb16 (buffer
)
1686 : bfd_getl16 (buffer
))
1687 & 0xf800) == 0x1800))
1688 baseaddr
= memaddr
- 4;
1691 status
= (*info
->read_memory_func
) (memaddr
- 2, buffer
,
1694 && (((info
->endian
== BFD_ENDIAN_BIG
1695 ? bfd_getb16 (buffer
)
1696 : bfd_getl16 (buffer
))
1697 & 0xf81f) == 0xe800))
1698 baseaddr
= memaddr
- 2;
1701 info
->target
= (baseaddr
& ~((1 << shift
) - 1)) + immed
;
1702 (*info
->print_address_func
) (info
->target
, info
);
1710 l
= ((l
& 0x1f) << 23) | ((l
& 0x3e0) << 13) | (extend
<< 2);
1711 info
->target
= ((memaddr
+ 4) & ~(bfd_vma
) 0x0fffffff) | l
;
1712 (*info
->print_address_func
) (info
->target
, info
);
1713 info
->insn_type
= dis_jsr
;
1714 info
->branch_delay_insns
= 1;
1720 int need_comma
, amask
, smask
;
1724 l
= (l
>> MIPS16OP_SH_IMM6
) & MIPS16OP_MASK_IMM6
;
1726 amask
= (l
>> 3) & 7;
1728 if (amask
> 0 && amask
< 5)
1730 (*info
->fprintf_func
) (info
->stream
, "%s", mips_gpr_names
[4]);
1732 (*info
->fprintf_func
) (info
->stream
, "-%s",
1733 mips_gpr_names
[amask
+ 3]);
1737 smask
= (l
>> 1) & 3;
1740 (*info
->fprintf_func
) (info
->stream
, "%s??",
1741 need_comma
? "," : "");
1746 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1747 need_comma
? "," : "",
1748 mips_gpr_names
[16]);
1750 (*info
->fprintf_func
) (info
->stream
, "-%s",
1751 mips_gpr_names
[smask
+ 15]);
1757 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1758 need_comma
? "," : "",
1759 mips_gpr_names
[31]);
1763 if (amask
== 5 || amask
== 6)
1765 (*info
->fprintf_func
) (info
->stream
, "%s$f0",
1766 need_comma
? "," : "");
1768 (*info
->fprintf_func
) (info
->stream
, "-$f1");
1774 /* xgettext:c-format */
1775 (*info
->fprintf_func
)
1777 _("# internal disassembler error, unrecognised modifier (%c)"),
1784 print_mips_disassembler_options (stream
)
1789 fprintf (stream
, _("\n\
1790 The following MIPS specific disassembler options are supported for use\n\
1791 with the -M switch (multiple options should be separated by commas):\n"));
1793 fprintf (stream
, _("\n\
1794 gpr-names=ABI Print GPR names according to specified ABI.\n\
1795 Default: based on binary being disassembled.\n"));
1797 fprintf (stream
, _("\n\
1798 fpr-names=ABI Print FPR names according to specified ABI.\n\
1799 Default: numeric.\n"));
1801 fprintf (stream
, _("\n\
1802 cp0-names=ARCH Print CP0 register names according to\n\
1803 specified architecture.\n\
1804 Default: based on binary being disassembled.\n"));
1806 fprintf (stream
, _("\n\
1807 hwr-names=ARCH Print HWR names according to specified \n\
1809 Default: based on binary being disassembled.\n"));
1811 fprintf (stream
, _("\n\
1812 reg-names=ABI Print GPR and FPR names according to\n\
1813 specified ABI.\n"));
1815 fprintf (stream
, _("\n\
1816 reg-names=ARCH Print CP0 register and HWR names according to\n\
1817 specified architecture.\n"));
1819 fprintf (stream
, _("\n\
1820 For the options above, the following values are supported for \"ABI\":\n\
1822 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
1823 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
1824 fprintf (stream
, _("\n"));
1826 fprintf (stream
, _("\n\
1827 For the options above, The following values are supported for \"ARCH\":\n\
1829 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
1830 if (*mips_arch_choices
[i
].name
!= '\0')
1831 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
1832 fprintf (stream
, _("\n"));
1834 fprintf (stream
, _("\n"));