gdb/
[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,
8b99bf0b 3 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2012
73da6b6b 4 Free Software Foundation, Inc.
252b5132
RH
5 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
6
9b201bb5 7 This file is part of the GNU opcodes library.
252b5132 8
9b201bb5 9 This library is free software; you can redistribute it and/or modify
47b0e7ad 10 it under the terms of the GNU General Public License as published by
9b201bb5
NC
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
252b5132 13
9b201bb5
NC
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 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
47b0e7ad
NC
54static const char * const mips_gpr_names_numeric[32] =
55{
640c0ccd
CD
56 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
57 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
58 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
59 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
aa5f19f2
NC
60};
61
47b0e7ad
NC
62static const char * const mips_gpr_names_oldabi[32] =
63{
640c0ccd
CD
64 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
65 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
66 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
67 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
aa5f19f2
NC
68};
69
47b0e7ad
NC
70static const char * const mips_gpr_names_newabi[32] =
71{
640c0ccd 72 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
0b14f26e 73 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
640c0ccd
CD
74 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
75 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
76};
77
47b0e7ad
NC
78static const char * const mips_fpr_names_numeric[32] =
79{
640c0ccd
CD
80 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
81 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
82 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
83 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
84};
85
47b0e7ad
NC
86static const char * const mips_fpr_names_32[32] =
87{
640c0ccd
CD
88 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
89 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
90 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
91 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
92};
93
47b0e7ad
NC
94static const char * const mips_fpr_names_n32[32] =
95{
640c0ccd
CD
96 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
97 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
98 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
99 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
100};
101
47b0e7ad
NC
102static const char * const mips_fpr_names_64[32] =
103{
640c0ccd
CD
104 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
105 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
106 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
107 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
108};
109
47b0e7ad
NC
110static const char * const mips_cp0_names_numeric[32] =
111{
640c0ccd
CD
112 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
113 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
114 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
115 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
116};
117
f409fd1e
MR
118static const char * const mips_cp0_names_r3000[32] =
119{
120 "c0_index", "c0_random", "c0_entrylo", "$3",
121 "c0_context", "$5", "$6", "$7",
122 "c0_badvaddr", "$9", "c0_entryhi", "$11",
123 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
124 "$16", "$17", "$18", "$19",
125 "$20", "$21", "$22", "$23",
126 "$24", "$25", "$26", "$27",
127 "$28", "$29", "$30", "$31",
128};
129
130static const char * const mips_cp0_names_r4000[32] =
131{
132 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
133 "c0_context", "c0_pagemask", "c0_wired", "$7",
134 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
135 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
136 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
137 "c0_xcontext", "$21", "$22", "$23",
138 "$24", "$25", "c0_ecc", "c0_cacheerr",
139 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
140};
141
e407c74b
NC
142static const char * const mips_cp0_names_r5900[32] =
143{
144 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
145 "c0_context", "c0_pagemask", "c0_wired", "$7",
146 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
147 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
148 "c0_config", "$17", "$18", "$19",
149 "$20", "$21", "$22", "c0_badpaddr",
150 "c0_depc", "c0_perfcnt", "$26", "$27",
151 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
152};
153
154static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900[] =
155{
156 { 24, 2, "c0_iab" },
157 { 24, 3, "c0_iabm" },
158 { 24, 4, "c0_dab" },
159 { 24, 5, "c0_dabm" },
160 { 24, 6, "c0_dvb" },
161 { 24, 7, "c0_dvbm" },
162 { 25, 1, "c0_perfcnt,1" },
163 { 25, 2, "c0_perfcnt,2" }
164};
165
47b0e7ad
NC
166static const char * const mips_cp0_names_mips3264[32] =
167{
640c0ccd
CD
168 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
169 "c0_context", "c0_pagemask", "c0_wired", "$7",
170 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
171 "c0_status", "c0_cause", "c0_epc", "c0_prid",
172 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
173 "c0_xcontext", "$21", "$22", "c0_debug",
174 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
175 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
176};
177
47b0e7ad
NC
178static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
179{
bbcc0807
CD
180 { 16, 1, "c0_config1" },
181 { 16, 2, "c0_config2" },
182 { 16, 3, "c0_config3" },
183 { 18, 1, "c0_watchlo,1" },
184 { 18, 2, "c0_watchlo,2" },
185 { 18, 3, "c0_watchlo,3" },
186 { 18, 4, "c0_watchlo,4" },
187 { 18, 5, "c0_watchlo,5" },
188 { 18, 6, "c0_watchlo,6" },
189 { 18, 7, "c0_watchlo,7" },
190 { 19, 1, "c0_watchhi,1" },
191 { 19, 2, "c0_watchhi,2" },
192 { 19, 3, "c0_watchhi,3" },
193 { 19, 4, "c0_watchhi,4" },
194 { 19, 5, "c0_watchhi,5" },
195 { 19, 6, "c0_watchhi,6" },
196 { 19, 7, "c0_watchhi,7" },
197 { 25, 1, "c0_perfcnt,1" },
198 { 25, 2, "c0_perfcnt,2" },
199 { 25, 3, "c0_perfcnt,3" },
200 { 25, 4, "c0_perfcnt,4" },
201 { 25, 5, "c0_perfcnt,5" },
202 { 25, 6, "c0_perfcnt,6" },
203 { 25, 7, "c0_perfcnt,7" },
204 { 27, 1, "c0_cacheerr,1" },
205 { 27, 2, "c0_cacheerr,2" },
206 { 27, 3, "c0_cacheerr,3" },
207 { 28, 1, "c0_datalo" },
208 { 29, 1, "c0_datahi" }
209};
210
47b0e7ad
NC
211static const char * const mips_cp0_names_mips3264r2[32] =
212{
af7ee8bf
CD
213 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
214 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
215 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
216 "c0_status", "c0_cause", "c0_epc", "c0_prid",
217 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
218 "c0_xcontext", "$21", "$22", "c0_debug",
219 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
220 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
221};
222
47b0e7ad
NC
223static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
224{
bbcc0807 225 { 4, 1, "c0_contextconfig" },
59c455b3
TS
226 { 0, 1, "c0_mvpcontrol" },
227 { 0, 2, "c0_mvpconf0" },
228 { 0, 3, "c0_mvpconf1" },
229 { 1, 1, "c0_vpecontrol" },
230 { 1, 2, "c0_vpeconf0" },
231 { 1, 3, "c0_vpeconf1" },
232 { 1, 4, "c0_yqmask" },
233 { 1, 5, "c0_vpeschedule" },
234 { 1, 6, "c0_vpeschefback" },
235 { 2, 1, "c0_tcstatus" },
236 { 2, 2, "c0_tcbind" },
237 { 2, 3, "c0_tcrestart" },
238 { 2, 4, "c0_tchalt" },
239 { 2, 5, "c0_tccontext" },
240 { 2, 6, "c0_tcschedule" },
241 { 2, 7, "c0_tcschefback" },
bbcc0807 242 { 5, 1, "c0_pagegrain" },
59c455b3
TS
243 { 6, 1, "c0_srsconf0" },
244 { 6, 2, "c0_srsconf1" },
245 { 6, 3, "c0_srsconf2" },
246 { 6, 4, "c0_srsconf3" },
247 { 6, 5, "c0_srsconf4" },
bbcc0807
CD
248 { 12, 1, "c0_intctl" },
249 { 12, 2, "c0_srsctl" },
250 { 12, 3, "c0_srsmap" },
251 { 15, 1, "c0_ebase" },
252 { 16, 1, "c0_config1" },
253 { 16, 2, "c0_config2" },
254 { 16, 3, "c0_config3" },
255 { 18, 1, "c0_watchlo,1" },
256 { 18, 2, "c0_watchlo,2" },
257 { 18, 3, "c0_watchlo,3" },
258 { 18, 4, "c0_watchlo,4" },
259 { 18, 5, "c0_watchlo,5" },
260 { 18, 6, "c0_watchlo,6" },
261 { 18, 7, "c0_watchlo,7" },
262 { 19, 1, "c0_watchhi,1" },
263 { 19, 2, "c0_watchhi,2" },
264 { 19, 3, "c0_watchhi,3" },
265 { 19, 4, "c0_watchhi,4" },
266 { 19, 5, "c0_watchhi,5" },
267 { 19, 6, "c0_watchhi,6" },
268 { 19, 7, "c0_watchhi,7" },
269 { 23, 1, "c0_tracecontrol" },
270 { 23, 2, "c0_tracecontrol2" },
271 { 23, 3, "c0_usertracedata" },
272 { 23, 4, "c0_tracebpc" },
273 { 25, 1, "c0_perfcnt,1" },
274 { 25, 2, "c0_perfcnt,2" },
275 { 25, 3, "c0_perfcnt,3" },
276 { 25, 4, "c0_perfcnt,4" },
277 { 25, 5, "c0_perfcnt,5" },
278 { 25, 6, "c0_perfcnt,6" },
279 { 25, 7, "c0_perfcnt,7" },
280 { 27, 1, "c0_cacheerr,1" },
281 { 27, 2, "c0_cacheerr,2" },
282 { 27, 3, "c0_cacheerr,3" },
283 { 28, 1, "c0_datalo" },
284 { 28, 2, "c0_taglo1" },
285 { 28, 3, "c0_datalo1" },
286 { 28, 4, "c0_taglo2" },
287 { 28, 5, "c0_datalo2" },
288 { 28, 6, "c0_taglo3" },
289 { 28, 7, "c0_datalo3" },
290 { 29, 1, "c0_datahi" },
291 { 29, 2, "c0_taghi1" },
292 { 29, 3, "c0_datahi1" },
293 { 29, 4, "c0_taghi2" },
294 { 29, 5, "c0_datahi2" },
295 { 29, 6, "c0_taghi3" },
296 { 29, 7, "c0_datahi3" },
297};
298
640c0ccd 299/* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
47b0e7ad
NC
300static const char * const mips_cp0_names_sb1[32] =
301{
640c0ccd
CD
302 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
303 "c0_context", "c0_pagemask", "c0_wired", "$7",
304 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
305 "c0_status", "c0_cause", "c0_epc", "c0_prid",
306 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
307 "c0_xcontext", "$21", "$22", "c0_debug",
308 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
309 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
310};
311
47b0e7ad
NC
312static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
313{
bbcc0807
CD
314 { 16, 1, "c0_config1" },
315 { 18, 1, "c0_watchlo,1" },
316 { 19, 1, "c0_watchhi,1" },
317 { 22, 0, "c0_perftrace" },
318 { 23, 3, "c0_edebug" },
319 { 25, 1, "c0_perfcnt,1" },
320 { 25, 2, "c0_perfcnt,2" },
321 { 25, 3, "c0_perfcnt,3" },
322 { 25, 4, "c0_perfcnt,4" },
323 { 25, 5, "c0_perfcnt,5" },
324 { 25, 6, "c0_perfcnt,6" },
325 { 25, 7, "c0_perfcnt,7" },
326 { 26, 1, "c0_buserr_pa" },
327 { 27, 1, "c0_cacheerr_d" },
328 { 27, 3, "c0_cacheerr_d_pa" },
329 { 28, 1, "c0_datalo_i" },
330 { 28, 2, "c0_taglo_d" },
331 { 28, 3, "c0_datalo_d" },
332 { 29, 1, "c0_datahi_i" },
333 { 29, 2, "c0_taghi_d" },
334 { 29, 3, "c0_datahi_d" },
335};
336
52b6b6b9
JM
337/* Xlr cop0 register names. */
338static const char * const mips_cp0_names_xlr[32] = {
339 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
340 "c0_context", "c0_pagemask", "c0_wired", "$7",
341 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
342 "c0_status", "c0_cause", "c0_epc", "c0_prid",
343 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
344 "c0_xcontext", "$21", "$22", "c0_debug",
345 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
346 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
347};
348
349/* XLR's CP0 Select Registers. */
350
351static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
352 { 9, 6, "c0_extintreq" },
353 { 9, 7, "c0_extintmask" },
354 { 15, 1, "c0_ebase" },
355 { 16, 1, "c0_config1" },
356 { 16, 2, "c0_config2" },
357 { 16, 3, "c0_config3" },
358 { 16, 7, "c0_procid2" },
359 { 18, 1, "c0_watchlo,1" },
360 { 18, 2, "c0_watchlo,2" },
361 { 18, 3, "c0_watchlo,3" },
362 { 18, 4, "c0_watchlo,4" },
363 { 18, 5, "c0_watchlo,5" },
364 { 18, 6, "c0_watchlo,6" },
365 { 18, 7, "c0_watchlo,7" },
366 { 19, 1, "c0_watchhi,1" },
367 { 19, 2, "c0_watchhi,2" },
368 { 19, 3, "c0_watchhi,3" },
369 { 19, 4, "c0_watchhi,4" },
370 { 19, 5, "c0_watchhi,5" },
371 { 19, 6, "c0_watchhi,6" },
372 { 19, 7, "c0_watchhi,7" },
373 { 25, 1, "c0_perfcnt,1" },
374 { 25, 2, "c0_perfcnt,2" },
375 { 25, 3, "c0_perfcnt,3" },
376 { 25, 4, "c0_perfcnt,4" },
377 { 25, 5, "c0_perfcnt,5" },
378 { 25, 6, "c0_perfcnt,6" },
379 { 25, 7, "c0_perfcnt,7" },
380 { 27, 1, "c0_cacheerr,1" },
381 { 27, 2, "c0_cacheerr,2" },
382 { 27, 3, "c0_cacheerr,3" },
383 { 28, 1, "c0_datalo" },
384 { 29, 1, "c0_datahi" }
385};
386
47b0e7ad
NC
387static const char * const mips_hwr_names_numeric[32] =
388{
af7ee8bf
CD
389 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
390 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
391 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
392 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
393};
394
47b0e7ad
NC
395static const char * const mips_hwr_names_mips3264r2[32] =
396{
af7ee8bf
CD
397 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
398 "$4", "$5", "$6", "$7",
399 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
400 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
401 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
402};
403
47b0e7ad
NC
404struct mips_abi_choice
405{
406 const char * name;
640c0ccd
CD
407 const char * const *gpr_names;
408 const char * const *fpr_names;
409};
410
47b0e7ad
NC
411struct mips_abi_choice mips_abi_choices[] =
412{
640c0ccd
CD
413 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
414 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
415 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
416 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
417};
418
47b0e7ad
NC
419struct mips_arch_choice
420{
640c0ccd
CD
421 const char *name;
422 int bfd_mach_valid;
423 unsigned long bfd_mach;
424 int processor;
425 int isa;
d301a56b 426 int ase;
640c0ccd 427 const char * const *cp0_names;
bbcc0807
CD
428 const struct mips_cp0sel_name *cp0sel_names;
429 unsigned int cp0sel_names_len;
af7ee8bf 430 const char * const *hwr_names;
640c0ccd
CD
431};
432
47b0e7ad
NC
433const struct mips_arch_choice mips_arch_choices[] =
434{
d301a56b 435 { "numeric", 0, 0, 0, 0, 0,
bbcc0807
CD
436 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
437
d301a56b 438 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
f409fd1e 439 mips_cp0_names_r3000, NULL, 0, mips_hwr_names_numeric },
d301a56b 440 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
bbcc0807 441 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 442 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
f409fd1e 443 mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
d301a56b 444 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
bbcc0807 445 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 446 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
bbcc0807 447 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 448 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
bbcc0807 449 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 450 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
bbcc0807 451 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 452 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
bbcc0807 453 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 454 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
f409fd1e 455 mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
d301a56b 456 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
bbcc0807 457 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 458 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
bbcc0807 459 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 460 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
bbcc0807 461 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 462 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
bbcc0807 463 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 464 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
bbcc0807 465 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 466 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
e407c74b 467 mips_cp0_names_r5900, NULL, 0, mips_hwr_names_numeric },
d301a56b 468 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
bbcc0807 469 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 470 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
5a7ea749 471 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 472 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
5a7ea749 473 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 474 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
bbcc0807 475 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 476 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
bbcc0807 477 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 478 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
bbcc0807 479 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 480 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
3aa3176b 481 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 482 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
3aa3176b 483 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 484 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
bbcc0807
CD
485 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
486
640c0ccd
CD
487 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
488 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
489 _MIPS32 Architecture For Programmers Volume I: Introduction to the
490 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
491 page 1. */
492 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
d301a56b 493 ISA_MIPS32, ASE_SMARTMIPS,
bbcc0807
CD
494 mips_cp0_names_mips3264,
495 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
496 mips_hwr_names_numeric },
497
af7ee8bf 498 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
d301a56b 499 ISA_MIPS32R2,
7f3c4072
CM
500 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
501 | ASE_MT | ASE_MCU | ASE_VIRT),
bbcc0807
CD
502 mips_cp0_names_mips3264r2,
503 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
504 mips_hwr_names_mips3264r2 },
505
640c0ccd
CD
506 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
507 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
d301a56b 508 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
bbcc0807
CD
509 mips_cp0_names_mips3264,
510 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
511 mips_hwr_names_numeric },
512
5f74bc13 513 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
d301a56b 514 ISA_MIPS64R2,
7f3c4072
CM
515 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
516 | ASE_MDMX | ASE_MCU | ASE_VIRT | ASE_VIRT64),
5f74bc13
CD
517 mips_cp0_names_mips3264r2,
518 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
519 mips_hwr_names_mips3264r2 },
520
640c0ccd 521 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
d301a56b 522 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
bbcc0807
CD
523 mips_cp0_names_sb1,
524 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
525 mips_hwr_names_numeric },
640c0ccd 526
350cc38d 527 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
d301a56b 528 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
350cc38d
MS
529 NULL, 0, mips_hwr_names_numeric },
530
531 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
d301a56b 532 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
350cc38d
MS
533 NULL, 0, mips_hwr_names_numeric },
534
fd503541 535 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
d301a56b 536 ISA_MIPS64 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
fd503541
NC
537 NULL, 0, mips_hwr_names_numeric },
538
57b592a3 539 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
d301a56b 540 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
57b592a3
AN
541 mips_hwr_names_numeric },
542
dd6a37e7 543 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
d301a56b 544 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
432233b3
AP
545 NULL, 0, mips_hwr_names_numeric },
546
547 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
d301a56b 548 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
dd6a37e7
AP
549 NULL, 0, mips_hwr_names_numeric },
550
52b6b6b9 551 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 552 ISA_MIPS64 | INSN_XLR, 0,
52b6b6b9
JM
553 mips_cp0_names_xlr,
554 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
555 mips_hwr_names_numeric },
556
55a36193
MK
557 /* XLP is mostly like XLR, with the prominent exception it is being
558 MIPS64R2. */
559 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 560 ISA_MIPS64R2 | INSN_XLR, 0,
55a36193
MK
561 mips_cp0_names_xlr,
562 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
563 mips_hwr_names_numeric },
564
640c0ccd
CD
565 /* This entry, mips16, is here only for ISA/processor selection; do
566 not print its name. */
d301a56b 567 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0,
bbcc0807 568 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd
CD
569};
570
571/* ISA and processor type to disassemble for, and register names to use.
572 set_default_mips_dis_options and parse_mips_dis_options fill in these
573 values. */
574static int mips_processor;
575static int mips_isa;
d301a56b 576static int mips_ase;
df58fc94 577static int micromips_ase;
640c0ccd
CD
578static const char * const *mips_gpr_names;
579static const char * const *mips_fpr_names;
580static const char * const *mips_cp0_names;
bbcc0807
CD
581static const struct mips_cp0sel_name *mips_cp0sel_names;
582static int mips_cp0sel_names_len;
af7ee8bf 583static const char * const *mips_hwr_names;
640c0ccd 584
986e18a5 585/* Other options */
47b0e7ad 586static int no_aliases; /* If set disassemble as most general inst. */
640c0ccd
CD
587\f
588static const struct mips_abi_choice *
47b0e7ad 589choose_abi_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
590{
591 const struct mips_abi_choice *c;
592 unsigned int i;
593
594 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
47b0e7ad
NC
595 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
596 && strlen (mips_abi_choices[i].name) == namelen)
597 c = &mips_abi_choices[i];
598
640c0ccd
CD
599 return c;
600}
601
602static const struct mips_arch_choice *
47b0e7ad 603choose_arch_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
604{
605 const struct mips_arch_choice *c = NULL;
606 unsigned int i;
607
608 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
47b0e7ad
NC
609 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
610 && strlen (mips_arch_choices[i].name) == namelen)
611 c = &mips_arch_choices[i];
612
640c0ccd
CD
613 return c;
614}
615
616static const struct mips_arch_choice *
47b0e7ad 617choose_arch_by_number (unsigned long mach)
640c0ccd
CD
618{
619 static unsigned long hint_bfd_mach;
620 static const struct mips_arch_choice *hint_arch_choice;
621 const struct mips_arch_choice *c;
622 unsigned int i;
623
624 /* We optimize this because even if the user specifies no
625 flags, this will be done for every instruction! */
626 if (hint_bfd_mach == mach
627 && hint_arch_choice != NULL
628 && hint_arch_choice->bfd_mach == hint_bfd_mach)
629 return hint_arch_choice;
630
631 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
632 {
633 if (mips_arch_choices[i].bfd_mach_valid
634 && mips_arch_choices[i].bfd_mach == mach)
635 {
636 c = &mips_arch_choices[i];
637 hint_bfd_mach = mach;
638 hint_arch_choice = c;
639 }
640 }
641 return c;
642}
643
47b0e7ad
NC
644/* Check if the object uses NewABI conventions. */
645
646static int
647is_newabi (Elf_Internal_Ehdr *header)
648{
649 /* There are no old-style ABIs which use 64-bit ELF. */
650 if (header->e_ident[EI_CLASS] == ELFCLASS64)
651 return 1;
652
653 /* If a 32-bit ELF file, n32 is a new-style ABI. */
654 if ((header->e_flags & EF_MIPS_ABI2) != 0)
655 return 1;
656
657 return 0;
658}
659
df58fc94
RS
660/* Check if the object has microMIPS ASE code. */
661
662static int
663is_micromips (Elf_Internal_Ehdr *header)
664{
665 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
666 return 1;
667
668 return 0;
669}
670
47b0e7ad
NC
671static void
672set_default_mips_dis_options (struct disassemble_info *info)
640c0ccd
CD
673{
674 const struct mips_arch_choice *chosen_arch;
675
df58fc94
RS
676 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
677 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
678 CP0 register, and HWR names. */
640c0ccd 679 mips_isa = ISA_MIPS3;
df58fc94
RS
680 mips_processor = CPU_R3000;
681 micromips_ase = 0;
d301a56b 682 mips_ase = 0;
640c0ccd
CD
683 mips_gpr_names = mips_gpr_names_oldabi;
684 mips_fpr_names = mips_fpr_names_numeric;
685 mips_cp0_names = mips_cp0_names_numeric;
bbcc0807
CD
686 mips_cp0sel_names = NULL;
687 mips_cp0sel_names_len = 0;
af7ee8bf 688 mips_hwr_names = mips_hwr_names_numeric;
986e18a5 689 no_aliases = 0;
640c0ccd 690
df58fc94 691 /* Update settings according to the ELF file header flags. */
fec06546 692 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
640c0ccd
CD
693 {
694 Elf_Internal_Ehdr *header;
695
fec06546 696 header = elf_elfheader (info->section->owner);
df58fc94 697 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
640c0ccd
CD
698 if (is_newabi (header))
699 mips_gpr_names = mips_gpr_names_newabi;
df58fc94
RS
700 /* If a microMIPS binary, then don't use MIPS16 bindings. */
701 micromips_ase = is_micromips (header);
640c0ccd
CD
702 }
703
704 /* Set ISA, architecture, and cp0 register names as best we can. */
705#if ! SYMTAB_AVAILABLE
706 /* This is running out on a target machine, not in a host tool.
707 FIXME: Where does mips_target_info come from? */
708 target_processor = mips_target_info.processor;
709 mips_isa = mips_target_info.isa;
d301a56b 710 mips_ase = mips_target_info.ase;
640c0ccd
CD
711#else
712 chosen_arch = choose_arch_by_number (info->mach);
713 if (chosen_arch != NULL)
714 {
715 mips_processor = chosen_arch->processor;
716 mips_isa = chosen_arch->isa;
d301a56b 717 mips_ase = chosen_arch->ase;
bbcc0807
CD
718 mips_cp0_names = chosen_arch->cp0_names;
719 mips_cp0sel_names = chosen_arch->cp0sel_names;
720 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
721 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
722 }
723#endif
724}
725
47b0e7ad
NC
726static void
727parse_mips_dis_option (const char *option, unsigned int len)
640c0ccd
CD
728{
729 unsigned int i, optionlen, vallen;
730 const char *val;
731 const struct mips_abi_choice *chosen_abi;
732 const struct mips_arch_choice *chosen_arch;
733
986e18a5 734 /* Try to match options that are simple flags */
0112cd26 735 if (CONST_STRNEQ (option, "no-aliases"))
986e18a5
FF
736 {
737 no_aliases = 1;
738 return;
739 }
b015e599
AP
740
741 if (CONST_STRNEQ (option, "virt"))
742 {
d301a56b 743 mips_ase |= ASE_VIRT;
b015e599 744 if (mips_isa & ISA_MIPS64R2)
d301a56b 745 mips_ase |= ASE_VIRT64;
b015e599
AP
746 return;
747 }
986e18a5 748
640c0ccd
CD
749 /* Look for the = that delimits the end of the option name. */
750 for (i = 0; i < len; i++)
47b0e7ad
NC
751 if (option[i] == '=')
752 break;
753
640c0ccd
CD
754 if (i == 0) /* Invalid option: no name before '='. */
755 return;
756 if (i == len) /* Invalid option: no '='. */
757 return;
758 if (i == (len - 1)) /* Invalid option: no value after '='. */
759 return;
760
761 optionlen = i;
762 val = option + (optionlen + 1);
763 vallen = len - (optionlen + 1);
764
47b0e7ad
NC
765 if (strncmp ("gpr-names", option, optionlen) == 0
766 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
767 {
768 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 769 if (chosen_abi != NULL)
640c0ccd
CD
770 mips_gpr_names = chosen_abi->gpr_names;
771 return;
772 }
773
47b0e7ad
NC
774 if (strncmp ("fpr-names", option, optionlen) == 0
775 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
776 {
777 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 778 if (chosen_abi != NULL)
640c0ccd
CD
779 mips_fpr_names = chosen_abi->fpr_names;
780 return;
781 }
782
47b0e7ad
NC
783 if (strncmp ("cp0-names", option, optionlen) == 0
784 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
785 {
786 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
787 if (chosen_arch != NULL)
788 {
789 mips_cp0_names = chosen_arch->cp0_names;
790 mips_cp0sel_names = chosen_arch->cp0sel_names;
791 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
792 }
640c0ccd
CD
793 return;
794 }
795
47b0e7ad
NC
796 if (strncmp ("hwr-names", option, optionlen) == 0
797 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
798 {
799 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 800 if (chosen_arch != NULL)
af7ee8bf
CD
801 mips_hwr_names = chosen_arch->hwr_names;
802 return;
803 }
804
47b0e7ad
NC
805 if (strncmp ("reg-names", option, optionlen) == 0
806 && strlen ("reg-names") == optionlen)
640c0ccd
CD
807 {
808 /* We check both ABI and ARCH here unconditionally, so
809 that "numeric" will do the desirable thing: select
810 numeric register names for all registers. Other than
811 that, a given name probably won't match both. */
812 chosen_abi = choose_abi_by_name (val, vallen);
813 if (chosen_abi != NULL)
814 {
bbcc0807
CD
815 mips_gpr_names = chosen_abi->gpr_names;
816 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
817 }
818 chosen_arch = choose_arch_by_name (val, vallen);
819 if (chosen_arch != NULL)
820 {
bbcc0807
CD
821 mips_cp0_names = chosen_arch->cp0_names;
822 mips_cp0sel_names = chosen_arch->cp0sel_names;
823 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
824 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
825 }
826 return;
827 }
828
829 /* Invalid option. */
830}
831
47b0e7ad
NC
832static void
833parse_mips_dis_options (const char *options)
640c0ccd
CD
834{
835 const char *option_end;
836
837 if (options == NULL)
838 return;
839
840 while (*options != '\0')
841 {
842 /* Skip empty options. */
843 if (*options == ',')
844 {
845 options++;
846 continue;
847 }
848
849 /* We know that *options is neither NUL or a comma. */
850 option_end = options + 1;
851 while (*option_end != ',' && *option_end != '\0')
852 option_end++;
853
854 parse_mips_dis_option (options, option_end - options);
855
856 /* Go on to the next one. If option_end points to a comma, it
857 will be skipped above. */
858 options = option_end;
859 }
860}
861
bbcc0807 862static const struct mips_cp0sel_name *
47b0e7ad
NC
863lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
864 unsigned int len,
865 unsigned int cp0reg,
866 unsigned int sel)
bbcc0807
CD
867{
868 unsigned int i;
869
870 for (i = 0; i < len; i++)
871 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
872 return &names[i];
873 return NULL;
874}
ab902481
RS
875
876/* Print register REGNO, of type TYPE, for instruction OPCODE. */
aa5f19f2 877
794ac9d0 878static void
ab902481
RS
879print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
880 enum mips_reg_operand_type type, int regno)
252b5132 881{
ab902481
RS
882 switch (type)
883 {
884 case OP_REG_GP:
885 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
886 break;
440cc0bc 887
ab902481
RS
888 case OP_REG_FP:
889 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
890 break;
252b5132 891
ab902481
RS
892 case OP_REG_CCC:
893 if (opcode->pinfo & (FP_D | FP_S))
894 info->fprintf_func (info->stream, "$fcc%d", regno);
895 else
896 info->fprintf_func (info->stream, "$cc%d", regno);
897 break;
794ac9d0 898
ab902481
RS
899 case OP_REG_VEC:
900 if (opcode->membership & INSN_5400)
901 info->fprintf_func (info->stream, "$f%d", regno);
902 else
903 info->fprintf_func (info->stream, "$v%d", regno);
904 break;
794ac9d0 905
ab902481
RS
906 case OP_REG_ACC:
907 info->fprintf_func (info->stream, "$ac%d", regno);
908 break;
794ac9d0 909
ab902481
RS
910 case OP_REG_COPRO:
911 if (opcode->name[strlen (opcode->name) - 1] == '0')
912 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
913 else
914 info->fprintf_func (info->stream, "$%d", regno);
915 break;
8b082fb1 916
ab902481
RS
917 case OP_REG_HW:
918 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
919 break;
14daeee3
RS
920
921 case OP_REG_VF:
922 info->fprintf_func (info->stream, "$vf%d", regno);
923 break;
924
925 case OP_REG_VI:
926 info->fprintf_func (info->stream, "$vi%d", regno);
927 break;
928
929 case OP_REG_R5900_I:
930 info->fprintf_func (info->stream, "$I");
931 break;
932
933 case OP_REG_R5900_Q:
934 info->fprintf_func (info->stream, "$Q");
935 break;
936
937 case OP_REG_R5900_R:
938 info->fprintf_func (info->stream, "$R");
939 break;
940
941 case OP_REG_R5900_ACC:
942 info->fprintf_func (info->stream, "$ACC");
943 break;
ab902481
RS
944 }
945}
946\f
947/* Used to track the state carried over from previous operands in
948 an instruction. */
949struct mips_print_arg_state {
950 /* The value of the last OP_INT seen. We only use this for OP_MSB,
951 where the value is known to be unsigned and small. */
952 unsigned int last_int;
953
954 /* The type and number of the last OP_REG seen. We only use this for
955 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
956 enum mips_reg_operand_type last_reg_type;
957 unsigned int last_regno;
958};
fd25c5a9 959
ab902481 960/* Initialize STATE for the start of an instruction. */
fd25c5a9 961
ab902481
RS
962static inline void
963init_print_arg_state (struct mips_print_arg_state *state)
964{
965 memset (state, 0, sizeof (*state));
966}
fd25c5a9 967
14daeee3
RS
968/* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
969 whose value is given by UVAL. */
970
971static void
972print_vu0_channel (struct disassemble_info *info,
973 const struct mips_operand *operand, unsigned int uval)
974{
975 if (operand->size == 4)
976 info->fprintf_func (info->stream, "%s%s%s%s",
977 uval & 8 ? "x" : "",
978 uval & 4 ? "y" : "",
979 uval & 2 ? "z" : "",
980 uval & 1 ? "w" : "");
981 else if (operand->size == 2)
982 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
983 else
984 abort ();
985}
986
ab902481
RS
987/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
988 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
989 the base address for OP_PCREL operands. */
fd25c5a9 990
ab902481
RS
991static void
992print_insn_arg (struct disassemble_info *info,
993 struct mips_print_arg_state *state,
994 const struct mips_opcode *opcode,
995 const struct mips_operand *operand,
996 bfd_vma base_pc,
997 unsigned int uval)
998{
999 const fprintf_ftype infprintf = info->fprintf_func;
1000 void *is = info->stream;
fd25c5a9 1001
ab902481
RS
1002 switch (operand->type)
1003 {
1004 case OP_INT:
1005 {
1006 const struct mips_int_operand *int_op;
fd25c5a9 1007
ab902481
RS
1008 int_op = (const struct mips_int_operand *) operand;
1009 uval = mips_decode_int_operand (int_op, uval);
1010 state->last_int = uval;
1011 if (int_op->print_hex)
1012 infprintf (is, "0x%x", uval);
1013 else
1014 infprintf (is, "%d", uval);
1015 }
1016 break;
fd25c5a9 1017
ab902481
RS
1018 case OP_MAPPED_INT:
1019 {
1020 const struct mips_mapped_int_operand *mint_op;
fd25c5a9 1021
ab902481
RS
1022 mint_op = (const struct mips_mapped_int_operand *) operand;
1023 uval = mint_op->int_map[uval];
1024 state->last_int = uval;
1025 if (mint_op->print_hex)
1026 infprintf (is, "0x%x", uval);
1027 else
1028 infprintf (is, "%d", uval);
1029 }
1030 break;
fd25c5a9 1031
ab902481
RS
1032 case OP_MSB:
1033 {
1034 const struct mips_msb_operand *msb_op;
dec0624d 1035
ab902481
RS
1036 msb_op = (const struct mips_msb_operand *) operand;
1037 uval += msb_op->bias;
1038 if (msb_op->add_lsb)
1039 uval -= state->last_int;
1040 infprintf (is, "0x%x", uval);
1041 }
1042 break;
dec0624d 1043
ab902481
RS
1044 case OP_REG:
1045 {
1046 const struct mips_reg_operand *reg_op;
fd25c5a9 1047
ab902481 1048 reg_op = (const struct mips_reg_operand *) operand;
fc76e730 1049 uval = mips_decode_reg_operand (reg_op, uval);
ab902481 1050 print_reg (info, opcode, reg_op->reg_type, uval);
fd25c5a9 1051
ab902481
RS
1052 state->last_reg_type = reg_op->reg_type;
1053 state->last_regno = uval;
1054 }
1055 break;
61cc0267 1056
ab902481
RS
1057 case OP_REG_PAIR:
1058 {
1059 const struct mips_reg_pair_operand *pair_op;
1060
1061 pair_op = (const struct mips_reg_pair_operand *) operand;
1062 print_reg (info, opcode, pair_op->reg_type,
1063 pair_op->reg1_map[uval]);
1064 infprintf (is, ",");
1065 print_reg (info, opcode, pair_op->reg_type,
1066 pair_op->reg2_map[uval]);
1067 }
1068 break;
61cc0267 1069
ab902481
RS
1070 case OP_PCREL:
1071 {
1072 const struct mips_pcrel_operand *pcrel_op;
61cc0267 1073
ab902481
RS
1074 pcrel_op = (const struct mips_pcrel_operand *) operand;
1075 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
61cc0267 1076
ab902481
RS
1077 /* Preserve the ISA bit for the GDB disassembler,
1078 otherwise clear it. */
1079 if (info->flavour != bfd_target_unknown_flavour)
1080 info->target &= -2;
61cc0267 1081
ab902481
RS
1082 (*info->print_address_func) (info->target, info);
1083 }
1084 break;
794ac9d0 1085
ab902481
RS
1086 case OP_PERF_REG:
1087 infprintf (is, "%d", uval);
1088 break;
794ac9d0 1089
ab902481
RS
1090 case OP_ADDIUSP_INT:
1091 {
1092 int sval;
794ac9d0 1093
ab902481
RS
1094 sval = mips_signed_operand (operand, uval) * 4;
1095 if (sval >= -8 && sval < 8)
1096 sval ^= 0x400;
1097 infprintf (is, "%d", sval);
1098 break;
1099 }
794ac9d0 1100
ab902481
RS
1101 case OP_CLO_CLZ_DEST:
1102 {
1103 unsigned int reg1, reg2;
1104
1105 reg1 = uval & 31;
1106 reg2 = uval >> 5;
1107 /* If one is zero use the other. */
1108 if (reg1 == reg2 || reg2 == 0)
1109 infprintf (is, "%s", mips_gpr_names[reg1]);
1110 else if (reg1 == 0)
1111 infprintf (is, "%s", mips_gpr_names[reg2]);
1112 else
1113 /* Bogus, result depends on processor. */
1114 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1115 mips_gpr_names[reg2]);
1116 }
1117 break;
794ac9d0 1118
ab902481
RS
1119 case OP_LWM_SWM_LIST:
1120 if (operand->size == 2)
1121 {
1122 if (uval == 0)
1123 infprintf (is, "%s,%s",
1124 mips_gpr_names[16],
1125 mips_gpr_names[31]);
1126 else
1127 infprintf (is, "%s-%s,%s",
1128 mips_gpr_names[16],
1129 mips_gpr_names[16 + uval],
1130 mips_gpr_names[31]);
1131 }
1132 else
1133 {
1134 int s_reg_encode;
794ac9d0 1135
ab902481
RS
1136 s_reg_encode = uval & 0xf;
1137 if (s_reg_encode != 0)
1138 {
1139 if (s_reg_encode == 1)
1140 infprintf (is, "%s", mips_gpr_names[16]);
1141 else if (s_reg_encode < 9)
1142 infprintf (is, "%s-%s",
1143 mips_gpr_names[16],
1144 mips_gpr_names[15 + s_reg_encode]);
1145 else if (s_reg_encode == 9)
1146 infprintf (is, "%s-%s,%s",
1147 mips_gpr_names[16],
1148 mips_gpr_names[23],
1149 mips_gpr_names[30]);
1150 else
1151 infprintf (is, "UNKNOWN");
1152 }
794ac9d0 1153
ab902481
RS
1154 if (uval & 0x10) /* For ra. */
1155 {
1156 if (s_reg_encode == 0)
1157 infprintf (is, "%s", mips_gpr_names[31]);
1158 else
1159 infprintf (is, ",%s", mips_gpr_names[31]);
1160 }
1161 }
1162 break;
794ac9d0 1163
c3c07478
RS
1164 case OP_ENTRY_EXIT_LIST:
1165 {
1166 const char *sep;
1167 unsigned int amask, smask;
1168
1169 sep = "";
1170 amask = (uval >> 3) & 7;
1171 if (amask > 0 && amask < 5)
1172 {
1173 infprintf (is, "%s", mips_gpr_names[4]);
1174 if (amask > 1)
1175 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1176 sep = ",";
1177 }
1178
1179 smask = (uval >> 1) & 3;
1180 if (smask == 3)
1181 {
1182 infprintf (is, "%s??", sep);
1183 sep = ",";
1184 }
1185 else if (smask > 0)
1186 {
1187 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1188 if (smask > 1)
1189 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1190 sep = ",";
1191 }
1192
1193 if (uval & 1)
1194 {
1195 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1196 sep = ",";
1197 }
1198
1199 if (amask == 5 || amask == 6)
1200 {
1201 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1202 if (amask == 6)
1203 infprintf (is, "-%s", mips_fpr_names[1]);
1204 }
1205 }
1206 break;
1207
1208 case OP_SAVE_RESTORE_LIST:
1209 /* Should be handled by the caller due to extend behavior. */
1210 abort ();
1211
ab902481
RS
1212 case OP_MDMX_IMM_REG:
1213 {
1214 unsigned int vsel;
794ac9d0 1215
ab902481
RS
1216 vsel = uval >> 5;
1217 uval &= 31;
1218 if ((vsel & 0x10) == 0)
794ac9d0 1219 {
ab902481
RS
1220 int fmt;
1221
1222 vsel &= 0x0f;
1223 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1224 if ((vsel & 1) == 0)
1225 break;
1226 print_reg (info, opcode, OP_REG_VEC, uval);
1227 infprintf (is, "[%d]", vsel >> 1);
794ac9d0 1228 }
ab902481
RS
1229 else if ((vsel & 0x08) == 0)
1230 print_reg (info, opcode, OP_REG_VEC, uval);
1231 else
1232 infprintf (is, "0x%x", uval);
1233 }
1234 break;
794ac9d0 1235
ab902481
RS
1236 case OP_REPEAT_PREV_REG:
1237 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1238 break;
794ac9d0 1239
ab902481
RS
1240 case OP_REPEAT_DEST_REG:
1241 /* Should always match OP_REPEAT_PREV_REG first. */
1242 abort ();
794ac9d0 1243
ab902481
RS
1244 case OP_PC:
1245 infprintf (is, "$pc");
1246 break;
14daeee3
RS
1247
1248 case OP_VU0_SUFFIX:
1249 case OP_VU0_MATCH_SUFFIX:
1250 print_vu0_channel (info, operand, uval);
1251 break;
ab902481
RS
1252 }
1253}
794ac9d0 1254
ab902481
RS
1255/* Print the arguments for INSN, which is described by OPCODE.
1256 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1257 as the base of OP_PCREL operands. */
af7ee8bf 1258
ab902481
RS
1259static void
1260print_insn_args (struct disassemble_info *info,
1261 const struct mips_opcode *opcode,
1262 const struct mips_operand *(*decode_operand) (const char *),
1263 unsigned int insn, bfd_vma base_pc)
1264{
1265 const fprintf_ftype infprintf = info->fprintf_func;
1266 void *is = info->stream;
1267 struct mips_print_arg_state state;
1268 const struct mips_operand *operand;
1269 const char *s;
794ac9d0 1270
ab902481
RS
1271 init_print_arg_state (&state);
1272 for (s = opcode->args; *s; ++s)
1273 {
1274 switch (*s)
1275 {
1276 case ',':
1277 case '(':
1278 case ')':
1279 infprintf (is, "%c", *s);
794ac9d0
CD
1280 break;
1281
14daeee3
RS
1282 case '#':
1283 ++s;
1284 infprintf (is, "%c%c", *s, *s);
1285 break;
1286
ab902481
RS
1287 default:
1288 operand = decode_operand (s);
1289 if (!operand)
fa7616a4 1290 {
ab902481
RS
1291 /* xgettext:c-format */
1292 infprintf (is,
1293 _("# internal error, undefined operand in `%s %s'"),
1294 opcode->name, opcode->args);
1295 return;
1296 }
1297 if (operand->type == OP_REG
1298 && s[1] == ','
1299 && s[2] == 'H'
1300 && opcode->name[strlen (opcode->name) - 1] == '0')
1301 {
1302 /* Coprocessor register 0 with sel field (MT ASE). */
1303 const struct mips_cp0sel_name *n;
1304 unsigned int reg, sel;
1305
1306 reg = mips_extract_operand (operand, insn);
1307 s += 2;
1308 operand = decode_operand (s);
1309 sel = mips_extract_operand (operand, insn);
1310
1311 /* CP0 register including 'sel' code for mftc0, to be
1312 printed textually if known. If not known, print both
1313 CP0 register name and sel numerically since CP0 register
1314 with sel 0 may have a name unrelated to register being
1315 printed. */
1316 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1317 mips_cp0sel_names_len,
1318 reg, sel);
1319 if (n != NULL)
1320 infprintf (is, "%s", n->name);
fa7616a4 1321 else
ab902481 1322 infprintf (is, "$%d,%d", reg, sel);
fa7616a4 1323 }
794ac9d0 1324 else
ab902481
RS
1325 print_insn_arg (info, &state, opcode, operand, base_pc,
1326 mips_extract_operand (operand, insn));
1327 if (*s == 'm' || *s == '+')
1328 ++s;
794ac9d0 1329 break;
af7ee8bf 1330 }
252b5132
RH
1331 }
1332}
1333\f
252b5132
RH
1334/* Print the mips instruction at address MEMADDR in debugged memory,
1335 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1336 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1337 this is little-endian code. */
1338
1339static int
47b0e7ad 1340print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1341 int word,
47b0e7ad 1342 struct disassemble_info *info)
252b5132 1343{
ab902481
RS
1344#define GET_OP(insn, field) \
1345 (((insn) >> OP_SH_##field) & OP_MASK_##field)
fc8c4fd1
MR
1346 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1347 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1348 const struct mips_opcode *op;
b34976b6 1349 static bfd_boolean init = 0;
fc8c4fd1 1350 void *is = info->stream;
252b5132
RH
1351
1352 /* Build a hash table to shorten the search time. */
1353 if (! init)
1354 {
1355 unsigned int i;
1356
1357 for (i = 0; i <= OP_MASK_OP; i++)
1358 {
1359 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1360 {
986e18a5 1361 if (op->pinfo == INSN_MACRO
9e836e3d 1362 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1363 continue;
fc8c4fd1 1364 if (i == GET_OP (op->match, OP))
252b5132
RH
1365 {
1366 mips_hash[i] = op;
1367 break;
1368 }
1369 }
7f6621cd 1370 }
252b5132
RH
1371
1372 init = 1;
1373 }
1374
aa5f19f2 1375 info->bytes_per_chunk = INSNLEN;
252b5132 1376 info->display_endian = info->endian;
9bb28706
CD
1377 info->insn_info_valid = 1;
1378 info->branch_delay_insns = 0;
def7143b 1379 info->data_size = 0;
9bb28706
CD
1380 info->insn_type = dis_nonbranch;
1381 info->target = 0;
1382 info->target2 = 0;
252b5132 1383
fc8c4fd1 1384 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1385 if (op != NULL)
1386 {
1387 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1388 {
986e18a5 1389 if (op->pinfo != INSN_MACRO
9e836e3d 1390 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1391 && (word & op->mask) == op->match)
252b5132 1392 {
3396de36 1393 /* We always allow to disassemble the jalx instruction. */
d301a56b 1394 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
3396de36 1395 && strcmp (op->name, "jalx"))
252b5132
RH
1396 continue;
1397
9bb28706
CD
1398 /* Figure out instruction type and branch delay information. */
1399 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1400 {
fc76e730 1401 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
9bb28706
CD
1402 info->insn_type = dis_jsr;
1403 else
1404 info->insn_type = dis_branch;
1405 info->branch_delay_insns = 1;
1406 }
1407 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1408 | INSN_COND_BRANCH_LIKELY)) != 0)
1409 {
c680e7f6 1410 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1411 info->insn_type = dis_condjsr;
1412 else
1413 info->insn_type = dis_condbranch;
1414 info->branch_delay_insns = 1;
1415 }
1416 else if ((op->pinfo & (INSN_STORE_MEMORY
1417 | INSN_LOAD_MEMORY_DELAY)) != 0)
1418 info->insn_type = dis_dref;
1419
fc8c4fd1 1420 infprintf (is, "%s", op->name);
14daeee3
RS
1421 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1422 {
1423 unsigned int uval;
1424
1425 infprintf (is, ".");
1426 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1427 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1428 }
252b5132 1429
ab902481 1430 if (op->args[0])
252b5132 1431 {
fc8c4fd1 1432 infprintf (is, "\t");
ab902481
RS
1433 print_insn_args (info, op, decode_mips_operand, word,
1434 memaddr + 4);
252b5132
RH
1435 }
1436
aa5f19f2 1437 return INSNLEN;
252b5132
RH
1438 }
1439 }
1440 }
fc8c4fd1 1441#undef GET_OP
252b5132
RH
1442
1443 /* Handle undefined instructions. */
9bb28706 1444 info->insn_type = dis_noninsn;
fc8c4fd1 1445 infprintf (is, "0x%x", word);
aa5f19f2 1446 return INSNLEN;
252b5132 1447}
aa5f19f2 1448\f
252b5132
RH
1449/* Disassemble an operand for a mips16 instruction. */
1450
1451static void
c3c07478
RS
1452print_mips16_insn_arg (struct disassemble_info *info,
1453 struct mips_print_arg_state *state,
1454 const struct mips_opcode *opcode,
1455 char type, bfd_vma memaddr,
1456 unsigned insn, bfd_boolean use_extend,
1457 unsigned extend, bfd_boolean is_offset)
252b5132 1458{
fc8c4fd1
MR
1459 const fprintf_ftype infprintf = info->fprintf_func;
1460 void *is = info->stream;
c3c07478
RS
1461 const struct mips_operand *operand, *ext_operand;
1462 unsigned int uval;
1463 bfd_vma baseaddr;
1464
1465 if (!use_extend)
1466 extend = 0;
fc8c4fd1 1467
252b5132
RH
1468 switch (type)
1469 {
1470 case ',':
1471 case '(':
1472 case ')':
fc8c4fd1 1473 infprintf (is, "%c", type);
252b5132
RH
1474 break;
1475
c3c07478
RS
1476 default:
1477 operand = decode_mips16_operand (type, FALSE);
1478 if (!operand)
1479 {
1480 /* xgettext:c-format */
1481 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1482 opcode->name, opcode->args);
1483 return;
1484 }
252b5132 1485
c3c07478
RS
1486 if (operand->type == OP_SAVE_RESTORE_LIST)
1487 {
1488 /* Handle this case here because of the complex interation
1489 with the EXTEND opcode. */
1490 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1491 const char *sep;
252b5132 1492
c3c07478
RS
1493 amask = extend & 0xf;
1494 if (amask == MIPS16_ALL_ARGS)
1495 {
1496 nargs = 4;
1497 nstatics = 0;
1498 }
1499 else if (amask == MIPS16_ALL_STATICS)
1500 {
1501 nargs = 0;
1502 nstatics = 4;
1503 }
1504 else
1505 {
1506 nargs = amask >> 2;
1507 nstatics = amask & 3;
1508 }
252b5132 1509
c3c07478
RS
1510 sep = "";
1511 if (nargs > 0)
1512 {
1513 infprintf (is, "%s", mips_gpr_names[4]);
1514 if (nargs > 1)
1515 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1516 sep = ",";
1517 }
252b5132 1518
c3c07478
RS
1519 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1520 if (frame_size == 0 && !use_extend)
1521 frame_size = 128;
1522 infprintf (is, "%s%d", sep, frame_size);
1523
1524 if (insn & 0x40) /* $ra */
1525 infprintf (is, ",%s", mips_gpr_names[31]);
1526
1527 nsreg = (extend >> 8) & 0x7;
1528 smask = 0;
1529 if (insn & 0x20) /* $s0 */
1530 smask |= 1 << 0;
1531 if (insn & 0x10) /* $s1 */
1532 smask |= 1 << 1;
1533 if (nsreg > 0) /* $s2-$s8 */
1534 smask |= ((1 << nsreg) - 1) << 2;
1535
1536 for (i = 0; i < 9; i++)
1537 if (smask & (1 << i))
252b5132 1538 {
c3c07478
RS
1539 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1540 /* Skip over string of set bits. */
1541 for (j = i; smask & (2 << j); j++)
1542 continue;
1543 if (j > i)
1544 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1545 i = j + 1;
252b5132 1546 }
c3c07478
RS
1547 /* Statics $ax - $a3. */
1548 if (nstatics == 1)
1549 infprintf (is, ",%s", mips_gpr_names[7]);
1550 else if (nstatics > 0)
1551 infprintf (is, ",%s-%s",
1552 mips_gpr_names[7 - nstatics + 1],
1553 mips_gpr_names[7]);
1554 break;
1555 }
252b5132 1556
c3c07478
RS
1557 if (is_offset && operand->type == OP_INT)
1558 {
1559 const struct mips_int_operand *int_op;
252b5132 1560
c3c07478
RS
1561 int_op = (const struct mips_int_operand *) operand;
1562 info->insn_type = dis_dref;
1563 info->data_size = 1 << int_op->shift;
1564 }
252b5132 1565
c3c07478
RS
1566 if (operand->size == 26)
1567 /* In this case INSN is the first two bytes of the instruction
1568 and EXTEND is the second two bytes. */
1569 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
1570 else
1571 {
1572 /* Calculate the full field value. */
1573 uval = mips_extract_operand (operand, insn);
1574 if (use_extend)
1575 {
1576 ext_operand = decode_mips16_operand (type, TRUE);
1577 if (ext_operand != operand)
1578 {
1579 operand = ext_operand;
1580 if (operand->size == 16)
1581 uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1582 else if (operand->size == 15)
1583 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1584 else
1585 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
1586 }
1587 }
1588 }
1589
1590 baseaddr = memaddr + 2;
1591 if (operand->type == OP_PCREL)
1592 {
1593 const struct mips_pcrel_operand *pcrel_op;
1594
1595 pcrel_op = (const struct mips_pcrel_operand *) operand;
1596 if (!pcrel_op->include_isa_bit && use_extend)
1597 baseaddr = memaddr - 2;
1598 else if (!pcrel_op->include_isa_bit)
1599 {
1600 bfd_byte buffer[2];
1601
1602 /* If this instruction is in the delay slot of a JR
1603 instruction, the base address is the address of the
1604 JR instruction. If it is in the delay slot of a JALR
1605 instruction, the base address is the address of the
1606 JALR instruction. This test is unreliable: we have
1607 no way of knowing whether the previous word is
1608 instruction or data. */
1609 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1610 && (((info->endian == BFD_ENDIAN_BIG
1611 ? bfd_getb16 (buffer)
1612 : bfd_getl16 (buffer))
1613 & 0xf800) == 0x1800))
1614 baseaddr = memaddr - 4;
1615 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1616 info) == 0
252b5132
RH
1617 && (((info->endian == BFD_ENDIAN_BIG
1618 ? bfd_getb16 (buffer)
1619 : bfd_getl16 (buffer))
1620 & 0xf81f) == 0xe800))
c3c07478
RS
1621 baseaddr = memaddr - 2;
1622 else
1623 baseaddr = memaddr;
1624 }
1625 }
0499d65b 1626
6d075bce 1627 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
0499d65b 1628 break;
252b5132
RH
1629 }
1630}
640c0ccd 1631
1bbce132
MR
1632
1633/* Check if the given address is the last word of a MIPS16 PLT entry.
1634 This word is data and depending on the value it may interfere with
1635 disassembly of further PLT entries. We make use of the fact PLT
1636 symbols are marked BSF_SYNTHETIC. */
1637static bfd_boolean
1638is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
1639{
1640 if (info->symbols
1641 && info->symbols[0]
1642 && (info->symbols[0]->flags & BSF_SYNTHETIC)
1643 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
1644 return TRUE;
1645
1646 return FALSE;
1647}
1648
47b0e7ad
NC
1649/* Disassemble mips16 instructions. */
1650
1651static int
1652print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1653{
fc8c4fd1 1654 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1655 int status;
1bbce132 1656 bfd_byte buffer[4];
47b0e7ad
NC
1657 int length;
1658 int insn;
1659 bfd_boolean use_extend;
1660 int extend = 0;
1661 const struct mips_opcode *op, *opend;
c3c07478 1662 struct mips_print_arg_state state;
fc8c4fd1 1663 void *is = info->stream;
47b0e7ad
NC
1664
1665 info->bytes_per_chunk = 2;
1666 info->display_endian = info->endian;
1667 info->insn_info_valid = 1;
1668 info->branch_delay_insns = 0;
1669 info->data_size = 0;
47b0e7ad
NC
1670 info->target = 0;
1671 info->target2 = 0;
1672
c3c07478
RS
1673#define GET_OP(insn, field) \
1674 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1bbce132
MR
1675 /* Decode PLT entry's GOT slot address word. */
1676 if (is_mips16_plt_tail (info, memaddr))
1677 {
1678 info->insn_type = dis_noninsn;
1679 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
1680 if (status == 0)
1681 {
1682 unsigned int gotslot;
1683
1684 if (info->endian == BFD_ENDIAN_BIG)
1685 gotslot = bfd_getb32 (buffer);
1686 else
1687 gotslot = bfd_getl32 (buffer);
1688 infprintf (is, ".word\t0x%x", gotslot);
1689
1690 return 4;
1691 }
1692 }
1693 else
1694 {
1695 info->insn_type = dis_nonbranch;
1696 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1697 }
47b0e7ad
NC
1698 if (status != 0)
1699 {
1700 (*info->memory_error_func) (status, memaddr, info);
1701 return -1;
1702 }
1703
1704 length = 2;
1705
1706 if (info->endian == BFD_ENDIAN_BIG)
1707 insn = bfd_getb16 (buffer);
1708 else
1709 insn = bfd_getl16 (buffer);
1710
1711 /* Handle the extend opcode specially. */
1712 use_extend = FALSE;
1713 if ((insn & 0xf800) == 0xf000)
1714 {
1715 use_extend = TRUE;
1716 extend = insn & 0x7ff;
1717
1718 memaddr += 2;
1719
1720 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1721 if (status != 0)
1722 {
fc8c4fd1 1723 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1724 (*info->memory_error_func) (status, memaddr, info);
1725 return -1;
1726 }
1727
1728 if (info->endian == BFD_ENDIAN_BIG)
1729 insn = bfd_getb16 (buffer);
1730 else
1731 insn = bfd_getl16 (buffer);
1732
1733 /* Check for an extend opcode followed by an extend opcode. */
1734 if ((insn & 0xf800) == 0xf000)
1735 {
fc8c4fd1 1736 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1737 info->insn_type = dis_noninsn;
1738 return length;
1739 }
1740
1741 length += 2;
1742 }
1743
1744 /* FIXME: Should probably use a hash table on the major opcode here. */
1745
1746 opend = mips16_opcodes + bfd_mips16_num_opcodes;
1747 for (op = mips16_opcodes; op < opend; op++)
1748 {
1749 if (op->pinfo != INSN_MACRO
1750 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1751 && (insn & op->mask) == op->match)
1752 {
1753 const char *s;
1754
27c5c572 1755 if (op->args[0] == 'a' || op->args[0] == 'i')
47b0e7ad
NC
1756 {
1757 if (use_extend)
1758 {
fc8c4fd1 1759 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1760 info->insn_type = dis_noninsn;
1761 return length - 2;
1762 }
1763
1764 use_extend = FALSE;
1765
1766 memaddr += 2;
1767
1768 status = (*info->read_memory_func) (memaddr, buffer, 2,
1769 info);
1770 if (status == 0)
1771 {
1772 use_extend = TRUE;
1773 if (info->endian == BFD_ENDIAN_BIG)
1774 extend = bfd_getb16 (buffer);
1775 else
1776 extend = bfd_getl16 (buffer);
1777 length += 2;
1778 }
1779 }
1780
fc8c4fd1 1781 infprintf (is, "%s", op->name);
47b0e7ad 1782 if (op->args[0] != '\0')
fc8c4fd1 1783 infprintf (is, "\t");
47b0e7ad 1784
c3c07478 1785 init_print_arg_state (&state);
47b0e7ad
NC
1786 for (s = op->args; *s != '\0'; s++)
1787 {
1788 if (*s == ','
1789 && s[1] == 'w'
fc8c4fd1 1790 && GET_OP (insn, RX) == GET_OP (insn, RY))
47b0e7ad
NC
1791 {
1792 /* Skip the register and the comma. */
1793 ++s;
1794 continue;
1795 }
1796 if (*s == ','
1797 && s[1] == 'v'
fc8c4fd1 1798 && GET_OP (insn, RZ) == GET_OP (insn, RX))
47b0e7ad
NC
1799 {
1800 /* Skip the register and the comma. */
1801 ++s;
1802 continue;
1803 }
c3c07478
RS
1804 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
1805 use_extend, extend, s[1] == '(');
47b0e7ad
NC
1806 }
1807
9a2c7088 1808 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 1809 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088 1810 info->branch_delay_insns = 1;
26545944
RS
1811 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
1812 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
47b0e7ad 1813 {
9a2c7088
MR
1814 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1815 info->insn_type = dis_jsr;
1816 else
47b0e7ad
NC
1817 info->insn_type = dis_branch;
1818 }
26545944 1819 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
9a2c7088 1820 info->insn_type = dis_condbranch;
47b0e7ad
NC
1821
1822 return length;
1823 }
1824 }
fc8c4fd1 1825#undef GET_OP
47b0e7ad
NC
1826
1827 if (use_extend)
fc8c4fd1
MR
1828 infprintf (is, "0x%x", extend | 0xf000);
1829 infprintf (is, "0x%x", insn);
47b0e7ad
NC
1830 info->insn_type = dis_noninsn;
1831
1832 return length;
1833}
1834
df58fc94
RS
1835/* Disassemble microMIPS instructions. */
1836
1837static int
1838print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
1839{
0c7533d3 1840 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94 1841 const struct mips_opcode *op, *opend;
df58fc94 1842 void *is = info->stream;
df58fc94 1843 bfd_byte buffer[2];
ab902481
RS
1844 unsigned int higher;
1845 unsigned int length;
df58fc94 1846 int status;
ab902481 1847 unsigned int insn;
df58fc94
RS
1848
1849 info->bytes_per_chunk = 2;
1850 info->display_endian = info->endian;
1851 info->insn_info_valid = 1;
1852 info->branch_delay_insns = 0;
1853 info->data_size = 0;
1854 info->insn_type = dis_nonbranch;
1855 info->target = 0;
1856 info->target2 = 0;
1857
1858 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1859 if (status != 0)
1860 {
1861 (*info->memory_error_func) (status, memaddr, info);
1862 return -1;
1863 }
1864
1865 length = 2;
1866
1867 if (info->endian == BFD_ENDIAN_BIG)
1868 insn = bfd_getb16 (buffer);
1869 else
1870 insn = bfd_getl16 (buffer);
1871
1872 if ((insn & 0xfc00) == 0x7c00)
1873 {
1874 /* This is a 48-bit microMIPS instruction. */
1875 higher = insn;
1876
1877 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
1878 if (status != 0)
1879 {
0c7533d3 1880 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
1881 (*info->memory_error_func) (status, memaddr + 2, info);
1882 return -1;
1883 }
1884 if (info->endian == BFD_ENDIAN_BIG)
1885 insn = bfd_getb16 (buffer);
1886 else
1887 insn = bfd_getl16 (buffer);
1888 higher = (higher << 16) | insn;
1889
1890 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
1891 if (status != 0)
1892 {
0c7533d3 1893 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
1894 (*info->memory_error_func) (status, memaddr + 4, info);
1895 return -1;
1896 }
1897 if (info->endian == BFD_ENDIAN_BIG)
1898 insn = bfd_getb16 (buffer);
1899 else
1900 insn = bfd_getl16 (buffer);
0c7533d3 1901 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
df58fc94
RS
1902
1903 info->insn_type = dis_noninsn;
1904 return 6;
1905 }
1906 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
1907 {
1908 /* This is a 32-bit microMIPS instruction. */
1909 higher = insn;
1910
1911 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
1912 if (status != 0)
1913 {
0c7533d3 1914 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
1915 (*info->memory_error_func) (status, memaddr + 2, info);
1916 return -1;
1917 }
1918
1919 if (info->endian == BFD_ENDIAN_BIG)
1920 insn = bfd_getb16 (buffer);
1921 else
1922 insn = bfd_getl16 (buffer);
1923
1924 insn = insn | (higher << 16);
1925
1926 length += 2;
1927 }
1928
1929 /* FIXME: Should probably use a hash table on the major opcode here. */
1930
df58fc94
RS
1931 opend = micromips_opcodes + bfd_micromips_num_opcodes;
1932 for (op = micromips_opcodes; op < opend; op++)
1933 {
1934 if (op->pinfo != INSN_MACRO
1935 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1936 && (insn & op->mask) == op->match
1937 && ((length == 2 && (op->mask & 0xffff0000) == 0)
1938 || (length == 4 && (op->mask & 0xffff0000) != 0)))
1939 {
0c7533d3 1940 infprintf (is, "%s", op->name);
df58fc94 1941
ab902481 1942 if (op->args[0])
df58fc94 1943 {
ab902481
RS
1944 infprintf (is, "\t");
1945 print_insn_args (info, op, decode_micromips_operand, insn,
1946 memaddr + length + 1);
df58fc94
RS
1947 }
1948
1949 /* Figure out instruction type and branch delay information. */
1950 if ((op->pinfo
1951 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
1952 info->branch_delay_insns = 1;
1953 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
1954 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
1955 {
fc76e730 1956 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
df58fc94
RS
1957 info->insn_type = dis_jsr;
1958 else
1959 info->insn_type = dis_branch;
1960 }
1961 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
1962 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
1963 {
1964 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1965 info->insn_type = dis_condjsr;
1966 else
1967 info->insn_type = dis_condbranch;
1968 }
1969 else if ((op->pinfo
1970 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY_DELAY)) != 0)
1971 info->insn_type = dis_dref;
1972
1973 return length;
1974 }
1975 }
df58fc94 1976
0c7533d3 1977 infprintf (is, "0x%x", insn);
df58fc94
RS
1978 info->insn_type = dis_noninsn;
1979
1980 return length;
1981}
1982
1983/* Return 1 if a symbol associated with the location being disassembled
1984 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
1985 all the symbols at the address being considered assuming if at least
1986 one of them indicates code compression, then such code has been
1987 genuinely produced here (other symbols could have been derived from
1988 function symbols defined elsewhere or could define data). Otherwise,
1989 return 0. */
1990
1991static bfd_boolean
1992is_compressed_mode_p (struct disassemble_info *info)
1993{
df58fc94 1994 int i;
1bbce132
MR
1995 int l;
1996
1997 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
1998 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
1999 && ((!micromips_ase
2000 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2001 || (micromips_ase
2002 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2003 return 1;
2004 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2005 && info->symtab[i]->section == info->section)
2006 {
2007 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2008 if ((!micromips_ase
2009 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2010 || (micromips_ase
2011 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2012 return 1;
2013 }
df58fc94
RS
2014
2015 return 0;
2016}
2017
47b0e7ad
NC
2018/* In an environment where we do not know the symbol type of the
2019 instruction we are forced to assume that the low order bit of the
2020 instructions' address may mark it as a mips16 instruction. If we
2021 are single stepping, or the pc is within the disassembled function,
2022 this works. Otherwise, we need a clue. Sometimes. */
2023
2024static int
2025_print_insn_mips (bfd_vma memaddr,
2026 struct disassemble_info *info,
2027 enum bfd_endian endianness)
2028{
df58fc94 2029 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
47b0e7ad
NC
2030 bfd_byte buffer[INSNLEN];
2031 int status;
2032
2033 set_default_mips_dis_options (info);
2034 parse_mips_dis_options (info->disassembler_options);
2035
df58fc94
RS
2036 if (info->mach == bfd_mach_mips16)
2037 return print_insn_mips16 (memaddr, info);
2038 if (info->mach == bfd_mach_mips_micromips)
2039 return print_insn_micromips (memaddr, info);
2040
2041 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
2042
47b0e7ad 2043#if 1
df58fc94 2044 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
2045 /* Only a few tools will work this way. */
2046 if (memaddr & 0x01)
df58fc94 2047 return print_insn_compr (memaddr, info);
47b0e7ad
NC
2048#endif
2049
2050#if SYMTAB_AVAILABLE
df58fc94
RS
2051 if (is_compressed_mode_p (info))
2052 return print_insn_compr (memaddr, info);
47b0e7ad
NC
2053#endif
2054
2055 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2056 if (status == 0)
2057 {
fc8c4fd1 2058 int insn;
47b0e7ad
NC
2059
2060 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 2061 insn = bfd_getb32 (buffer);
47b0e7ad 2062 else
fc8c4fd1 2063 insn = bfd_getl32 (buffer);
47b0e7ad
NC
2064
2065 return print_insn_mips (memaddr, insn, info);
2066 }
2067 else
2068 {
2069 (*info->memory_error_func) (status, memaddr, info);
2070 return -1;
2071 }
2072}
2073
2074int
2075print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2076{
2077 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2078}
2079
2080int
2081print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2082{
2083 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2084}
2085\f
640c0ccd 2086void
47b0e7ad 2087print_mips_disassembler_options (FILE *stream)
640c0ccd 2088{
4a9a3c54 2089 unsigned int i;
640c0ccd
CD
2090
2091 fprintf (stream, _("\n\
2092The following MIPS specific disassembler options are supported for use\n\
2093with the -M switch (multiple options should be separated by commas):\n"));
2094
b015e599
AP
2095 fprintf (stream, _("\n\
2096 virt Recognize the virtualization ASE instructions.\n"));
2097
640c0ccd
CD
2098 fprintf (stream, _("\n\
2099 gpr-names=ABI Print GPR names according to specified ABI.\n\
2100 Default: based on binary being disassembled.\n"));
2101
2102 fprintf (stream, _("\n\
2103 fpr-names=ABI Print FPR names according to specified ABI.\n\
2104 Default: numeric.\n"));
2105
2106 fprintf (stream, _("\n\
2107 cp0-names=ARCH Print CP0 register names according to\n\
2108 specified architecture.\n\
2109 Default: based on binary being disassembled.\n"));
2110
af7ee8bf
CD
2111 fprintf (stream, _("\n\
2112 hwr-names=ARCH Print HWR names according to specified \n\
2113 architecture.\n\
2114 Default: based on binary being disassembled.\n"));
2115
640c0ccd
CD
2116 fprintf (stream, _("\n\
2117 reg-names=ABI Print GPR and FPR names according to\n\
2118 specified ABI.\n"));
2119
2120 fprintf (stream, _("\n\
af7ee8bf 2121 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
2122 specified architecture.\n"));
2123
2124 fprintf (stream, _("\n\
2125 For the options above, the following values are supported for \"ABI\":\n\
2126 "));
4a9a3c54 2127 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
2128 fprintf (stream, " %s", mips_abi_choices[i].name);
2129 fprintf (stream, _("\n"));
2130
2131 fprintf (stream, _("\n\
2132 For the options above, The following values are supported for \"ARCH\":\n\
2133 "));
4a9a3c54 2134 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
2135 if (*mips_arch_choices[i].name != '\0')
2136 fprintf (stream, " %s", mips_arch_choices[i].name);
2137 fprintf (stream, _("\n"));
2138
2139 fprintf (stream, _("\n"));
2140}
This page took 0.732462 seconds and 4 git commands to generate.