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