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