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