Fix attributation of DWARF augmentation patch.
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
CommitLineData
252b5132 1/* Print mips instructions for GDB, the GNU debugger, or for objdump.
82704155 2 Copyright (C) 1989-2019 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 22#include "sysdep.h"
6394c606 23#include "disassemble.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
47b0e7ad
NC
160static const char * const mips_cp0_names_mips3264[32] =
161{
640c0ccd
CD
162 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
163 "c0_context", "c0_pagemask", "c0_wired", "$7",
164 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
165 "c0_status", "c0_cause", "c0_epc", "c0_prid",
166 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
167 "c0_xcontext", "$21", "$22", "c0_debug",
168 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
169 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
170};
171
dc76d757
AB
172static const char * const mips_cp1_names_mips3264[32] =
173{
174 "c1_fir", "c1_ufr", "$2", "$3",
175 "c1_unfr", "$5", "$6", "$7",
176 "$8", "$9", "$10", "$11",
177 "$12", "$13", "$14", "$15",
178 "$16", "$17", "$18", "$19",
179 "$20", "$21", "$22", "$23",
180 "$24", "c1_fccr", "c1_fexr", "$27",
181 "c1_fenr", "$29", "$30", "c1_fcsr"
182};
183
47b0e7ad
NC
184static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
185{
bbcc0807
CD
186 { 16, 1, "c0_config1" },
187 { 16, 2, "c0_config2" },
188 { 16, 3, "c0_config3" },
189 { 18, 1, "c0_watchlo,1" },
190 { 18, 2, "c0_watchlo,2" },
191 { 18, 3, "c0_watchlo,3" },
192 { 18, 4, "c0_watchlo,4" },
193 { 18, 5, "c0_watchlo,5" },
194 { 18, 6, "c0_watchlo,6" },
195 { 18, 7, "c0_watchlo,7" },
196 { 19, 1, "c0_watchhi,1" },
197 { 19, 2, "c0_watchhi,2" },
198 { 19, 3, "c0_watchhi,3" },
199 { 19, 4, "c0_watchhi,4" },
200 { 19, 5, "c0_watchhi,5" },
201 { 19, 6, "c0_watchhi,6" },
202 { 19, 7, "c0_watchhi,7" },
203 { 25, 1, "c0_perfcnt,1" },
204 { 25, 2, "c0_perfcnt,2" },
205 { 25, 3, "c0_perfcnt,3" },
206 { 25, 4, "c0_perfcnt,4" },
207 { 25, 5, "c0_perfcnt,5" },
208 { 25, 6, "c0_perfcnt,6" },
209 { 25, 7, "c0_perfcnt,7" },
210 { 27, 1, "c0_cacheerr,1" },
211 { 27, 2, "c0_cacheerr,2" },
212 { 27, 3, "c0_cacheerr,3" },
213 { 28, 1, "c0_datalo" },
214 { 29, 1, "c0_datahi" }
215};
216
47b0e7ad
NC
217static const char * const mips_cp0_names_mips3264r2[32] =
218{
af7ee8bf
CD
219 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
220 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
221 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
222 "c0_status", "c0_cause", "c0_epc", "c0_prid",
223 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
224 "c0_xcontext", "$21", "$22", "c0_debug",
225 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
226 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
227};
228
47b0e7ad
NC
229static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
230{
bbcc0807 231 { 4, 1, "c0_contextconfig" },
59c455b3
TS
232 { 0, 1, "c0_mvpcontrol" },
233 { 0, 2, "c0_mvpconf0" },
234 { 0, 3, "c0_mvpconf1" },
235 { 1, 1, "c0_vpecontrol" },
236 { 1, 2, "c0_vpeconf0" },
237 { 1, 3, "c0_vpeconf1" },
238 { 1, 4, "c0_yqmask" },
239 { 1, 5, "c0_vpeschedule" },
240 { 1, 6, "c0_vpeschefback" },
241 { 2, 1, "c0_tcstatus" },
242 { 2, 2, "c0_tcbind" },
243 { 2, 3, "c0_tcrestart" },
244 { 2, 4, "c0_tchalt" },
245 { 2, 5, "c0_tccontext" },
246 { 2, 6, "c0_tcschedule" },
247 { 2, 7, "c0_tcschefback" },
bbcc0807 248 { 5, 1, "c0_pagegrain" },
59c455b3
TS
249 { 6, 1, "c0_srsconf0" },
250 { 6, 2, "c0_srsconf1" },
251 { 6, 3, "c0_srsconf2" },
252 { 6, 4, "c0_srsconf3" },
253 { 6, 5, "c0_srsconf4" },
bbcc0807
CD
254 { 12, 1, "c0_intctl" },
255 { 12, 2, "c0_srsctl" },
256 { 12, 3, "c0_srsmap" },
257 { 15, 1, "c0_ebase" },
258 { 16, 1, "c0_config1" },
259 { 16, 2, "c0_config2" },
260 { 16, 3, "c0_config3" },
261 { 18, 1, "c0_watchlo,1" },
262 { 18, 2, "c0_watchlo,2" },
263 { 18, 3, "c0_watchlo,3" },
264 { 18, 4, "c0_watchlo,4" },
265 { 18, 5, "c0_watchlo,5" },
266 { 18, 6, "c0_watchlo,6" },
267 { 18, 7, "c0_watchlo,7" },
268 { 19, 1, "c0_watchhi,1" },
269 { 19, 2, "c0_watchhi,2" },
270 { 19, 3, "c0_watchhi,3" },
271 { 19, 4, "c0_watchhi,4" },
272 { 19, 5, "c0_watchhi,5" },
273 { 19, 6, "c0_watchhi,6" },
274 { 19, 7, "c0_watchhi,7" },
275 { 23, 1, "c0_tracecontrol" },
276 { 23, 2, "c0_tracecontrol2" },
277 { 23, 3, "c0_usertracedata" },
278 { 23, 4, "c0_tracebpc" },
279 { 25, 1, "c0_perfcnt,1" },
280 { 25, 2, "c0_perfcnt,2" },
281 { 25, 3, "c0_perfcnt,3" },
282 { 25, 4, "c0_perfcnt,4" },
283 { 25, 5, "c0_perfcnt,5" },
284 { 25, 6, "c0_perfcnt,6" },
285 { 25, 7, "c0_perfcnt,7" },
286 { 27, 1, "c0_cacheerr,1" },
287 { 27, 2, "c0_cacheerr,2" },
288 { 27, 3, "c0_cacheerr,3" },
289 { 28, 1, "c0_datalo" },
290 { 28, 2, "c0_taglo1" },
291 { 28, 3, "c0_datalo1" },
292 { 28, 4, "c0_taglo2" },
293 { 28, 5, "c0_datalo2" },
294 { 28, 6, "c0_taglo3" },
295 { 28, 7, "c0_datalo3" },
296 { 29, 1, "c0_datahi" },
297 { 29, 2, "c0_taghi1" },
298 { 29, 3, "c0_datahi1" },
299 { 29, 4, "c0_taghi2" },
300 { 29, 5, "c0_datahi2" },
301 { 29, 6, "c0_taghi3" },
302 { 29, 7, "c0_datahi3" },
303};
304
640c0ccd 305/* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
47b0e7ad
NC
306static const char * const mips_cp0_names_sb1[32] =
307{
640c0ccd
CD
308 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
309 "c0_context", "c0_pagemask", "c0_wired", "$7",
310 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
311 "c0_status", "c0_cause", "c0_epc", "c0_prid",
312 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
313 "c0_xcontext", "$21", "$22", "c0_debug",
314 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
315 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
316};
317
47b0e7ad
NC
318static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
319{
bbcc0807
CD
320 { 16, 1, "c0_config1" },
321 { 18, 1, "c0_watchlo,1" },
322 { 19, 1, "c0_watchhi,1" },
323 { 22, 0, "c0_perftrace" },
324 { 23, 3, "c0_edebug" },
325 { 25, 1, "c0_perfcnt,1" },
326 { 25, 2, "c0_perfcnt,2" },
327 { 25, 3, "c0_perfcnt,3" },
328 { 25, 4, "c0_perfcnt,4" },
329 { 25, 5, "c0_perfcnt,5" },
330 { 25, 6, "c0_perfcnt,6" },
331 { 25, 7, "c0_perfcnt,7" },
332 { 26, 1, "c0_buserr_pa" },
333 { 27, 1, "c0_cacheerr_d" },
334 { 27, 3, "c0_cacheerr_d_pa" },
335 { 28, 1, "c0_datalo_i" },
336 { 28, 2, "c0_taglo_d" },
337 { 28, 3, "c0_datalo_d" },
338 { 29, 1, "c0_datahi_i" },
339 { 29, 2, "c0_taghi_d" },
340 { 29, 3, "c0_datahi_d" },
341};
342
52b6b6b9
JM
343/* Xlr cop0 register names. */
344static const char * const mips_cp0_names_xlr[32] = {
345 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
346 "c0_context", "c0_pagemask", "c0_wired", "$7",
347 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
348 "c0_status", "c0_cause", "c0_epc", "c0_prid",
349 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
350 "c0_xcontext", "$21", "$22", "c0_debug",
351 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
352 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
353};
354
355/* XLR's CP0 Select Registers. */
356
357static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
358 { 9, 6, "c0_extintreq" },
359 { 9, 7, "c0_extintmask" },
360 { 15, 1, "c0_ebase" },
361 { 16, 1, "c0_config1" },
362 { 16, 2, "c0_config2" },
363 { 16, 3, "c0_config3" },
364 { 16, 7, "c0_procid2" },
365 { 18, 1, "c0_watchlo,1" },
366 { 18, 2, "c0_watchlo,2" },
367 { 18, 3, "c0_watchlo,3" },
368 { 18, 4, "c0_watchlo,4" },
369 { 18, 5, "c0_watchlo,5" },
370 { 18, 6, "c0_watchlo,6" },
371 { 18, 7, "c0_watchlo,7" },
372 { 19, 1, "c0_watchhi,1" },
373 { 19, 2, "c0_watchhi,2" },
374 { 19, 3, "c0_watchhi,3" },
375 { 19, 4, "c0_watchhi,4" },
376 { 19, 5, "c0_watchhi,5" },
377 { 19, 6, "c0_watchhi,6" },
378 { 19, 7, "c0_watchhi,7" },
379 { 25, 1, "c0_perfcnt,1" },
380 { 25, 2, "c0_perfcnt,2" },
381 { 25, 3, "c0_perfcnt,3" },
382 { 25, 4, "c0_perfcnt,4" },
383 { 25, 5, "c0_perfcnt,5" },
384 { 25, 6, "c0_perfcnt,6" },
385 { 25, 7, "c0_perfcnt,7" },
386 { 27, 1, "c0_cacheerr,1" },
387 { 27, 2, "c0_cacheerr,2" },
388 { 27, 3, "c0_cacheerr,3" },
389 { 28, 1, "c0_datalo" },
390 { 29, 1, "c0_datahi" }
391};
392
47b0e7ad
NC
393static const char * const mips_hwr_names_numeric[32] =
394{
af7ee8bf
CD
395 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
396 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
397 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
398 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
399};
400
47b0e7ad
NC
401static const char * const mips_hwr_names_mips3264r2[32] =
402{
af7ee8bf
CD
403 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
404 "$4", "$5", "$6", "$7",
405 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
406 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
407 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
408};
409
4edbb8e3
CF
410static const char * const msa_control_names[32] =
411{
412 "msa_ir", "msa_csr", "msa_access", "msa_save",
413 "msa_modify", "msa_request", "msa_map", "msa_unmap",
414 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
415 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
416 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
417};
418
47b0e7ad
NC
419struct mips_abi_choice
420{
421 const char * name;
640c0ccd
CD
422 const char * const *gpr_names;
423 const char * const *fpr_names;
424};
425
47b0e7ad
NC
426struct mips_abi_choice mips_abi_choices[] =
427{
640c0ccd
CD
428 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
429 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
430 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
431 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
432};
433
47b0e7ad
NC
434struct mips_arch_choice
435{
640c0ccd
CD
436 const char *name;
437 int bfd_mach_valid;
438 unsigned long bfd_mach;
439 int processor;
440 int isa;
d301a56b 441 int ase;
640c0ccd 442 const char * const *cp0_names;
bbcc0807
CD
443 const struct mips_cp0sel_name *cp0sel_names;
444 unsigned int cp0sel_names_len;
dc76d757 445 const char * const *cp1_names;
af7ee8bf 446 const char * const *hwr_names;
640c0ccd
CD
447};
448
47b0e7ad
NC
449const struct mips_arch_choice mips_arch_choices[] =
450{
d301a56b 451 { "numeric", 0, 0, 0, 0, 0,
dc76d757
AB
452 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
453 mips_hwr_names_numeric },
bbcc0807 454
d301a56b 455 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
dc76d757
AB
456 mips_cp0_names_r3000, NULL, 0, mips_cp1_names_numeric,
457 mips_hwr_names_numeric },
d301a56b 458 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
dc76d757
AB
459 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
460 mips_hwr_names_numeric },
d301a56b 461 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
dc76d757
AB
462 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
463 mips_hwr_names_numeric },
d301a56b 464 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
dc76d757
AB
465 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
466 mips_hwr_names_numeric },
d301a56b 467 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
dc76d757
AB
468 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
469 mips_hwr_names_numeric },
d301a56b 470 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
dc76d757
AB
471 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
472 mips_hwr_names_numeric },
d301a56b 473 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
dc76d757
AB
474 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
475 mips_hwr_names_numeric },
d301a56b 476 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
dc76d757
AB
477 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
478 mips_hwr_names_numeric },
d301a56b 479 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
dc76d757
AB
480 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
481 mips_hwr_names_numeric },
d301a56b 482 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
dc76d757
AB
483 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
484 mips_hwr_names_numeric },
d301a56b 485 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
dc76d757
AB
486 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
487 mips_hwr_names_numeric },
d301a56b 488 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
dc76d757
AB
489 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
490 mips_hwr_names_numeric },
d301a56b 491 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
dc76d757
AB
492 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
493 mips_hwr_names_numeric },
d301a56b 494 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
dc76d757
AB
495 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
496 mips_hwr_names_numeric },
d301a56b 497 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
dc76d757
AB
498 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_numeric,
499 mips_hwr_names_numeric },
d301a56b 500 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
dc76d757
AB
501 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
502 mips_hwr_names_numeric },
d301a56b 503 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
dc76d757
AB
504 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
505 mips_hwr_names_numeric },
d301a56b 506 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
dc76d757
AB
507 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
508 mips_hwr_names_numeric },
d301a56b 509 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
dc76d757
AB
510 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
511 mips_hwr_names_numeric },
d301a56b 512 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
dc76d757
AB
513 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
514 mips_hwr_names_numeric },
d301a56b 515 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
dc76d757
AB
516 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
517 mips_hwr_names_numeric },
d301a56b 518 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
dc76d757
AB
519 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
520 mips_hwr_names_numeric },
d301a56b 521 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
dc76d757
AB
522 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
523 mips_hwr_names_numeric },
d301a56b 524 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
dc76d757
AB
525 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
526 mips_hwr_names_numeric },
bbcc0807 527
640c0ccd
CD
528 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
529 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
530 _MIPS32 Architecture For Programmers Volume I: Introduction to the
531 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
532 page 1. */
533 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
d301a56b 534 ISA_MIPS32, ASE_SMARTMIPS,
bbcc0807
CD
535 mips_cp0_names_mips3264,
536 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
dc76d757 537 mips_cp1_names_mips3264, mips_hwr_names_numeric },
bbcc0807 538
af7ee8bf 539 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
d301a56b 540 ISA_MIPS32R2,
7f3c4072 541 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
7d64c587 542 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
bbcc0807
CD
543 mips_cp0_names_mips3264r2,
544 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
dc76d757 545 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
bbcc0807 546
ae52f483
AB
547 { "mips32r3", 1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
548 ISA_MIPS32R3,
549 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
550 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
551 mips_cp0_names_mips3264r2,
552 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
553 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
554
555 { "mips32r5", 1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
556 ISA_MIPS32R5,
557 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
558 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
559 mips_cp0_names_mips3264r2,
560 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
561 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
562
7361da2c
AB
563 { "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
564 ISA_MIPS32R6,
565 (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
6f20c942 566 | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC | ASE_GINV),
7361da2c
AB
567 mips_cp0_names_mips3264r2,
568 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
569 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
570
640c0ccd
CD
571 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
572 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
d301a56b 573 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
bbcc0807
CD
574 mips_cp0_names_mips3264,
575 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
dc76d757 576 mips_cp1_names_mips3264, mips_hwr_names_numeric },
bbcc0807 577
5f74bc13 578 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
d301a56b 579 ISA_MIPS64R2,
7f3c4072 580 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
7d64c587 581 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
5f74bc13
CD
582 mips_cp0_names_mips3264r2,
583 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
dc76d757 584 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
5f74bc13 585
ae52f483
AB
586 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
587 ISA_MIPS64R3,
588 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
589 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
590 mips_cp0_names_mips3264r2,
591 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
592 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
593
594 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
595 ISA_MIPS64R5,
596 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
597 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
598 mips_cp0_names_mips3264r2,
599 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
600 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
601
7361da2c
AB
602 { "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
603 ISA_MIPS64R6,
604 (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
730c3174 605 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC
6f20c942 606 | ASE_CRC64 | ASE_GINV),
7361da2c
AB
607 mips_cp0_names_mips3264r2,
608 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
609 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
610
38bf472a
MR
611 { "interaptiv-mr2", 1, bfd_mach_mips_interaptiv_mr2, CPU_INTERAPTIV_MR2,
612 ISA_MIPS32R3,
613 ASE_MT | ASE_EVA | ASE_DSP | ASE_DSPR2 | ASE_MIPS16E2 | ASE_MIPS16E2_MT,
614 mips_cp0_names_mips3264r2,
615 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
616 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
617
640c0ccd 618 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
d301a56b 619 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
bbcc0807
CD
620 mips_cp0_names_sb1,
621 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
dc76d757 622 mips_cp1_names_mips3264, mips_hwr_names_numeric },
640c0ccd 623
350cc38d 624 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
d301a56b 625 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
dc76d757 626 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d
MS
627
628 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
8095d2f7 629 ISA_MIPS3 | INSN_LOONGSON_2F, ASE_LOONGSON_MMI, mips_cp0_names_numeric,
dc76d757 630 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d 631
ac8cb70f
CX
632 /* The loongson3a is an alias of gs464 for compatibility */
633 { "loongson3a", 1, bfd_mach_mips_gs464, CPU_GS464,
634 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
635 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
636 mips_hwr_names_numeric },
637
57299f48 638 { "gs464", 1, bfd_mach_mips_gs464, CPU_GS464,
bdc6c06e 639 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
716c08de
CX
640 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
641 mips_hwr_names_numeric },
fd503541 642
57299f48 643 { "gs464e", 1, bfd_mach_mips_gs464e, CPU_GS464E,
bd782c07
CX
644 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
645 | ASE_LOONGSON_EXT2, mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
646 mips_hwr_names_numeric },
647
57299f48 648 { "gs264e", 1, bfd_mach_mips_gs464e, CPU_GS264E,
9108bc33
CX
649 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT
650 | ASE_LOONGSON_EXT2 | ASE_MSA | ASE_MSA64, mips_cp0_names_numeric, NULL,
651 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
652
57b592a3 653 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
d301a56b 654 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
dc76d757 655 mips_cp1_names_mips3264, mips_hwr_names_numeric },
57b592a3 656
dd6a37e7 657 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
d301a56b 658 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
dc76d757 659 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
432233b3
AP
660
661 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
d301a56b 662 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
dc76d757 663 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
dd6a37e7 664
2c629856
N
665 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
666 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
667 mips_cp0_names_numeric,
668 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
669
52b6b6b9 670 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 671 ISA_MIPS64 | INSN_XLR, 0,
52b6b6b9
JM
672 mips_cp0_names_xlr,
673 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 674 mips_cp1_names_mips3264, mips_hwr_names_numeric },
52b6b6b9 675
55a36193
MK
676 /* XLP is mostly like XLR, with the prominent exception it is being
677 MIPS64R2. */
678 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 679 ISA_MIPS64R2 | INSN_XLR, 0,
55a36193
MK
680 mips_cp0_names_xlr,
681 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 682 mips_cp1_names_mips3264, mips_hwr_names_numeric },
55a36193 683
640c0ccd
CD
684 /* This entry, mips16, is here only for ISA/processor selection; do
685 not print its name. */
25499ac7
MR
686 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
687 ASE_MIPS16E2 | ASE_MIPS16E2_MT,
dc76d757
AB
688 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
689 mips_hwr_names_numeric },
640c0ccd
CD
690};
691
692/* ISA and processor type to disassemble for, and register names to use.
693 set_default_mips_dis_options and parse_mips_dis_options fill in these
694 values. */
695static int mips_processor;
696static int mips_isa;
d301a56b 697static int mips_ase;
df58fc94 698static int micromips_ase;
640c0ccd
CD
699static const char * const *mips_gpr_names;
700static const char * const *mips_fpr_names;
701static const char * const *mips_cp0_names;
bbcc0807
CD
702static const struct mips_cp0sel_name *mips_cp0sel_names;
703static int mips_cp0sel_names_len;
dc76d757 704static const char * const *mips_cp1_names;
af7ee8bf 705static const char * const *mips_hwr_names;
640c0ccd 706
986e18a5 707/* Other options */
47b0e7ad 708static int no_aliases; /* If set disassemble as most general inst. */
640c0ccd
CD
709\f
710static const struct mips_abi_choice *
47b0e7ad 711choose_abi_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
712{
713 const struct mips_abi_choice *c;
714 unsigned int i;
715
716 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
47b0e7ad
NC
717 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
718 && strlen (mips_abi_choices[i].name) == namelen)
719 c = &mips_abi_choices[i];
720
640c0ccd
CD
721 return c;
722}
723
724static const struct mips_arch_choice *
47b0e7ad 725choose_arch_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
726{
727 const struct mips_arch_choice *c = NULL;
728 unsigned int i;
729
730 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
47b0e7ad
NC
731 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
732 && strlen (mips_arch_choices[i].name) == namelen)
733 c = &mips_arch_choices[i];
734
640c0ccd
CD
735 return c;
736}
737
738static const struct mips_arch_choice *
47b0e7ad 739choose_arch_by_number (unsigned long mach)
640c0ccd
CD
740{
741 static unsigned long hint_bfd_mach;
742 static const struct mips_arch_choice *hint_arch_choice;
743 const struct mips_arch_choice *c;
744 unsigned int i;
745
746 /* We optimize this because even if the user specifies no
747 flags, this will be done for every instruction! */
748 if (hint_bfd_mach == mach
749 && hint_arch_choice != NULL
750 && hint_arch_choice->bfd_mach == hint_bfd_mach)
751 return hint_arch_choice;
752
753 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
754 {
755 if (mips_arch_choices[i].bfd_mach_valid
756 && mips_arch_choices[i].bfd_mach == mach)
757 {
758 c = &mips_arch_choices[i];
759 hint_bfd_mach = mach;
760 hint_arch_choice = c;
761 }
762 }
763 return c;
764}
765
47b0e7ad
NC
766/* Check if the object uses NewABI conventions. */
767
768static int
769is_newabi (Elf_Internal_Ehdr *header)
770{
771 /* There are no old-style ABIs which use 64-bit ELF. */
772 if (header->e_ident[EI_CLASS] == ELFCLASS64)
773 return 1;
774
775 /* If a 32-bit ELF file, n32 is a new-style ABI. */
776 if ((header->e_flags & EF_MIPS_ABI2) != 0)
777 return 1;
778
779 return 0;
780}
781
df58fc94
RS
782/* Check if the object has microMIPS ASE code. */
783
784static int
785is_micromips (Elf_Internal_Ehdr *header)
786{
787 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
788 return 1;
789
790 return 0;
791}
792
5e7fc731
MR
793/* Convert ASE flags from .MIPS.abiflags to internal values. */
794
795static unsigned long
796mips_convert_abiflags_ases (unsigned long afl_ases)
797{
798 unsigned long opcode_ases = 0;
799
800 if (afl_ases & AFL_ASE_DSP)
801 opcode_ases |= ASE_DSP;
802 if (afl_ases & AFL_ASE_DSPR2)
803 opcode_ases |= ASE_DSPR2;
804 if (afl_ases & AFL_ASE_EVA)
805 opcode_ases |= ASE_EVA;
806 if (afl_ases & AFL_ASE_MCU)
807 opcode_ases |= ASE_MCU;
808 if (afl_ases & AFL_ASE_MDMX)
809 opcode_ases |= ASE_MDMX;
810 if (afl_ases & AFL_ASE_MIPS3D)
811 opcode_ases |= ASE_MIPS3D;
812 if (afl_ases & AFL_ASE_MT)
813 opcode_ases |= ASE_MT;
814 if (afl_ases & AFL_ASE_SMARTMIPS)
815 opcode_ases |= ASE_SMARTMIPS;
816 if (afl_ases & AFL_ASE_VIRT)
817 opcode_ases |= ASE_VIRT;
818 if (afl_ases & AFL_ASE_MSA)
819 opcode_ases |= ASE_MSA;
820 if (afl_ases & AFL_ASE_XPA)
821 opcode_ases |= ASE_XPA;
822 if (afl_ases & AFL_ASE_DSPR3)
823 opcode_ases |= ASE_DSPR3;
25499ac7
MR
824 if (afl_ases & AFL_ASE_MIPS16E2)
825 opcode_ases |= ASE_MIPS16E2;
5e7fc731
MR
826 return opcode_ases;
827}
828
60804c53
MR
829/* Calculate combination ASE flags from regular ASE flags. */
830
831static unsigned long
41cee089 832mips_calculate_combination_ases (int opcode_isa, unsigned long opcode_ases)
60804c53
MR
833{
834 unsigned long combination_ases = 0;
835
9785fc2a
MR
836 if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
837 combination_ases |= ASE_XPA_VIRT;
60804c53
MR
838 if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
839 combination_ases |= ASE_MIPS16E2_MT;
41cee089
FS
840 if ((opcode_ases & ASE_EVA)
841 && ((opcode_isa & INSN_ISA_MASK) == ISA_MIPS64R6
842 || (opcode_isa & INSN_ISA_MASK) == ISA_MIPS32R6))
843 combination_ases |= ASE_EVA_R6;
60804c53
MR
844 return combination_ases;
845}
846
47b0e7ad
NC
847static void
848set_default_mips_dis_options (struct disassemble_info *info)
640c0ccd
CD
849{
850 const struct mips_arch_choice *chosen_arch;
851
df58fc94
RS
852 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
853 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
854 CP0 register, and HWR names. */
640c0ccd 855 mips_isa = ISA_MIPS3;
df58fc94
RS
856 mips_processor = CPU_R3000;
857 micromips_ase = 0;
d301a56b 858 mips_ase = 0;
640c0ccd
CD
859 mips_gpr_names = mips_gpr_names_oldabi;
860 mips_fpr_names = mips_fpr_names_numeric;
861 mips_cp0_names = mips_cp0_names_numeric;
bbcc0807
CD
862 mips_cp0sel_names = NULL;
863 mips_cp0sel_names_len = 0;
dc76d757 864 mips_cp1_names = mips_cp1_names_numeric;
af7ee8bf 865 mips_hwr_names = mips_hwr_names_numeric;
986e18a5 866 no_aliases = 0;
640c0ccd 867
640c0ccd
CD
868 /* Set ISA, architecture, and cp0 register names as best we can. */
869#if ! SYMTAB_AVAILABLE
870 /* This is running out on a target machine, not in a host tool.
871 FIXME: Where does mips_target_info come from? */
872 target_processor = mips_target_info.processor;
873 mips_isa = mips_target_info.isa;
d301a56b 874 mips_ase = mips_target_info.ase;
640c0ccd
CD
875#else
876 chosen_arch = choose_arch_by_number (info->mach);
877 if (chosen_arch != NULL)
878 {
879 mips_processor = chosen_arch->processor;
880 mips_isa = chosen_arch->isa;
d301a56b 881 mips_ase = chosen_arch->ase;
bbcc0807
CD
882 mips_cp0_names = chosen_arch->cp0_names;
883 mips_cp0sel_names = chosen_arch->cp0sel_names;
884 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 885 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 886 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd 887 }
8184783a
MR
888
889 /* Update settings according to the ELF file header flags. */
890 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
891 {
5e7fc731
MR
892 struct bfd *abfd = info->section->owner;
893 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
4df995c7
MR
894 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
895
9e76c212
MR
896 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
897 because we won't then have a MIPS/ELF BFD, however we need
898 to guard against a link error in a `--enable-targets=...'
899 configuration with a 32-bit host where the MIPS target is
900 a secondary, or with MIPS/ECOFF configurations. */
901#ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
4df995c7
MR
902 abiflags = bfd_mips_elf_get_abiflags (abfd);
903#endif
8184783a
MR
904 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
905 if (is_newabi (header))
906 mips_gpr_names = mips_gpr_names_newabi;
907 /* If a microMIPS binary, then don't use MIPS16 bindings. */
908 micromips_ase = is_micromips (header);
5e7fc731
MR
909 /* OR in any extra ASE flags set in ELF file structures. */
910 if (abiflags)
911 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
912 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
913 mips_ase |= ASE_MDMX;
8184783a 914 }
91068ec6 915#endif
41cee089 916 mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
640c0ccd
CD
917}
918
9785fc2a
MR
919/* Parse an ASE disassembler option and set the corresponding global
920 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
b015e599 921
9785fc2a
MR
922static bfd_boolean
923parse_mips_ase_option (const char *option)
924{
4edbb8e3
CF
925 if (CONST_STRNEQ (option, "msa"))
926 {
927 mips_ase |= ASE_MSA;
ae52f483
AB
928 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
929 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
7361da2c
AB
930 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
931 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
4edbb8e3 932 mips_ase |= ASE_MSA64;
9785fc2a 933 return TRUE;
4edbb8e3
CF
934 }
935
b015e599
AP
936 if (CONST_STRNEQ (option, "virt"))
937 {
d301a56b 938 mips_ase |= ASE_VIRT;
ae52f483
AB
939 if (mips_isa & ISA_MIPS64R2
940 || mips_isa & ISA_MIPS64R3
7361da2c
AB
941 || mips_isa & ISA_MIPS64R5
942 || mips_isa & ISA_MIPS64R6)
d301a56b 943 mips_ase |= ASE_VIRT64;
9785fc2a 944 return TRUE;
b015e599 945 }
7d64c587
AB
946
947 if (CONST_STRNEQ (option, "xpa"))
948 {
949 mips_ase |= ASE_XPA;
9785fc2a
MR
950 return TRUE;
951 }
952
6f20c942
FS
953 if (CONST_STRNEQ (option, "ginv"))
954 {
955 mips_ase |= ASE_GINV;
956 return TRUE;
957 }
958
8095d2f7
CX
959 if (CONST_STRNEQ (option, "loongson-mmi"))
960 {
961 mips_ase |= ASE_LOONGSON_MMI;
962 return TRUE;
963 }
964
716c08de
CX
965 if (CONST_STRNEQ (option, "loongson-cam"))
966 {
967 mips_ase |= ASE_LOONGSON_CAM;
968 return TRUE;
969 }
a693765e
CX
970
971 /* Put here for match ext2 frist */
972 if (CONST_STRNEQ (option, "loongson-ext2"))
973 {
974 mips_ase |= ASE_LOONGSON_EXT2;
975 return TRUE;
976 }
716c08de 977
bdc6c06e
CX
978 if (CONST_STRNEQ (option, "loongson-ext"))
979 {
980 mips_ase |= ASE_LOONGSON_EXT;
981 return TRUE;
982 }
983
9785fc2a
MR
984 return FALSE;
985}
986
987static void
988parse_mips_dis_option (const char *option, unsigned int len)
989{
990 unsigned int i, optionlen, vallen;
991 const char *val;
992 const struct mips_abi_choice *chosen_abi;
993 const struct mips_arch_choice *chosen_arch;
994
995 /* Try to match options that are simple flags */
996 if (CONST_STRNEQ (option, "no-aliases"))
997 {
998 no_aliases = 1;
7d64c587
AB
999 return;
1000 }
43e65147 1001
9785fc2a
MR
1002 if (parse_mips_ase_option (option))
1003 {
41cee089 1004 mips_ase |= mips_calculate_combination_ases (mips_isa, mips_ase);
9785fc2a
MR
1005 return;
1006 }
43e65147 1007
640c0ccd
CD
1008 /* Look for the = that delimits the end of the option name. */
1009 for (i = 0; i < len; i++)
47b0e7ad
NC
1010 if (option[i] == '=')
1011 break;
1012
640c0ccd
CD
1013 if (i == 0) /* Invalid option: no name before '='. */
1014 return;
1015 if (i == len) /* Invalid option: no '='. */
1016 return;
1017 if (i == (len - 1)) /* Invalid option: no value after '='. */
1018 return;
1019
1020 optionlen = i;
1021 val = option + (optionlen + 1);
1022 vallen = len - (optionlen + 1);
1023
47b0e7ad
NC
1024 if (strncmp ("gpr-names", option, optionlen) == 0
1025 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
1026 {
1027 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 1028 if (chosen_abi != NULL)
640c0ccd
CD
1029 mips_gpr_names = chosen_abi->gpr_names;
1030 return;
1031 }
1032
47b0e7ad
NC
1033 if (strncmp ("fpr-names", option, optionlen) == 0
1034 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
1035 {
1036 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 1037 if (chosen_abi != NULL)
640c0ccd
CD
1038 mips_fpr_names = chosen_abi->fpr_names;
1039 return;
1040 }
1041
47b0e7ad
NC
1042 if (strncmp ("cp0-names", option, optionlen) == 0
1043 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
1044 {
1045 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
1046 if (chosen_arch != NULL)
1047 {
1048 mips_cp0_names = chosen_arch->cp0_names;
1049 mips_cp0sel_names = chosen_arch->cp0sel_names;
1050 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1051 }
640c0ccd
CD
1052 return;
1053 }
1054
dc76d757
AB
1055 if (strncmp ("cp1-names", option, optionlen) == 0
1056 && strlen ("cp1-names") == optionlen)
1057 {
1058 chosen_arch = choose_arch_by_name (val, vallen);
1059 if (chosen_arch != NULL)
1060 mips_cp1_names = chosen_arch->cp1_names;
1061 return;
1062 }
1063
47b0e7ad
NC
1064 if (strncmp ("hwr-names", option, optionlen) == 0
1065 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
1066 {
1067 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 1068 if (chosen_arch != NULL)
af7ee8bf
CD
1069 mips_hwr_names = chosen_arch->hwr_names;
1070 return;
1071 }
1072
47b0e7ad
NC
1073 if (strncmp ("reg-names", option, optionlen) == 0
1074 && strlen ("reg-names") == optionlen)
640c0ccd
CD
1075 {
1076 /* We check both ABI and ARCH here unconditionally, so
1077 that "numeric" will do the desirable thing: select
1078 numeric register names for all registers. Other than
1079 that, a given name probably won't match both. */
1080 chosen_abi = choose_abi_by_name (val, vallen);
1081 if (chosen_abi != NULL)
1082 {
bbcc0807
CD
1083 mips_gpr_names = chosen_abi->gpr_names;
1084 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
1085 }
1086 chosen_arch = choose_arch_by_name (val, vallen);
1087 if (chosen_arch != NULL)
1088 {
bbcc0807
CD
1089 mips_cp0_names = chosen_arch->cp0_names;
1090 mips_cp0sel_names = chosen_arch->cp0sel_names;
1091 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 1092 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 1093 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
1094 }
1095 return;
1096 }
1097
1098 /* Invalid option. */
1099}
1100
47b0e7ad
NC
1101static void
1102parse_mips_dis_options (const char *options)
640c0ccd
CD
1103{
1104 const char *option_end;
1105
1106 if (options == NULL)
1107 return;
1108
1109 while (*options != '\0')
1110 {
1111 /* Skip empty options. */
1112 if (*options == ',')
1113 {
1114 options++;
1115 continue;
1116 }
1117
1118 /* We know that *options is neither NUL or a comma. */
1119 option_end = options + 1;
1120 while (*option_end != ',' && *option_end != '\0')
1121 option_end++;
1122
1123 parse_mips_dis_option (options, option_end - options);
1124
1125 /* Go on to the next one. If option_end points to a comma, it
1126 will be skipped above. */
1127 options = option_end;
1128 }
1129}
1130
bbcc0807 1131static const struct mips_cp0sel_name *
47b0e7ad
NC
1132lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1133 unsigned int len,
1134 unsigned int cp0reg,
1135 unsigned int sel)
bbcc0807
CD
1136{
1137 unsigned int i;
1138
1139 for (i = 0; i < len; i++)
1140 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1141 return &names[i];
1142 return NULL;
1143}
ab902481
RS
1144
1145/* Print register REGNO, of type TYPE, for instruction OPCODE. */
aa5f19f2 1146
794ac9d0 1147static void
ab902481
RS
1148print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1149 enum mips_reg_operand_type type, int regno)
252b5132 1150{
ab902481
RS
1151 switch (type)
1152 {
1153 case OP_REG_GP:
1154 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1155 break;
440cc0bc 1156
ab902481
RS
1157 case OP_REG_FP:
1158 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1159 break;
252b5132 1160
ab902481
RS
1161 case OP_REG_CCC:
1162 if (opcode->pinfo & (FP_D | FP_S))
1163 info->fprintf_func (info->stream, "$fcc%d", regno);
1164 else
1165 info->fprintf_func (info->stream, "$cc%d", regno);
1166 break;
794ac9d0 1167
ab902481
RS
1168 case OP_REG_VEC:
1169 if (opcode->membership & INSN_5400)
1170 info->fprintf_func (info->stream, "$f%d", regno);
1171 else
1172 info->fprintf_func (info->stream, "$v%d", regno);
1173 break;
794ac9d0 1174
ab902481
RS
1175 case OP_REG_ACC:
1176 info->fprintf_func (info->stream, "$ac%d", regno);
1177 break;
794ac9d0 1178
ab902481
RS
1179 case OP_REG_COPRO:
1180 if (opcode->name[strlen (opcode->name) - 1] == '0')
1181 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
dc76d757
AB
1182 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1183 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
ab902481
RS
1184 else
1185 info->fprintf_func (info->stream, "$%d", regno);
1186 break;
8b082fb1 1187
ab902481
RS
1188 case OP_REG_HW:
1189 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1190 break;
14daeee3
RS
1191
1192 case OP_REG_VF:
1193 info->fprintf_func (info->stream, "$vf%d", regno);
1194 break;
1195
1196 case OP_REG_VI:
1197 info->fprintf_func (info->stream, "$vi%d", regno);
1198 break;
1199
1200 case OP_REG_R5900_I:
1201 info->fprintf_func (info->stream, "$I");
1202 break;
1203
1204 case OP_REG_R5900_Q:
1205 info->fprintf_func (info->stream, "$Q");
1206 break;
1207
1208 case OP_REG_R5900_R:
1209 info->fprintf_func (info->stream, "$R");
1210 break;
1211
1212 case OP_REG_R5900_ACC:
1213 info->fprintf_func (info->stream, "$ACC");
1214 break;
4edbb8e3
CF
1215
1216 case OP_REG_MSA:
1217 info->fprintf_func (info->stream, "$w%d", regno);
1218 break;
1219
1220 case OP_REG_MSA_CTRL:
1221 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1222 break;
1223
ab902481
RS
1224 }
1225}
1226\f
1227/* Used to track the state carried over from previous operands in
1228 an instruction. */
1229struct mips_print_arg_state {
1230 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1231 where the value is known to be unsigned and small. */
1232 unsigned int last_int;
1233
1234 /* The type and number of the last OP_REG seen. We only use this for
1235 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1236 enum mips_reg_operand_type last_reg_type;
1237 unsigned int last_regno;
7361da2c
AB
1238 unsigned int dest_regno;
1239 unsigned int seen_dest;
ab902481 1240};
fd25c5a9 1241
ab902481 1242/* Initialize STATE for the start of an instruction. */
fd25c5a9 1243
ab902481
RS
1244static inline void
1245init_print_arg_state (struct mips_print_arg_state *state)
1246{
1247 memset (state, 0, sizeof (*state));
1248}
fd25c5a9 1249
14daeee3
RS
1250/* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1251 whose value is given by UVAL. */
1252
1253static void
1254print_vu0_channel (struct disassemble_info *info,
1255 const struct mips_operand *operand, unsigned int uval)
1256{
1257 if (operand->size == 4)
1258 info->fprintf_func (info->stream, "%s%s%s%s",
1259 uval & 8 ? "x" : "",
1260 uval & 4 ? "y" : "",
1261 uval & 2 ? "z" : "",
1262 uval & 1 ? "w" : "");
1263 else if (operand->size == 2)
1264 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1265 else
1266 abort ();
1267}
1268
7361da2c
AB
1269/* Record information about a register operand. */
1270
1271static void
1272mips_seen_register (struct mips_print_arg_state *state,
1273 unsigned int regno,
1274 enum mips_reg_operand_type reg_type)
1275{
1276 state->last_reg_type = reg_type;
1277 state->last_regno = regno;
1278
1279 if (!state->seen_dest)
1280 {
1281 state->seen_dest = 1;
1282 state->dest_regno = regno;
1283 }
1284}
1285
38bf472a
MR
1286/* Print SAVE/RESTORE instruction operands according to the argument
1287 register mask AMASK, the number of static registers saved NSREG,
1288 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1289 and the frame size FRAME_SIZE. */
1290
1291static void
1292mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
1293 unsigned int nsreg, unsigned int ra,
1294 unsigned int s0, unsigned int s1,
1295 unsigned int frame_size)
1296{
1297 const fprintf_ftype infprintf = info->fprintf_func;
1298 unsigned int nargs, nstatics, smask, i, j;
1299 void *is = info->stream;
1300 const char *sep;
1301
1302 if (amask == MIPS_SVRS_ALL_ARGS)
1303 {
1304 nargs = 4;
1305 nstatics = 0;
1306 }
1307 else if (amask == MIPS_SVRS_ALL_STATICS)
1308 {
1309 nargs = 0;
1310 nstatics = 4;
1311 }
1312 else
1313 {
1314 nargs = amask >> 2;
1315 nstatics = amask & 3;
1316 }
1317
1318 sep = "";
1319 if (nargs > 0)
1320 {
1321 infprintf (is, "%s", mips_gpr_names[4]);
1322 if (nargs > 1)
1323 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1324 sep = ",";
1325 }
1326
1327 infprintf (is, "%s%d", sep, frame_size);
1328
1329 if (ra) /* $ra */
1330 infprintf (is, ",%s", mips_gpr_names[31]);
1331
1332 smask = 0;
1333 if (s0) /* $s0 */
1334 smask |= 1 << 0;
1335 if (s1) /* $s1 */
1336 smask |= 1 << 1;
1337 if (nsreg > 0) /* $s2-$s8 */
1338 smask |= ((1 << nsreg) - 1) << 2;
1339
1340 for (i = 0; i < 9; i++)
1341 if (smask & (1 << i))
1342 {
1343 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1344 /* Skip over string of set bits. */
1345 for (j = i; smask & (2 << j); j++)
1346 continue;
1347 if (j > i)
1348 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1349 i = j + 1;
1350 }
1351 /* Statics $ax - $a3. */
1352 if (nstatics == 1)
1353 infprintf (is, ",%s", mips_gpr_names[7]);
1354 else if (nstatics > 0)
1355 infprintf (is, ",%s-%s",
1356 mips_gpr_names[7 - nstatics + 1],
1357 mips_gpr_names[7]);
1358}
1359
1360
ab902481
RS
1361/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1362 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1363 the base address for OP_PCREL operands. */
fd25c5a9 1364
ab902481
RS
1365static void
1366print_insn_arg (struct disassemble_info *info,
1367 struct mips_print_arg_state *state,
1368 const struct mips_opcode *opcode,
1369 const struct mips_operand *operand,
1370 bfd_vma base_pc,
1371 unsigned int uval)
1372{
1373 const fprintf_ftype infprintf = info->fprintf_func;
1374 void *is = info->stream;
fd25c5a9 1375
ab902481
RS
1376 switch (operand->type)
1377 {
1378 case OP_INT:
1379 {
1380 const struct mips_int_operand *int_op;
fd25c5a9 1381
ab902481
RS
1382 int_op = (const struct mips_int_operand *) operand;
1383 uval = mips_decode_int_operand (int_op, uval);
1384 state->last_int = uval;
1385 if (int_op->print_hex)
1386 infprintf (is, "0x%x", uval);
1387 else
1388 infprintf (is, "%d", uval);
1389 }
1390 break;
fd25c5a9 1391
ab902481
RS
1392 case OP_MAPPED_INT:
1393 {
1394 const struct mips_mapped_int_operand *mint_op;
fd25c5a9 1395
ab902481
RS
1396 mint_op = (const struct mips_mapped_int_operand *) operand;
1397 uval = mint_op->int_map[uval];
1398 state->last_int = uval;
1399 if (mint_op->print_hex)
1400 infprintf (is, "0x%x", uval);
1401 else
1402 infprintf (is, "%d", uval);
1403 }
1404 break;
fd25c5a9 1405
ab902481
RS
1406 case OP_MSB:
1407 {
1408 const struct mips_msb_operand *msb_op;
dec0624d 1409
ab902481
RS
1410 msb_op = (const struct mips_msb_operand *) operand;
1411 uval += msb_op->bias;
1412 if (msb_op->add_lsb)
1413 uval -= state->last_int;
1414 infprintf (is, "0x%x", uval);
1415 }
1416 break;
dec0624d 1417
ab902481 1418 case OP_REG:
0f35dbc4 1419 case OP_OPTIONAL_REG:
ab902481
RS
1420 {
1421 const struct mips_reg_operand *reg_op;
fd25c5a9 1422
ab902481 1423 reg_op = (const struct mips_reg_operand *) operand;
fc76e730 1424 uval = mips_decode_reg_operand (reg_op, uval);
ab902481 1425 print_reg (info, opcode, reg_op->reg_type, uval);
fd25c5a9 1426
7361da2c 1427 mips_seen_register (state, uval, reg_op->reg_type);
ab902481
RS
1428 }
1429 break;
61cc0267 1430
ab902481
RS
1431 case OP_REG_PAIR:
1432 {
1433 const struct mips_reg_pair_operand *pair_op;
1434
1435 pair_op = (const struct mips_reg_pair_operand *) operand;
1436 print_reg (info, opcode, pair_op->reg_type,
1437 pair_op->reg1_map[uval]);
1438 infprintf (is, ",");
1439 print_reg (info, opcode, pair_op->reg_type,
1440 pair_op->reg2_map[uval]);
1441 }
1442 break;
61cc0267 1443
ab902481
RS
1444 case OP_PCREL:
1445 {
1446 const struct mips_pcrel_operand *pcrel_op;
61cc0267 1447
ab902481
RS
1448 pcrel_op = (const struct mips_pcrel_operand *) operand;
1449 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
61cc0267 1450
a4ddc54e
MR
1451 /* For jumps and branches clear the ISA bit except for
1452 the GDB disassembler. */
1453 if (pcrel_op->include_isa_bit
1454 && info->flavour != bfd_target_unknown_flavour)
ab902481 1455 info->target &= -2;
61cc0267 1456
ab902481
RS
1457 (*info->print_address_func) (info->target, info);
1458 }
1459 break;
794ac9d0 1460
ab902481
RS
1461 case OP_PERF_REG:
1462 infprintf (is, "%d", uval);
1463 break;
794ac9d0 1464
ab902481
RS
1465 case OP_ADDIUSP_INT:
1466 {
1467 int sval;
794ac9d0 1468
ab902481
RS
1469 sval = mips_signed_operand (operand, uval) * 4;
1470 if (sval >= -8 && sval < 8)
1471 sval ^= 0x400;
1472 infprintf (is, "%d", sval);
1473 break;
1474 }
794ac9d0 1475
ab902481
RS
1476 case OP_CLO_CLZ_DEST:
1477 {
1478 unsigned int reg1, reg2;
1479
1480 reg1 = uval & 31;
1481 reg2 = uval >> 5;
1482 /* If one is zero use the other. */
1483 if (reg1 == reg2 || reg2 == 0)
1484 infprintf (is, "%s", mips_gpr_names[reg1]);
1485 else if (reg1 == 0)
1486 infprintf (is, "%s", mips_gpr_names[reg2]);
1487 else
1488 /* Bogus, result depends on processor. */
1489 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1490 mips_gpr_names[reg2]);
1491 }
1492 break;
794ac9d0 1493
7361da2c
AB
1494 case OP_SAME_RS_RT:
1495 case OP_CHECK_PREV:
1496 case OP_NON_ZERO_REG:
1497 {
1498 print_reg (info, opcode, OP_REG_GP, uval & 31);
1499 mips_seen_register (state, uval, OP_REG_GP);
1500 }
1501 break;
1502
ab902481
RS
1503 case OP_LWM_SWM_LIST:
1504 if (operand->size == 2)
1505 {
1506 if (uval == 0)
1507 infprintf (is, "%s,%s",
1508 mips_gpr_names[16],
1509 mips_gpr_names[31]);
1510 else
1511 infprintf (is, "%s-%s,%s",
1512 mips_gpr_names[16],
1513 mips_gpr_names[16 + uval],
1514 mips_gpr_names[31]);
1515 }
1516 else
1517 {
1518 int s_reg_encode;
794ac9d0 1519
ab902481
RS
1520 s_reg_encode = uval & 0xf;
1521 if (s_reg_encode != 0)
1522 {
1523 if (s_reg_encode == 1)
1524 infprintf (is, "%s", mips_gpr_names[16]);
1525 else if (s_reg_encode < 9)
1526 infprintf (is, "%s-%s",
1527 mips_gpr_names[16],
1528 mips_gpr_names[15 + s_reg_encode]);
1529 else if (s_reg_encode == 9)
1530 infprintf (is, "%s-%s,%s",
1531 mips_gpr_names[16],
1532 mips_gpr_names[23],
1533 mips_gpr_names[30]);
1534 else
1535 infprintf (is, "UNKNOWN");
1536 }
794ac9d0 1537
ab902481
RS
1538 if (uval & 0x10) /* For ra. */
1539 {
1540 if (s_reg_encode == 0)
1541 infprintf (is, "%s", mips_gpr_names[31]);
1542 else
1543 infprintf (is, ",%s", mips_gpr_names[31]);
1544 }
1545 }
1546 break;
794ac9d0 1547
c3c07478
RS
1548 case OP_ENTRY_EXIT_LIST:
1549 {
1550 const char *sep;
1551 unsigned int amask, smask;
1552
1553 sep = "";
1554 amask = (uval >> 3) & 7;
1555 if (amask > 0 && amask < 5)
1556 {
1557 infprintf (is, "%s", mips_gpr_names[4]);
1558 if (amask > 1)
1559 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1560 sep = ",";
1561 }
1562
1563 smask = (uval >> 1) & 3;
1564 if (smask == 3)
1565 {
1566 infprintf (is, "%s??", sep);
1567 sep = ",";
1568 }
1569 else if (smask > 0)
1570 {
1571 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1572 if (smask > 1)
1573 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1574 sep = ",";
1575 }
1576
1577 if (uval & 1)
1578 {
1579 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1580 sep = ",";
1581 }
1582
1583 if (amask == 5 || amask == 6)
1584 {
1585 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1586 if (amask == 6)
1587 infprintf (is, "-%s", mips_fpr_names[1]);
1588 }
1589 }
1590 break;
1591
1592 case OP_SAVE_RESTORE_LIST:
38bf472a 1593 /* Should be handled by the caller due to complex behavior. */
c3c07478
RS
1594 abort ();
1595
ab902481
RS
1596 case OP_MDMX_IMM_REG:
1597 {
1598 unsigned int vsel;
794ac9d0 1599
ab902481
RS
1600 vsel = uval >> 5;
1601 uval &= 31;
1602 if ((vsel & 0x10) == 0)
794ac9d0 1603 {
ab902481
RS
1604 int fmt;
1605
1606 vsel &= 0x0f;
1607 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1608 if ((vsel & 1) == 0)
1609 break;
1610 print_reg (info, opcode, OP_REG_VEC, uval);
1611 infprintf (is, "[%d]", vsel >> 1);
794ac9d0 1612 }
ab902481
RS
1613 else if ((vsel & 0x08) == 0)
1614 print_reg (info, opcode, OP_REG_VEC, uval);
1615 else
1616 infprintf (is, "0x%x", uval);
1617 }
1618 break;
794ac9d0 1619
ab902481
RS
1620 case OP_REPEAT_PREV_REG:
1621 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1622 break;
794ac9d0 1623
ab902481 1624 case OP_REPEAT_DEST_REG:
7361da2c
AB
1625 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1626 break;
794ac9d0 1627
ab902481
RS
1628 case OP_PC:
1629 infprintf (is, "$pc");
1630 break;
14daeee3 1631
25499ac7
MR
1632 case OP_REG28:
1633 print_reg (info, opcode, OP_REG_GP, 28);
1634 break;
1635
14daeee3
RS
1636 case OP_VU0_SUFFIX:
1637 case OP_VU0_MATCH_SUFFIX:
1638 print_vu0_channel (info, operand, uval);
1639 break;
4edbb8e3
CF
1640
1641 case OP_IMM_INDEX:
1642 infprintf (is, "[%d]", uval);
1643 break;
1644
1645 case OP_REG_INDEX:
1646 infprintf (is, "[");
1647 print_reg (info, opcode, OP_REG_GP, uval);
1648 infprintf (is, "]");
1649 break;
ab902481
RS
1650 }
1651}
794ac9d0 1652
7361da2c
AB
1653/* Validate the arguments for INSN, which is described by OPCODE.
1654 Use DECODE_OPERAND to get the encoding of each operand. */
1655
1656static bfd_boolean
1657validate_insn_args (const struct mips_opcode *opcode,
1658 const struct mips_operand *(*decode_operand) (const char *),
1659 unsigned int insn)
1660{
1661 struct mips_print_arg_state state;
1662 const struct mips_operand *operand;
1663 const char *s;
1664 unsigned int uval;
1665
1666 init_print_arg_state (&state);
1667 for (s = opcode->args; *s; ++s)
1668 {
1669 switch (*s)
1670 {
1671 case ',':
1672 case '(':
1673 case ')':
1674 break;
1675
1676 case '#':
1677 ++s;
1678 break;
1679
1680 default:
1681 operand = decode_operand (s);
1682
1683 if (operand)
1684 {
1685 uval = mips_extract_operand (operand, insn);
1686 switch (operand->type)
1687 {
1688 case OP_REG:
1689 case OP_OPTIONAL_REG:
1690 {
1691 const struct mips_reg_operand *reg_op;
1692
1693 reg_op = (const struct mips_reg_operand *) operand;
1694 uval = mips_decode_reg_operand (reg_op, uval);
1695 mips_seen_register (&state, uval, reg_op->reg_type);
1696 }
1697 break;
1698
1699 case OP_SAME_RS_RT:
1700 {
1701 unsigned int reg1, reg2;
1702
1703 reg1 = uval & 31;
1704 reg2 = uval >> 5;
1705
1706 if (reg1 != reg2 || reg1 == 0)
1707 return FALSE;
1708 }
1709 break;
1710
1711 case OP_CHECK_PREV:
1712 {
1713 const struct mips_check_prev_operand *prev_op;
1714
1715 prev_op = (const struct mips_check_prev_operand *) operand;
1716
1717 if (!prev_op->zero_ok && uval == 0)
1718 return FALSE;
1719
1720 if (((prev_op->less_than_ok && uval < state.last_regno)
1721 || (prev_op->greater_than_ok && uval > state.last_regno)
1722 || (prev_op->equal_ok && uval == state.last_regno)))
1723 break;
1724
1725 return FALSE;
1726 }
1727
1728 case OP_NON_ZERO_REG:
1729 {
1730 if (uval == 0)
1731 return FALSE;
1732 }
1733 break;
1734
1735 case OP_INT:
1736 case OP_MAPPED_INT:
1737 case OP_MSB:
1738 case OP_REG_PAIR:
1739 case OP_PCREL:
1740 case OP_PERF_REG:
1741 case OP_ADDIUSP_INT:
1742 case OP_CLO_CLZ_DEST:
1743 case OP_LWM_SWM_LIST:
1744 case OP_ENTRY_EXIT_LIST:
1745 case OP_MDMX_IMM_REG:
1746 case OP_REPEAT_PREV_REG:
1747 case OP_REPEAT_DEST_REG:
1748 case OP_PC:
25499ac7 1749 case OP_REG28:
7361da2c
AB
1750 case OP_VU0_SUFFIX:
1751 case OP_VU0_MATCH_SUFFIX:
1752 case OP_IMM_INDEX:
1753 case OP_REG_INDEX:
7361da2c 1754 case OP_SAVE_RESTORE_LIST:
38bf472a 1755 break;
7361da2c
AB
1756 }
1757 }
1758 if (*s == 'm' || *s == '+' || *s == '-')
1759 ++s;
1760 }
1761 }
1762 return TRUE;
1763}
1764
ab902481
RS
1765/* Print the arguments for INSN, which is described by OPCODE.
1766 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
7361da2c
AB
1767 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1768 operand is for a branch or jump. */
af7ee8bf 1769
ab902481
RS
1770static void
1771print_insn_args (struct disassemble_info *info,
1772 const struct mips_opcode *opcode,
1773 const struct mips_operand *(*decode_operand) (const char *),
7361da2c 1774 unsigned int insn, bfd_vma insn_pc, unsigned int length)
ab902481
RS
1775{
1776 const fprintf_ftype infprintf = info->fprintf_func;
1777 void *is = info->stream;
1778 struct mips_print_arg_state state;
1779 const struct mips_operand *operand;
1780 const char *s;
794ac9d0 1781
ab902481
RS
1782 init_print_arg_state (&state);
1783 for (s = opcode->args; *s; ++s)
1784 {
1785 switch (*s)
1786 {
1787 case ',':
1788 case '(':
1789 case ')':
1790 infprintf (is, "%c", *s);
794ac9d0
CD
1791 break;
1792
14daeee3
RS
1793 case '#':
1794 ++s;
1795 infprintf (is, "%c%c", *s, *s);
1796 break;
1797
ab902481
RS
1798 default:
1799 operand = decode_operand (s);
1800 if (!operand)
fa7616a4 1801 {
ab902481
RS
1802 /* xgettext:c-format */
1803 infprintf (is,
1804 _("# internal error, undefined operand in `%s %s'"),
1805 opcode->name, opcode->args);
1806 return;
1807 }
38bf472a
MR
1808
1809 if (operand->type == OP_SAVE_RESTORE_LIST)
1810 {
1811 /* Handle this case here because of the complex behavior. */
1812 unsigned int amask = (insn >> 15) & 0xf;
1813 unsigned int nsreg = (insn >> 23) & 0x7;
1814 unsigned int ra = insn & 0x1000; /* $ra */
1815 unsigned int s0 = insn & 0x800; /* $s0 */
1816 unsigned int s1 = insn & 0x400; /* $s1 */
1817 unsigned int frame_size = (((insn >> 15) & 0xf0)
1818 | ((insn >> 6) & 0x0f)) * 8;
1819 mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1820 frame_size);
1821 }
1822 else if (operand->type == OP_REG
1823 && s[1] == ','
1824 && s[2] == 'H'
1825 && opcode->name[strlen (opcode->name) - 1] == '0')
ab902481 1826 {
fdfb4752 1827 /* Coprocessor register 0 with sel field. */
ab902481
RS
1828 const struct mips_cp0sel_name *n;
1829 unsigned int reg, sel;
1830
1831 reg = mips_extract_operand (operand, insn);
1832 s += 2;
1833 operand = decode_operand (s);
1834 sel = mips_extract_operand (operand, insn);
1835
1836 /* CP0 register including 'sel' code for mftc0, to be
1837 printed textually if known. If not known, print both
1838 CP0 register name and sel numerically since CP0 register
1839 with sel 0 may have a name unrelated to register being
1840 printed. */
1841 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1842 mips_cp0sel_names_len,
1843 reg, sel);
1844 if (n != NULL)
1845 infprintf (is, "%s", n->name);
fa7616a4 1846 else
ab902481 1847 infprintf (is, "$%d,%d", reg, sel);
fa7616a4 1848 }
794ac9d0 1849 else
7361da2c
AB
1850 {
1851 bfd_vma base_pc = insn_pc;
1852
1853 /* Adjust the PC relative base so that branch/jump insns use
1854 the following PC as the base but genuinely PC relative
1855 operands use the current PC. */
1856 if (operand->type == OP_PCREL)
1857 {
1858 const struct mips_pcrel_operand *pcrel_op;
1859
1860 pcrel_op = (const struct mips_pcrel_operand *) operand;
1861 /* The include_isa_bit flag is sufficient to distinguish
1862 branch/jump from other PC relative operands. */
1863 if (pcrel_op->include_isa_bit)
1864 base_pc += length;
1865 }
1866
1867 print_insn_arg (info, &state, opcode, operand, base_pc,
1868 mips_extract_operand (operand, insn));
1869 }
1870 if (*s == 'm' || *s == '+' || *s == '-')
ab902481 1871 ++s;
794ac9d0 1872 break;
af7ee8bf 1873 }
252b5132
RH
1874 }
1875}
1876\f
252b5132
RH
1877/* Print the mips instruction at address MEMADDR in debugged memory,
1878 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1879 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1880 this is little-endian code. */
1881
1882static int
47b0e7ad 1883print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1884 int word,
47b0e7ad 1885 struct disassemble_info *info)
252b5132 1886{
ab902481
RS
1887#define GET_OP(insn, field) \
1888 (((insn) >> OP_SH_##field) & OP_MASK_##field)
fc8c4fd1
MR
1889 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1890 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1891 const struct mips_opcode *op;
b34976b6 1892 static bfd_boolean init = 0;
fc8c4fd1 1893 void *is = info->stream;
252b5132
RH
1894
1895 /* Build a hash table to shorten the search time. */
1896 if (! init)
1897 {
1898 unsigned int i;
1899
1900 for (i = 0; i <= OP_MASK_OP; i++)
1901 {
1902 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1903 {
986e18a5 1904 if (op->pinfo == INSN_MACRO
9e836e3d 1905 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1906 continue;
fc8c4fd1 1907 if (i == GET_OP (op->match, OP))
252b5132
RH
1908 {
1909 mips_hash[i] = op;
1910 break;
1911 }
1912 }
7f6621cd 1913 }
252b5132
RH
1914
1915 init = 1;
1916 }
1917
aa5f19f2 1918 info->bytes_per_chunk = INSNLEN;
252b5132 1919 info->display_endian = info->endian;
9bb28706
CD
1920 info->insn_info_valid = 1;
1921 info->branch_delay_insns = 0;
def7143b 1922 info->data_size = 0;
9bb28706
CD
1923 info->insn_type = dis_nonbranch;
1924 info->target = 0;
1925 info->target2 = 0;
252b5132 1926
fc8c4fd1 1927 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1928 if (op != NULL)
1929 {
1930 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1931 {
43e65147 1932 if (op->pinfo != INSN_MACRO
9e836e3d 1933 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1934 && (word & op->mask) == op->match)
252b5132 1935 {
7361da2c 1936 /* We always disassemble the jalx instruction, except for MIPS r6. */
d301a56b 1937 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
7361da2c
AB
1938 && (strcmp (op->name, "jalx")
1939 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1940 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
252b5132
RH
1941 continue;
1942
9bb28706
CD
1943 /* Figure out instruction type and branch delay information. */
1944 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1945 {
fc76e730 1946 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
9bb28706
CD
1947 info->insn_type = dis_jsr;
1948 else
1949 info->insn_type = dis_branch;
1950 info->branch_delay_insns = 1;
1951 }
1952 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1953 | INSN_COND_BRANCH_LIKELY)) != 0)
1954 {
c680e7f6 1955 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1956 info->insn_type = dis_condjsr;
1957 else
1958 info->insn_type = dis_condbranch;
1959 info->branch_delay_insns = 1;
1960 }
1961 else if ((op->pinfo & (INSN_STORE_MEMORY
67dc82bc 1962 | INSN_LOAD_MEMORY)) != 0)
9bb28706
CD
1963 info->insn_type = dis_dref;
1964
7361da2c
AB
1965 if (!validate_insn_args (op, decode_mips_operand, word))
1966 continue;
1967
fc8c4fd1 1968 infprintf (is, "%s", op->name);
14daeee3
RS
1969 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1970 {
1971 unsigned int uval;
1972
1973 infprintf (is, ".");
1974 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1975 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1976 }
252b5132 1977
ab902481 1978 if (op->args[0])
252b5132 1979 {
fc8c4fd1 1980 infprintf (is, "\t");
ab902481 1981 print_insn_args (info, op, decode_mips_operand, word,
7361da2c 1982 memaddr, 4);
252b5132
RH
1983 }
1984
aa5f19f2 1985 return INSNLEN;
252b5132
RH
1986 }
1987 }
1988 }
fc8c4fd1 1989#undef GET_OP
252b5132
RH
1990
1991 /* Handle undefined instructions. */
9bb28706 1992 info->insn_type = dis_noninsn;
fc8c4fd1 1993 infprintf (is, "0x%x", word);
aa5f19f2 1994 return INSNLEN;
252b5132 1995}
aa5f19f2 1996\f
252b5132
RH
1997/* Disassemble an operand for a mips16 instruction. */
1998
1999static void
c3c07478
RS
2000print_mips16_insn_arg (struct disassemble_info *info,
2001 struct mips_print_arg_state *state,
2002 const struct mips_opcode *opcode,
2003 char type, bfd_vma memaddr,
2004 unsigned insn, bfd_boolean use_extend,
2005 unsigned extend, bfd_boolean is_offset)
252b5132 2006{
fc8c4fd1
MR
2007 const fprintf_ftype infprintf = info->fprintf_func;
2008 void *is = info->stream;
c3c07478 2009 const struct mips_operand *operand, *ext_operand;
bdd15286 2010 unsigned short ext_size;
c3c07478
RS
2011 unsigned int uval;
2012 bfd_vma baseaddr;
2013
2014 if (!use_extend)
2015 extend = 0;
fc8c4fd1 2016
252b5132
RH
2017 switch (type)
2018 {
2019 case ',':
2020 case '(':
2021 case ')':
fc8c4fd1 2022 infprintf (is, "%c", type);
252b5132
RH
2023 break;
2024
c3c07478
RS
2025 default:
2026 operand = decode_mips16_operand (type, FALSE);
2027 if (!operand)
2028 {
2029 /* xgettext:c-format */
2030 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
2031 opcode->name, opcode->args);
2032 return;
2033 }
252b5132 2034
c3c07478
RS
2035 if (operand->type == OP_SAVE_RESTORE_LIST)
2036 {
5f5c6e03 2037 /* Handle this case here because of the complex interaction
c3c07478 2038 with the EXTEND opcode. */
38bf472a
MR
2039 unsigned int amask = extend & 0xf;
2040 unsigned int nsreg = (extend >> 8) & 0x7;
2041 unsigned int ra = insn & 0x40; /* $ra */
2042 unsigned int s0 = insn & 0x20; /* $s0 */
2043 unsigned int s1 = insn & 0x10; /* $s1 */
2044 unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
c3c07478
RS
2045 if (frame_size == 0 && !use_extend)
2046 frame_size = 128;
38bf472a 2047 mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
c3c07478
RS
2048 break;
2049 }
252b5132 2050
c3c07478
RS
2051 if (is_offset && operand->type == OP_INT)
2052 {
2053 const struct mips_int_operand *int_op;
252b5132 2054
c3c07478
RS
2055 int_op = (const struct mips_int_operand *) operand;
2056 info->insn_type = dis_dref;
2057 info->data_size = 1 << int_op->shift;
2058 }
252b5132 2059
bdd15286
MR
2060 ext_size = 0;
2061 if (use_extend)
c3c07478 2062 {
bdd15286 2063 ext_operand = decode_mips16_operand (type, TRUE);
25499ac7
MR
2064 if (ext_operand != operand
2065 || (operand->type == OP_INT && operand->lsb == 0
2066 && mips_opcode_32bit_p (opcode)))
c3c07478 2067 {
bdd15286
MR
2068 ext_size = ext_operand->size;
2069 operand = ext_operand;
c3c07478
RS
2070 }
2071 }
bdd15286
MR
2072 if (operand->size == 26)
2073 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
25499ac7 2074 else if (ext_size == 16 || ext_size == 9)
bdd15286
MR
2075 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2076 else if (ext_size == 15)
2077 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2078 else if (ext_size == 6)
2079 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2080 else
2081 uval = mips_extract_operand (operand, (extend << 16) | insn);
25499ac7
MR
2082 if (ext_size == 9)
2083 uval &= (1U << ext_size) - 1;
c3c07478
RS
2084
2085 baseaddr = memaddr + 2;
2086 if (operand->type == OP_PCREL)
2087 {
2088 const struct mips_pcrel_operand *pcrel_op;
2089
2090 pcrel_op = (const struct mips_pcrel_operand *) operand;
2091 if (!pcrel_op->include_isa_bit && use_extend)
2092 baseaddr = memaddr - 2;
2093 else if (!pcrel_op->include_isa_bit)
39f66f3a
MR
2094 {
2095 bfd_byte buffer[2];
2096
2097 /* If this instruction is in the delay slot of a JAL/JALX
2098 instruction, the base address is the address of the
2099 JAL/JALX instruction. If it is in the delay slot of
2100 a JR/JALR instruction, the base address is the address
2101 of the JR/JALR instruction. This test is unreliable:
2102 we have no way of knowing whether the previous word is
2103 instruction or data. */
2104 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2105 && (((info->endian == BFD_ENDIAN_BIG
2106 ? bfd_getb16 (buffer)
2107 : bfd_getl16 (buffer))
2108 & 0xf800) == 0x1800))
2109 baseaddr = memaddr - 4;
2110 else if (info->read_memory_func (memaddr - 2, buffer, 2,
2111 info) == 0
2112 && (((info->endian == BFD_ENDIAN_BIG
2113 ? bfd_getb16 (buffer)
2114 : bfd_getl16 (buffer))
2115 & 0xf89f) == 0xe800)
2116 && (((info->endian == BFD_ENDIAN_BIG
2117 ? bfd_getb16 (buffer)
2118 : bfd_getl16 (buffer))
2119 & 0x0060) != 0x0060))
2120 baseaddr = memaddr - 2;
2121 else
2122 baseaddr = memaddr;
2123 }
c3c07478 2124 }
0499d65b 2125
6d075bce 2126 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
0499d65b 2127 break;
252b5132
RH
2128 }
2129}
640c0ccd 2130
1bbce132
MR
2131
2132/* Check if the given address is the last word of a MIPS16 PLT entry.
2133 This word is data and depending on the value it may interfere with
2134 disassembly of further PLT entries. We make use of the fact PLT
2135 symbols are marked BSF_SYNTHETIC. */
2136static bfd_boolean
2137is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2138{
2139 if (info->symbols
2140 && info->symbols[0]
2141 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2142 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2143 return TRUE;
2144
2145 return FALSE;
2146}
2147
7fd53920
MR
2148/* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2149
2150enum match_kind
2151{
2152 MATCH_NONE,
2153 MATCH_FULL,
2154 MATCH_SHORT
2155};
2156
47b0e7ad
NC
2157/* Disassemble mips16 instructions. */
2158
2159static int
2160print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2161{
fc8c4fd1 2162 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 2163 int status;
1bbce132 2164 bfd_byte buffer[4];
47b0e7ad 2165 const struct mips_opcode *op, *opend;
c3c07478 2166 struct mips_print_arg_state state;
fc8c4fd1 2167 void *is = info->stream;
7fd53920 2168 bfd_boolean have_second;
25499ac7 2169 bfd_boolean extend_only;
7fd53920
MR
2170 unsigned int second;
2171 unsigned int first;
2172 unsigned int full;
47b0e7ad
NC
2173
2174 info->bytes_per_chunk = 2;
2175 info->display_endian = info->endian;
2176 info->insn_info_valid = 1;
2177 info->branch_delay_insns = 0;
2178 info->data_size = 0;
47b0e7ad
NC
2179 info->target = 0;
2180 info->target2 = 0;
2181
c3c07478
RS
2182#define GET_OP(insn, field) \
2183 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1bbce132
MR
2184 /* Decode PLT entry's GOT slot address word. */
2185 if (is_mips16_plt_tail (info, memaddr))
2186 {
2187 info->insn_type = dis_noninsn;
2188 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2189 if (status == 0)
2190 {
2191 unsigned int gotslot;
2192
2193 if (info->endian == BFD_ENDIAN_BIG)
2194 gotslot = bfd_getb32 (buffer);
2195 else
2196 gotslot = bfd_getl32 (buffer);
2197 infprintf (is, ".word\t0x%x", gotslot);
2198
2199 return 4;
2200 }
2201 }
2202 else
2203 {
2204 info->insn_type = dis_nonbranch;
2205 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2206 }
47b0e7ad
NC
2207 if (status != 0)
2208 {
2209 (*info->memory_error_func) (status, memaddr, info);
2210 return -1;
2211 }
2212
25499ac7
MR
2213 extend_only = FALSE;
2214
47b0e7ad 2215 if (info->endian == BFD_ENDIAN_BIG)
7fd53920 2216 first = bfd_getb16 (buffer);
47b0e7ad 2217 else
7fd53920 2218 first = bfd_getl16 (buffer);
47b0e7ad 2219
7fd53920
MR
2220 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2221 if (status == 0)
47b0e7ad 2222 {
7fd53920 2223 have_second = TRUE;
47b0e7ad 2224 if (info->endian == BFD_ENDIAN_BIG)
7fd53920 2225 second = bfd_getb16 (buffer);
47b0e7ad 2226 else
7fd53920
MR
2227 second = bfd_getl16 (buffer);
2228 full = (first << 16) | second;
2229 }
2230 else
2231 {
2232 have_second = FALSE;
2233 second = 0;
2234 full = first;
47b0e7ad
NC
2235 }
2236
2237 /* FIXME: Should probably use a hash table on the major opcode here. */
2238
2239 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2240 for (op = mips16_opcodes; op < opend; op++)
2241 {
7fd53920 2242 enum match_kind match;
47b0e7ad 2243
11dd08e9
MR
2244 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2245 continue;
2246
7fd53920
MR
2247 if (op->pinfo == INSN_MACRO
2248 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2249 match = MATCH_NONE;
2250 else if (mips_opcode_32bit_p (op))
2251 {
2252 if (have_second
2253 && (full & op->mask) == op->match)
2254 match = MATCH_FULL;
2255 else
2256 match = MATCH_NONE;
2257 }
2258 else if ((first & op->mask) == op->match)
2259 {
2260 match = MATCH_SHORT;
2261 second = 0;
2262 full = first;
2263 }
2264 else if ((first & 0xf800) == 0xf000
2265 && have_second
25499ac7 2266 && !extend_only
7fd53920 2267 && (second & op->mask) == op->match)
25499ac7
MR
2268 {
2269 if (op->pinfo2 & INSN2_SHORT_ONLY)
2270 {
2271 match = MATCH_NONE;
2272 extend_only = TRUE;
2273 }
2274 else
2275 match = MATCH_FULL;
2276 }
7fd53920
MR
2277 else
2278 match = MATCH_NONE;
47b0e7ad 2279
7fd53920
MR
2280 if (match != MATCH_NONE)
2281 {
2282 const char *s;
47b0e7ad 2283
fc8c4fd1 2284 infprintf (is, "%s", op->name);
47b0e7ad 2285 if (op->args[0] != '\0')
fc8c4fd1 2286 infprintf (is, "\t");
47b0e7ad 2287
c3c07478 2288 init_print_arg_state (&state);
47b0e7ad
NC
2289 for (s = op->args; *s != '\0'; s++)
2290 {
2291 if (*s == ','
2292 && s[1] == 'w'
7fd53920 2293 && GET_OP (full, RX) == GET_OP (full, RY))
47b0e7ad
NC
2294 {
2295 /* Skip the register and the comma. */
2296 ++s;
2297 continue;
2298 }
2299 if (*s == ','
2300 && s[1] == 'v'
7fd53920 2301 && GET_OP (full, RZ) == GET_OP (full, RX))
47b0e7ad
NC
2302 {
2303 /* Skip the register and the comma. */
2304 ++s;
2305 continue;
2306 }
25499ac7
MR
2307 if (s[0] == 'N'
2308 && s[1] == ','
2309 && s[2] == 'O'
2310 && op->name[strlen (op->name) - 1] == '0')
7fd53920 2311 {
25499ac7
MR
2312 /* Coprocessor register 0 with sel field. */
2313 const struct mips_cp0sel_name *n;
2314 const struct mips_operand *operand;
2315 unsigned int reg, sel;
2316
2317 operand = decode_mips16_operand (*s, TRUE);
2318 reg = mips_extract_operand (operand, (first << 16) | second);
2319 s += 2;
2320 operand = decode_mips16_operand (*s, TRUE);
2321 sel = mips_extract_operand (operand, (first << 16) | second);
2322
2323 /* CP0 register including 'sel' code for mftc0, to be
2324 printed textually if known. If not known, print both
2325 CP0 register name and sel numerically since CP0 register
2326 with sel 0 may have a name unrelated to register being
2327 printed. */
2328 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2329 mips_cp0sel_names_len,
2330 reg, sel);
2331 if (n != NULL)
2332 infprintf (is, "%s", n->name);
2333 else
2334 infprintf (is, "$%d,%d", reg, sel);
7fd53920 2335 }
25499ac7
MR
2336 else
2337 switch (match)
2338 {
2339 case MATCH_FULL:
2340 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2341 second, TRUE, first, s[1] == '(');
2342 break;
2343 case MATCH_SHORT:
2344 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2345 first, FALSE, 0, s[1] == '(');
2346 break;
2347 case MATCH_NONE: /* Stop the compiler complaining. */
2348 break;
2349 }
47b0e7ad
NC
2350 }
2351
9a2c7088 2352 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 2353 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088 2354 info->branch_delay_insns = 1;
26545944
RS
2355 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2356 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
47b0e7ad 2357 {
9a2c7088
MR
2358 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2359 info->insn_type = dis_jsr;
2360 else
47b0e7ad
NC
2361 info->insn_type = dis_branch;
2362 }
26545944 2363 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
9a2c7088 2364 info->insn_type = dis_condbranch;
47b0e7ad 2365
7fd53920 2366 return match == MATCH_FULL ? 4 : 2;
47b0e7ad
NC
2367 }
2368 }
fc8c4fd1 2369#undef GET_OP
47b0e7ad 2370
7fd53920 2371 infprintf (is, "0x%x", first);
47b0e7ad
NC
2372 info->insn_type = dis_noninsn;
2373
7fd53920 2374 return 2;
47b0e7ad
NC
2375}
2376
df58fc94
RS
2377/* Disassemble microMIPS instructions. */
2378
2379static int
2380print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2381{
0c7533d3 2382 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94 2383 const struct mips_opcode *op, *opend;
df58fc94 2384 void *is = info->stream;
df58fc94 2385 bfd_byte buffer[2];
ab902481
RS
2386 unsigned int higher;
2387 unsigned int length;
df58fc94 2388 int status;
ab902481 2389 unsigned int insn;
df58fc94
RS
2390
2391 info->bytes_per_chunk = 2;
2392 info->display_endian = info->endian;
2393 info->insn_info_valid = 1;
2394 info->branch_delay_insns = 0;
2395 info->data_size = 0;
2396 info->insn_type = dis_nonbranch;
2397 info->target = 0;
2398 info->target2 = 0;
2399
2400 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2401 if (status != 0)
2402 {
2403 (*info->memory_error_func) (status, memaddr, info);
2404 return -1;
2405 }
2406
2407 length = 2;
2408
2409 if (info->endian == BFD_ENDIAN_BIG)
2410 insn = bfd_getb16 (buffer);
2411 else
2412 insn = bfd_getl16 (buffer);
2413
100b4f2e 2414 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
df58fc94
RS
2415 {
2416 /* This is a 32-bit microMIPS instruction. */
2417 higher = insn;
2418
2419 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2420 if (status != 0)
2421 {
0c7533d3 2422 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2423 (*info->memory_error_func) (status, memaddr + 2, info);
2424 return -1;
2425 }
2426
2427 if (info->endian == BFD_ENDIAN_BIG)
2428 insn = bfd_getb16 (buffer);
2429 else
2430 insn = bfd_getl16 (buffer);
2431
2432 insn = insn | (higher << 16);
2433
2434 length += 2;
2435 }
2436
2437 /* FIXME: Should probably use a hash table on the major opcode here. */
2438
df58fc94
RS
2439 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2440 for (op = micromips_opcodes; op < opend; op++)
2441 {
2442 if (op->pinfo != INSN_MACRO
2443 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2444 && (insn & op->mask) == op->match
2445 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2446 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2447 {
7361da2c
AB
2448 if (!validate_insn_args (op, decode_micromips_operand, insn))
2449 continue;
2450
0c7533d3 2451 infprintf (is, "%s", op->name);
df58fc94 2452
ab902481 2453 if (op->args[0])
df58fc94 2454 {
ab902481
RS
2455 infprintf (is, "\t");
2456 print_insn_args (info, op, decode_micromips_operand, insn,
7361da2c 2457 memaddr + 1, length);
df58fc94
RS
2458 }
2459
2460 /* Figure out instruction type and branch delay information. */
2461 if ((op->pinfo
2462 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2463 info->branch_delay_insns = 1;
2464 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2465 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2466 {
fc76e730 2467 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
df58fc94
RS
2468 info->insn_type = dis_jsr;
2469 else
2470 info->insn_type = dis_branch;
2471 }
2472 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2473 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2474 {
2475 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2476 info->insn_type = dis_condjsr;
2477 else
2478 info->insn_type = dis_condbranch;
2479 }
2480 else if ((op->pinfo
67dc82bc 2481 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
df58fc94
RS
2482 info->insn_type = dis_dref;
2483
2484 return length;
2485 }
2486 }
df58fc94 2487
0c7533d3 2488 infprintf (is, "0x%x", insn);
df58fc94
RS
2489 info->insn_type = dis_noninsn;
2490
2491 return length;
2492}
2493
2494/* Return 1 if a symbol associated with the location being disassembled
1401d2fe
MR
2495 indicates a compressed mode, either MIPS16 or microMIPS, according to
2496 MICROMIPS_P. We iterate over all the symbols at the address being
2497 considered assuming if at least one of them indicates code compression,
2498 then such code has been genuinely produced here (other symbols could
2499 have been derived from function symbols defined elsewhere or could
2500 define data). Otherwise, return 0. */
df58fc94
RS
2501
2502static bfd_boolean
1401d2fe 2503is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
df58fc94 2504{
df58fc94 2505 int i;
1bbce132
MR
2506 int l;
2507
2508 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2509 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
1401d2fe 2510 && ((!micromips_p
1bbce132 2511 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
1401d2fe 2512 || (micromips_p
1bbce132
MR
2513 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2514 return 1;
2515 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2516 && info->symtab[i]->section == info->section)
2517 {
2518 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
1401d2fe 2519 if ((!micromips_p
1bbce132 2520 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
1401d2fe 2521 || (micromips_p
1bbce132
MR
2522 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2523 return 1;
2524 }
df58fc94
RS
2525
2526 return 0;
2527}
2528
47b0e7ad
NC
2529/* In an environment where we do not know the symbol type of the
2530 instruction we are forced to assume that the low order bit of the
2531 instructions' address may mark it as a mips16 instruction. If we
2532 are single stepping, or the pc is within the disassembled function,
2533 this works. Otherwise, we need a clue. Sometimes. */
2534
2535static int
2536_print_insn_mips (bfd_vma memaddr,
2537 struct disassemble_info *info,
2538 enum bfd_endian endianness)
2539{
2540 bfd_byte buffer[INSNLEN];
2541 int status;
2542
2543 set_default_mips_dis_options (info);
2544 parse_mips_dis_options (info->disassembler_options);
2545
df58fc94
RS
2546 if (info->mach == bfd_mach_mips16)
2547 return print_insn_mips16 (memaddr, info);
2548 if (info->mach == bfd_mach_mips_micromips)
2549 return print_insn_micromips (memaddr, info);
2550
47b0e7ad 2551#if 1
df58fc94 2552 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
2553 /* Only a few tools will work this way. */
2554 if (memaddr & 0x01)
1401d2fe
MR
2555 {
2556 if (micromips_ase)
2557 return print_insn_micromips (memaddr, info);
2558 else
2559 return print_insn_mips16 (memaddr, info);
2560 }
47b0e7ad
NC
2561#endif
2562
2563#if SYMTAB_AVAILABLE
1401d2fe
MR
2564 if (is_compressed_mode_p (info, TRUE))
2565 return print_insn_micromips (memaddr, info);
2566 if (is_compressed_mode_p (info, FALSE))
2567 return print_insn_mips16 (memaddr, info);
47b0e7ad
NC
2568#endif
2569
2570 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2571 if (status == 0)
2572 {
fc8c4fd1 2573 int insn;
47b0e7ad
NC
2574
2575 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 2576 insn = bfd_getb32 (buffer);
47b0e7ad 2577 else
fc8c4fd1 2578 insn = bfd_getl32 (buffer);
47b0e7ad
NC
2579
2580 return print_insn_mips (memaddr, insn, info);
2581 }
2582 else
2583 {
2584 (*info->memory_error_func) (status, memaddr, info);
2585 return -1;
2586 }
2587}
2588
2589int
2590print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2591{
2592 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2593}
2594
2595int
2596print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2597{
2598 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2599}
2600\f
471b9d15
MR
2601/* Indices into option argument vector for options accepting an argument.
2602 Use MIPS_OPTION_ARG_NONE for options accepting no argument. */
2603typedef enum
640c0ccd 2604{
471b9d15
MR
2605 MIPS_OPTION_ARG_NONE = -1,
2606 MIPS_OPTION_ARG_ABI,
2607 MIPS_OPTION_ARG_ARCH,
2608 MIPS_OPTION_ARG_SIZE
2609} mips_option_arg_t;
2610
2611/* Valid MIPS disassembler options. */
2612static struct
2613{
2614 const char *name;
2615 const char *description;
2616 mips_option_arg_t arg;
2617} mips_options[] =
2618{
2619 { "no-aliases", N_("Use canonical instruction forms.\n"),
2620 MIPS_OPTION_ARG_NONE },
2621 { "msa", N_("Recognize MSA instructions.\n"),
2622 MIPS_OPTION_ARG_NONE },
2623 { "virt", N_("Recognize the virtualization ASE instructions.\n"),
2624 MIPS_OPTION_ARG_NONE },
2625 { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\
2626 instructions.\n"),
2627 MIPS_OPTION_ARG_NONE },
2628 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2629 "instructions.\n"),
2630 MIPS_OPTION_ARG_NONE },
8095d2f7
CX
2631 { "loongson-mmi",
2632 N_("Recognize the Loongson MultiMedia extensions "
2633 "Instructions (MMI) ASE instructions.\n"),
2634 MIPS_OPTION_ARG_NONE },
716c08de
CX
2635 { "loongson-cam",
2636 N_("Recognize the Loongson Content Address Memory (CAM) "
2637 " instructions.\n"),
2638 MIPS_OPTION_ARG_NONE },
bdc6c06e
CX
2639 { "loongson-ext",
2640 N_("Recognize the Loongson EXTensions (EXT) "
2641 " instructions.\n"),
2642 MIPS_OPTION_ARG_NONE },
a693765e
CX
2643 { "loongson-ext2",
2644 N_("Recognize the Loongson EXTensions R2 (EXT2) "
2645 " instructions.\n"),
2646 MIPS_OPTION_ARG_NONE },
471b9d15
MR
2647 { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
2648 Default: based on binary being disassembled.\n"),
2649 MIPS_OPTION_ARG_ABI },
2650 { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
2651 Default: numeric.\n"),
2652 MIPS_OPTION_ARG_ABI },
2653 { "cp0-names=", N_("Print CP0 register names according to specified "
2654 "architecture.\n\
2655 Default: based on binary being disassembled.\n"),
2656 MIPS_OPTION_ARG_ARCH },
2657 { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
2658 Default: based on binary being disassembled.\n"),
2659 MIPS_OPTION_ARG_ARCH },
2660 { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
2661 MIPS_OPTION_ARG_ABI },
2662 { "reg-names=", N_("Print CP0 register and HWR names according to "
2663 "specified\n\
2664 architecture."),
2665 MIPS_OPTION_ARG_ARCH }
2666};
0348fd79 2667
471b9d15
MR
2668/* Build the structure representing valid MIPS disassembler options.
2669 This is done dynamically for maintenance ease purpose; a static
2670 initializer would be unreadable. */
4edbb8e3 2671
471b9d15
MR
2672const disasm_options_and_args_t *
2673disassembler_options_mips (void)
2674{
2675 static disasm_options_and_args_t *opts_and_args;
b015e599 2676
471b9d15
MR
2677 if (opts_and_args == NULL)
2678 {
2679 size_t num_options = ARRAY_SIZE (mips_options);
2680 size_t num_args = MIPS_OPTION_ARG_SIZE;
2681 disasm_option_arg_t *args;
2682 disasm_options_t *opts;
2683 size_t i;
2684 size_t j;
2685
2686 args = XNEWVEC (disasm_option_arg_t, num_args + 1);
2687
2688 args[MIPS_OPTION_ARG_ABI].name = "ABI";
2689 args[MIPS_OPTION_ARG_ABI].values
2690 = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1);
2691 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2692 args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name;
2693 /* The array we return must be NULL terminated. */
2694 args[MIPS_OPTION_ARG_ABI].values[i] = NULL;
2695
2696 args[MIPS_OPTION_ARG_ARCH].name = "ARCH";
2697 args[MIPS_OPTION_ARG_ARCH].values
2698 = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1);
2699 for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2700 if (*mips_arch_choices[i].name != '\0')
2701 args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name;
2702 /* The array we return must be NULL terminated. */
2703 args[MIPS_OPTION_ARG_ARCH].values[j] = NULL;
2704
2705 /* The array we return must be NULL terminated. */
2706 args[MIPS_OPTION_ARG_SIZE].name = NULL;
2707 args[MIPS_OPTION_ARG_SIZE].values = NULL;
2708
2709 opts_and_args = XNEW (disasm_options_and_args_t);
2710 opts_and_args->args = args;
2711
2712 opts = &opts_and_args->options;
2713 opts->name = XNEWVEC (const char *, num_options + 1);
2714 opts->description = XNEWVEC (const char *, num_options + 1);
2715 opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
2716 for (i = 0; i < num_options; i++)
2717 {
2718 opts->name[i] = mips_options[i].name;
2719 opts->description[i] = _(mips_options[i].description);
2720 if (mips_options[i].arg != MIPS_OPTION_ARG_NONE)
2721 opts->arg[i] = &args[mips_options[i].arg];
2722 else
2723 opts->arg[i] = NULL;
2724 }
2725 /* The array we return must be NULL terminated. */
2726 opts->name[i] = NULL;
2727 opts->description[i] = NULL;
2728 opts->arg[i] = NULL;
2729 }
7d64c587 2730
471b9d15
MR
2731 return opts_and_args;
2732}
6f20c942 2733
471b9d15
MR
2734void
2735print_mips_disassembler_options (FILE *stream)
2736{
2737 const disasm_options_and_args_t *opts_and_args;
2738 const disasm_option_arg_t *args;
2739 const disasm_options_t *opts;
2740 size_t max_len = 0;
2741 size_t i;
2742 size_t j;
640c0ccd 2743
471b9d15
MR
2744 opts_and_args = disassembler_options_mips ();
2745 opts = &opts_and_args->options;
2746 args = opts_and_args->args;
640c0ccd
CD
2747
2748 fprintf (stream, _("\n\
471b9d15
MR
2749The following MIPS specific disassembler options are supported for use\n\
2750with the -M switch (multiple options should be separated by commas):\n\n"));
640c0ccd 2751
471b9d15
MR
2752 /* Compute the length of the longest option name. */
2753 for (i = 0; opts->name[i] != NULL; i++)
2754 {
2755 size_t len = strlen (opts->name[i]);
af7ee8bf 2756
471b9d15
MR
2757 if (opts->arg[i] != NULL)
2758 len += strlen (opts->arg[i]->name);
2759 if (max_len < len)
2760 max_len = len;
2761 }
640c0ccd 2762
471b9d15
MR
2763 for (i = 0, max_len++; opts->name[i] != NULL; i++)
2764 {
2765 fprintf (stream, " %s", opts->name[i]);
2766 if (opts->arg[i] != NULL)
2767 fprintf (stream, "%s", opts->arg[i]->name);
2768 if (opts->description[i] != NULL)
2769 {
2770 size_t len = strlen (opts->name[i]);
640c0ccd 2771
471b9d15
MR
2772 if (opts->arg[i] != NULL)
2773 len += strlen (opts->arg[i]->name);
2774 fprintf (stream,
2775 "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
2776 }
2777 fprintf (stream, _("\n"));
2778 }
640c0ccd 2779
471b9d15
MR
2780 for (i = 0; args[i].name != NULL; i++)
2781 {
2782 fprintf (stream, _("\n\
2783 For the options above, the following values are supported for \"%s\":\n "),
2784 args[i].name);
2785 for (j = 0; args[i].values[j] != NULL; j++)
2786 fprintf (stream, " %s", args[i].values[j]);
2787 fprintf (stream, _("\n"));
2788 }
640c0ccd
CD
2789
2790 fprintf (stream, _("\n"));
2791}
This page took 1.359553 seconds and 4 git commands to generate.