]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/mips-dis.c
Remove duplicated chunk in previous patch.
[thirdparty/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,
fd25c5a9 379 ISA_MIPS32R2 | INSN_MIPS16 | INSN_DSP,
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
794ac9d0
CD
774 default:
775 /* xgettext:c-format */
776 (*info->fprintf_func) (info->stream,
777 _("# internal error, undefined extension sequence (+%c)"),
778 *d);
779 return;
780 }
781 break;
782
fd25c5a9
CF
783 case '3':
784 (*info->fprintf_func) (info->stream, "0x%lx",
785 (l >> OP_SH_SA3) & OP_MASK_SA3);
786 break;
787
788 case '4':
789 (*info->fprintf_func) (info->stream, "0x%lx",
790 (l >> OP_SH_SA4) & OP_MASK_SA4);
791 break;
792
793 case '5':
794 (*info->fprintf_func) (info->stream, "0x%lx",
795 (l >> OP_SH_IMM8) & OP_MASK_IMM8);
796 break;
797
798 case '6':
799 (*info->fprintf_func) (info->stream, "0x%lx",
800 (l >> OP_SH_RS) & OP_MASK_RS);
801 break;
802
803 case '7':
804 (*info->fprintf_func) (info->stream, "$ac%ld",
805 (l >> OP_SH_DSPACC) & OP_MASK_DSPACC);
806 break;
807
808 case '8':
809 (*info->fprintf_func) (info->stream, "0x%lx",
810 (l >> OP_SH_WRDSP) & OP_MASK_WRDSP);
811 break;
812
813 case '9':
814 (*info->fprintf_func) (info->stream, "$ac%ld",
815 (l >> OP_SH_DSPACC_S) & OP_MASK_DSPACC_S);
816 break;
817
818 case '0': /* dsp 6-bit signed immediate in bit 20 */
819 delta = ((l >> OP_SH_DSPSFT) & OP_MASK_DSPSFT);
820 if (delta & 0x20) /* test sign bit */
821 delta |= ~OP_MASK_DSPSFT;
822 (*info->fprintf_func) (info->stream, "%d", delta);
823 break;
824
825 case ':': /* dsp 7-bit signed immediate in bit 19 */
826 delta = ((l >> OP_SH_DSPSFT_7) & OP_MASK_DSPSFT_7);
827 if (delta & 0x40) /* test sign bit */
828 delta |= ~OP_MASK_DSPSFT_7;
829 (*info->fprintf_func) (info->stream, "%d", delta);
830 break;
831
832 case '\'':
833 (*info->fprintf_func) (info->stream, "0x%lx",
834 (l >> OP_SH_RDDSP) & OP_MASK_RDDSP);
835 break;
836
837 case '@': /* dsp 10-bit signed immediate in bit 16 */
838 delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
839 if (delta & 0x200) /* test sign bit */
840 delta |= ~OP_MASK_IMM10;
841 (*info->fprintf_func) (info->stream, "%d", delta);
842 break;
843
794ac9d0
CD
844 case 's':
845 case 'b':
846 case 'r':
847 case 'v':
848 (*info->fprintf_func) (info->stream, "%s",
849 mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
850 break;
851
852 case 't':
853 case 'w':
854 (*info->fprintf_func) (info->stream, "%s",
855 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
856 break;
857
858 case 'i':
859 case 'u':
0fd3a477 860 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
861 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
862 break;
863
864 case 'j': /* Same as i, but sign-extended. */
865 case 'o':
866 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
867 if (delta & 0x8000)
868 delta |= ~0xffff;
869 (*info->fprintf_func) (info->stream, "%d",
870 delta);
871 break;
872
873 case 'h':
874 (*info->fprintf_func) (info->stream, "0x%x",
875 (unsigned int) ((l >> OP_SH_PREFX)
876 & OP_MASK_PREFX));
877 break;
878
879 case 'k':
880 (*info->fprintf_func) (info->stream, "0x%x",
881 (unsigned int) ((l >> OP_SH_CACHE)
882 & OP_MASK_CACHE));
883 break;
884
885 case 'a':
886 info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
887 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
888 (*info->print_address_func) (info->target, info);
889 break;
890
891 case 'p':
892 /* Sign extend the displacement. */
893 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
894 if (delta & 0x8000)
895 delta |= ~0xffff;
896 info->target = (delta << 2) + pc + INSNLEN;
897 (*info->print_address_func) (info->target, info);
898 break;
899
900 case 'd':
901 (*info->fprintf_func) (info->stream, "%s",
902 mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
903 break;
904
905 case 'U':
906 {
907 /* First check for both rd and rt being equal. */
908 unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
909 if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
910 (*info->fprintf_func) (info->stream, "%s",
911 mips_gpr_names[reg]);
912 else
913 {
914 /* If one is zero use the other. */
915 if (reg == 0)
916 (*info->fprintf_func) (info->stream, "%s",
917 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
918 else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
919 (*info->fprintf_func) (info->stream, "%s",
920 mips_gpr_names[reg]);
921 else /* Bogus, result depends on processor. */
922 (*info->fprintf_func) (info->stream, "%s or %s",
923 mips_gpr_names[reg],
924 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
925 }
926 }
927 break;
928
929 case 'z':
930 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
931 break;
932
933 case '<':
0fd3a477 934 (*info->fprintf_func) (info->stream, "0x%lx",
af7ee8bf
CD
935 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
936 break;
794ac9d0
CD
937
938 case 'c':
0fd3a477 939 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
940 (l >> OP_SH_CODE) & OP_MASK_CODE);
941 break;
942
943 case 'q':
0fd3a477 944 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0 945 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
af7ee8bf
CD
946 break;
947
948 case 'C':
0fd3a477 949 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
950 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
951 break;
952
953 case 'B':
0fd3a477
JW
954 (*info->fprintf_func) (info->stream, "0x%lx",
955
794ac9d0
CD
956 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
957 break;
958
959 case 'J':
0fd3a477 960 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
961 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
962 break;
963
964 case 'S':
965 case 'V':
966 (*info->fprintf_func) (info->stream, "%s",
967 mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
968 break;
969
970 case 'T':
971 case 'W':
972 (*info->fprintf_func) (info->stream, "%s",
973 mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
af7ee8bf
CD
974 break;
975
bbcc0807 976 case 'D':
794ac9d0
CD
977 (*info->fprintf_func) (info->stream, "%s",
978 mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
979 break;
980
981 case 'R':
982 (*info->fprintf_func) (info->stream, "%s",
983 mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
984 break;
985
986 case 'E':
987 /* Coprocessor register for lwcN instructions, et al.
988
989 Note that there is no load/store cp0 instructions, and
990 that FPU (cp1) instructions disassemble this field using
991 'T' format. Therefore, until we gain understanding of
992 cp2 register names, we can simply print the register
993 numbers. */
0fd3a477 994 (*info->fprintf_func) (info->stream, "$%ld",
794ac9d0
CD
995 (l >> OP_SH_RT) & OP_MASK_RT);
996 break;
997
998 case 'G':
999 /* Coprocessor register for mtcN instructions, et al. Note
1000 that FPU (cp1) instructions disassemble this field using
1001 'S' format. Therefore, we only need to worry about cp0,
1002 cp2, and cp3. */
1003 op = (l >> OP_SH_OP) & OP_MASK_OP;
1004 if (op == OP_OP_COP0)
1005 (*info->fprintf_func) (info->stream, "%s",
1006 mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1007 else
0fd3a477 1008 (*info->fprintf_func) (info->stream, "$%ld",
794ac9d0
CD
1009 (l >> OP_SH_RD) & OP_MASK_RD);
1010 break;
1011
1012 case 'K':
1013 (*info->fprintf_func) (info->stream, "%s",
1014 mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1015 break;
1016
1017 case 'N':
0fd3a477 1018 (*info->fprintf_func) (info->stream, "$fcc%ld",
794ac9d0
CD
1019 (l >> OP_SH_BCC) & OP_MASK_BCC);
1020 break;
1021
1022 case 'M':
0fd3a477 1023 (*info->fprintf_func) (info->stream, "$fcc%ld",
794ac9d0
CD
1024 (l >> OP_SH_CCC) & OP_MASK_CCC);
1025 break;
1026
1027 case 'P':
0fd3a477 1028 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1029 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
1030 break;
1031
1032 case 'e':
0fd3a477 1033 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1034 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
1035 break;
1036
1037 case '%':
0fd3a477 1038 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1039 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
1040 break;
1041
1042 case 'H':
0fd3a477 1043 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1044 (l >> OP_SH_SEL) & OP_MASK_SEL);
1045 break;
1046
1047 case 'O':
0fd3a477 1048 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1049 (l >> OP_SH_ALN) & OP_MASK_ALN);
1050 break;
1051
1052 case 'Q':
bbcc0807 1053 {
794ac9d0 1054 unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
47b0e7ad 1055
794ac9d0
CD
1056 if ((vsel & 0x10) == 0)
1057 {
1058 int fmt;
47b0e7ad 1059
794ac9d0
CD
1060 vsel &= 0x0f;
1061 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1062 if ((vsel & 1) == 0)
1063 break;
0fd3a477 1064 (*info->fprintf_func) (info->stream, "$v%ld[%d]",
794ac9d0
CD
1065 (l >> OP_SH_FT) & OP_MASK_FT,
1066 vsel >> 1);
1067 }
1068 else if ((vsel & 0x08) == 0)
1069 {
0fd3a477 1070 (*info->fprintf_func) (info->stream, "$v%ld",
794ac9d0
CD
1071 (l >> OP_SH_FT) & OP_MASK_FT);
1072 }
bbcc0807 1073 else
794ac9d0 1074 {
0fd3a477 1075 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
1076 (l >> OP_SH_FT) & OP_MASK_FT);
1077 }
bbcc0807 1078 }
794ac9d0
CD
1079 break;
1080
1081 case 'X':
0fd3a477 1082 (*info->fprintf_func) (info->stream, "$v%ld",
794ac9d0
CD
1083 (l >> OP_SH_FD) & OP_MASK_FD);
1084 break;
1085
1086 case 'Y':
0fd3a477 1087 (*info->fprintf_func) (info->stream, "$v%ld",
794ac9d0
CD
1088 (l >> OP_SH_FS) & OP_MASK_FS);
1089 break;
1090
1091 case 'Z':
0fd3a477 1092 (*info->fprintf_func) (info->stream, "$v%ld",
794ac9d0
CD
1093 (l >> OP_SH_FT) & OP_MASK_FT);
1094 break;
bbcc0807 1095
af7ee8bf
CD
1096 default:
1097 /* xgettext:c-format */
1098 (*info->fprintf_func) (info->stream,
794ac9d0 1099 _("# internal error, undefined modifier(%c)"),
af7ee8bf 1100 *d);
794ac9d0 1101 return;
af7ee8bf 1102 }
252b5132
RH
1103 }
1104}
1105\f
252b5132
RH
1106/* Print the mips instruction at address MEMADDR in debugged memory,
1107 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1108 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1109 this is little-endian code. */
1110
1111static int
47b0e7ad
NC
1112print_insn_mips (bfd_vma memaddr,
1113 unsigned long int word,
1114 struct disassemble_info *info)
252b5132 1115{
47b0e7ad 1116 const struct mips_opcode *op;
b34976b6 1117 static bfd_boolean init = 0;
252b5132
RH
1118 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1119
1120 /* Build a hash table to shorten the search time. */
1121 if (! init)
1122 {
1123 unsigned int i;
1124
1125 for (i = 0; i <= OP_MASK_OP; i++)
1126 {
1127 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1128 {
986e18a5 1129 if (op->pinfo == INSN_MACRO
9e836e3d 1130 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132
RH
1131 continue;
1132 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
1133 {
1134 mips_hash[i] = op;
1135 break;
1136 }
1137 }
7f6621cd 1138 }
252b5132
RH
1139
1140 init = 1;
1141 }
1142
aa5f19f2 1143 info->bytes_per_chunk = INSNLEN;
252b5132 1144 info->display_endian = info->endian;
9bb28706
CD
1145 info->insn_info_valid = 1;
1146 info->branch_delay_insns = 0;
def7143b 1147 info->data_size = 0;
9bb28706
CD
1148 info->insn_type = dis_nonbranch;
1149 info->target = 0;
1150 info->target2 = 0;
252b5132
RH
1151
1152 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
1153 if (op != NULL)
1154 {
1155 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1156 {
986e18a5 1157 if (op->pinfo != INSN_MACRO
9e836e3d 1158 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1159 && (word & op->mask) == op->match)
252b5132 1160 {
47b0e7ad 1161 const char *d;
2bd7f1f3 1162
3396de36 1163 /* We always allow to disassemble the jalx instruction. */
640c0ccd 1164 if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
3396de36 1165 && strcmp (op->name, "jalx"))
252b5132
RH
1166 continue;
1167
9bb28706
CD
1168 /* Figure out instruction type and branch delay information. */
1169 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1170 {
1171 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1172 info->insn_type = dis_jsr;
1173 else
1174 info->insn_type = dis_branch;
1175 info->branch_delay_insns = 1;
1176 }
1177 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1178 | INSN_COND_BRANCH_LIKELY)) != 0)
1179 {
1180 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1181 info->insn_type = dis_condjsr;
1182 else
1183 info->insn_type = dis_condbranch;
1184 info->branch_delay_insns = 1;
1185 }
1186 else if ((op->pinfo & (INSN_STORE_MEMORY
1187 | INSN_LOAD_MEMORY_DELAY)) != 0)
1188 info->insn_type = dis_dref;
1189
252b5132
RH
1190 (*info->fprintf_func) (info->stream, "%s", op->name);
1191
1192 d = op->args;
1193 if (d != NULL && *d != '\0')
1194 {
7f6621cd 1195 (*info->fprintf_func) (info->stream, "\t");
794ac9d0 1196 print_insn_args (d, word, memaddr, info);
252b5132
RH
1197 }
1198
aa5f19f2 1199 return INSNLEN;
252b5132
RH
1200 }
1201 }
1202 }
1203
1204 /* Handle undefined instructions. */
9bb28706 1205 info->insn_type = dis_noninsn;
0fd3a477 1206 (*info->fprintf_func) (info->stream, "0x%lx", word);
aa5f19f2 1207 return INSNLEN;
252b5132 1208}
aa5f19f2 1209\f
252b5132
RH
1210/* Disassemble an operand for a mips16 instruction. */
1211
1212static void
47b0e7ad
NC
1213print_mips16_insn_arg (char type,
1214 const struct mips_opcode *op,
1215 int l,
1216 bfd_boolean use_extend,
1217 int extend,
1218 bfd_vma memaddr,
1219 struct disassemble_info *info)
252b5132
RH
1220{
1221 switch (type)
1222 {
1223 case ',':
1224 case '(':
1225 case ')':
1226 (*info->fprintf_func) (info->stream, "%c", type);
1227 break;
1228
1229 case 'y':
1230 case 'w':
aa5f19f2 1231 (*info->fprintf_func) (info->stream, "%s",
252b5132
RH
1232 mips16_reg_names[((l >> MIPS16OP_SH_RY)
1233 & MIPS16OP_MASK_RY)]);
1234 break;
1235
1236 case 'x':
1237 case 'v':
aa5f19f2 1238 (*info->fprintf_func) (info->stream, "%s",
252b5132
RH
1239 mips16_reg_names[((l >> MIPS16OP_SH_RX)
1240 & MIPS16OP_MASK_RX)]);
1241 break;
1242
1243 case 'z':
aa5f19f2 1244 (*info->fprintf_func) (info->stream, "%s",
252b5132
RH
1245 mips16_reg_names[((l >> MIPS16OP_SH_RZ)
1246 & MIPS16OP_MASK_RZ)]);
1247 break;
1248
1249 case 'Z':
aa5f19f2 1250 (*info->fprintf_func) (info->stream, "%s",
252b5132
RH
1251 mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
1252 & MIPS16OP_MASK_MOVE32Z)]);
1253 break;
1254
1255 case '0':
640c0ccd 1256 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
252b5132
RH
1257 break;
1258
1259 case 'S':
640c0ccd 1260 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]);
252b5132
RH
1261 break;
1262
1263 case 'P':
1264 (*info->fprintf_func) (info->stream, "$pc");
1265 break;
1266
1267 case 'R':
640c0ccd 1268 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]);
252b5132
RH
1269 break;
1270
1271 case 'X':
aa5f19f2 1272 (*info->fprintf_func) (info->stream, "%s",
640c0ccd
CD
1273 mips_gpr_names[((l >> MIPS16OP_SH_REGR32)
1274 & MIPS16OP_MASK_REGR32)]);
252b5132
RH
1275 break;
1276
1277 case 'Y':
aa5f19f2 1278 (*info->fprintf_func) (info->stream, "%s",
640c0ccd 1279 mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
252b5132
RH
1280 break;
1281
1282 case '<':
1283 case '>':
1284 case '[':
1285 case ']':
1286 case '4':
1287 case '5':
1288 case 'H':
1289 case 'W':
1290 case 'D':
1291 case 'j':
1292 case '6':
1293 case '8':
1294 case 'V':
1295 case 'C':
1296 case 'U':
1297 case 'k':
1298 case 'K':
1299 case 'p':
1300 case 'q':
1301 case 'A':
1302 case 'B':
1303 case 'E':
1304 {
1305 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
1306
1307 shift = 0;
1308 signedp = 0;
1309 extbits = 16;
1310 pcrel = 0;
1311 extu = 0;
1312 branch = 0;
1313 switch (type)
1314 {
1315 case '<':
1316 nbits = 3;
1317 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1318 extbits = 5;
1319 extu = 1;
1320 break;
1321 case '>':
1322 nbits = 3;
1323 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1324 extbits = 5;
1325 extu = 1;
1326 break;
1327 case '[':
1328 nbits = 3;
1329 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1330 extbits = 6;
1331 extu = 1;
1332 break;
1333 case ']':
1334 nbits = 3;
1335 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1336 extbits = 6;
1337 extu = 1;
1338 break;
1339 case '4':
1340 nbits = 4;
1341 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
1342 signedp = 1;
1343 extbits = 15;
1344 break;
1345 case '5':
1346 nbits = 5;
1347 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1348 info->insn_type = dis_dref;
1349 info->data_size = 1;
1350 break;
1351 case 'H':
1352 nbits = 5;
1353 shift = 1;
1354 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1355 info->insn_type = dis_dref;
1356 info->data_size = 2;
1357 break;
1358 case 'W':
1359 nbits = 5;
1360 shift = 2;
1361 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1362 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1363 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1364 {
1365 info->insn_type = dis_dref;
1366 info->data_size = 4;
1367 }
1368 break;
1369 case 'D':
1370 nbits = 5;
1371 shift = 3;
1372 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1373 info->insn_type = dis_dref;
1374 info->data_size = 8;
1375 break;
1376 case 'j':
1377 nbits = 5;
1378 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1379 signedp = 1;
1380 break;
1381 case '6':
1382 nbits = 6;
1383 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1384 break;
1385 case '8':
1386 nbits = 8;
1387 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1388 break;
1389 case 'V':
1390 nbits = 8;
1391 shift = 2;
1392 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1393 /* FIXME: This might be lw, or it might be addiu to $sp or
1394 $pc. We assume it's load. */
1395 info->insn_type = dis_dref;
1396 info->data_size = 4;
1397 break;
1398 case 'C':
1399 nbits = 8;
1400 shift = 3;
1401 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1402 info->insn_type = dis_dref;
1403 info->data_size = 8;
1404 break;
1405 case 'U':
1406 nbits = 8;
1407 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1408 extu = 1;
1409 break;
1410 case 'k':
1411 nbits = 8;
1412 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1413 signedp = 1;
1414 break;
1415 case 'K':
1416 nbits = 8;
1417 shift = 3;
1418 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1419 signedp = 1;
1420 break;
1421 case 'p':
1422 nbits = 8;
1423 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1424 signedp = 1;
1425 pcrel = 1;
1426 branch = 1;
1427 info->insn_type = dis_condbranch;
1428 break;
1429 case 'q':
1430 nbits = 11;
1431 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1432 signedp = 1;
1433 pcrel = 1;
1434 branch = 1;
1435 info->insn_type = dis_branch;
1436 break;
1437 case 'A':
1438 nbits = 8;
1439 shift = 2;
1440 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1441 pcrel = 1;
1442 /* FIXME: This can be lw or la. We assume it is lw. */
1443 info->insn_type = dis_dref;
1444 info->data_size = 4;
1445 break;
1446 case 'B':
1447 nbits = 5;
1448 shift = 3;
1449 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1450 pcrel = 1;
1451 info->insn_type = dis_dref;
1452 info->data_size = 8;
1453 break;
1454 case 'E':
1455 nbits = 5;
1456 shift = 2;
1457 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1458 pcrel = 1;
1459 break;
1460 default:
1461 abort ();
1462 }
1463
1464 if (! use_extend)
1465 {
1466 if (signedp && immed >= (1 << (nbits - 1)))
1467 immed -= 1 << nbits;
1468 immed <<= shift;
1469 if ((type == '<' || type == '>' || type == '[' || type == ']')
1470 && immed == 0)
1471 immed = 8;
1472 }
1473 else
1474 {
1475 if (extbits == 16)
1476 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1477 else if (extbits == 15)
1478 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1479 else
1480 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1481 immed &= (1 << extbits) - 1;
1482 if (! extu && immed >= (1 << (extbits - 1)))
1483 immed -= 1 << extbits;
1484 }
1485
1486 if (! pcrel)
1487 (*info->fprintf_func) (info->stream, "%d", immed);
1488 else
1489 {
1490 bfd_vma baseaddr;
252b5132
RH
1491
1492 if (branch)
1493 {
1494 immed *= 2;
1495 baseaddr = memaddr + 2;
1496 }
1497 else if (use_extend)
1498 baseaddr = memaddr - 2;
1499 else
1500 {
1501 int status;
1502 bfd_byte buffer[2];
1503
1504 baseaddr = memaddr;
1505
1506 /* If this instruction is in the delay slot of a jr
1507 instruction, the base address is the address of the
1508 jr instruction. If it is in the delay slot of jalr
1509 instruction, the base address is the address of the
1510 jalr instruction. This test is unreliable: we have
1511 no way of knowing whether the previous word is
1512 instruction or data. */
1513 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1514 info);
1515 if (status == 0
1516 && (((info->endian == BFD_ENDIAN_BIG
1517 ? bfd_getb16 (buffer)
1518 : bfd_getl16 (buffer))
1519 & 0xf800) == 0x1800))
1520 baseaddr = memaddr - 4;
1521 else
1522 {
1523 status = (*info->read_memory_func) (memaddr - 2, buffer,
1524 2, info);
1525 if (status == 0
1526 && (((info->endian == BFD_ENDIAN_BIG
1527 ? bfd_getb16 (buffer)
1528 : bfd_getl16 (buffer))
1529 & 0xf81f) == 0xe800))
1530 baseaddr = memaddr - 2;
1531 }
1532 }
9bb28706
CD
1533 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1534 (*info->print_address_func) (info->target, info);
252b5132
RH
1535 }
1536 }
1537 break;
1538
1539 case 'a':
1540 if (! use_extend)
1541 extend = 0;
1542 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
9bb28706
CD
1543 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1544 (*info->print_address_func) (info->target, info);
252b5132 1545 info->insn_type = dis_jsr;
252b5132
RH
1546 info->branch_delay_insns = 1;
1547 break;
1548
1549 case 'l':
1550 case 'L':
1551 {
1552 int need_comma, amask, smask;
1553
1554 need_comma = 0;
1555
1556 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1557
1558 amask = (l >> 3) & 7;
1559
1560 if (amask > 0 && amask < 5)
1561 {
640c0ccd 1562 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
252b5132 1563 if (amask > 1)
aa5f19f2 1564 (*info->fprintf_func) (info->stream, "-%s",
640c0ccd 1565 mips_gpr_names[amask + 3]);
252b5132
RH
1566 need_comma = 1;
1567 }
1568
1569 smask = (l >> 1) & 3;
1570 if (smask == 3)
1571 {
1572 (*info->fprintf_func) (info->stream, "%s??",
1573 need_comma ? "," : "");
1574 need_comma = 1;
1575 }
1576 else if (smask > 0)
1577 {
aa5f19f2 1578 (*info->fprintf_func) (info->stream, "%s%s",
252b5132 1579 need_comma ? "," : "",
640c0ccd 1580 mips_gpr_names[16]);
252b5132 1581 if (smask > 1)
aa5f19f2 1582 (*info->fprintf_func) (info->stream, "-%s",
640c0ccd 1583 mips_gpr_names[smask + 15]);
252b5132
RH
1584 need_comma = 1;
1585 }
1586
1587 if (l & 1)
1588 {
aa5f19f2 1589 (*info->fprintf_func) (info->stream, "%s%s",
252b5132 1590 need_comma ? "," : "",
640c0ccd 1591 mips_gpr_names[31]);
252b5132
RH
1592 need_comma = 1;
1593 }
1594
1595 if (amask == 5 || amask == 6)
1596 {
1597 (*info->fprintf_func) (info->stream, "%s$f0",
1598 need_comma ? "," : "");
1599 if (amask == 6)
1600 (*info->fprintf_func) (info->stream, "-$f1");
1601 }
1602 }
1603 break;
1604
1605 default:
aa5f19f2
NC
1606 /* xgettext:c-format */
1607 (*info->fprintf_func)
1608 (info->stream,
1609 _("# internal disassembler error, unrecognised modifier (%c)"),
1610 type);
252b5132
RH
1611 abort ();
1612 }
1613}
640c0ccd 1614
47b0e7ad
NC
1615/* Disassemble mips16 instructions. */
1616
1617static int
1618print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1619{
1620 int status;
1621 bfd_byte buffer[2];
1622 int length;
1623 int insn;
1624 bfd_boolean use_extend;
1625 int extend = 0;
1626 const struct mips_opcode *op, *opend;
1627
1628 info->bytes_per_chunk = 2;
1629 info->display_endian = info->endian;
1630 info->insn_info_valid = 1;
1631 info->branch_delay_insns = 0;
1632 info->data_size = 0;
1633 info->insn_type = dis_nonbranch;
1634 info->target = 0;
1635 info->target2 = 0;
1636
1637 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1638 if (status != 0)
1639 {
1640 (*info->memory_error_func) (status, memaddr, info);
1641 return -1;
1642 }
1643
1644 length = 2;
1645
1646 if (info->endian == BFD_ENDIAN_BIG)
1647 insn = bfd_getb16 (buffer);
1648 else
1649 insn = bfd_getl16 (buffer);
1650
1651 /* Handle the extend opcode specially. */
1652 use_extend = FALSE;
1653 if ((insn & 0xf800) == 0xf000)
1654 {
1655 use_extend = TRUE;
1656 extend = insn & 0x7ff;
1657
1658 memaddr += 2;
1659
1660 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1661 if (status != 0)
1662 {
1663 (*info->fprintf_func) (info->stream, "extend 0x%x",
1664 (unsigned int) extend);
1665 (*info->memory_error_func) (status, memaddr, info);
1666 return -1;
1667 }
1668
1669 if (info->endian == BFD_ENDIAN_BIG)
1670 insn = bfd_getb16 (buffer);
1671 else
1672 insn = bfd_getl16 (buffer);
1673
1674 /* Check for an extend opcode followed by an extend opcode. */
1675 if ((insn & 0xf800) == 0xf000)
1676 {
1677 (*info->fprintf_func) (info->stream, "extend 0x%x",
1678 (unsigned int) extend);
1679 info->insn_type = dis_noninsn;
1680 return length;
1681 }
1682
1683 length += 2;
1684 }
1685
1686 /* FIXME: Should probably use a hash table on the major opcode here. */
1687
1688 opend = mips16_opcodes + bfd_mips16_num_opcodes;
1689 for (op = mips16_opcodes; op < opend; op++)
1690 {
1691 if (op->pinfo != INSN_MACRO
1692 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1693 && (insn & op->mask) == op->match)
1694 {
1695 const char *s;
1696
1697 if (strchr (op->args, 'a') != NULL)
1698 {
1699 if (use_extend)
1700 {
1701 (*info->fprintf_func) (info->stream, "extend 0x%x",
1702 (unsigned int) extend);
1703 info->insn_type = dis_noninsn;
1704 return length - 2;
1705 }
1706
1707 use_extend = FALSE;
1708
1709 memaddr += 2;
1710
1711 status = (*info->read_memory_func) (memaddr, buffer, 2,
1712 info);
1713 if (status == 0)
1714 {
1715 use_extend = TRUE;
1716 if (info->endian == BFD_ENDIAN_BIG)
1717 extend = bfd_getb16 (buffer);
1718 else
1719 extend = bfd_getl16 (buffer);
1720 length += 2;
1721 }
1722 }
1723
1724 (*info->fprintf_func) (info->stream, "%s", op->name);
1725 if (op->args[0] != '\0')
1726 (*info->fprintf_func) (info->stream, "\t");
1727
1728 for (s = op->args; *s != '\0'; s++)
1729 {
1730 if (*s == ','
1731 && s[1] == 'w'
1732 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
1733 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
1734 {
1735 /* Skip the register and the comma. */
1736 ++s;
1737 continue;
1738 }
1739 if (*s == ','
1740 && s[1] == 'v'
1741 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
1742 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
1743 {
1744 /* Skip the register and the comma. */
1745 ++s;
1746 continue;
1747 }
1748 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
1749 info);
1750 }
1751
1752 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1753 {
1754 info->branch_delay_insns = 1;
1755 if (info->insn_type != dis_jsr)
1756 info->insn_type = dis_branch;
1757 }
1758
1759 return length;
1760 }
1761 }
1762
1763 if (use_extend)
1764 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
1765 (*info->fprintf_func) (info->stream, "0x%x", insn);
1766 info->insn_type = dis_noninsn;
1767
1768 return length;
1769}
1770
1771/* In an environment where we do not know the symbol type of the
1772 instruction we are forced to assume that the low order bit of the
1773 instructions' address may mark it as a mips16 instruction. If we
1774 are single stepping, or the pc is within the disassembled function,
1775 this works. Otherwise, we need a clue. Sometimes. */
1776
1777static int
1778_print_insn_mips (bfd_vma memaddr,
1779 struct disassemble_info *info,
1780 enum bfd_endian endianness)
1781{
1782 bfd_byte buffer[INSNLEN];
1783 int status;
1784
1785 set_default_mips_dis_options (info);
1786 parse_mips_dis_options (info->disassembler_options);
1787
1788#if 1
1789 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
1790 /* Only a few tools will work this way. */
1791 if (memaddr & 0x01)
1792 return print_insn_mips16 (memaddr, info);
1793#endif
1794
1795#if SYMTAB_AVAILABLE
1796 if (info->mach == bfd_mach_mips16
1797 || (info->flavour == bfd_target_elf_flavour
1798 && info->symbols != NULL
1799 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
1800 == STO_MIPS16)))
1801 return print_insn_mips16 (memaddr, info);
1802#endif
1803
1804 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
1805 if (status == 0)
1806 {
1807 unsigned long insn;
1808
1809 if (endianness == BFD_ENDIAN_BIG)
1810 insn = (unsigned long) bfd_getb32 (buffer);
1811 else
1812 insn = (unsigned long) bfd_getl32 (buffer);
1813
1814 return print_insn_mips (memaddr, insn, info);
1815 }
1816 else
1817 {
1818 (*info->memory_error_func) (status, memaddr, info);
1819 return -1;
1820 }
1821}
1822
1823int
1824print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
1825{
1826 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
1827}
1828
1829int
1830print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
1831{
1832 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
1833}
1834\f
640c0ccd 1835void
47b0e7ad 1836print_mips_disassembler_options (FILE *stream)
640c0ccd 1837{
4a9a3c54 1838 unsigned int i;
640c0ccd
CD
1839
1840 fprintf (stream, _("\n\
1841The following MIPS specific disassembler options are supported for use\n\
1842with the -M switch (multiple options should be separated by commas):\n"));
1843
1844 fprintf (stream, _("\n\
1845 gpr-names=ABI Print GPR names according to specified ABI.\n\
1846 Default: based on binary being disassembled.\n"));
1847
1848 fprintf (stream, _("\n\
1849 fpr-names=ABI Print FPR names according to specified ABI.\n\
1850 Default: numeric.\n"));
1851
1852 fprintf (stream, _("\n\
1853 cp0-names=ARCH Print CP0 register names according to\n\
1854 specified architecture.\n\
1855 Default: based on binary being disassembled.\n"));
1856
af7ee8bf
CD
1857 fprintf (stream, _("\n\
1858 hwr-names=ARCH Print HWR names according to specified \n\
1859 architecture.\n\
1860 Default: based on binary being disassembled.\n"));
1861
640c0ccd
CD
1862 fprintf (stream, _("\n\
1863 reg-names=ABI Print GPR and FPR names according to\n\
1864 specified ABI.\n"));
1865
1866 fprintf (stream, _("\n\
af7ee8bf 1867 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
1868 specified architecture.\n"));
1869
1870 fprintf (stream, _("\n\
1871 For the options above, the following values are supported for \"ABI\":\n\
1872 "));
4a9a3c54 1873 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
1874 fprintf (stream, " %s", mips_abi_choices[i].name);
1875 fprintf (stream, _("\n"));
1876
1877 fprintf (stream, _("\n\
1878 For the options above, The following values are supported for \"ARCH\":\n\
1879 "));
4a9a3c54 1880 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
1881 if (*mips_arch_choices[i].name != '\0')
1882 fprintf (stream, " %s", mips_arch_choices[i].name);
1883 fprintf (stream, _("\n"));
1884
1885 fprintf (stream, _("\n"));
1886}