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