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