daily update
[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;
920 }
921}
922\f
923/* Used to track the state carried over from previous operands in
924 an instruction. */
925struct mips_print_arg_state {
926 /* The value of the last OP_INT seen. We only use this for OP_MSB,
927 where the value is known to be unsigned and small. */
928 unsigned int last_int;
929
930 /* The type and number of the last OP_REG seen. We only use this for
931 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
932 enum mips_reg_operand_type last_reg_type;
933 unsigned int last_regno;
934};
fd25c5a9 935
ab902481 936/* Initialize STATE for the start of an instruction. */
fd25c5a9 937
ab902481
RS
938static inline void
939init_print_arg_state (struct mips_print_arg_state *state)
940{
941 memset (state, 0, sizeof (*state));
942}
fd25c5a9 943
ab902481
RS
944/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
945 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
946 the base address for OP_PCREL operands. */
fd25c5a9 947
ab902481
RS
948static void
949print_insn_arg (struct disassemble_info *info,
950 struct mips_print_arg_state *state,
951 const struct mips_opcode *opcode,
952 const struct mips_operand *operand,
953 bfd_vma base_pc,
954 unsigned int uval)
955{
956 const fprintf_ftype infprintf = info->fprintf_func;
957 void *is = info->stream;
fd25c5a9 958
ab902481
RS
959 switch (operand->type)
960 {
961 case OP_INT:
962 {
963 const struct mips_int_operand *int_op;
fd25c5a9 964
ab902481
RS
965 int_op = (const struct mips_int_operand *) operand;
966 uval = mips_decode_int_operand (int_op, uval);
967 state->last_int = uval;
968 if (int_op->print_hex)
969 infprintf (is, "0x%x", uval);
970 else
971 infprintf (is, "%d", uval);
972 }
973 break;
fd25c5a9 974
ab902481
RS
975 case OP_MAPPED_INT:
976 {
977 const struct mips_mapped_int_operand *mint_op;
fd25c5a9 978
ab902481
RS
979 mint_op = (const struct mips_mapped_int_operand *) operand;
980 uval = mint_op->int_map[uval];
981 state->last_int = uval;
982 if (mint_op->print_hex)
983 infprintf (is, "0x%x", uval);
984 else
985 infprintf (is, "%d", uval);
986 }
987 break;
fd25c5a9 988
ab902481
RS
989 case OP_MSB:
990 {
991 const struct mips_msb_operand *msb_op;
dec0624d 992
ab902481
RS
993 msb_op = (const struct mips_msb_operand *) operand;
994 uval += msb_op->bias;
995 if (msb_op->add_lsb)
996 uval -= state->last_int;
997 infprintf (is, "0x%x", uval);
998 }
999 break;
dec0624d 1000
ab902481
RS
1001 case OP_REG:
1002 {
1003 const struct mips_reg_operand *reg_op;
fd25c5a9 1004
ab902481 1005 reg_op = (const struct mips_reg_operand *) operand;
fc76e730 1006 uval = mips_decode_reg_operand (reg_op, uval);
ab902481 1007 print_reg (info, opcode, reg_op->reg_type, uval);
fd25c5a9 1008
ab902481
RS
1009 state->last_reg_type = reg_op->reg_type;
1010 state->last_regno = uval;
1011 }
1012 break;
61cc0267 1013
ab902481
RS
1014 case OP_REG_PAIR:
1015 {
1016 const struct mips_reg_pair_operand *pair_op;
1017
1018 pair_op = (const struct mips_reg_pair_operand *) operand;
1019 print_reg (info, opcode, pair_op->reg_type,
1020 pair_op->reg1_map[uval]);
1021 infprintf (is, ",");
1022 print_reg (info, opcode, pair_op->reg_type,
1023 pair_op->reg2_map[uval]);
1024 }
1025 break;
61cc0267 1026
ab902481
RS
1027 case OP_PCREL:
1028 {
1029 const struct mips_pcrel_operand *pcrel_op;
61cc0267 1030
ab902481
RS
1031 pcrel_op = (const struct mips_pcrel_operand *) operand;
1032 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
61cc0267 1033
ab902481
RS
1034 /* Preserve the ISA bit for the GDB disassembler,
1035 otherwise clear it. */
1036 if (info->flavour != bfd_target_unknown_flavour)
1037 info->target &= -2;
61cc0267 1038
ab902481
RS
1039 (*info->print_address_func) (info->target, info);
1040 }
1041 break;
794ac9d0 1042
ab902481
RS
1043 case OP_PERF_REG:
1044 infprintf (is, "%d", uval);
1045 break;
794ac9d0 1046
ab902481
RS
1047 case OP_ADDIUSP_INT:
1048 {
1049 int sval;
794ac9d0 1050
ab902481
RS
1051 sval = mips_signed_operand (operand, uval) * 4;
1052 if (sval >= -8 && sval < 8)
1053 sval ^= 0x400;
1054 infprintf (is, "%d", sval);
1055 break;
1056 }
794ac9d0 1057
ab902481
RS
1058 case OP_CLO_CLZ_DEST:
1059 {
1060 unsigned int reg1, reg2;
1061
1062 reg1 = uval & 31;
1063 reg2 = uval >> 5;
1064 /* If one is zero use the other. */
1065 if (reg1 == reg2 || reg2 == 0)
1066 infprintf (is, "%s", mips_gpr_names[reg1]);
1067 else if (reg1 == 0)
1068 infprintf (is, "%s", mips_gpr_names[reg2]);
1069 else
1070 /* Bogus, result depends on processor. */
1071 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1072 mips_gpr_names[reg2]);
1073 }
1074 break;
794ac9d0 1075
ab902481
RS
1076 case OP_LWM_SWM_LIST:
1077 if (operand->size == 2)
1078 {
1079 if (uval == 0)
1080 infprintf (is, "%s,%s",
1081 mips_gpr_names[16],
1082 mips_gpr_names[31]);
1083 else
1084 infprintf (is, "%s-%s,%s",
1085 mips_gpr_names[16],
1086 mips_gpr_names[16 + uval],
1087 mips_gpr_names[31]);
1088 }
1089 else
1090 {
1091 int s_reg_encode;
794ac9d0 1092
ab902481
RS
1093 s_reg_encode = uval & 0xf;
1094 if (s_reg_encode != 0)
1095 {
1096 if (s_reg_encode == 1)
1097 infprintf (is, "%s", mips_gpr_names[16]);
1098 else if (s_reg_encode < 9)
1099 infprintf (is, "%s-%s",
1100 mips_gpr_names[16],
1101 mips_gpr_names[15 + s_reg_encode]);
1102 else if (s_reg_encode == 9)
1103 infprintf (is, "%s-%s,%s",
1104 mips_gpr_names[16],
1105 mips_gpr_names[23],
1106 mips_gpr_names[30]);
1107 else
1108 infprintf (is, "UNKNOWN");
1109 }
794ac9d0 1110
ab902481
RS
1111 if (uval & 0x10) /* For ra. */
1112 {
1113 if (s_reg_encode == 0)
1114 infprintf (is, "%s", mips_gpr_names[31]);
1115 else
1116 infprintf (is, ",%s", mips_gpr_names[31]);
1117 }
1118 }
1119 break;
794ac9d0 1120
c3c07478
RS
1121 case OP_ENTRY_EXIT_LIST:
1122 {
1123 const char *sep;
1124 unsigned int amask, smask;
1125
1126 sep = "";
1127 amask = (uval >> 3) & 7;
1128 if (amask > 0 && amask < 5)
1129 {
1130 infprintf (is, "%s", mips_gpr_names[4]);
1131 if (amask > 1)
1132 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1133 sep = ",";
1134 }
1135
1136 smask = (uval >> 1) & 3;
1137 if (smask == 3)
1138 {
1139 infprintf (is, "%s??", sep);
1140 sep = ",";
1141 }
1142 else if (smask > 0)
1143 {
1144 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1145 if (smask > 1)
1146 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1147 sep = ",";
1148 }
1149
1150 if (uval & 1)
1151 {
1152 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1153 sep = ",";
1154 }
1155
1156 if (amask == 5 || amask == 6)
1157 {
1158 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1159 if (amask == 6)
1160 infprintf (is, "-%s", mips_fpr_names[1]);
1161 }
1162 }
1163 break;
1164
1165 case OP_SAVE_RESTORE_LIST:
1166 /* Should be handled by the caller due to extend behavior. */
1167 abort ();
1168
ab902481
RS
1169 case OP_MDMX_IMM_REG:
1170 {
1171 unsigned int vsel;
794ac9d0 1172
ab902481
RS
1173 vsel = uval >> 5;
1174 uval &= 31;
1175 if ((vsel & 0x10) == 0)
794ac9d0 1176 {
ab902481
RS
1177 int fmt;
1178
1179 vsel &= 0x0f;
1180 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1181 if ((vsel & 1) == 0)
1182 break;
1183 print_reg (info, opcode, OP_REG_VEC, uval);
1184 infprintf (is, "[%d]", vsel >> 1);
794ac9d0 1185 }
ab902481
RS
1186 else if ((vsel & 0x08) == 0)
1187 print_reg (info, opcode, OP_REG_VEC, uval);
1188 else
1189 infprintf (is, "0x%x", uval);
1190 }
1191 break;
794ac9d0 1192
ab902481
RS
1193 case OP_REPEAT_PREV_REG:
1194 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1195 break;
794ac9d0 1196
ab902481
RS
1197 case OP_REPEAT_DEST_REG:
1198 /* Should always match OP_REPEAT_PREV_REG first. */
1199 abort ();
794ac9d0 1200
ab902481
RS
1201 case OP_PC:
1202 infprintf (is, "$pc");
1203 break;
1204 }
1205}
794ac9d0 1206
ab902481
RS
1207/* Print the arguments for INSN, which is described by OPCODE.
1208 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1209 as the base of OP_PCREL operands. */
af7ee8bf 1210
ab902481
RS
1211static void
1212print_insn_args (struct disassemble_info *info,
1213 const struct mips_opcode *opcode,
1214 const struct mips_operand *(*decode_operand) (const char *),
1215 unsigned int insn, bfd_vma base_pc)
1216{
1217 const fprintf_ftype infprintf = info->fprintf_func;
1218 void *is = info->stream;
1219 struct mips_print_arg_state state;
1220 const struct mips_operand *operand;
1221 const char *s;
794ac9d0 1222
ab902481
RS
1223 init_print_arg_state (&state);
1224 for (s = opcode->args; *s; ++s)
1225 {
1226 switch (*s)
1227 {
1228 case ',':
1229 case '(':
1230 case ')':
1231 infprintf (is, "%c", *s);
794ac9d0
CD
1232 break;
1233
ab902481
RS
1234 default:
1235 operand = decode_operand (s);
1236 if (!operand)
fa7616a4 1237 {
ab902481
RS
1238 /* xgettext:c-format */
1239 infprintf (is,
1240 _("# internal error, undefined operand in `%s %s'"),
1241 opcode->name, opcode->args);
1242 return;
1243 }
1244 if (operand->type == OP_REG
1245 && s[1] == ','
1246 && s[2] == 'H'
1247 && opcode->name[strlen (opcode->name) - 1] == '0')
1248 {
1249 /* Coprocessor register 0 with sel field (MT ASE). */
1250 const struct mips_cp0sel_name *n;
1251 unsigned int reg, sel;
1252
1253 reg = mips_extract_operand (operand, insn);
1254 s += 2;
1255 operand = decode_operand (s);
1256 sel = mips_extract_operand (operand, insn);
1257
1258 /* CP0 register including 'sel' code for mftc0, to be
1259 printed textually if known. If not known, print both
1260 CP0 register name and sel numerically since CP0 register
1261 with sel 0 may have a name unrelated to register being
1262 printed. */
1263 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1264 mips_cp0sel_names_len,
1265 reg, sel);
1266 if (n != NULL)
1267 infprintf (is, "%s", n->name);
fa7616a4 1268 else
ab902481 1269 infprintf (is, "$%d,%d", reg, sel);
fa7616a4 1270 }
794ac9d0 1271 else
ab902481
RS
1272 print_insn_arg (info, &state, opcode, operand, base_pc,
1273 mips_extract_operand (operand, insn));
1274 if (*s == 'm' || *s == '+')
1275 ++s;
794ac9d0 1276 break;
af7ee8bf 1277 }
252b5132
RH
1278 }
1279}
1280\f
252b5132
RH
1281/* Print the mips instruction at address MEMADDR in debugged memory,
1282 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1283 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1284 this is little-endian code. */
1285
1286static int
47b0e7ad 1287print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1288 int word,
47b0e7ad 1289 struct disassemble_info *info)
252b5132 1290{
ab902481
RS
1291#define GET_OP(insn, field) \
1292 (((insn) >> OP_SH_##field) & OP_MASK_##field)
fc8c4fd1
MR
1293 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1294 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1295 const struct mips_opcode *op;
b34976b6 1296 static bfd_boolean init = 0;
fc8c4fd1 1297 void *is = info->stream;
252b5132
RH
1298
1299 /* Build a hash table to shorten the search time. */
1300 if (! init)
1301 {
1302 unsigned int i;
1303
1304 for (i = 0; i <= OP_MASK_OP; i++)
1305 {
1306 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1307 {
986e18a5 1308 if (op->pinfo == INSN_MACRO
9e836e3d 1309 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1310 continue;
fc8c4fd1 1311 if (i == GET_OP (op->match, OP))
252b5132
RH
1312 {
1313 mips_hash[i] = op;
1314 break;
1315 }
1316 }
7f6621cd 1317 }
252b5132
RH
1318
1319 init = 1;
1320 }
1321
aa5f19f2 1322 info->bytes_per_chunk = INSNLEN;
252b5132 1323 info->display_endian = info->endian;
9bb28706
CD
1324 info->insn_info_valid = 1;
1325 info->branch_delay_insns = 0;
def7143b 1326 info->data_size = 0;
9bb28706
CD
1327 info->insn_type = dis_nonbranch;
1328 info->target = 0;
1329 info->target2 = 0;
252b5132 1330
fc8c4fd1 1331 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1332 if (op != NULL)
1333 {
1334 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1335 {
986e18a5 1336 if (op->pinfo != INSN_MACRO
9e836e3d 1337 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1338 && (word & op->mask) == op->match)
252b5132 1339 {
3396de36 1340 /* We always allow to disassemble the jalx instruction. */
d301a56b 1341 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
3396de36 1342 && strcmp (op->name, "jalx"))
252b5132
RH
1343 continue;
1344
9bb28706
CD
1345 /* Figure out instruction type and branch delay information. */
1346 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1347 {
fc76e730 1348 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
9bb28706
CD
1349 info->insn_type = dis_jsr;
1350 else
1351 info->insn_type = dis_branch;
1352 info->branch_delay_insns = 1;
1353 }
1354 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1355 | INSN_COND_BRANCH_LIKELY)) != 0)
1356 {
c680e7f6 1357 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1358 info->insn_type = dis_condjsr;
1359 else
1360 info->insn_type = dis_condbranch;
1361 info->branch_delay_insns = 1;
1362 }
1363 else if ((op->pinfo & (INSN_STORE_MEMORY
1364 | INSN_LOAD_MEMORY_DELAY)) != 0)
1365 info->insn_type = dis_dref;
1366
fc8c4fd1 1367 infprintf (is, "%s", op->name);
252b5132 1368
ab902481 1369 if (op->args[0])
252b5132 1370 {
fc8c4fd1 1371 infprintf (is, "\t");
ab902481
RS
1372 print_insn_args (info, op, decode_mips_operand, word,
1373 memaddr + 4);
252b5132
RH
1374 }
1375
aa5f19f2 1376 return INSNLEN;
252b5132
RH
1377 }
1378 }
1379 }
fc8c4fd1 1380#undef GET_OP
252b5132
RH
1381
1382 /* Handle undefined instructions. */
9bb28706 1383 info->insn_type = dis_noninsn;
fc8c4fd1 1384 infprintf (is, "0x%x", word);
aa5f19f2 1385 return INSNLEN;
252b5132 1386}
aa5f19f2 1387\f
252b5132
RH
1388/* Disassemble an operand for a mips16 instruction. */
1389
1390static void
c3c07478
RS
1391print_mips16_insn_arg (struct disassemble_info *info,
1392 struct mips_print_arg_state *state,
1393 const struct mips_opcode *opcode,
1394 char type, bfd_vma memaddr,
1395 unsigned insn, bfd_boolean use_extend,
1396 unsigned extend, bfd_boolean is_offset)
252b5132 1397{
fc8c4fd1
MR
1398 const fprintf_ftype infprintf = info->fprintf_func;
1399 void *is = info->stream;
c3c07478
RS
1400 const struct mips_operand *operand, *ext_operand;
1401 unsigned int uval;
1402 bfd_vma baseaddr;
1403
1404 if (!use_extend)
1405 extend = 0;
fc8c4fd1 1406
252b5132
RH
1407 switch (type)
1408 {
1409 case ',':
1410 case '(':
1411 case ')':
fc8c4fd1 1412 infprintf (is, "%c", type);
252b5132
RH
1413 break;
1414
c3c07478
RS
1415 default:
1416 operand = decode_mips16_operand (type, FALSE);
1417 if (!operand)
1418 {
1419 /* xgettext:c-format */
1420 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1421 opcode->name, opcode->args);
1422 return;
1423 }
252b5132 1424
c3c07478
RS
1425 if (operand->type == OP_SAVE_RESTORE_LIST)
1426 {
1427 /* Handle this case here because of the complex interation
1428 with the EXTEND opcode. */
1429 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1430 const char *sep;
252b5132 1431
c3c07478
RS
1432 amask = extend & 0xf;
1433 if (amask == MIPS16_ALL_ARGS)
1434 {
1435 nargs = 4;
1436 nstatics = 0;
1437 }
1438 else if (amask == MIPS16_ALL_STATICS)
1439 {
1440 nargs = 0;
1441 nstatics = 4;
1442 }
1443 else
1444 {
1445 nargs = amask >> 2;
1446 nstatics = amask & 3;
1447 }
252b5132 1448
c3c07478
RS
1449 sep = "";
1450 if (nargs > 0)
1451 {
1452 infprintf (is, "%s", mips_gpr_names[4]);
1453 if (nargs > 1)
1454 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1455 sep = ",";
1456 }
252b5132 1457
c3c07478
RS
1458 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1459 if (frame_size == 0 && !use_extend)
1460 frame_size = 128;
1461 infprintf (is, "%s%d", sep, frame_size);
1462
1463 if (insn & 0x40) /* $ra */
1464 infprintf (is, ",%s", mips_gpr_names[31]);
1465
1466 nsreg = (extend >> 8) & 0x7;
1467 smask = 0;
1468 if (insn & 0x20) /* $s0 */
1469 smask |= 1 << 0;
1470 if (insn & 0x10) /* $s1 */
1471 smask |= 1 << 1;
1472 if (nsreg > 0) /* $s2-$s8 */
1473 smask |= ((1 << nsreg) - 1) << 2;
1474
1475 for (i = 0; i < 9; i++)
1476 if (smask & (1 << i))
252b5132 1477 {
c3c07478
RS
1478 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1479 /* Skip over string of set bits. */
1480 for (j = i; smask & (2 << j); j++)
1481 continue;
1482 if (j > i)
1483 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1484 i = j + 1;
252b5132 1485 }
c3c07478
RS
1486 /* Statics $ax - $a3. */
1487 if (nstatics == 1)
1488 infprintf (is, ",%s", mips_gpr_names[7]);
1489 else if (nstatics > 0)
1490 infprintf (is, ",%s-%s",
1491 mips_gpr_names[7 - nstatics + 1],
1492 mips_gpr_names[7]);
1493 break;
1494 }
252b5132 1495
c3c07478
RS
1496 if (is_offset && operand->type == OP_INT)
1497 {
1498 const struct mips_int_operand *int_op;
252b5132 1499
c3c07478
RS
1500 int_op = (const struct mips_int_operand *) operand;
1501 info->insn_type = dis_dref;
1502 info->data_size = 1 << int_op->shift;
1503 }
252b5132 1504
c3c07478
RS
1505 if (operand->size == 26)
1506 /* In this case INSN is the first two bytes of the instruction
1507 and EXTEND is the second two bytes. */
1508 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
1509 else
1510 {
1511 /* Calculate the full field value. */
1512 uval = mips_extract_operand (operand, insn);
1513 if (use_extend)
1514 {
1515 ext_operand = decode_mips16_operand (type, TRUE);
1516 if (ext_operand != operand)
1517 {
1518 operand = ext_operand;
1519 if (operand->size == 16)
1520 uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1521 else if (operand->size == 15)
1522 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1523 else
1524 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
1525 }
1526 }
1527 }
1528
1529 baseaddr = memaddr + 2;
1530 if (operand->type == OP_PCREL)
1531 {
1532 const struct mips_pcrel_operand *pcrel_op;
1533
1534 pcrel_op = (const struct mips_pcrel_operand *) operand;
1535 if (!pcrel_op->include_isa_bit && use_extend)
1536 baseaddr = memaddr - 2;
1537 else if (!pcrel_op->include_isa_bit)
1538 {
1539 bfd_byte buffer[2];
1540
1541 /* If this instruction is in the delay slot of a JR
1542 instruction, the base address is the address of the
1543 JR instruction. If it is in the delay slot of a JALR
1544 instruction, the base address is the address of the
1545 JALR instruction. This test is unreliable: we have
1546 no way of knowing whether the previous word is
1547 instruction or data. */
1548 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1549 && (((info->endian == BFD_ENDIAN_BIG
1550 ? bfd_getb16 (buffer)
1551 : bfd_getl16 (buffer))
1552 & 0xf800) == 0x1800))
1553 baseaddr = memaddr - 4;
1554 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1555 info) == 0
252b5132
RH
1556 && (((info->endian == BFD_ENDIAN_BIG
1557 ? bfd_getb16 (buffer)
1558 : bfd_getl16 (buffer))
1559 & 0xf81f) == 0xe800))
c3c07478
RS
1560 baseaddr = memaddr - 2;
1561 else
1562 baseaddr = memaddr;
1563 }
1564 }
0499d65b 1565
6d075bce 1566 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
0499d65b 1567 break;
252b5132
RH
1568 }
1569}
640c0ccd 1570
1bbce132
MR
1571
1572/* Check if the given address is the last word of a MIPS16 PLT entry.
1573 This word is data and depending on the value it may interfere with
1574 disassembly of further PLT entries. We make use of the fact PLT
1575 symbols are marked BSF_SYNTHETIC. */
1576static bfd_boolean
1577is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
1578{
1579 if (info->symbols
1580 && info->symbols[0]
1581 && (info->symbols[0]->flags & BSF_SYNTHETIC)
1582 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
1583 return TRUE;
1584
1585 return FALSE;
1586}
1587
47b0e7ad
NC
1588/* Disassemble mips16 instructions. */
1589
1590static int
1591print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1592{
fc8c4fd1 1593 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1594 int status;
1bbce132 1595 bfd_byte buffer[4];
47b0e7ad
NC
1596 int length;
1597 int insn;
1598 bfd_boolean use_extend;
1599 int extend = 0;
1600 const struct mips_opcode *op, *opend;
c3c07478 1601 struct mips_print_arg_state state;
fc8c4fd1 1602 void *is = info->stream;
47b0e7ad
NC
1603
1604 info->bytes_per_chunk = 2;
1605 info->display_endian = info->endian;
1606 info->insn_info_valid = 1;
1607 info->branch_delay_insns = 0;
1608 info->data_size = 0;
47b0e7ad
NC
1609 info->target = 0;
1610 info->target2 = 0;
1611
c3c07478
RS
1612#define GET_OP(insn, field) \
1613 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1bbce132
MR
1614 /* Decode PLT entry's GOT slot address word. */
1615 if (is_mips16_plt_tail (info, memaddr))
1616 {
1617 info->insn_type = dis_noninsn;
1618 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
1619 if (status == 0)
1620 {
1621 unsigned int gotslot;
1622
1623 if (info->endian == BFD_ENDIAN_BIG)
1624 gotslot = bfd_getb32 (buffer);
1625 else
1626 gotslot = bfd_getl32 (buffer);
1627 infprintf (is, ".word\t0x%x", gotslot);
1628
1629 return 4;
1630 }
1631 }
1632 else
1633 {
1634 info->insn_type = dis_nonbranch;
1635 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1636 }
47b0e7ad
NC
1637 if (status != 0)
1638 {
1639 (*info->memory_error_func) (status, memaddr, info);
1640 return -1;
1641 }
1642
1643 length = 2;
1644
1645 if (info->endian == BFD_ENDIAN_BIG)
1646 insn = bfd_getb16 (buffer);
1647 else
1648 insn = bfd_getl16 (buffer);
1649
1650 /* Handle the extend opcode specially. */
1651 use_extend = FALSE;
1652 if ((insn & 0xf800) == 0xf000)
1653 {
1654 use_extend = TRUE;
1655 extend = insn & 0x7ff;
1656
1657 memaddr += 2;
1658
1659 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1660 if (status != 0)
1661 {
fc8c4fd1 1662 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1663 (*info->memory_error_func) (status, memaddr, info);
1664 return -1;
1665 }
1666
1667 if (info->endian == BFD_ENDIAN_BIG)
1668 insn = bfd_getb16 (buffer);
1669 else
1670 insn = bfd_getl16 (buffer);
1671
1672 /* Check for an extend opcode followed by an extend opcode. */
1673 if ((insn & 0xf800) == 0xf000)
1674 {
fc8c4fd1 1675 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1676 info->insn_type = dis_noninsn;
1677 return length;
1678 }
1679
1680 length += 2;
1681 }
1682
1683 /* FIXME: Should probably use a hash table on the major opcode here. */
1684
1685 opend = mips16_opcodes + bfd_mips16_num_opcodes;
1686 for (op = mips16_opcodes; op < opend; op++)
1687 {
1688 if (op->pinfo != INSN_MACRO
1689 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1690 && (insn & op->mask) == op->match)
1691 {
1692 const char *s;
1693
27c5c572 1694 if (op->args[0] == 'a' || op->args[0] == 'i')
47b0e7ad
NC
1695 {
1696 if (use_extend)
1697 {
fc8c4fd1 1698 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1699 info->insn_type = dis_noninsn;
1700 return length - 2;
1701 }
1702
1703 use_extend = FALSE;
1704
1705 memaddr += 2;
1706
1707 status = (*info->read_memory_func) (memaddr, buffer, 2,
1708 info);
1709 if (status == 0)
1710 {
1711 use_extend = TRUE;
1712 if (info->endian == BFD_ENDIAN_BIG)
1713 extend = bfd_getb16 (buffer);
1714 else
1715 extend = bfd_getl16 (buffer);
1716 length += 2;
1717 }
1718 }
1719
fc8c4fd1 1720 infprintf (is, "%s", op->name);
47b0e7ad 1721 if (op->args[0] != '\0')
fc8c4fd1 1722 infprintf (is, "\t");
47b0e7ad 1723
c3c07478 1724 init_print_arg_state (&state);
47b0e7ad
NC
1725 for (s = op->args; *s != '\0'; s++)
1726 {
1727 if (*s == ','
1728 && s[1] == 'w'
fc8c4fd1 1729 && GET_OP (insn, RX) == GET_OP (insn, RY))
47b0e7ad
NC
1730 {
1731 /* Skip the register and the comma. */
1732 ++s;
1733 continue;
1734 }
1735 if (*s == ','
1736 && s[1] == 'v'
fc8c4fd1 1737 && GET_OP (insn, RZ) == GET_OP (insn, RX))
47b0e7ad
NC
1738 {
1739 /* Skip the register and the comma. */
1740 ++s;
1741 continue;
1742 }
c3c07478
RS
1743 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
1744 use_extend, extend, s[1] == '(');
47b0e7ad
NC
1745 }
1746
9a2c7088 1747 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 1748 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088 1749 info->branch_delay_insns = 1;
26545944
RS
1750 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
1751 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
47b0e7ad 1752 {
9a2c7088
MR
1753 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1754 info->insn_type = dis_jsr;
1755 else
47b0e7ad
NC
1756 info->insn_type = dis_branch;
1757 }
26545944 1758 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
9a2c7088 1759 info->insn_type = dis_condbranch;
47b0e7ad
NC
1760
1761 return length;
1762 }
1763 }
fc8c4fd1 1764#undef GET_OP
47b0e7ad
NC
1765
1766 if (use_extend)
fc8c4fd1
MR
1767 infprintf (is, "0x%x", extend | 0xf000);
1768 infprintf (is, "0x%x", insn);
47b0e7ad
NC
1769 info->insn_type = dis_noninsn;
1770
1771 return length;
1772}
1773
df58fc94
RS
1774/* Disassemble microMIPS instructions. */
1775
1776static int
1777print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
1778{
0c7533d3 1779 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94 1780 const struct mips_opcode *op, *opend;
df58fc94 1781 void *is = info->stream;
df58fc94 1782 bfd_byte buffer[2];
ab902481
RS
1783 unsigned int higher;
1784 unsigned int length;
df58fc94 1785 int status;
ab902481 1786 unsigned int insn;
df58fc94
RS
1787
1788 info->bytes_per_chunk = 2;
1789 info->display_endian = info->endian;
1790 info->insn_info_valid = 1;
1791 info->branch_delay_insns = 0;
1792 info->data_size = 0;
1793 info->insn_type = dis_nonbranch;
1794 info->target = 0;
1795 info->target2 = 0;
1796
1797 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1798 if (status != 0)
1799 {
1800 (*info->memory_error_func) (status, memaddr, info);
1801 return -1;
1802 }
1803
1804 length = 2;
1805
1806 if (info->endian == BFD_ENDIAN_BIG)
1807 insn = bfd_getb16 (buffer);
1808 else
1809 insn = bfd_getl16 (buffer);
1810
1811 if ((insn & 0xfc00) == 0x7c00)
1812 {
1813 /* This is a 48-bit microMIPS instruction. */
1814 higher = insn;
1815
1816 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
1817 if (status != 0)
1818 {
0c7533d3 1819 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
1820 (*info->memory_error_func) (status, memaddr + 2, info);
1821 return -1;
1822 }
1823 if (info->endian == BFD_ENDIAN_BIG)
1824 insn = bfd_getb16 (buffer);
1825 else
1826 insn = bfd_getl16 (buffer);
1827 higher = (higher << 16) | insn;
1828
1829 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
1830 if (status != 0)
1831 {
0c7533d3 1832 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
1833 (*info->memory_error_func) (status, memaddr + 4, info);
1834 return -1;
1835 }
1836 if (info->endian == BFD_ENDIAN_BIG)
1837 insn = bfd_getb16 (buffer);
1838 else
1839 insn = bfd_getl16 (buffer);
0c7533d3 1840 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
df58fc94
RS
1841
1842 info->insn_type = dis_noninsn;
1843 return 6;
1844 }
1845 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
1846 {
1847 /* This is a 32-bit microMIPS instruction. */
1848 higher = insn;
1849
1850 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
1851 if (status != 0)
1852 {
0c7533d3 1853 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
1854 (*info->memory_error_func) (status, memaddr + 2, info);
1855 return -1;
1856 }
1857
1858 if (info->endian == BFD_ENDIAN_BIG)
1859 insn = bfd_getb16 (buffer);
1860 else
1861 insn = bfd_getl16 (buffer);
1862
1863 insn = insn | (higher << 16);
1864
1865 length += 2;
1866 }
1867
1868 /* FIXME: Should probably use a hash table on the major opcode here. */
1869
df58fc94
RS
1870 opend = micromips_opcodes + bfd_micromips_num_opcodes;
1871 for (op = micromips_opcodes; op < opend; op++)
1872 {
1873 if (op->pinfo != INSN_MACRO
1874 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1875 && (insn & op->mask) == op->match
1876 && ((length == 2 && (op->mask & 0xffff0000) == 0)
1877 || (length == 4 && (op->mask & 0xffff0000) != 0)))
1878 {
0c7533d3 1879 infprintf (is, "%s", op->name);
df58fc94 1880
ab902481 1881 if (op->args[0])
df58fc94 1882 {
ab902481
RS
1883 infprintf (is, "\t");
1884 print_insn_args (info, op, decode_micromips_operand, insn,
1885 memaddr + length + 1);
df58fc94
RS
1886 }
1887
1888 /* Figure out instruction type and branch delay information. */
1889 if ((op->pinfo
1890 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
1891 info->branch_delay_insns = 1;
1892 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
1893 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
1894 {
fc76e730 1895 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
df58fc94
RS
1896 info->insn_type = dis_jsr;
1897 else
1898 info->insn_type = dis_branch;
1899 }
1900 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
1901 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
1902 {
1903 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1904 info->insn_type = dis_condjsr;
1905 else
1906 info->insn_type = dis_condbranch;
1907 }
1908 else if ((op->pinfo
1909 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY_DELAY)) != 0)
1910 info->insn_type = dis_dref;
1911
1912 return length;
1913 }
1914 }
df58fc94 1915
0c7533d3 1916 infprintf (is, "0x%x", insn);
df58fc94
RS
1917 info->insn_type = dis_noninsn;
1918
1919 return length;
1920}
1921
1922/* Return 1 if a symbol associated with the location being disassembled
1923 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
1924 all the symbols at the address being considered assuming if at least
1925 one of them indicates code compression, then such code has been
1926 genuinely produced here (other symbols could have been derived from
1927 function symbols defined elsewhere or could define data). Otherwise,
1928 return 0. */
1929
1930static bfd_boolean
1931is_compressed_mode_p (struct disassemble_info *info)
1932{
df58fc94 1933 int i;
1bbce132
MR
1934 int l;
1935
1936 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
1937 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
1938 && ((!micromips_ase
1939 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
1940 || (micromips_ase
1941 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
1942 return 1;
1943 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
1944 && info->symtab[i]->section == info->section)
1945 {
1946 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
1947 if ((!micromips_ase
1948 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
1949 || (micromips_ase
1950 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
1951 return 1;
1952 }
df58fc94
RS
1953
1954 return 0;
1955}
1956
47b0e7ad
NC
1957/* In an environment where we do not know the symbol type of the
1958 instruction we are forced to assume that the low order bit of the
1959 instructions' address may mark it as a mips16 instruction. If we
1960 are single stepping, or the pc is within the disassembled function,
1961 this works. Otherwise, we need a clue. Sometimes. */
1962
1963static int
1964_print_insn_mips (bfd_vma memaddr,
1965 struct disassemble_info *info,
1966 enum bfd_endian endianness)
1967{
df58fc94 1968 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
47b0e7ad
NC
1969 bfd_byte buffer[INSNLEN];
1970 int status;
1971
1972 set_default_mips_dis_options (info);
1973 parse_mips_dis_options (info->disassembler_options);
1974
df58fc94
RS
1975 if (info->mach == bfd_mach_mips16)
1976 return print_insn_mips16 (memaddr, info);
1977 if (info->mach == bfd_mach_mips_micromips)
1978 return print_insn_micromips (memaddr, info);
1979
1980 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
1981
47b0e7ad 1982#if 1
df58fc94 1983 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
1984 /* Only a few tools will work this way. */
1985 if (memaddr & 0x01)
df58fc94 1986 return print_insn_compr (memaddr, info);
47b0e7ad
NC
1987#endif
1988
1989#if SYMTAB_AVAILABLE
df58fc94
RS
1990 if (is_compressed_mode_p (info))
1991 return print_insn_compr (memaddr, info);
47b0e7ad
NC
1992#endif
1993
1994 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
1995 if (status == 0)
1996 {
fc8c4fd1 1997 int insn;
47b0e7ad
NC
1998
1999 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 2000 insn = bfd_getb32 (buffer);
47b0e7ad 2001 else
fc8c4fd1 2002 insn = bfd_getl32 (buffer);
47b0e7ad
NC
2003
2004 return print_insn_mips (memaddr, insn, info);
2005 }
2006 else
2007 {
2008 (*info->memory_error_func) (status, memaddr, info);
2009 return -1;
2010 }
2011}
2012
2013int
2014print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2015{
2016 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2017}
2018
2019int
2020print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2021{
2022 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2023}
2024\f
640c0ccd 2025void
47b0e7ad 2026print_mips_disassembler_options (FILE *stream)
640c0ccd 2027{
4a9a3c54 2028 unsigned int i;
640c0ccd
CD
2029
2030 fprintf (stream, _("\n\
2031The following MIPS specific disassembler options are supported for use\n\
2032with the -M switch (multiple options should be separated by commas):\n"));
2033
b015e599
AP
2034 fprintf (stream, _("\n\
2035 virt Recognize the virtualization ASE instructions.\n"));
2036
640c0ccd
CD
2037 fprintf (stream, _("\n\
2038 gpr-names=ABI Print GPR names according to specified ABI.\n\
2039 Default: based on binary being disassembled.\n"));
2040
2041 fprintf (stream, _("\n\
2042 fpr-names=ABI Print FPR names according to specified ABI.\n\
2043 Default: numeric.\n"));
2044
2045 fprintf (stream, _("\n\
2046 cp0-names=ARCH Print CP0 register names according to\n\
2047 specified architecture.\n\
2048 Default: based on binary being disassembled.\n"));
2049
af7ee8bf
CD
2050 fprintf (stream, _("\n\
2051 hwr-names=ARCH Print HWR names according to specified \n\
2052 architecture.\n\
2053 Default: based on binary being disassembled.\n"));
2054
640c0ccd
CD
2055 fprintf (stream, _("\n\
2056 reg-names=ABI Print GPR and FPR names according to\n\
2057 specified ABI.\n"));
2058
2059 fprintf (stream, _("\n\
af7ee8bf 2060 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
2061 specified architecture.\n"));
2062
2063 fprintf (stream, _("\n\
2064 For the options above, the following values are supported for \"ABI\":\n\
2065 "));
4a9a3c54 2066 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
2067 fprintf (stream, " %s", mips_abi_choices[i].name);
2068 fprintf (stream, _("\n"));
2069
2070 fprintf (stream, _("\n\
2071 For the options above, The following values are supported for \"ARCH\":\n\
2072 "));
4a9a3c54 2073 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
2074 if (*mips_arch_choices[i].name != '\0')
2075 fprintf (stream, " %s", mips_arch_choices[i].name);
2076 fprintf (stream, _("\n"));
2077
2078 fprintf (stream, _("\n"));
2079}
This page took 0.750577 seconds and 4 git commands to generate.