source: vendor/binutils/current/opcodes/mips-dis.c

Last change on this file was 609, checked in by bird, 22 years ago

binutils v2.14 - offical sources.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 50.2 KB
Line 
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
4 Free Software Foundation, Inc.
5 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
6
7This file is part of GDB, GAS, and the GNU binutils.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23#include "sysdep.h"
24#include "dis-asm.h"
25#include "libiberty.h"
26#include "opcode/mips.h"
27#include "opintl.h"
28
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. */
33
34#if !defined(EMBEDDED_ENV)
35#define SYMTAB_AVAILABLE 1
36#include "elf-bfd.h"
37#include "elf/mips.h"
38#endif
39
40/* Mips instructions are at maximum this many bytes long. */
41#define INSNLEN 4
42
43static void set_default_mips_dis_options
44 PARAMS ((struct disassemble_info *));
45static void parse_mips_dis_option
46 PARAMS ((const char *, unsigned int));
47static void parse_mips_dis_options
48 PARAMS ((const char *));
49static int _print_insn_mips
50 PARAMS ((bfd_vma, struct disassemble_info *, enum bfd_endian));
51static int print_insn_mips
52 PARAMS ((bfd_vma, unsigned long int, struct disassemble_info *));
53static void print_insn_args
54 PARAMS ((const char *, unsigned long, bfd_vma, struct disassemble_info *));
55static int print_insn_mips16
56 PARAMS ((bfd_vma, struct disassemble_info *));
57static int is_newabi
58 PARAMS ((Elf_Internal_Ehdr *));
59static void print_mips16_insn_arg
60 PARAMS ((int, const struct mips_opcode *, int, bfd_boolean, int, bfd_vma,
61 struct disassemble_info *));
62
63
64/* FIXME: These should be shared with gdb somehow. */
65
66struct mips_cp0sel_name {
67 unsigned int cp0reg;
68 unsigned int sel;
69 const char * const name;
70};
71
72/* The mips16 register names. */
73static const char * const mips16_reg_names[] = {
74 "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
75};
76
77static const char * const mips_gpr_names_numeric[32] = {
78 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
79 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
80 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
81 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
82};
83
84static const char * const mips_gpr_names_oldabi[32] = {
85 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
86 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
87 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
88 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
89};
90
91static const char * const mips_gpr_names_newabi[32] = {
92 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
93 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
94 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
95 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
96};
97
98static const char * const mips_fpr_names_numeric[32] = {
99 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
100 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
101 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
102 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
103};
104
105static const char * const mips_fpr_names_32[32] = {
106 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
107 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
108 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
109 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
110};
111
112static const char * const mips_fpr_names_n32[32] = {
113 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
114 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
115 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
116 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
117};
118
119static const char * const mips_fpr_names_64[32] = {
120 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
121 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
122 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
123 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
124};
125
126static const char * const mips_cp0_names_numeric[32] = {
127 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
128 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
129 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
130 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
131};
132
133static const char * const mips_cp0_names_mips3264[32] = {
134 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
135 "c0_context", "c0_pagemask", "c0_wired", "$7",
136 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
137 "c0_status", "c0_cause", "c0_epc", "c0_prid",
138 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
139 "c0_xcontext", "$21", "$22", "c0_debug",
140 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
141 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
142};
143
144static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] = {
145 { 16, 1, "c0_config1" },
146 { 16, 2, "c0_config2" },
147 { 16, 3, "c0_config3" },
148 { 18, 1, "c0_watchlo,1" },
149 { 18, 2, "c0_watchlo,2" },
150 { 18, 3, "c0_watchlo,3" },
151 { 18, 4, "c0_watchlo,4" },
152 { 18, 5, "c0_watchlo,5" },
153 { 18, 6, "c0_watchlo,6" },
154 { 18, 7, "c0_watchlo,7" },
155 { 19, 1, "c0_watchhi,1" },
156 { 19, 2, "c0_watchhi,2" },
157 { 19, 3, "c0_watchhi,3" },
158 { 19, 4, "c0_watchhi,4" },
159 { 19, 5, "c0_watchhi,5" },
160 { 19, 6, "c0_watchhi,6" },
161 { 19, 7, "c0_watchhi,7" },
162 { 25, 1, "c0_perfcnt,1" },
163 { 25, 2, "c0_perfcnt,2" },
164 { 25, 3, "c0_perfcnt,3" },
165 { 25, 4, "c0_perfcnt,4" },
166 { 25, 5, "c0_perfcnt,5" },
167 { 25, 6, "c0_perfcnt,6" },
168 { 25, 7, "c0_perfcnt,7" },
169 { 27, 1, "c0_cacheerr,1" },
170 { 27, 2, "c0_cacheerr,2" },
171 { 27, 3, "c0_cacheerr,3" },
172 { 28, 1, "c0_datalo" },
173 { 29, 1, "c0_datahi" }
174};
175
176static const char * const mips_cp0_names_mips3264r2[32] = {
177 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
178 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
179 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
180 "c0_status", "c0_cause", "c0_epc", "c0_prid",
181 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
182 "c0_xcontext", "$21", "$22", "c0_debug",
183 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
184 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
185};
186
187static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] = {
188 { 4, 1, "c0_contextconfig" },
189 { 5, 1, "c0_pagegrain" },
190 { 12, 1, "c0_intctl" },
191 { 12, 2, "c0_srsctl" },
192 { 12, 3, "c0_srsmap" },
193 { 15, 1, "c0_ebase" },
194 { 16, 1, "c0_config1" },
195 { 16, 2, "c0_config2" },
196 { 16, 3, "c0_config3" },
197 { 18, 1, "c0_watchlo,1" },
198 { 18, 2, "c0_watchlo,2" },
199 { 18, 3, "c0_watchlo,3" },
200 { 18, 4, "c0_watchlo,4" },
201 { 18, 5, "c0_watchlo,5" },
202 { 18, 6, "c0_watchlo,6" },
203 { 18, 7, "c0_watchlo,7" },
204 { 19, 1, "c0_watchhi,1" },
205 { 19, 2, "c0_watchhi,2" },
206 { 19, 3, "c0_watchhi,3" },
207 { 19, 4, "c0_watchhi,4" },
208 { 19, 5, "c0_watchhi,5" },
209 { 19, 6, "c0_watchhi,6" },
210 { 19, 7, "c0_watchhi,7" },
211 { 23, 1, "c0_tracecontrol" },
212 { 23, 2, "c0_tracecontrol2" },
213 { 23, 3, "c0_usertracedata" },
214 { 23, 4, "c0_tracebpc" },
215 { 25, 1, "c0_perfcnt,1" },
216 { 25, 2, "c0_perfcnt,2" },
217 { 25, 3, "c0_perfcnt,3" },
218 { 25, 4, "c0_perfcnt,4" },
219 { 25, 5, "c0_perfcnt,5" },
220 { 25, 6, "c0_perfcnt,6" },
221 { 25, 7, "c0_perfcnt,7" },
222 { 27, 1, "c0_cacheerr,1" },
223 { 27, 2, "c0_cacheerr,2" },
224 { 27, 3, "c0_cacheerr,3" },
225 { 28, 1, "c0_datalo" },
226 { 28, 2, "c0_taglo1" },
227 { 28, 3, "c0_datalo1" },
228 { 28, 4, "c0_taglo2" },
229 { 28, 5, "c0_datalo2" },
230 { 28, 6, "c0_taglo3" },
231 { 28, 7, "c0_datalo3" },
232 { 29, 1, "c0_datahi" },
233 { 29, 2, "c0_taghi1" },
234 { 29, 3, "c0_datahi1" },
235 { 29, 4, "c0_taghi2" },
236 { 29, 5, "c0_datahi2" },
237 { 29, 6, "c0_taghi3" },
238 { 29, 7, "c0_datahi3" },
239};
240
241/* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
242static const char * const mips_cp0_names_sb1[32] = {
243 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
244 "c0_context", "c0_pagemask", "c0_wired", "$7",
245 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
246 "c0_status", "c0_cause", "c0_epc", "c0_prid",
247 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
248 "c0_xcontext", "$21", "$22", "c0_debug",
249 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
250 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
251};
252
253static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] = {
254 { 16, 1, "c0_config1" },
255 { 18, 1, "c0_watchlo,1" },
256 { 19, 1, "c0_watchhi,1" },
257 { 22, 0, "c0_perftrace" },
258 { 23, 3, "c0_edebug" },
259 { 25, 1, "c0_perfcnt,1" },
260 { 25, 2, "c0_perfcnt,2" },
261 { 25, 3, "c0_perfcnt,3" },
262 { 25, 4, "c0_perfcnt,4" },
263 { 25, 5, "c0_perfcnt,5" },
264 { 25, 6, "c0_perfcnt,6" },
265 { 25, 7, "c0_perfcnt,7" },
266 { 26, 1, "c0_buserr_pa" },
267 { 27, 1, "c0_cacheerr_d" },
268 { 27, 3, "c0_cacheerr_d_pa" },
269 { 28, 1, "c0_datalo_i" },
270 { 28, 2, "c0_taglo_d" },
271 { 28, 3, "c0_datalo_d" },
272 { 29, 1, "c0_datahi_i" },
273 { 29, 2, "c0_taghi_d" },
274 { 29, 3, "c0_datahi_d" },
275};
276
277static const char * const mips_hwr_names_numeric[32] = {
278 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
279 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
280 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
281 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
282};
283
284static const char * const mips_hwr_names_mips3264r2[32] = {
285 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
286 "$4", "$5", "$6", "$7",
287 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
288 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
289 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
290};
291
292struct mips_abi_choice {
293 const char *name;
294 const char * const *gpr_names;
295 const char * const *fpr_names;
296};
297
298struct mips_abi_choice mips_abi_choices[] = {
299 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
300 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
301 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
302 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
303};
304
305struct mips_arch_choice {
306 const char *name;
307 int bfd_mach_valid;
308 unsigned long bfd_mach;
309 int processor;
310 int isa;
311 const char * const *cp0_names;
312 const struct mips_cp0sel_name *cp0sel_names;
313 unsigned int cp0sel_names_len;
314 const char * const *hwr_names;
315};
316
317const struct mips_arch_choice mips_arch_choices[] = {
318 { "numeric", 0, 0, 0, 0,
319 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
320
321 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1,
322 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
323 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1,
324 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
325 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3,
326 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
327 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2,
328 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
329 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3,
330 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
331 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3,
332 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
333 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3,
334 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
335 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3,
336 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
337 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3,
338 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
339 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3,
340 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
341 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3,
342 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
343 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4,
344 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
345 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4,
346 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
347 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4,
348 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
349 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2,
350 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
351 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4,
352 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
353 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4,
354 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
355 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4,
356 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
357 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5,
358 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
359
360 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
361 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
362 _MIPS32 Architecture For Programmers Volume I: Introduction to the
363 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
364 page 1. */
365 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
366 ISA_MIPS32 | INSN_MIPS16,
367 mips_cp0_names_mips3264,
368 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
369 mips_hwr_names_numeric },
370
371 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
372 ISA_MIPS32R2 | INSN_MIPS16,
373 mips_cp0_names_mips3264r2,
374 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
375 mips_hwr_names_mips3264r2 },
376
377 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
378 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
379 ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX,
380 mips_cp0_names_mips3264,
381 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
382 mips_hwr_names_numeric },
383
384 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
385 ISA_MIPS64 | INSN_MIPS3D | INSN_SB1,
386 mips_cp0_names_sb1,
387 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
388 mips_hwr_names_numeric },
389
390 /* This entry, mips16, is here only for ISA/processor selection; do
391 not print its name. */
392 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3 | INSN_MIPS16,
393 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
394};
395
396/* ISA and processor type to disassemble for, and register names to use.
397 set_default_mips_dis_options and parse_mips_dis_options fill in these
398 values. */
399static int mips_processor;
400static int mips_isa;
401static const char * const *mips_gpr_names;
402static const char * const *mips_fpr_names;
403static const char * const *mips_cp0_names;
404static const struct mips_cp0sel_name *mips_cp0sel_names;
405static int mips_cp0sel_names_len;
406static const char * const *mips_hwr_names;
407
408static const struct mips_abi_choice *choose_abi_by_name
409 PARAMS ((const char *, unsigned int));
410static const struct mips_arch_choice *choose_arch_by_name
411 PARAMS ((const char *, unsigned int));
412static const struct mips_arch_choice *choose_arch_by_number
413 PARAMS ((unsigned long));
414static const struct mips_cp0sel_name *lookup_mips_cp0sel_name
415 PARAMS ((const struct mips_cp0sel_name *, unsigned int, unsigned int,
416 unsigned int));
417
418
419static const struct mips_abi_choice *
420choose_abi_by_name (name, namelen)
421 const char *name;
422 unsigned int namelen;
423{
424 const struct mips_abi_choice *c;
425 unsigned int i;
426
427 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
428 {
429 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
430 && strlen (mips_abi_choices[i].name) == namelen)
431 c = &mips_abi_choices[i];
432 }
433 return c;
434}
435
436static const struct mips_arch_choice *
437choose_arch_by_name (name, namelen)
438 const char *name;
439 unsigned int namelen;
440{
441 const struct mips_arch_choice *c = NULL;
442 unsigned int i;
443
444 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
445 {
446 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
447 && strlen (mips_arch_choices[i].name) == namelen)
448 c = &mips_arch_choices[i];
449 }
450 return c;
451}
452
453static const struct mips_arch_choice *
454choose_arch_by_number (mach)
455 unsigned long mach;
456{
457 static unsigned long hint_bfd_mach;
458 static const struct mips_arch_choice *hint_arch_choice;
459 const struct mips_arch_choice *c;
460 unsigned int i;
461
462 /* We optimize this because even if the user specifies no
463 flags, this will be done for every instruction! */
464 if (hint_bfd_mach == mach
465 && hint_arch_choice != NULL
466 && hint_arch_choice->bfd_mach == hint_bfd_mach)
467 return hint_arch_choice;
468
469 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
470 {
471 if (mips_arch_choices[i].bfd_mach_valid
472 && mips_arch_choices[i].bfd_mach == mach)
473 {
474 c = &mips_arch_choices[i];
475 hint_bfd_mach = mach;
476 hint_arch_choice = c;
477 }
478 }
479 return c;
480}
481
482void
483set_default_mips_dis_options (info)
484 struct disassemble_info *info;
485{
486 const struct mips_arch_choice *chosen_arch;
487
488 /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names,
489 and numeric FPR, CP0 register, and HWR names. */
490 mips_isa = ISA_MIPS3;
491 mips_processor = CPU_R3000;
492 mips_gpr_names = mips_gpr_names_oldabi;
493 mips_fpr_names = mips_fpr_names_numeric;
494 mips_cp0_names = mips_cp0_names_numeric;
495 mips_cp0sel_names = NULL;
496 mips_cp0sel_names_len = 0;
497 mips_hwr_names = mips_hwr_names_numeric;
498
499 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
500 if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
501 {
502 Elf_Internal_Ehdr *header;
503
504 header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
505 if (is_newabi (header))
506 mips_gpr_names = mips_gpr_names_newabi;
507 }
508
509 /* Set ISA, architecture, and cp0 register names as best we can. */
510#if ! SYMTAB_AVAILABLE
511 /* This is running out on a target machine, not in a host tool.
512 FIXME: Where does mips_target_info come from? */
513 target_processor = mips_target_info.processor;
514 mips_isa = mips_target_info.isa;
515#else
516 chosen_arch = choose_arch_by_number (info->mach);
517 if (chosen_arch != NULL)
518 {
519 mips_processor = chosen_arch->processor;
520 mips_isa = chosen_arch->isa;
521 mips_cp0_names = chosen_arch->cp0_names;
522 mips_cp0sel_names = chosen_arch->cp0sel_names;
523 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
524 mips_hwr_names = chosen_arch->hwr_names;
525 }
526#endif
527}
528
529void
530parse_mips_dis_option (option, len)
531 const char *option;
532 unsigned int len;
533{
534 unsigned int i, optionlen, vallen;
535 const char *val;
536 const struct mips_abi_choice *chosen_abi;
537 const struct mips_arch_choice *chosen_arch;
538
539 /* Look for the = that delimits the end of the option name. */
540 for (i = 0; i < len; i++)
541 {
542 if (option[i] == '=')
543 break;
544 }
545 if (i == 0) /* Invalid option: no name before '='. */
546 return;
547 if (i == len) /* Invalid option: no '='. */
548 return;
549 if (i == (len - 1)) /* Invalid option: no value after '='. */
550 return;
551
552 optionlen = i;
553 val = option + (optionlen + 1);
554 vallen = len - (optionlen + 1);
555
556 if (strncmp("gpr-names", option, optionlen) == 0
557 && strlen("gpr-names") == optionlen)
558 {
559 chosen_abi = choose_abi_by_name (val, vallen);
560 if (chosen_abi != NULL)
561 mips_gpr_names = chosen_abi->gpr_names;
562 return;
563 }
564
565 if (strncmp("fpr-names", option, optionlen) == 0
566 && strlen("fpr-names") == optionlen)
567 {
568 chosen_abi = choose_abi_by_name (val, vallen);
569 if (chosen_abi != NULL)
570 mips_fpr_names = chosen_abi->fpr_names;
571 return;
572 }
573
574 if (strncmp("cp0-names", option, optionlen) == 0
575 && strlen("cp0-names") == optionlen)
576 {
577 chosen_arch = choose_arch_by_name (val, vallen);
578 if (chosen_arch != NULL)
579 {
580 mips_cp0_names = chosen_arch->cp0_names;
581 mips_cp0sel_names = chosen_arch->cp0sel_names;
582 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
583 }
584 return;
585 }
586
587 if (strncmp("hwr-names", option, optionlen) == 0
588 && strlen("hwr-names") == optionlen)
589 {
590 chosen_arch = choose_arch_by_name (val, vallen);
591 if (chosen_arch != NULL)
592 mips_hwr_names = chosen_arch->hwr_names;
593 return;
594 }
595
596 if (strncmp("reg-names", option, optionlen) == 0
597 && strlen("reg-names") == optionlen)
598 {
599 /* We check both ABI and ARCH here unconditionally, so
600 that "numeric" will do the desirable thing: select
601 numeric register names for all registers. Other than
602 that, a given name probably won't match both. */
603 chosen_abi = choose_abi_by_name (val, vallen);
604 if (chosen_abi != NULL)
605 {
606 mips_gpr_names = chosen_abi->gpr_names;
607 mips_fpr_names = chosen_abi->fpr_names;
608 }
609 chosen_arch = choose_arch_by_name (val, vallen);
610 if (chosen_arch != NULL)
611 {
612 mips_cp0_names = chosen_arch->cp0_names;
613 mips_cp0sel_names = chosen_arch->cp0sel_names;
614 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
615 mips_hwr_names = chosen_arch->hwr_names;
616 }
617 return;
618 }
619
620 /* Invalid option. */
621}
622
623void
624parse_mips_dis_options (options)
625 const char *options;
626{
627 const char *option_end;
628
629 if (options == NULL)
630 return;
631
632 while (*options != '\0')
633 {
634 /* Skip empty options. */
635 if (*options == ',')
636 {
637 options++;
638 continue;
639 }
640
641 /* We know that *options is neither NUL or a comma. */
642 option_end = options + 1;
643 while (*option_end != ',' && *option_end != '\0')
644 option_end++;
645
646 parse_mips_dis_option (options, option_end - options);
647
648 /* Go on to the next one. If option_end points to a comma, it
649 will be skipped above. */
650 options = option_end;
651 }
652}
653
654static const struct mips_cp0sel_name *
655lookup_mips_cp0sel_name(names, len, cp0reg, sel)
656 const struct mips_cp0sel_name *names;
657 unsigned int len, cp0reg, sel;
658{
659 unsigned int i;
660
661 for (i = 0; i < len; i++)
662 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
663 return &names[i];
664 return NULL;
665}
666
667
668/* Print insn arguments for 32/64-bit code. */
669
670static void
671print_insn_args (d, l, pc, info)
672 const char *d;
673 register unsigned long int l;
674 bfd_vma pc;
675 struct disassemble_info *info;
676{
677 int op, delta;
678 unsigned int lsb, msb, msbd;
679
680 lsb = 0;
681
682 for (; *d != '\0'; d++)
683 {
684 switch (*d)
685 {
686 case ',':
687 case '(':
688 case ')':
689 case '[':
690 case ']':
691 (*info->fprintf_func) (info->stream, "%c", *d);
692 break;
693
694 case '+':
695 /* Extension character; switch for second char. */
696 d++;
697 switch (*d)
698 {
699 case '\0':
700 /* xgettext:c-format */
701 (*info->fprintf_func) (info->stream,
702 _("# internal error, incomplete extension sequence (+)"));
703 return;
704
705 case 'A':
706 lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT;
707 (*info->fprintf_func) (info->stream, "0x%x", lsb);
708 break;
709
710 case 'B':
711 msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB;
712 (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
713 break;
714
715 case 'C':
716 msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
717 (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
718 break;
719
720 case 'D':
721 {
722 const struct mips_cp0sel_name *n;
723 unsigned int cp0reg, sel;
724
725 cp0reg = (l >> OP_SH_RD) & OP_MASK_RD;
726 sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
727
728 /* CP0 register including 'sel' code for mtcN (et al.), to be
729 printed textually if known. If not known, print both
730 CP0 register name and sel numerically since CP0 register
731 with sel 0 may have a name unrelated to register being
732 printed. */
733 n = lookup_mips_cp0sel_name(mips_cp0sel_names,
734 mips_cp0sel_names_len, cp0reg, sel);
735 if (n != NULL)
736 (*info->fprintf_func) (info->stream, "%s", n->name);
737 else
738 (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
739 break;
740 }
741
742 default:
743 /* xgettext:c-format */
744 (*info->fprintf_func) (info->stream,
745 _("# internal error, undefined extension sequence (+%c)"),
746 *d);
747 return;
748 }
749 break;
750
751 case 's':
752 case 'b':
753 case 'r':
754 case 'v':
755 (*info->fprintf_func) (info->stream, "%s",
756 mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
757 break;
758
759 case 't':
760 case 'w':
761 (*info->fprintf_func) (info->stream, "%s",
762 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
763 break;
764
765 case 'i':
766 case 'u':
767 (*info->fprintf_func) (info->stream, "0x%x",
768 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
769 break;
770
771 case 'j': /* Same as i, but sign-extended. */
772 case 'o':
773 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
774 if (delta & 0x8000)
775 delta |= ~0xffff;
776 (*info->fprintf_func) (info->stream, "%d",
777 delta);
778 break;
779
780 case 'h':
781 (*info->fprintf_func) (info->stream, "0x%x",
782 (unsigned int) ((l >> OP_SH_PREFX)
783 & OP_MASK_PREFX));
784 break;
785
786 case 'k':
787 (*info->fprintf_func) (info->stream, "0x%x",
788 (unsigned int) ((l >> OP_SH_CACHE)
789 & OP_MASK_CACHE));
790 break;
791
792 case 'a':
793 info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
794 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
795 (*info->print_address_func) (info->target, info);
796 break;
797
798 case 'p':
799 /* Sign extend the displacement. */
800 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
801 if (delta & 0x8000)
802 delta |= ~0xffff;
803 info->target = (delta << 2) + pc + INSNLEN;
804 (*info->print_address_func) (info->target, info);
805 break;
806
807 case 'd':
808 (*info->fprintf_func) (info->stream, "%s",
809 mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
810 break;
811
812 case 'U':
813 {
814 /* First check for both rd and rt being equal. */
815 unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
816 if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
817 (*info->fprintf_func) (info->stream, "%s",
818 mips_gpr_names[reg]);
819 else
820 {
821 /* If one is zero use the other. */
822 if (reg == 0)
823 (*info->fprintf_func) (info->stream, "%s",
824 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
825 else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
826 (*info->fprintf_func) (info->stream, "%s",
827 mips_gpr_names[reg]);
828 else /* Bogus, result depends on processor. */
829 (*info->fprintf_func) (info->stream, "%s or %s",
830 mips_gpr_names[reg],
831 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
832 }
833 }
834 break;
835
836 case 'z':
837 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
838 break;
839
840 case '<':
841 (*info->fprintf_func) (info->stream, "0x%x",
842 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
843 break;
844
845 case 'c':
846 (*info->fprintf_func) (info->stream, "0x%x",
847 (l >> OP_SH_CODE) & OP_MASK_CODE);
848 break;
849
850 case 'q':
851 (*info->fprintf_func) (info->stream, "0x%x",
852 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
853 break;
854
855 case 'C':
856 (*info->fprintf_func) (info->stream, "0x%x",
857 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
858 break;
859
860 case 'B':
861 (*info->fprintf_func) (info->stream, "0x%x",
862 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
863 break;
864
865 case 'J':
866 (*info->fprintf_func) (info->stream, "0x%x",
867 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
868 break;
869
870 case 'S':
871 case 'V':
872 (*info->fprintf_func) (info->stream, "%s",
873 mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
874 break;
875
876 case 'T':
877 case 'W':
878 (*info->fprintf_func) (info->stream, "%s",
879 mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
880 break;
881
882 case 'D':
883 (*info->fprintf_func) (info->stream, "%s",
884 mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
885 break;
886
887 case 'R':
888 (*info->fprintf_func) (info->stream, "%s",
889 mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
890 break;
891
892 case 'E':
893 /* Coprocessor register for lwcN instructions, et al.
894
895 Note that there is no load/store cp0 instructions, and
896 that FPU (cp1) instructions disassemble this field using
897 'T' format. Therefore, until we gain understanding of
898 cp2 register names, we can simply print the register
899 numbers. */
900 (*info->fprintf_func) (info->stream, "$%d",
901 (l >> OP_SH_RT) & OP_MASK_RT);
902 break;
903
904 case 'G':
905 /* Coprocessor register for mtcN instructions, et al. Note
906 that FPU (cp1) instructions disassemble this field using
907 'S' format. Therefore, we only need to worry about cp0,
908 cp2, and cp3. */
909 op = (l >> OP_SH_OP) & OP_MASK_OP;
910 if (op == OP_OP_COP0)
911 (*info->fprintf_func) (info->stream, "%s",
912 mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
913 else
914 (*info->fprintf_func) (info->stream, "$%d",
915 (l >> OP_SH_RD) & OP_MASK_RD);
916 break;
917
918 case 'K':
919 (*info->fprintf_func) (info->stream, "%s",
920 mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
921 break;
922
923 case 'N':
924 (*info->fprintf_func) (info->stream, "$fcc%d",
925 (l >> OP_SH_BCC) & OP_MASK_BCC);
926 break;
927
928 case 'M':
929 (*info->fprintf_func) (info->stream, "$fcc%d",
930 (l >> OP_SH_CCC) & OP_MASK_CCC);
931 break;
932
933 case 'P':
934 (*info->fprintf_func) (info->stream, "%d",
935 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
936 break;
937
938 case 'e':
939 (*info->fprintf_func) (info->stream, "%d",
940 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
941 break;
942
943 case '%':
944 (*info->fprintf_func) (info->stream, "%d",
945 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
946 break;
947
948 case 'H':
949 (*info->fprintf_func) (info->stream, "%d",
950 (l >> OP_SH_SEL) & OP_MASK_SEL);
951 break;
952
953 case 'O':
954 (*info->fprintf_func) (info->stream, "%d",
955 (l >> OP_SH_ALN) & OP_MASK_ALN);
956 break;
957
958 case 'Q':
959 {
960 unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
961 if ((vsel & 0x10) == 0)
962 {
963 int fmt;
964 vsel &= 0x0f;
965 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
966 if ((vsel & 1) == 0)
967 break;
968 (*info->fprintf_func) (info->stream, "$v%d[%d]",
969 (l >> OP_SH_FT) & OP_MASK_FT,
970 vsel >> 1);
971 }
972 else if ((vsel & 0x08) == 0)
973 {
974 (*info->fprintf_func) (info->stream, "$v%d",
975 (l >> OP_SH_FT) & OP_MASK_FT);
976 }
977 else
978 {
979 (*info->fprintf_func) (info->stream, "0x%x",
980 (l >> OP_SH_FT) & OP_MASK_FT);
981 }
982 }
983 break;
984
985 case 'X':
986 (*info->fprintf_func) (info->stream, "$v%d",
987 (l >> OP_SH_FD) & OP_MASK_FD);
988 break;
989
990 case 'Y':
991 (*info->fprintf_func) (info->stream, "$v%d",
992 (l >> OP_SH_FS) & OP_MASK_FS);
993 break;
994
995 case 'Z':
996 (*info->fprintf_func) (info->stream, "$v%d",
997 (l >> OP_SH_FT) & OP_MASK_FT);
998 break;
999
1000 default:
1001 /* xgettext:c-format */
1002 (*info->fprintf_func) (info->stream,
1003 _("# internal error, undefined modifier(%c)"),
1004 *d);
1005 return;
1006 }
1007 }
1008}
1009
1010
1011/* Check if the object uses NewABI conventions. */
1012
1013static int
1014is_newabi (header)
1015 Elf_Internal_Ehdr *header;
1016{
1017 /* There are no old-style ABIs which use 64-bit ELF. */
1018 if (header->e_ident[EI_CLASS] == ELFCLASS64)
1019 return 1;
1020
1021 /* If a 32-bit ELF file, n32 is a new-style ABI. */
1022 if ((header->e_flags & EF_MIPS_ABI2) != 0)
1023 return 1;
1024
1025 return 0;
1026}
1027
1028
1029/* Print the mips instruction at address MEMADDR in debugged memory,
1030 on using INFO. Returns length of the instruction, in bytes, which is
1031 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1032 this is little-endian code. */
1033
1034static int
1035print_insn_mips (memaddr, word, info)
1036 bfd_vma memaddr;
1037 unsigned long int word;
1038 struct disassemble_info *info;
1039{
1040 register const struct mips_opcode *op;
1041 static bfd_boolean init = 0;
1042 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1043
1044 /* Build a hash table to shorten the search time. */
1045 if (! init)
1046 {
1047 unsigned int i;
1048
1049 for (i = 0; i <= OP_MASK_OP; i++)
1050 {
1051 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1052 {
1053 if (op->pinfo == INSN_MACRO)
1054 continue;
1055 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
1056 {
1057 mips_hash[i] = op;
1058 break;
1059 }
1060 }
1061 }
1062
1063 init = 1;
1064 }
1065
1066 info->bytes_per_chunk = INSNLEN;
1067 info->display_endian = info->endian;
1068 info->insn_info_valid = 1;
1069 info->branch_delay_insns = 0;
1070 info->data_size = 0;
1071 info->insn_type = dis_nonbranch;
1072 info->target = 0;
1073 info->target2 = 0;
1074
1075 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
1076 if (op != NULL)
1077 {
1078 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1079 {
1080 if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
1081 {
1082 register const char *d;
1083
1084 /* We always allow to disassemble the jalx instruction. */
1085 if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
1086 && strcmp (op->name, "jalx"))
1087 continue;
1088
1089 /* Figure out instruction type and branch delay information. */
1090 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1091 {
1092 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1093 info->insn_type = dis_jsr;
1094 else
1095 info->insn_type = dis_branch;
1096 info->branch_delay_insns = 1;
1097 }
1098 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1099 | INSN_COND_BRANCH_LIKELY)) != 0)
1100 {
1101 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1102 info->insn_type = dis_condjsr;
1103 else
1104 info->insn_type = dis_condbranch;
1105 info->branch_delay_insns = 1;
1106 }
1107 else if ((op->pinfo & (INSN_STORE_MEMORY
1108 | INSN_LOAD_MEMORY_DELAY)) != 0)
1109 info->insn_type = dis_dref;
1110
1111 (*info->fprintf_func) (info->stream, "%s", op->name);
1112
1113 d = op->args;
1114 if (d != NULL && *d != '\0')
1115 {
1116 (*info->fprintf_func) (info->stream, "\t");
1117 print_insn_args (d, word, memaddr, info);
1118 }
1119
1120 return INSNLEN;
1121 }
1122 }
1123 }
1124
1125 /* Handle undefined instructions. */
1126 info->insn_type = dis_noninsn;
1127 (*info->fprintf_func) (info->stream, "0x%x", word);
1128 return INSNLEN;
1129}
1130
1131
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. */
1137
1138static int
1139_print_insn_mips (memaddr, info, endianness)
1140 bfd_vma memaddr;
1141 struct disassemble_info *info;
1142 enum bfd_endian endianness;
1143{
1144 bfd_byte buffer[INSNLEN];
1145 int status;
1146
1147 set_default_mips_dis_options (info);
1148 parse_mips_dis_options (info->disassembler_options);
1149
1150#if 1
1151 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
1152 /* Only a few tools will work this way. */
1153 if (memaddr & 0x01)
1154 return print_insn_mips16 (memaddr, info);
1155#endif
1156
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
1162 == STO_MIPS16)))
1163 return print_insn_mips16 (memaddr, info);
1164#endif
1165
1166 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
1167 if (status == 0)
1168 {
1169 unsigned long insn;
1170
1171 if (endianness == BFD_ENDIAN_BIG)
1172 insn = (unsigned long) bfd_getb32 (buffer);
1173 else
1174 insn = (unsigned long) bfd_getl32 (buffer);
1175
1176 return print_insn_mips (memaddr, insn, info);
1177 }
1178 else
1179 {
1180 (*info->memory_error_func) (status, memaddr, info);
1181 return -1;
1182 }
1183}
1184
1185int
1186print_insn_big_mips (memaddr, info)
1187 bfd_vma memaddr;
1188 struct disassemble_info *info;
1189{
1190 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
1191}
1192
1193int
1194print_insn_little_mips (memaddr, info)
1195 bfd_vma memaddr;
1196 struct disassemble_info *info;
1197{
1198 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
1199}
1200
1201
1202/* Disassemble mips16 instructions. */
1203
1204static int
1205print_insn_mips16 (memaddr, info)
1206 bfd_vma memaddr;
1207 struct disassemble_info *info;
1208{
1209 int status;
1210 bfd_byte buffer[2];
1211 int length;
1212 int insn;
1213 bfd_boolean use_extend;
1214 int extend = 0;
1215 const struct mips_opcode *op, *opend;
1216
1217 info->bytes_per_chunk = 2;
1218 info->display_endian = info->endian;
1219 info->insn_info_valid = 1;
1220 info->branch_delay_insns = 0;
1221 info->data_size = 0;
1222 info->insn_type = dis_nonbranch;
1223 info->target = 0;
1224 info->target2 = 0;
1225
1226 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1227 if (status != 0)
1228 {
1229 (*info->memory_error_func) (status, memaddr, info);
1230 return -1;
1231 }
1232
1233 length = 2;
1234
1235 if (info->endian == BFD_ENDIAN_BIG)
1236 insn = bfd_getb16 (buffer);
1237 else
1238 insn = bfd_getl16 (buffer);
1239
1240 /* Handle the extend opcode specially. */
1241 use_extend = FALSE;
1242 if ((insn & 0xf800) == 0xf000)
1243 {
1244 use_extend = TRUE;
1245 extend = insn & 0x7ff;
1246
1247 memaddr += 2;
1248
1249 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1250 if (status != 0)
1251 {
1252 (*info->fprintf_func) (info->stream, "extend 0x%x",
1253 (unsigned int) extend);
1254 (*info->memory_error_func) (status, memaddr, info);
1255 return -1;
1256 }
1257
1258 if (info->endian == BFD_ENDIAN_BIG)
1259 insn = bfd_getb16 (buffer);
1260 else
1261 insn = bfd_getl16 (buffer);
1262
1263 /* Check for an extend opcode followed by an extend opcode. */
1264 if ((insn & 0xf800) == 0xf000)
1265 {
1266 (*info->fprintf_func) (info->stream, "extend 0x%x",
1267 (unsigned int) extend);
1268 info->insn_type = dis_noninsn;
1269 return length;
1270 }
1271
1272 length += 2;
1273 }
1274
1275 /* FIXME: Should probably use a hash table on the major opcode here. */
1276
1277 opend = mips16_opcodes + bfd_mips16_num_opcodes;
1278 for (op = mips16_opcodes; op < opend; op++)
1279 {
1280 if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
1281 {
1282 const char *s;
1283
1284 if (strchr (op->args, 'a') != NULL)
1285 {
1286 if (use_extend)
1287 {
1288 (*info->fprintf_func) (info->stream, "extend 0x%x",
1289 (unsigned int) extend);
1290 info->insn_type = dis_noninsn;
1291 return length - 2;
1292 }
1293
1294 use_extend = FALSE;
1295
1296 memaddr += 2;
1297
1298 status = (*info->read_memory_func) (memaddr, buffer, 2,
1299 info);
1300 if (status == 0)
1301 {
1302 use_extend = TRUE;
1303 if (info->endian == BFD_ENDIAN_BIG)
1304 extend = bfd_getb16 (buffer);
1305 else
1306 extend = bfd_getl16 (buffer);
1307 length += 2;
1308 }
1309 }
1310
1311 (*info->fprintf_func) (info->stream, "%s", op->name);
1312 if (op->args[0] != '\0')
1313 (*info->fprintf_func) (info->stream, "\t");
1314
1315 for (s = op->args; *s != '\0'; s++)
1316 {
1317 if (*s == ','
1318 && s[1] == 'w'
1319 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
1320 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
1321 {
1322 /* Skip the register and the comma. */
1323 ++s;
1324 continue;
1325 }
1326 if (*s == ','
1327 && s[1] == 'v'
1328 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
1329 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
1330 {
1331 /* Skip the register and the comma. */
1332 ++s;
1333 continue;
1334 }
1335 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
1336 info);
1337 }
1338
1339 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1340 {
1341 info->branch_delay_insns = 1;
1342 if (info->insn_type != dis_jsr)
1343 info->insn_type = dis_branch;
1344 }
1345
1346 return length;
1347 }
1348 }
1349
1350 if (use_extend)
1351 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
1352 (*info->fprintf_func) (info->stream, "0x%x", insn);
1353 info->insn_type = dis_noninsn;
1354
1355 return length;
1356}
1357
1358/* Disassemble an operand for a mips16 instruction. */
1359
1360static void
1361print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
1362 char type;
1363 const struct mips_opcode *op;
1364 int l;
1365 bfd_boolean use_extend;
1366 int extend;
1367 bfd_vma memaddr;
1368 struct disassemble_info *info;
1369{
1370 switch (type)
1371 {
1372 case ',':
1373 case '(':
1374 case ')':
1375 (*info->fprintf_func) (info->stream, "%c", type);
1376 break;
1377
1378 case 'y':
1379 case 'w':
1380 (*info->fprintf_func) (info->stream, "%s",
1381 mips16_reg_names[((l >> MIPS16OP_SH_RY)
1382 & MIPS16OP_MASK_RY)]);
1383 break;
1384
1385 case 'x':
1386 case 'v':
1387 (*info->fprintf_func) (info->stream, "%s",
1388 mips16_reg_names[((l >> MIPS16OP_SH_RX)
1389 & MIPS16OP_MASK_RX)]);
1390 break;
1391
1392 case 'z':
1393 (*info->fprintf_func) (info->stream, "%s",
1394 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
1395 & MIPS16OP_MASK_RZ)]);
1396 break;
1397
1398 case 'Z':
1399 (*info->fprintf_func) (info->stream, "%s",
1400 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
1401 & MIPS16OP_MASK_MOVE32Z)]);
1402 break;
1403
1404 case '0':
1405 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
1406 break;
1407
1408 case 'S':
1409 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]);
1410 break;
1411
1412 case 'P':
1413 (*info->fprintf_func) (info->stream, "$pc");
1414 break;
1415
1416 case 'R':
1417 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]);
1418 break;
1419
1420 case 'X':
1421 (*info->fprintf_func) (info->stream, "%s",
1422 mips_gpr_names[((l >> MIPS16OP_SH_REGR32)
1423 & MIPS16OP_MASK_REGR32)]);
1424 break;
1425
1426 case 'Y':
1427 (*info->fprintf_func) (info->stream, "%s",
1428 mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
1429 break;
1430
1431 case '<':
1432 case '>':
1433 case '[':
1434 case ']':
1435 case '4':
1436 case '5':
1437 case 'H':
1438 case 'W':
1439 case 'D':
1440 case 'j':
1441 case '6':
1442 case '8':
1443 case 'V':
1444 case 'C':
1445 case 'U':
1446 case 'k':
1447 case 'K':
1448 case 'p':
1449 case 'q':
1450 case 'A':
1451 case 'B':
1452 case 'E':
1453 {
1454 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
1455
1456 shift = 0;
1457 signedp = 0;
1458 extbits = 16;
1459 pcrel = 0;
1460 extu = 0;
1461 branch = 0;
1462 switch (type)
1463 {
1464 case '<':
1465 nbits = 3;
1466 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1467 extbits = 5;
1468 extu = 1;
1469 break;
1470 case '>':
1471 nbits = 3;
1472 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1473 extbits = 5;
1474 extu = 1;
1475 break;
1476 case '[':
1477 nbits = 3;
1478 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1479 extbits = 6;
1480 extu = 1;
1481 break;
1482 case ']':
1483 nbits = 3;
1484 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1485 extbits = 6;
1486 extu = 1;
1487 break;
1488 case '4':
1489 nbits = 4;
1490 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
1491 signedp = 1;
1492 extbits = 15;
1493 break;
1494 case '5':
1495 nbits = 5;
1496 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1497 info->insn_type = dis_dref;
1498 info->data_size = 1;
1499 break;
1500 case 'H':
1501 nbits = 5;
1502 shift = 1;
1503 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1504 info->insn_type = dis_dref;
1505 info->data_size = 2;
1506 break;
1507 case 'W':
1508 nbits = 5;
1509 shift = 2;
1510 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1511 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1512 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1513 {
1514 info->insn_type = dis_dref;
1515 info->data_size = 4;
1516 }
1517 break;
1518 case 'D':
1519 nbits = 5;
1520 shift = 3;
1521 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1522 info->insn_type = dis_dref;
1523 info->data_size = 8;
1524 break;
1525 case 'j':
1526 nbits = 5;
1527 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1528 signedp = 1;
1529 break;
1530 case '6':
1531 nbits = 6;
1532 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1533 break;
1534 case '8':
1535 nbits = 8;
1536 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1537 break;
1538 case 'V':
1539 nbits = 8;
1540 shift = 2;
1541 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1542 /* FIXME: This might be lw, or it might be addiu to $sp or
1543 $pc. We assume it's load. */
1544 info->insn_type = dis_dref;
1545 info->data_size = 4;
1546 break;
1547 case 'C':
1548 nbits = 8;
1549 shift = 3;
1550 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1551 info->insn_type = dis_dref;
1552 info->data_size = 8;
1553 break;
1554 case 'U':
1555 nbits = 8;
1556 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1557 extu = 1;
1558 break;
1559 case 'k':
1560 nbits = 8;
1561 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1562 signedp = 1;
1563 break;
1564 case 'K':
1565 nbits = 8;
1566 shift = 3;
1567 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1568 signedp = 1;
1569 break;
1570 case 'p':
1571 nbits = 8;
1572 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1573 signedp = 1;
1574 pcrel = 1;
1575 branch = 1;
1576 info->insn_type = dis_condbranch;
1577 break;
1578 case 'q':
1579 nbits = 11;
1580 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1581 signedp = 1;
1582 pcrel = 1;
1583 branch = 1;
1584 info->insn_type = dis_branch;
1585 break;
1586 case 'A':
1587 nbits = 8;
1588 shift = 2;
1589 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1590 pcrel = 1;
1591 /* FIXME: This can be lw or la. We assume it is lw. */
1592 info->insn_type = dis_dref;
1593 info->data_size = 4;
1594 break;
1595 case 'B':
1596 nbits = 5;
1597 shift = 3;
1598 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1599 pcrel = 1;
1600 info->insn_type = dis_dref;
1601 info->data_size = 8;
1602 break;
1603 case 'E':
1604 nbits = 5;
1605 shift = 2;
1606 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1607 pcrel = 1;
1608 break;
1609 default:
1610 abort ();
1611 }
1612
1613 if (! use_extend)
1614 {
1615 if (signedp && immed >= (1 << (nbits - 1)))
1616 immed -= 1 << nbits;
1617 immed <<= shift;
1618 if ((type == '<' || type == '>' || type == '[' || type == ']')
1619 && immed == 0)
1620 immed = 8;
1621 }
1622 else
1623 {
1624 if (extbits == 16)
1625 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1626 else if (extbits == 15)
1627 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1628 else
1629 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1630 immed &= (1 << extbits) - 1;
1631 if (! extu && immed >= (1 << (extbits - 1)))
1632 immed -= 1 << extbits;
1633 }
1634
1635 if (! pcrel)
1636 (*info->fprintf_func) (info->stream, "%d", immed);
1637 else
1638 {
1639 bfd_vma baseaddr;
1640
1641 if (branch)
1642 {
1643 immed *= 2;
1644 baseaddr = memaddr + 2;
1645 }
1646 else if (use_extend)
1647 baseaddr = memaddr - 2;
1648 else
1649 {
1650 int status;
1651 bfd_byte buffer[2];
1652
1653 baseaddr = memaddr;
1654
1655 /* If this instruction is in the delay slot of a jr
1656 instruction, the base address is the address of the
1657 jr instruction. If it is in the delay slot of jalr
1658 instruction, the base address is the address of the
1659 jalr instruction. This test is unreliable: we have
1660 no way of knowing whether the previous word is
1661 instruction or data. */
1662 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1663 info);
1664 if (status == 0
1665 && (((info->endian == BFD_ENDIAN_BIG
1666 ? bfd_getb16 (buffer)
1667 : bfd_getl16 (buffer))
1668 & 0xf800) == 0x1800))
1669 baseaddr = memaddr - 4;
1670 else
1671 {
1672 status = (*info->read_memory_func) (memaddr - 2, buffer,
1673 2, info);
1674 if (status == 0
1675 && (((info->endian == BFD_ENDIAN_BIG
1676 ? bfd_getb16 (buffer)
1677 : bfd_getl16 (buffer))
1678 & 0xf81f) == 0xe800))
1679 baseaddr = memaddr - 2;
1680 }
1681 }
1682 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1683 (*info->print_address_func) (info->target, info);
1684 }
1685 }
1686 break;
1687
1688 case 'a':
1689 if (! use_extend)
1690 extend = 0;
1691 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1692 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1693 (*info->print_address_func) (info->target, info);
1694 info->insn_type = dis_jsr;
1695 info->branch_delay_insns = 1;
1696 break;
1697
1698 case 'l':
1699 case 'L':
1700 {
1701 int need_comma, amask, smask;
1702
1703 need_comma = 0;
1704
1705 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1706
1707 amask = (l >> 3) & 7;
1708
1709 if (amask > 0 && amask < 5)
1710 {
1711 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
1712 if (amask > 1)
1713 (*info->fprintf_func) (info->stream, "-%s",
1714 mips_gpr_names[amask + 3]);
1715 need_comma = 1;
1716 }
1717
1718 smask = (l >> 1) & 3;
1719 if (smask == 3)
1720 {
1721 (*info->fprintf_func) (info->stream, "%s??",
1722 need_comma ? "," : "");
1723 need_comma = 1;
1724 }
1725 else if (smask > 0)
1726 {
1727 (*info->fprintf_func) (info->stream, "%s%s",
1728 need_comma ? "," : "",
1729 mips_gpr_names[16]);
1730 if (smask > 1)
1731 (*info->fprintf_func) (info->stream, "-%s",
1732 mips_gpr_names[smask + 15]);
1733 need_comma = 1;
1734 }
1735
1736 if (l & 1)
1737 {
1738 (*info->fprintf_func) (info->stream, "%s%s",
1739 need_comma ? "," : "",
1740 mips_gpr_names[31]);
1741 need_comma = 1;
1742 }
1743
1744 if (amask == 5 || amask == 6)
1745 {
1746 (*info->fprintf_func) (info->stream, "%s$f0",
1747 need_comma ? "," : "");
1748 if (amask == 6)
1749 (*info->fprintf_func) (info->stream, "-$f1");
1750 }
1751 }
1752 break;
1753
1754 default:
1755 /* xgettext:c-format */
1756 (*info->fprintf_func)
1757 (info->stream,
1758 _("# internal disassembler error, unrecognised modifier (%c)"),
1759 type);
1760 abort ();
1761 }
1762}
1763
1764void
1765print_mips_disassembler_options (stream)
1766 FILE *stream;
1767{
1768 unsigned int i;
1769
1770 fprintf (stream, _("\n\
1771The following MIPS specific disassembler options are supported for use\n\
1772with the -M switch (multiple options should be separated by commas):\n"));
1773
1774 fprintf (stream, _("\n\
1775 gpr-names=ABI Print GPR names according to specified ABI.\n\
1776 Default: based on binary being disassembled.\n"));
1777
1778 fprintf (stream, _("\n\
1779 fpr-names=ABI Print FPR names according to specified ABI.\n\
1780 Default: numeric.\n"));
1781
1782 fprintf (stream, _("\n\
1783 cp0-names=ARCH Print CP0 register names according to\n\
1784 specified architecture.\n\
1785 Default: based on binary being disassembled.\n"));
1786
1787 fprintf (stream, _("\n\
1788 hwr-names=ARCH Print HWR names according to specified \n\
1789 architecture.\n\
1790 Default: based on binary being disassembled.\n"));
1791
1792 fprintf (stream, _("\n\
1793 reg-names=ABI Print GPR and FPR names according to\n\
1794 specified ABI.\n"));
1795
1796 fprintf (stream, _("\n\
1797 reg-names=ARCH Print CP0 register and HWR names according to\n\
1798 specified architecture.\n"));
1799
1800 fprintf (stream, _("\n\
1801 For the options above, the following values are supported for \"ABI\":\n\
1802 "));
1803 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
1804 fprintf (stream, " %s", mips_abi_choices[i].name);
1805 fprintf (stream, _("\n"));
1806
1807 fprintf (stream, _("\n\
1808 For the options above, The following values are supported for \"ARCH\":\n\
1809 "));
1810 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
1811 if (*mips_arch_choices[i].name != '\0')
1812 fprintf (stream, " %s", mips_arch_choices[i].name);
1813 fprintf (stream, _("\n"));
1814
1815 fprintf (stream, _("\n"));
1816}
Note: See TracBrowser for help on using the repository browser.