infcall-nested-structs: Test up to five fields
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
CommitLineData
252b5132 1/* Print mips instructions for GDB, the GNU debugger, or for objdump.
219d1afa 2 Copyright (C) 1989-2018 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
fd503541 632 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
8095d2f7 633 ISA_MIPS64R2 | INSN_LOONGSON_3A, ASE_LOONGSON_MMI, mips_cp0_names_numeric,
dc76d757 634 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
fd503541 635
57b592a3 636 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
d301a56b 637 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
dc76d757 638 mips_cp1_names_mips3264, mips_hwr_names_numeric },
57b592a3 639
dd6a37e7 640 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
d301a56b 641 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
dc76d757 642 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
432233b3
AP
643
644 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
d301a56b 645 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
dc76d757 646 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
dd6a37e7 647
2c629856
N
648 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
649 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
650 mips_cp0_names_numeric,
651 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
652
52b6b6b9 653 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 654 ISA_MIPS64 | INSN_XLR, 0,
52b6b6b9
JM
655 mips_cp0_names_xlr,
656 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 657 mips_cp1_names_mips3264, mips_hwr_names_numeric },
52b6b6b9 658
55a36193
MK
659 /* XLP is mostly like XLR, with the prominent exception it is being
660 MIPS64R2. */
661 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 662 ISA_MIPS64R2 | INSN_XLR, 0,
55a36193
MK
663 mips_cp0_names_xlr,
664 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 665 mips_cp1_names_mips3264, mips_hwr_names_numeric },
55a36193 666
640c0ccd
CD
667 /* This entry, mips16, is here only for ISA/processor selection; do
668 not print its name. */
25499ac7
MR
669 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
670 ASE_MIPS16E2 | ASE_MIPS16E2_MT,
dc76d757
AB
671 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
672 mips_hwr_names_numeric },
640c0ccd
CD
673};
674
675/* ISA and processor type to disassemble for, and register names to use.
676 set_default_mips_dis_options and parse_mips_dis_options fill in these
677 values. */
678static int mips_processor;
679static int mips_isa;
d301a56b 680static int mips_ase;
df58fc94 681static int micromips_ase;
640c0ccd
CD
682static const char * const *mips_gpr_names;
683static const char * const *mips_fpr_names;
684static const char * const *mips_cp0_names;
bbcc0807
CD
685static const struct mips_cp0sel_name *mips_cp0sel_names;
686static int mips_cp0sel_names_len;
dc76d757 687static const char * const *mips_cp1_names;
af7ee8bf 688static const char * const *mips_hwr_names;
640c0ccd 689
986e18a5 690/* Other options */
47b0e7ad 691static int no_aliases; /* If set disassemble as most general inst. */
640c0ccd
CD
692\f
693static const struct mips_abi_choice *
47b0e7ad 694choose_abi_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
695{
696 const struct mips_abi_choice *c;
697 unsigned int i;
698
699 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
47b0e7ad
NC
700 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
701 && strlen (mips_abi_choices[i].name) == namelen)
702 c = &mips_abi_choices[i];
703
640c0ccd
CD
704 return c;
705}
706
707static const struct mips_arch_choice *
47b0e7ad 708choose_arch_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
709{
710 const struct mips_arch_choice *c = NULL;
711 unsigned int i;
712
713 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
47b0e7ad
NC
714 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
715 && strlen (mips_arch_choices[i].name) == namelen)
716 c = &mips_arch_choices[i];
717
640c0ccd
CD
718 return c;
719}
720
721static const struct mips_arch_choice *
47b0e7ad 722choose_arch_by_number (unsigned long mach)
640c0ccd
CD
723{
724 static unsigned long hint_bfd_mach;
725 static const struct mips_arch_choice *hint_arch_choice;
726 const struct mips_arch_choice *c;
727 unsigned int i;
728
729 /* We optimize this because even if the user specifies no
730 flags, this will be done for every instruction! */
731 if (hint_bfd_mach == mach
732 && hint_arch_choice != NULL
733 && hint_arch_choice->bfd_mach == hint_bfd_mach)
734 return hint_arch_choice;
735
736 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
737 {
738 if (mips_arch_choices[i].bfd_mach_valid
739 && mips_arch_choices[i].bfd_mach == mach)
740 {
741 c = &mips_arch_choices[i];
742 hint_bfd_mach = mach;
743 hint_arch_choice = c;
744 }
745 }
746 return c;
747}
748
47b0e7ad
NC
749/* Check if the object uses NewABI conventions. */
750
751static int
752is_newabi (Elf_Internal_Ehdr *header)
753{
754 /* There are no old-style ABIs which use 64-bit ELF. */
755 if (header->e_ident[EI_CLASS] == ELFCLASS64)
756 return 1;
757
758 /* If a 32-bit ELF file, n32 is a new-style ABI. */
759 if ((header->e_flags & EF_MIPS_ABI2) != 0)
760 return 1;
761
762 return 0;
763}
764
df58fc94
RS
765/* Check if the object has microMIPS ASE code. */
766
767static int
768is_micromips (Elf_Internal_Ehdr *header)
769{
770 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
771 return 1;
772
773 return 0;
774}
775
5e7fc731
MR
776/* Convert ASE flags from .MIPS.abiflags to internal values. */
777
778static unsigned long
779mips_convert_abiflags_ases (unsigned long afl_ases)
780{
781 unsigned long opcode_ases = 0;
782
783 if (afl_ases & AFL_ASE_DSP)
784 opcode_ases |= ASE_DSP;
785 if (afl_ases & AFL_ASE_DSPR2)
786 opcode_ases |= ASE_DSPR2;
787 if (afl_ases & AFL_ASE_EVA)
788 opcode_ases |= ASE_EVA;
789 if (afl_ases & AFL_ASE_MCU)
790 opcode_ases |= ASE_MCU;
791 if (afl_ases & AFL_ASE_MDMX)
792 opcode_ases |= ASE_MDMX;
793 if (afl_ases & AFL_ASE_MIPS3D)
794 opcode_ases |= ASE_MIPS3D;
795 if (afl_ases & AFL_ASE_MT)
796 opcode_ases |= ASE_MT;
797 if (afl_ases & AFL_ASE_SMARTMIPS)
798 opcode_ases |= ASE_SMARTMIPS;
799 if (afl_ases & AFL_ASE_VIRT)
800 opcode_ases |= ASE_VIRT;
801 if (afl_ases & AFL_ASE_MSA)
802 opcode_ases |= ASE_MSA;
803 if (afl_ases & AFL_ASE_XPA)
804 opcode_ases |= ASE_XPA;
805 if (afl_ases & AFL_ASE_DSPR3)
806 opcode_ases |= ASE_DSPR3;
25499ac7
MR
807 if (afl_ases & AFL_ASE_MIPS16E2)
808 opcode_ases |= ASE_MIPS16E2;
5e7fc731
MR
809 return opcode_ases;
810}
811
60804c53
MR
812/* Calculate combination ASE flags from regular ASE flags. */
813
814static unsigned long
815mips_calculate_combination_ases (unsigned long opcode_ases)
816{
817 unsigned long combination_ases = 0;
818
9785fc2a
MR
819 if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
820 combination_ases |= ASE_XPA_VIRT;
60804c53
MR
821 if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
822 combination_ases |= ASE_MIPS16E2_MT;
823 return combination_ases;
824}
825
47b0e7ad
NC
826static void
827set_default_mips_dis_options (struct disassemble_info *info)
640c0ccd
CD
828{
829 const struct mips_arch_choice *chosen_arch;
830
df58fc94
RS
831 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
832 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
833 CP0 register, and HWR names. */
640c0ccd 834 mips_isa = ISA_MIPS3;
df58fc94
RS
835 mips_processor = CPU_R3000;
836 micromips_ase = 0;
d301a56b 837 mips_ase = 0;
640c0ccd
CD
838 mips_gpr_names = mips_gpr_names_oldabi;
839 mips_fpr_names = mips_fpr_names_numeric;
840 mips_cp0_names = mips_cp0_names_numeric;
bbcc0807
CD
841 mips_cp0sel_names = NULL;
842 mips_cp0sel_names_len = 0;
dc76d757 843 mips_cp1_names = mips_cp1_names_numeric;
af7ee8bf 844 mips_hwr_names = mips_hwr_names_numeric;
986e18a5 845 no_aliases = 0;
640c0ccd 846
640c0ccd
CD
847 /* Set ISA, architecture, and cp0 register names as best we can. */
848#if ! SYMTAB_AVAILABLE
849 /* This is running out on a target machine, not in a host tool.
850 FIXME: Where does mips_target_info come from? */
851 target_processor = mips_target_info.processor;
852 mips_isa = mips_target_info.isa;
d301a56b 853 mips_ase = mips_target_info.ase;
640c0ccd
CD
854#else
855 chosen_arch = choose_arch_by_number (info->mach);
856 if (chosen_arch != NULL)
857 {
858 mips_processor = chosen_arch->processor;
859 mips_isa = chosen_arch->isa;
d301a56b 860 mips_ase = chosen_arch->ase;
bbcc0807
CD
861 mips_cp0_names = chosen_arch->cp0_names;
862 mips_cp0sel_names = chosen_arch->cp0sel_names;
863 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 864 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 865 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd 866 }
8184783a
MR
867
868 /* Update settings according to the ELF file header flags. */
869 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
870 {
5e7fc731
MR
871 struct bfd *abfd = info->section->owner;
872 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
4df995c7
MR
873 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
874
9e76c212
MR
875 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
876 because we won't then have a MIPS/ELF BFD, however we need
877 to guard against a link error in a `--enable-targets=...'
878 configuration with a 32-bit host where the MIPS target is
879 a secondary, or with MIPS/ECOFF configurations. */
880#ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
4df995c7
MR
881 abiflags = bfd_mips_elf_get_abiflags (abfd);
882#endif
8184783a
MR
883 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
884 if (is_newabi (header))
885 mips_gpr_names = mips_gpr_names_newabi;
886 /* If a microMIPS binary, then don't use MIPS16 bindings. */
887 micromips_ase = is_micromips (header);
5e7fc731
MR
888 /* OR in any extra ASE flags set in ELF file structures. */
889 if (abiflags)
890 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
891 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
892 mips_ase |= ASE_MDMX;
8184783a 893 }
91068ec6 894#endif
60804c53 895 mips_ase |= mips_calculate_combination_ases (mips_ase);
640c0ccd
CD
896}
897
9785fc2a
MR
898/* Parse an ASE disassembler option and set the corresponding global
899 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
b015e599 900
9785fc2a
MR
901static bfd_boolean
902parse_mips_ase_option (const char *option)
903{
4edbb8e3
CF
904 if (CONST_STRNEQ (option, "msa"))
905 {
906 mips_ase |= ASE_MSA;
ae52f483
AB
907 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
908 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
7361da2c
AB
909 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
910 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
4edbb8e3 911 mips_ase |= ASE_MSA64;
9785fc2a 912 return TRUE;
4edbb8e3
CF
913 }
914
b015e599
AP
915 if (CONST_STRNEQ (option, "virt"))
916 {
d301a56b 917 mips_ase |= ASE_VIRT;
ae52f483
AB
918 if (mips_isa & ISA_MIPS64R2
919 || mips_isa & ISA_MIPS64R3
7361da2c
AB
920 || mips_isa & ISA_MIPS64R5
921 || mips_isa & ISA_MIPS64R6)
d301a56b 922 mips_ase |= ASE_VIRT64;
9785fc2a 923 return TRUE;
b015e599 924 }
7d64c587
AB
925
926 if (CONST_STRNEQ (option, "xpa"))
927 {
928 mips_ase |= ASE_XPA;
9785fc2a
MR
929 return TRUE;
930 }
931
6f20c942
FS
932 if (CONST_STRNEQ (option, "ginv"))
933 {
934 mips_ase |= ASE_GINV;
935 return TRUE;
936 }
937
8095d2f7
CX
938 if (CONST_STRNEQ (option, "loongson-mmi"))
939 {
940 mips_ase |= ASE_LOONGSON_MMI;
941 return TRUE;
942 }
943
9785fc2a
MR
944 return FALSE;
945}
946
947static void
948parse_mips_dis_option (const char *option, unsigned int len)
949{
950 unsigned int i, optionlen, vallen;
951 const char *val;
952 const struct mips_abi_choice *chosen_abi;
953 const struct mips_arch_choice *chosen_arch;
954
955 /* Try to match options that are simple flags */
956 if (CONST_STRNEQ (option, "no-aliases"))
957 {
958 no_aliases = 1;
7d64c587
AB
959 return;
960 }
43e65147 961
9785fc2a
MR
962 if (parse_mips_ase_option (option))
963 {
964 mips_ase |= mips_calculate_combination_ases (mips_ase);
965 return;
966 }
43e65147 967
640c0ccd
CD
968 /* Look for the = that delimits the end of the option name. */
969 for (i = 0; i < len; i++)
47b0e7ad
NC
970 if (option[i] == '=')
971 break;
972
640c0ccd
CD
973 if (i == 0) /* Invalid option: no name before '='. */
974 return;
975 if (i == len) /* Invalid option: no '='. */
976 return;
977 if (i == (len - 1)) /* Invalid option: no value after '='. */
978 return;
979
980 optionlen = i;
981 val = option + (optionlen + 1);
982 vallen = len - (optionlen + 1);
983
47b0e7ad
NC
984 if (strncmp ("gpr-names", option, optionlen) == 0
985 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
986 {
987 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 988 if (chosen_abi != NULL)
640c0ccd
CD
989 mips_gpr_names = chosen_abi->gpr_names;
990 return;
991 }
992
47b0e7ad
NC
993 if (strncmp ("fpr-names", option, optionlen) == 0
994 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
995 {
996 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 997 if (chosen_abi != NULL)
640c0ccd
CD
998 mips_fpr_names = chosen_abi->fpr_names;
999 return;
1000 }
1001
47b0e7ad
NC
1002 if (strncmp ("cp0-names", option, optionlen) == 0
1003 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
1004 {
1005 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
1006 if (chosen_arch != NULL)
1007 {
1008 mips_cp0_names = chosen_arch->cp0_names;
1009 mips_cp0sel_names = chosen_arch->cp0sel_names;
1010 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1011 }
640c0ccd
CD
1012 return;
1013 }
1014
dc76d757
AB
1015 if (strncmp ("cp1-names", option, optionlen) == 0
1016 && strlen ("cp1-names") == optionlen)
1017 {
1018 chosen_arch = choose_arch_by_name (val, vallen);
1019 if (chosen_arch != NULL)
1020 mips_cp1_names = chosen_arch->cp1_names;
1021 return;
1022 }
1023
47b0e7ad
NC
1024 if (strncmp ("hwr-names", option, optionlen) == 0
1025 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
1026 {
1027 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 1028 if (chosen_arch != NULL)
af7ee8bf
CD
1029 mips_hwr_names = chosen_arch->hwr_names;
1030 return;
1031 }
1032
47b0e7ad
NC
1033 if (strncmp ("reg-names", option, optionlen) == 0
1034 && strlen ("reg-names") == optionlen)
640c0ccd
CD
1035 {
1036 /* We check both ABI and ARCH here unconditionally, so
1037 that "numeric" will do the desirable thing: select
1038 numeric register names for all registers. Other than
1039 that, a given name probably won't match both. */
1040 chosen_abi = choose_abi_by_name (val, vallen);
1041 if (chosen_abi != NULL)
1042 {
bbcc0807
CD
1043 mips_gpr_names = chosen_abi->gpr_names;
1044 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
1045 }
1046 chosen_arch = choose_arch_by_name (val, vallen);
1047 if (chosen_arch != NULL)
1048 {
bbcc0807
CD
1049 mips_cp0_names = chosen_arch->cp0_names;
1050 mips_cp0sel_names = chosen_arch->cp0sel_names;
1051 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 1052 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 1053 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
1054 }
1055 return;
1056 }
1057
1058 /* Invalid option. */
1059}
1060
47b0e7ad
NC
1061static void
1062parse_mips_dis_options (const char *options)
640c0ccd
CD
1063{
1064 const char *option_end;
1065
1066 if (options == NULL)
1067 return;
1068
1069 while (*options != '\0')
1070 {
1071 /* Skip empty options. */
1072 if (*options == ',')
1073 {
1074 options++;
1075 continue;
1076 }
1077
1078 /* We know that *options is neither NUL or a comma. */
1079 option_end = options + 1;
1080 while (*option_end != ',' && *option_end != '\0')
1081 option_end++;
1082
1083 parse_mips_dis_option (options, option_end - options);
1084
1085 /* Go on to the next one. If option_end points to a comma, it
1086 will be skipped above. */
1087 options = option_end;
1088 }
1089}
1090
bbcc0807 1091static const struct mips_cp0sel_name *
47b0e7ad
NC
1092lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1093 unsigned int len,
1094 unsigned int cp0reg,
1095 unsigned int sel)
bbcc0807
CD
1096{
1097 unsigned int i;
1098
1099 for (i = 0; i < len; i++)
1100 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1101 return &names[i];
1102 return NULL;
1103}
ab902481
RS
1104
1105/* Print register REGNO, of type TYPE, for instruction OPCODE. */
aa5f19f2 1106
794ac9d0 1107static void
ab902481
RS
1108print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1109 enum mips_reg_operand_type type, int regno)
252b5132 1110{
ab902481
RS
1111 switch (type)
1112 {
1113 case OP_REG_GP:
1114 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1115 break;
440cc0bc 1116
ab902481
RS
1117 case OP_REG_FP:
1118 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1119 break;
252b5132 1120
ab902481
RS
1121 case OP_REG_CCC:
1122 if (opcode->pinfo & (FP_D | FP_S))
1123 info->fprintf_func (info->stream, "$fcc%d", regno);
1124 else
1125 info->fprintf_func (info->stream, "$cc%d", regno);
1126 break;
794ac9d0 1127
ab902481
RS
1128 case OP_REG_VEC:
1129 if (opcode->membership & INSN_5400)
1130 info->fprintf_func (info->stream, "$f%d", regno);
1131 else
1132 info->fprintf_func (info->stream, "$v%d", regno);
1133 break;
794ac9d0 1134
ab902481
RS
1135 case OP_REG_ACC:
1136 info->fprintf_func (info->stream, "$ac%d", regno);
1137 break;
794ac9d0 1138
ab902481
RS
1139 case OP_REG_COPRO:
1140 if (opcode->name[strlen (opcode->name) - 1] == '0')
1141 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
dc76d757
AB
1142 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1143 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
ab902481
RS
1144 else
1145 info->fprintf_func (info->stream, "$%d", regno);
1146 break;
8b082fb1 1147
ab902481
RS
1148 case OP_REG_HW:
1149 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1150 break;
14daeee3
RS
1151
1152 case OP_REG_VF:
1153 info->fprintf_func (info->stream, "$vf%d", regno);
1154 break;
1155
1156 case OP_REG_VI:
1157 info->fprintf_func (info->stream, "$vi%d", regno);
1158 break;
1159
1160 case OP_REG_R5900_I:
1161 info->fprintf_func (info->stream, "$I");
1162 break;
1163
1164 case OP_REG_R5900_Q:
1165 info->fprintf_func (info->stream, "$Q");
1166 break;
1167
1168 case OP_REG_R5900_R:
1169 info->fprintf_func (info->stream, "$R");
1170 break;
1171
1172 case OP_REG_R5900_ACC:
1173 info->fprintf_func (info->stream, "$ACC");
1174 break;
4edbb8e3
CF
1175
1176 case OP_REG_MSA:
1177 info->fprintf_func (info->stream, "$w%d", regno);
1178 break;
1179
1180 case OP_REG_MSA_CTRL:
1181 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1182 break;
1183
ab902481
RS
1184 }
1185}
1186\f
1187/* Used to track the state carried over from previous operands in
1188 an instruction. */
1189struct mips_print_arg_state {
1190 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1191 where the value is known to be unsigned and small. */
1192 unsigned int last_int;
1193
1194 /* The type and number of the last OP_REG seen. We only use this for
1195 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1196 enum mips_reg_operand_type last_reg_type;
1197 unsigned int last_regno;
7361da2c
AB
1198 unsigned int dest_regno;
1199 unsigned int seen_dest;
ab902481 1200};
fd25c5a9 1201
ab902481 1202/* Initialize STATE for the start of an instruction. */
fd25c5a9 1203
ab902481
RS
1204static inline void
1205init_print_arg_state (struct mips_print_arg_state *state)
1206{
1207 memset (state, 0, sizeof (*state));
1208}
fd25c5a9 1209
14daeee3
RS
1210/* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1211 whose value is given by UVAL. */
1212
1213static void
1214print_vu0_channel (struct disassemble_info *info,
1215 const struct mips_operand *operand, unsigned int uval)
1216{
1217 if (operand->size == 4)
1218 info->fprintf_func (info->stream, "%s%s%s%s",
1219 uval & 8 ? "x" : "",
1220 uval & 4 ? "y" : "",
1221 uval & 2 ? "z" : "",
1222 uval & 1 ? "w" : "");
1223 else if (operand->size == 2)
1224 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1225 else
1226 abort ();
1227}
1228
7361da2c
AB
1229/* Record information about a register operand. */
1230
1231static void
1232mips_seen_register (struct mips_print_arg_state *state,
1233 unsigned int regno,
1234 enum mips_reg_operand_type reg_type)
1235{
1236 state->last_reg_type = reg_type;
1237 state->last_regno = regno;
1238
1239 if (!state->seen_dest)
1240 {
1241 state->seen_dest = 1;
1242 state->dest_regno = regno;
1243 }
1244}
1245
38bf472a
MR
1246/* Print SAVE/RESTORE instruction operands according to the argument
1247 register mask AMASK, the number of static registers saved NSREG,
1248 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1249 and the frame size FRAME_SIZE. */
1250
1251static void
1252mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
1253 unsigned int nsreg, unsigned int ra,
1254 unsigned int s0, unsigned int s1,
1255 unsigned int frame_size)
1256{
1257 const fprintf_ftype infprintf = info->fprintf_func;
1258 unsigned int nargs, nstatics, smask, i, j;
1259 void *is = info->stream;
1260 const char *sep;
1261
1262 if (amask == MIPS_SVRS_ALL_ARGS)
1263 {
1264 nargs = 4;
1265 nstatics = 0;
1266 }
1267 else if (amask == MIPS_SVRS_ALL_STATICS)
1268 {
1269 nargs = 0;
1270 nstatics = 4;
1271 }
1272 else
1273 {
1274 nargs = amask >> 2;
1275 nstatics = amask & 3;
1276 }
1277
1278 sep = "";
1279 if (nargs > 0)
1280 {
1281 infprintf (is, "%s", mips_gpr_names[4]);
1282 if (nargs > 1)
1283 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1284 sep = ",";
1285 }
1286
1287 infprintf (is, "%s%d", sep, frame_size);
1288
1289 if (ra) /* $ra */
1290 infprintf (is, ",%s", mips_gpr_names[31]);
1291
1292 smask = 0;
1293 if (s0) /* $s0 */
1294 smask |= 1 << 0;
1295 if (s1) /* $s1 */
1296 smask |= 1 << 1;
1297 if (nsreg > 0) /* $s2-$s8 */
1298 smask |= ((1 << nsreg) - 1) << 2;
1299
1300 for (i = 0; i < 9; i++)
1301 if (smask & (1 << i))
1302 {
1303 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1304 /* Skip over string of set bits. */
1305 for (j = i; smask & (2 << j); j++)
1306 continue;
1307 if (j > i)
1308 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1309 i = j + 1;
1310 }
1311 /* Statics $ax - $a3. */
1312 if (nstatics == 1)
1313 infprintf (is, ",%s", mips_gpr_names[7]);
1314 else if (nstatics > 0)
1315 infprintf (is, ",%s-%s",
1316 mips_gpr_names[7 - nstatics + 1],
1317 mips_gpr_names[7]);
1318}
1319
1320
ab902481
RS
1321/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1322 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1323 the base address for OP_PCREL operands. */
fd25c5a9 1324
ab902481
RS
1325static void
1326print_insn_arg (struct disassemble_info *info,
1327 struct mips_print_arg_state *state,
1328 const struct mips_opcode *opcode,
1329 const struct mips_operand *operand,
1330 bfd_vma base_pc,
1331 unsigned int uval)
1332{
1333 const fprintf_ftype infprintf = info->fprintf_func;
1334 void *is = info->stream;
fd25c5a9 1335
ab902481
RS
1336 switch (operand->type)
1337 {
1338 case OP_INT:
1339 {
1340 const struct mips_int_operand *int_op;
fd25c5a9 1341
ab902481
RS
1342 int_op = (const struct mips_int_operand *) operand;
1343 uval = mips_decode_int_operand (int_op, uval);
1344 state->last_int = uval;
1345 if (int_op->print_hex)
1346 infprintf (is, "0x%x", uval);
1347 else
1348 infprintf (is, "%d", uval);
1349 }
1350 break;
fd25c5a9 1351
ab902481
RS
1352 case OP_MAPPED_INT:
1353 {
1354 const struct mips_mapped_int_operand *mint_op;
fd25c5a9 1355
ab902481
RS
1356 mint_op = (const struct mips_mapped_int_operand *) operand;
1357 uval = mint_op->int_map[uval];
1358 state->last_int = uval;
1359 if (mint_op->print_hex)
1360 infprintf (is, "0x%x", uval);
1361 else
1362 infprintf (is, "%d", uval);
1363 }
1364 break;
fd25c5a9 1365
ab902481
RS
1366 case OP_MSB:
1367 {
1368 const struct mips_msb_operand *msb_op;
dec0624d 1369
ab902481
RS
1370 msb_op = (const struct mips_msb_operand *) operand;
1371 uval += msb_op->bias;
1372 if (msb_op->add_lsb)
1373 uval -= state->last_int;
1374 infprintf (is, "0x%x", uval);
1375 }
1376 break;
dec0624d 1377
ab902481 1378 case OP_REG:
0f35dbc4 1379 case OP_OPTIONAL_REG:
ab902481
RS
1380 {
1381 const struct mips_reg_operand *reg_op;
fd25c5a9 1382
ab902481 1383 reg_op = (const struct mips_reg_operand *) operand;
fc76e730 1384 uval = mips_decode_reg_operand (reg_op, uval);
ab902481 1385 print_reg (info, opcode, reg_op->reg_type, uval);
fd25c5a9 1386
7361da2c 1387 mips_seen_register (state, uval, reg_op->reg_type);
ab902481
RS
1388 }
1389 break;
61cc0267 1390
ab902481
RS
1391 case OP_REG_PAIR:
1392 {
1393 const struct mips_reg_pair_operand *pair_op;
1394
1395 pair_op = (const struct mips_reg_pair_operand *) operand;
1396 print_reg (info, opcode, pair_op->reg_type,
1397 pair_op->reg1_map[uval]);
1398 infprintf (is, ",");
1399 print_reg (info, opcode, pair_op->reg_type,
1400 pair_op->reg2_map[uval]);
1401 }
1402 break;
61cc0267 1403
ab902481
RS
1404 case OP_PCREL:
1405 {
1406 const struct mips_pcrel_operand *pcrel_op;
61cc0267 1407
ab902481
RS
1408 pcrel_op = (const struct mips_pcrel_operand *) operand;
1409 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
61cc0267 1410
a4ddc54e
MR
1411 /* For jumps and branches clear the ISA bit except for
1412 the GDB disassembler. */
1413 if (pcrel_op->include_isa_bit
1414 && info->flavour != bfd_target_unknown_flavour)
ab902481 1415 info->target &= -2;
61cc0267 1416
ab902481
RS
1417 (*info->print_address_func) (info->target, info);
1418 }
1419 break;
794ac9d0 1420
ab902481
RS
1421 case OP_PERF_REG:
1422 infprintf (is, "%d", uval);
1423 break;
794ac9d0 1424
ab902481
RS
1425 case OP_ADDIUSP_INT:
1426 {
1427 int sval;
794ac9d0 1428
ab902481
RS
1429 sval = mips_signed_operand (operand, uval) * 4;
1430 if (sval >= -8 && sval < 8)
1431 sval ^= 0x400;
1432 infprintf (is, "%d", sval);
1433 break;
1434 }
794ac9d0 1435
ab902481
RS
1436 case OP_CLO_CLZ_DEST:
1437 {
1438 unsigned int reg1, reg2;
1439
1440 reg1 = uval & 31;
1441 reg2 = uval >> 5;
1442 /* If one is zero use the other. */
1443 if (reg1 == reg2 || reg2 == 0)
1444 infprintf (is, "%s", mips_gpr_names[reg1]);
1445 else if (reg1 == 0)
1446 infprintf (is, "%s", mips_gpr_names[reg2]);
1447 else
1448 /* Bogus, result depends on processor. */
1449 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1450 mips_gpr_names[reg2]);
1451 }
1452 break;
794ac9d0 1453
7361da2c
AB
1454 case OP_SAME_RS_RT:
1455 case OP_CHECK_PREV:
1456 case OP_NON_ZERO_REG:
1457 {
1458 print_reg (info, opcode, OP_REG_GP, uval & 31);
1459 mips_seen_register (state, uval, OP_REG_GP);
1460 }
1461 break;
1462
ab902481
RS
1463 case OP_LWM_SWM_LIST:
1464 if (operand->size == 2)
1465 {
1466 if (uval == 0)
1467 infprintf (is, "%s,%s",
1468 mips_gpr_names[16],
1469 mips_gpr_names[31]);
1470 else
1471 infprintf (is, "%s-%s,%s",
1472 mips_gpr_names[16],
1473 mips_gpr_names[16 + uval],
1474 mips_gpr_names[31]);
1475 }
1476 else
1477 {
1478 int s_reg_encode;
794ac9d0 1479
ab902481
RS
1480 s_reg_encode = uval & 0xf;
1481 if (s_reg_encode != 0)
1482 {
1483 if (s_reg_encode == 1)
1484 infprintf (is, "%s", mips_gpr_names[16]);
1485 else if (s_reg_encode < 9)
1486 infprintf (is, "%s-%s",
1487 mips_gpr_names[16],
1488 mips_gpr_names[15 + s_reg_encode]);
1489 else if (s_reg_encode == 9)
1490 infprintf (is, "%s-%s,%s",
1491 mips_gpr_names[16],
1492 mips_gpr_names[23],
1493 mips_gpr_names[30]);
1494 else
1495 infprintf (is, "UNKNOWN");
1496 }
794ac9d0 1497
ab902481
RS
1498 if (uval & 0x10) /* For ra. */
1499 {
1500 if (s_reg_encode == 0)
1501 infprintf (is, "%s", mips_gpr_names[31]);
1502 else
1503 infprintf (is, ",%s", mips_gpr_names[31]);
1504 }
1505 }
1506 break;
794ac9d0 1507
c3c07478
RS
1508 case OP_ENTRY_EXIT_LIST:
1509 {
1510 const char *sep;
1511 unsigned int amask, smask;
1512
1513 sep = "";
1514 amask = (uval >> 3) & 7;
1515 if (amask > 0 && amask < 5)
1516 {
1517 infprintf (is, "%s", mips_gpr_names[4]);
1518 if (amask > 1)
1519 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1520 sep = ",";
1521 }
1522
1523 smask = (uval >> 1) & 3;
1524 if (smask == 3)
1525 {
1526 infprintf (is, "%s??", sep);
1527 sep = ",";
1528 }
1529 else if (smask > 0)
1530 {
1531 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1532 if (smask > 1)
1533 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1534 sep = ",";
1535 }
1536
1537 if (uval & 1)
1538 {
1539 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1540 sep = ",";
1541 }
1542
1543 if (amask == 5 || amask == 6)
1544 {
1545 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1546 if (amask == 6)
1547 infprintf (is, "-%s", mips_fpr_names[1]);
1548 }
1549 }
1550 break;
1551
1552 case OP_SAVE_RESTORE_LIST:
38bf472a 1553 /* Should be handled by the caller due to complex behavior. */
c3c07478
RS
1554 abort ();
1555
ab902481
RS
1556 case OP_MDMX_IMM_REG:
1557 {
1558 unsigned int vsel;
794ac9d0 1559
ab902481
RS
1560 vsel = uval >> 5;
1561 uval &= 31;
1562 if ((vsel & 0x10) == 0)
794ac9d0 1563 {
ab902481
RS
1564 int fmt;
1565
1566 vsel &= 0x0f;
1567 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1568 if ((vsel & 1) == 0)
1569 break;
1570 print_reg (info, opcode, OP_REG_VEC, uval);
1571 infprintf (is, "[%d]", vsel >> 1);
794ac9d0 1572 }
ab902481
RS
1573 else if ((vsel & 0x08) == 0)
1574 print_reg (info, opcode, OP_REG_VEC, uval);
1575 else
1576 infprintf (is, "0x%x", uval);
1577 }
1578 break;
794ac9d0 1579
ab902481
RS
1580 case OP_REPEAT_PREV_REG:
1581 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1582 break;
794ac9d0 1583
ab902481 1584 case OP_REPEAT_DEST_REG:
7361da2c
AB
1585 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1586 break;
794ac9d0 1587
ab902481
RS
1588 case OP_PC:
1589 infprintf (is, "$pc");
1590 break;
14daeee3 1591
25499ac7
MR
1592 case OP_REG28:
1593 print_reg (info, opcode, OP_REG_GP, 28);
1594 break;
1595
14daeee3
RS
1596 case OP_VU0_SUFFIX:
1597 case OP_VU0_MATCH_SUFFIX:
1598 print_vu0_channel (info, operand, uval);
1599 break;
4edbb8e3
CF
1600
1601 case OP_IMM_INDEX:
1602 infprintf (is, "[%d]", uval);
1603 break;
1604
1605 case OP_REG_INDEX:
1606 infprintf (is, "[");
1607 print_reg (info, opcode, OP_REG_GP, uval);
1608 infprintf (is, "]");
1609 break;
ab902481
RS
1610 }
1611}
794ac9d0 1612
7361da2c
AB
1613/* Validate the arguments for INSN, which is described by OPCODE.
1614 Use DECODE_OPERAND to get the encoding of each operand. */
1615
1616static bfd_boolean
1617validate_insn_args (const struct mips_opcode *opcode,
1618 const struct mips_operand *(*decode_operand) (const char *),
1619 unsigned int insn)
1620{
1621 struct mips_print_arg_state state;
1622 const struct mips_operand *operand;
1623 const char *s;
1624 unsigned int uval;
1625
1626 init_print_arg_state (&state);
1627 for (s = opcode->args; *s; ++s)
1628 {
1629 switch (*s)
1630 {
1631 case ',':
1632 case '(':
1633 case ')':
1634 break;
1635
1636 case '#':
1637 ++s;
1638 break;
1639
1640 default:
1641 operand = decode_operand (s);
1642
1643 if (operand)
1644 {
1645 uval = mips_extract_operand (operand, insn);
1646 switch (operand->type)
1647 {
1648 case OP_REG:
1649 case OP_OPTIONAL_REG:
1650 {
1651 const struct mips_reg_operand *reg_op;
1652
1653 reg_op = (const struct mips_reg_operand *) operand;
1654 uval = mips_decode_reg_operand (reg_op, uval);
1655 mips_seen_register (&state, uval, reg_op->reg_type);
1656 }
1657 break;
1658
1659 case OP_SAME_RS_RT:
1660 {
1661 unsigned int reg1, reg2;
1662
1663 reg1 = uval & 31;
1664 reg2 = uval >> 5;
1665
1666 if (reg1 != reg2 || reg1 == 0)
1667 return FALSE;
1668 }
1669 break;
1670
1671 case OP_CHECK_PREV:
1672 {
1673 const struct mips_check_prev_operand *prev_op;
1674
1675 prev_op = (const struct mips_check_prev_operand *) operand;
1676
1677 if (!prev_op->zero_ok && uval == 0)
1678 return FALSE;
1679
1680 if (((prev_op->less_than_ok && uval < state.last_regno)
1681 || (prev_op->greater_than_ok && uval > state.last_regno)
1682 || (prev_op->equal_ok && uval == state.last_regno)))
1683 break;
1684
1685 return FALSE;
1686 }
1687
1688 case OP_NON_ZERO_REG:
1689 {
1690 if (uval == 0)
1691 return FALSE;
1692 }
1693 break;
1694
1695 case OP_INT:
1696 case OP_MAPPED_INT:
1697 case OP_MSB:
1698 case OP_REG_PAIR:
1699 case OP_PCREL:
1700 case OP_PERF_REG:
1701 case OP_ADDIUSP_INT:
1702 case OP_CLO_CLZ_DEST:
1703 case OP_LWM_SWM_LIST:
1704 case OP_ENTRY_EXIT_LIST:
1705 case OP_MDMX_IMM_REG:
1706 case OP_REPEAT_PREV_REG:
1707 case OP_REPEAT_DEST_REG:
1708 case OP_PC:
25499ac7 1709 case OP_REG28:
7361da2c
AB
1710 case OP_VU0_SUFFIX:
1711 case OP_VU0_MATCH_SUFFIX:
1712 case OP_IMM_INDEX:
1713 case OP_REG_INDEX:
7361da2c 1714 case OP_SAVE_RESTORE_LIST:
38bf472a 1715 break;
7361da2c
AB
1716 }
1717 }
1718 if (*s == 'm' || *s == '+' || *s == '-')
1719 ++s;
1720 }
1721 }
1722 return TRUE;
1723}
1724
ab902481
RS
1725/* Print the arguments for INSN, which is described by OPCODE.
1726 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
7361da2c
AB
1727 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1728 operand is for a branch or jump. */
af7ee8bf 1729
ab902481
RS
1730static void
1731print_insn_args (struct disassemble_info *info,
1732 const struct mips_opcode *opcode,
1733 const struct mips_operand *(*decode_operand) (const char *),
7361da2c 1734 unsigned int insn, bfd_vma insn_pc, unsigned int length)
ab902481
RS
1735{
1736 const fprintf_ftype infprintf = info->fprintf_func;
1737 void *is = info->stream;
1738 struct mips_print_arg_state state;
1739 const struct mips_operand *operand;
1740 const char *s;
794ac9d0 1741
ab902481
RS
1742 init_print_arg_state (&state);
1743 for (s = opcode->args; *s; ++s)
1744 {
1745 switch (*s)
1746 {
1747 case ',':
1748 case '(':
1749 case ')':
1750 infprintf (is, "%c", *s);
794ac9d0
CD
1751 break;
1752
14daeee3
RS
1753 case '#':
1754 ++s;
1755 infprintf (is, "%c%c", *s, *s);
1756 break;
1757
ab902481
RS
1758 default:
1759 operand = decode_operand (s);
1760 if (!operand)
fa7616a4 1761 {
ab902481
RS
1762 /* xgettext:c-format */
1763 infprintf (is,
1764 _("# internal error, undefined operand in `%s %s'"),
1765 opcode->name, opcode->args);
1766 return;
1767 }
38bf472a
MR
1768
1769 if (operand->type == OP_SAVE_RESTORE_LIST)
1770 {
1771 /* Handle this case here because of the complex behavior. */
1772 unsigned int amask = (insn >> 15) & 0xf;
1773 unsigned int nsreg = (insn >> 23) & 0x7;
1774 unsigned int ra = insn & 0x1000; /* $ra */
1775 unsigned int s0 = insn & 0x800; /* $s0 */
1776 unsigned int s1 = insn & 0x400; /* $s1 */
1777 unsigned int frame_size = (((insn >> 15) & 0xf0)
1778 | ((insn >> 6) & 0x0f)) * 8;
1779 mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1780 frame_size);
1781 }
1782 else if (operand->type == OP_REG
1783 && s[1] == ','
1784 && s[2] == 'H'
1785 && opcode->name[strlen (opcode->name) - 1] == '0')
ab902481 1786 {
fdfb4752 1787 /* Coprocessor register 0 with sel field. */
ab902481
RS
1788 const struct mips_cp0sel_name *n;
1789 unsigned int reg, sel;
1790
1791 reg = mips_extract_operand (operand, insn);
1792 s += 2;
1793 operand = decode_operand (s);
1794 sel = mips_extract_operand (operand, insn);
1795
1796 /* CP0 register including 'sel' code for mftc0, to be
1797 printed textually if known. If not known, print both
1798 CP0 register name and sel numerically since CP0 register
1799 with sel 0 may have a name unrelated to register being
1800 printed. */
1801 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1802 mips_cp0sel_names_len,
1803 reg, sel);
1804 if (n != NULL)
1805 infprintf (is, "%s", n->name);
fa7616a4 1806 else
ab902481 1807 infprintf (is, "$%d,%d", reg, sel);
fa7616a4 1808 }
794ac9d0 1809 else
7361da2c
AB
1810 {
1811 bfd_vma base_pc = insn_pc;
1812
1813 /* Adjust the PC relative base so that branch/jump insns use
1814 the following PC as the base but genuinely PC relative
1815 operands use the current PC. */
1816 if (operand->type == OP_PCREL)
1817 {
1818 const struct mips_pcrel_operand *pcrel_op;
1819
1820 pcrel_op = (const struct mips_pcrel_operand *) operand;
1821 /* The include_isa_bit flag is sufficient to distinguish
1822 branch/jump from other PC relative operands. */
1823 if (pcrel_op->include_isa_bit)
1824 base_pc += length;
1825 }
1826
1827 print_insn_arg (info, &state, opcode, operand, base_pc,
1828 mips_extract_operand (operand, insn));
1829 }
1830 if (*s == 'm' || *s == '+' || *s == '-')
ab902481 1831 ++s;
794ac9d0 1832 break;
af7ee8bf 1833 }
252b5132
RH
1834 }
1835}
1836\f
252b5132
RH
1837/* Print the mips instruction at address MEMADDR in debugged memory,
1838 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1839 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1840 this is little-endian code. */
1841
1842static int
47b0e7ad 1843print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1844 int word,
47b0e7ad 1845 struct disassemble_info *info)
252b5132 1846{
ab902481
RS
1847#define GET_OP(insn, field) \
1848 (((insn) >> OP_SH_##field) & OP_MASK_##field)
fc8c4fd1
MR
1849 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1850 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1851 const struct mips_opcode *op;
b34976b6 1852 static bfd_boolean init = 0;
fc8c4fd1 1853 void *is = info->stream;
252b5132
RH
1854
1855 /* Build a hash table to shorten the search time. */
1856 if (! init)
1857 {
1858 unsigned int i;
1859
1860 for (i = 0; i <= OP_MASK_OP; i++)
1861 {
1862 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1863 {
986e18a5 1864 if (op->pinfo == INSN_MACRO
9e836e3d 1865 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1866 continue;
fc8c4fd1 1867 if (i == GET_OP (op->match, OP))
252b5132
RH
1868 {
1869 mips_hash[i] = op;
1870 break;
1871 }
1872 }
7f6621cd 1873 }
252b5132
RH
1874
1875 init = 1;
1876 }
1877
aa5f19f2 1878 info->bytes_per_chunk = INSNLEN;
252b5132 1879 info->display_endian = info->endian;
9bb28706
CD
1880 info->insn_info_valid = 1;
1881 info->branch_delay_insns = 0;
def7143b 1882 info->data_size = 0;
9bb28706
CD
1883 info->insn_type = dis_nonbranch;
1884 info->target = 0;
1885 info->target2 = 0;
252b5132 1886
fc8c4fd1 1887 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1888 if (op != NULL)
1889 {
1890 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1891 {
43e65147 1892 if (op->pinfo != INSN_MACRO
9e836e3d 1893 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1894 && (word & op->mask) == op->match)
252b5132 1895 {
7361da2c 1896 /* We always disassemble the jalx instruction, except for MIPS r6. */
d301a56b 1897 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
7361da2c
AB
1898 && (strcmp (op->name, "jalx")
1899 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1900 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
252b5132
RH
1901 continue;
1902
9bb28706
CD
1903 /* Figure out instruction type and branch delay information. */
1904 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1905 {
fc76e730 1906 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
9bb28706
CD
1907 info->insn_type = dis_jsr;
1908 else
1909 info->insn_type = dis_branch;
1910 info->branch_delay_insns = 1;
1911 }
1912 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1913 | INSN_COND_BRANCH_LIKELY)) != 0)
1914 {
c680e7f6 1915 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1916 info->insn_type = dis_condjsr;
1917 else
1918 info->insn_type = dis_condbranch;
1919 info->branch_delay_insns = 1;
1920 }
1921 else if ((op->pinfo & (INSN_STORE_MEMORY
67dc82bc 1922 | INSN_LOAD_MEMORY)) != 0)
9bb28706
CD
1923 info->insn_type = dis_dref;
1924
7361da2c
AB
1925 if (!validate_insn_args (op, decode_mips_operand, word))
1926 continue;
1927
fc8c4fd1 1928 infprintf (is, "%s", op->name);
14daeee3
RS
1929 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1930 {
1931 unsigned int uval;
1932
1933 infprintf (is, ".");
1934 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1935 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1936 }
252b5132 1937
ab902481 1938 if (op->args[0])
252b5132 1939 {
fc8c4fd1 1940 infprintf (is, "\t");
ab902481 1941 print_insn_args (info, op, decode_mips_operand, word,
7361da2c 1942 memaddr, 4);
252b5132
RH
1943 }
1944
aa5f19f2 1945 return INSNLEN;
252b5132
RH
1946 }
1947 }
1948 }
fc8c4fd1 1949#undef GET_OP
252b5132
RH
1950
1951 /* Handle undefined instructions. */
9bb28706 1952 info->insn_type = dis_noninsn;
fc8c4fd1 1953 infprintf (is, "0x%x", word);
aa5f19f2 1954 return INSNLEN;
252b5132 1955}
aa5f19f2 1956\f
252b5132
RH
1957/* Disassemble an operand for a mips16 instruction. */
1958
1959static void
c3c07478
RS
1960print_mips16_insn_arg (struct disassemble_info *info,
1961 struct mips_print_arg_state *state,
1962 const struct mips_opcode *opcode,
1963 char type, bfd_vma memaddr,
1964 unsigned insn, bfd_boolean use_extend,
1965 unsigned extend, bfd_boolean is_offset)
252b5132 1966{
fc8c4fd1
MR
1967 const fprintf_ftype infprintf = info->fprintf_func;
1968 void *is = info->stream;
c3c07478 1969 const struct mips_operand *operand, *ext_operand;
bdd15286 1970 unsigned short ext_size;
c3c07478
RS
1971 unsigned int uval;
1972 bfd_vma baseaddr;
1973
1974 if (!use_extend)
1975 extend = 0;
fc8c4fd1 1976
252b5132
RH
1977 switch (type)
1978 {
1979 case ',':
1980 case '(':
1981 case ')':
fc8c4fd1 1982 infprintf (is, "%c", type);
252b5132
RH
1983 break;
1984
c3c07478
RS
1985 default:
1986 operand = decode_mips16_operand (type, FALSE);
1987 if (!operand)
1988 {
1989 /* xgettext:c-format */
1990 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1991 opcode->name, opcode->args);
1992 return;
1993 }
252b5132 1994
c3c07478
RS
1995 if (operand->type == OP_SAVE_RESTORE_LIST)
1996 {
5f5c6e03 1997 /* Handle this case here because of the complex interaction
c3c07478 1998 with the EXTEND opcode. */
38bf472a
MR
1999 unsigned int amask = extend & 0xf;
2000 unsigned int nsreg = (extend >> 8) & 0x7;
2001 unsigned int ra = insn & 0x40; /* $ra */
2002 unsigned int s0 = insn & 0x20; /* $s0 */
2003 unsigned int s1 = insn & 0x10; /* $s1 */
2004 unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
c3c07478
RS
2005 if (frame_size == 0 && !use_extend)
2006 frame_size = 128;
38bf472a 2007 mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
c3c07478
RS
2008 break;
2009 }
252b5132 2010
c3c07478
RS
2011 if (is_offset && operand->type == OP_INT)
2012 {
2013 const struct mips_int_operand *int_op;
252b5132 2014
c3c07478
RS
2015 int_op = (const struct mips_int_operand *) operand;
2016 info->insn_type = dis_dref;
2017 info->data_size = 1 << int_op->shift;
2018 }
252b5132 2019
bdd15286
MR
2020 ext_size = 0;
2021 if (use_extend)
c3c07478 2022 {
bdd15286 2023 ext_operand = decode_mips16_operand (type, TRUE);
25499ac7
MR
2024 if (ext_operand != operand
2025 || (operand->type == OP_INT && operand->lsb == 0
2026 && mips_opcode_32bit_p (opcode)))
c3c07478 2027 {
bdd15286
MR
2028 ext_size = ext_operand->size;
2029 operand = ext_operand;
c3c07478
RS
2030 }
2031 }
bdd15286
MR
2032 if (operand->size == 26)
2033 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
25499ac7 2034 else if (ext_size == 16 || ext_size == 9)
bdd15286
MR
2035 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2036 else if (ext_size == 15)
2037 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2038 else if (ext_size == 6)
2039 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2040 else
2041 uval = mips_extract_operand (operand, (extend << 16) | insn);
25499ac7
MR
2042 if (ext_size == 9)
2043 uval &= (1U << ext_size) - 1;
c3c07478
RS
2044
2045 baseaddr = memaddr + 2;
2046 if (operand->type == OP_PCREL)
2047 {
2048 const struct mips_pcrel_operand *pcrel_op;
2049
2050 pcrel_op = (const struct mips_pcrel_operand *) operand;
2051 if (!pcrel_op->include_isa_bit && use_extend)
2052 baseaddr = memaddr - 2;
2053 else if (!pcrel_op->include_isa_bit)
39f66f3a
MR
2054 {
2055 bfd_byte buffer[2];
2056
2057 /* If this instruction is in the delay slot of a JAL/JALX
2058 instruction, the base address is the address of the
2059 JAL/JALX instruction. If it is in the delay slot of
2060 a JR/JALR instruction, the base address is the address
2061 of the JR/JALR instruction. This test is unreliable:
2062 we have no way of knowing whether the previous word is
2063 instruction or data. */
2064 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2065 && (((info->endian == BFD_ENDIAN_BIG
2066 ? bfd_getb16 (buffer)
2067 : bfd_getl16 (buffer))
2068 & 0xf800) == 0x1800))
2069 baseaddr = memaddr - 4;
2070 else if (info->read_memory_func (memaddr - 2, buffer, 2,
2071 info) == 0
2072 && (((info->endian == BFD_ENDIAN_BIG
2073 ? bfd_getb16 (buffer)
2074 : bfd_getl16 (buffer))
2075 & 0xf89f) == 0xe800)
2076 && (((info->endian == BFD_ENDIAN_BIG
2077 ? bfd_getb16 (buffer)
2078 : bfd_getl16 (buffer))
2079 & 0x0060) != 0x0060))
2080 baseaddr = memaddr - 2;
2081 else
2082 baseaddr = memaddr;
2083 }
c3c07478 2084 }
0499d65b 2085
6d075bce 2086 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
0499d65b 2087 break;
252b5132
RH
2088 }
2089}
640c0ccd 2090
1bbce132
MR
2091
2092/* Check if the given address is the last word of a MIPS16 PLT entry.
2093 This word is data and depending on the value it may interfere with
2094 disassembly of further PLT entries. We make use of the fact PLT
2095 symbols are marked BSF_SYNTHETIC. */
2096static bfd_boolean
2097is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2098{
2099 if (info->symbols
2100 && info->symbols[0]
2101 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2102 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2103 return TRUE;
2104
2105 return FALSE;
2106}
2107
7fd53920
MR
2108/* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2109
2110enum match_kind
2111{
2112 MATCH_NONE,
2113 MATCH_FULL,
2114 MATCH_SHORT
2115};
2116
47b0e7ad
NC
2117/* Disassemble mips16 instructions. */
2118
2119static int
2120print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2121{
fc8c4fd1 2122 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 2123 int status;
1bbce132 2124 bfd_byte buffer[4];
47b0e7ad 2125 const struct mips_opcode *op, *opend;
c3c07478 2126 struct mips_print_arg_state state;
fc8c4fd1 2127 void *is = info->stream;
7fd53920 2128 bfd_boolean have_second;
25499ac7 2129 bfd_boolean extend_only;
7fd53920
MR
2130 unsigned int second;
2131 unsigned int first;
2132 unsigned int full;
47b0e7ad
NC
2133
2134 info->bytes_per_chunk = 2;
2135 info->display_endian = info->endian;
2136 info->insn_info_valid = 1;
2137 info->branch_delay_insns = 0;
2138 info->data_size = 0;
47b0e7ad
NC
2139 info->target = 0;
2140 info->target2 = 0;
2141
c3c07478
RS
2142#define GET_OP(insn, field) \
2143 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1bbce132
MR
2144 /* Decode PLT entry's GOT slot address word. */
2145 if (is_mips16_plt_tail (info, memaddr))
2146 {
2147 info->insn_type = dis_noninsn;
2148 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2149 if (status == 0)
2150 {
2151 unsigned int gotslot;
2152
2153 if (info->endian == BFD_ENDIAN_BIG)
2154 gotslot = bfd_getb32 (buffer);
2155 else
2156 gotslot = bfd_getl32 (buffer);
2157 infprintf (is, ".word\t0x%x", gotslot);
2158
2159 return 4;
2160 }
2161 }
2162 else
2163 {
2164 info->insn_type = dis_nonbranch;
2165 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2166 }
47b0e7ad
NC
2167 if (status != 0)
2168 {
2169 (*info->memory_error_func) (status, memaddr, info);
2170 return -1;
2171 }
2172
25499ac7
MR
2173 extend_only = FALSE;
2174
47b0e7ad 2175 if (info->endian == BFD_ENDIAN_BIG)
7fd53920 2176 first = bfd_getb16 (buffer);
47b0e7ad 2177 else
7fd53920 2178 first = bfd_getl16 (buffer);
47b0e7ad 2179
7fd53920
MR
2180 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2181 if (status == 0)
47b0e7ad 2182 {
7fd53920 2183 have_second = TRUE;
47b0e7ad 2184 if (info->endian == BFD_ENDIAN_BIG)
7fd53920 2185 second = bfd_getb16 (buffer);
47b0e7ad 2186 else
7fd53920
MR
2187 second = bfd_getl16 (buffer);
2188 full = (first << 16) | second;
2189 }
2190 else
2191 {
2192 have_second = FALSE;
2193 second = 0;
2194 full = first;
47b0e7ad
NC
2195 }
2196
2197 /* FIXME: Should probably use a hash table on the major opcode here. */
2198
2199 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2200 for (op = mips16_opcodes; op < opend; op++)
2201 {
7fd53920 2202 enum match_kind match;
47b0e7ad 2203
11dd08e9
MR
2204 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2205 continue;
2206
7fd53920
MR
2207 if (op->pinfo == INSN_MACRO
2208 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2209 match = MATCH_NONE;
2210 else if (mips_opcode_32bit_p (op))
2211 {
2212 if (have_second
2213 && (full & op->mask) == op->match)
2214 match = MATCH_FULL;
2215 else
2216 match = MATCH_NONE;
2217 }
2218 else if ((first & op->mask) == op->match)
2219 {
2220 match = MATCH_SHORT;
2221 second = 0;
2222 full = first;
2223 }
2224 else if ((first & 0xf800) == 0xf000
2225 && have_second
25499ac7 2226 && !extend_only
7fd53920 2227 && (second & op->mask) == op->match)
25499ac7
MR
2228 {
2229 if (op->pinfo2 & INSN2_SHORT_ONLY)
2230 {
2231 match = MATCH_NONE;
2232 extend_only = TRUE;
2233 }
2234 else
2235 match = MATCH_FULL;
2236 }
7fd53920
MR
2237 else
2238 match = MATCH_NONE;
47b0e7ad 2239
7fd53920
MR
2240 if (match != MATCH_NONE)
2241 {
2242 const char *s;
47b0e7ad 2243
fc8c4fd1 2244 infprintf (is, "%s", op->name);
47b0e7ad 2245 if (op->args[0] != '\0')
fc8c4fd1 2246 infprintf (is, "\t");
47b0e7ad 2247
c3c07478 2248 init_print_arg_state (&state);
47b0e7ad
NC
2249 for (s = op->args; *s != '\0'; s++)
2250 {
2251 if (*s == ','
2252 && s[1] == 'w'
7fd53920 2253 && GET_OP (full, RX) == GET_OP (full, RY))
47b0e7ad
NC
2254 {
2255 /* Skip the register and the comma. */
2256 ++s;
2257 continue;
2258 }
2259 if (*s == ','
2260 && s[1] == 'v'
7fd53920 2261 && GET_OP (full, RZ) == GET_OP (full, RX))
47b0e7ad
NC
2262 {
2263 /* Skip the register and the comma. */
2264 ++s;
2265 continue;
2266 }
25499ac7
MR
2267 if (s[0] == 'N'
2268 && s[1] == ','
2269 && s[2] == 'O'
2270 && op->name[strlen (op->name) - 1] == '0')
7fd53920 2271 {
25499ac7
MR
2272 /* Coprocessor register 0 with sel field. */
2273 const struct mips_cp0sel_name *n;
2274 const struct mips_operand *operand;
2275 unsigned int reg, sel;
2276
2277 operand = decode_mips16_operand (*s, TRUE);
2278 reg = mips_extract_operand (operand, (first << 16) | second);
2279 s += 2;
2280 operand = decode_mips16_operand (*s, TRUE);
2281 sel = mips_extract_operand (operand, (first << 16) | second);
2282
2283 /* CP0 register including 'sel' code for mftc0, to be
2284 printed textually if known. If not known, print both
2285 CP0 register name and sel numerically since CP0 register
2286 with sel 0 may have a name unrelated to register being
2287 printed. */
2288 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2289 mips_cp0sel_names_len,
2290 reg, sel);
2291 if (n != NULL)
2292 infprintf (is, "%s", n->name);
2293 else
2294 infprintf (is, "$%d,%d", reg, sel);
7fd53920 2295 }
25499ac7
MR
2296 else
2297 switch (match)
2298 {
2299 case MATCH_FULL:
2300 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2301 second, TRUE, first, s[1] == '(');
2302 break;
2303 case MATCH_SHORT:
2304 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2305 first, FALSE, 0, s[1] == '(');
2306 break;
2307 case MATCH_NONE: /* Stop the compiler complaining. */
2308 break;
2309 }
47b0e7ad
NC
2310 }
2311
9a2c7088 2312 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 2313 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088 2314 info->branch_delay_insns = 1;
26545944
RS
2315 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2316 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
47b0e7ad 2317 {
9a2c7088
MR
2318 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2319 info->insn_type = dis_jsr;
2320 else
47b0e7ad
NC
2321 info->insn_type = dis_branch;
2322 }
26545944 2323 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
9a2c7088 2324 info->insn_type = dis_condbranch;
47b0e7ad 2325
7fd53920 2326 return match == MATCH_FULL ? 4 : 2;
47b0e7ad
NC
2327 }
2328 }
fc8c4fd1 2329#undef GET_OP
47b0e7ad 2330
7fd53920 2331 infprintf (is, "0x%x", first);
47b0e7ad
NC
2332 info->insn_type = dis_noninsn;
2333
7fd53920 2334 return 2;
47b0e7ad
NC
2335}
2336
df58fc94
RS
2337/* Disassemble microMIPS instructions. */
2338
2339static int
2340print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2341{
0c7533d3 2342 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94 2343 const struct mips_opcode *op, *opend;
df58fc94 2344 void *is = info->stream;
df58fc94 2345 bfd_byte buffer[2];
ab902481
RS
2346 unsigned int higher;
2347 unsigned int length;
df58fc94 2348 int status;
ab902481 2349 unsigned int insn;
df58fc94
RS
2350
2351 info->bytes_per_chunk = 2;
2352 info->display_endian = info->endian;
2353 info->insn_info_valid = 1;
2354 info->branch_delay_insns = 0;
2355 info->data_size = 0;
2356 info->insn_type = dis_nonbranch;
2357 info->target = 0;
2358 info->target2 = 0;
2359
2360 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2361 if (status != 0)
2362 {
2363 (*info->memory_error_func) (status, memaddr, info);
2364 return -1;
2365 }
2366
2367 length = 2;
2368
2369 if (info->endian == BFD_ENDIAN_BIG)
2370 insn = bfd_getb16 (buffer);
2371 else
2372 insn = bfd_getl16 (buffer);
2373
100b4f2e 2374 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
df58fc94
RS
2375 {
2376 /* This is a 32-bit microMIPS instruction. */
2377 higher = insn;
2378
2379 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2380 if (status != 0)
2381 {
0c7533d3 2382 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2383 (*info->memory_error_func) (status, memaddr + 2, info);
2384 return -1;
2385 }
2386
2387 if (info->endian == BFD_ENDIAN_BIG)
2388 insn = bfd_getb16 (buffer);
2389 else
2390 insn = bfd_getl16 (buffer);
2391
2392 insn = insn | (higher << 16);
2393
2394 length += 2;
2395 }
2396
2397 /* FIXME: Should probably use a hash table on the major opcode here. */
2398
df58fc94
RS
2399 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2400 for (op = micromips_opcodes; op < opend; op++)
2401 {
2402 if (op->pinfo != INSN_MACRO
2403 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2404 && (insn & op->mask) == op->match
2405 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2406 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2407 {
7361da2c
AB
2408 if (!validate_insn_args (op, decode_micromips_operand, insn))
2409 continue;
2410
0c7533d3 2411 infprintf (is, "%s", op->name);
df58fc94 2412
ab902481 2413 if (op->args[0])
df58fc94 2414 {
ab902481
RS
2415 infprintf (is, "\t");
2416 print_insn_args (info, op, decode_micromips_operand, insn,
7361da2c 2417 memaddr + 1, length);
df58fc94
RS
2418 }
2419
2420 /* Figure out instruction type and branch delay information. */
2421 if ((op->pinfo
2422 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2423 info->branch_delay_insns = 1;
2424 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2425 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2426 {
fc76e730 2427 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
df58fc94
RS
2428 info->insn_type = dis_jsr;
2429 else
2430 info->insn_type = dis_branch;
2431 }
2432 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2433 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2434 {
2435 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2436 info->insn_type = dis_condjsr;
2437 else
2438 info->insn_type = dis_condbranch;
2439 }
2440 else if ((op->pinfo
67dc82bc 2441 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
df58fc94
RS
2442 info->insn_type = dis_dref;
2443
2444 return length;
2445 }
2446 }
df58fc94 2447
0c7533d3 2448 infprintf (is, "0x%x", insn);
df58fc94
RS
2449 info->insn_type = dis_noninsn;
2450
2451 return length;
2452}
2453
2454/* Return 1 if a symbol associated with the location being disassembled
1401d2fe
MR
2455 indicates a compressed mode, either MIPS16 or microMIPS, according to
2456 MICROMIPS_P. We iterate over all the symbols at the address being
2457 considered assuming if at least one of them indicates code compression,
2458 then such code has been genuinely produced here (other symbols could
2459 have been derived from function symbols defined elsewhere or could
2460 define data). Otherwise, return 0. */
df58fc94
RS
2461
2462static bfd_boolean
1401d2fe 2463is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
df58fc94 2464{
df58fc94 2465 int i;
1bbce132
MR
2466 int l;
2467
2468 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2469 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
1401d2fe 2470 && ((!micromips_p
1bbce132 2471 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
1401d2fe 2472 || (micromips_p
1bbce132
MR
2473 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2474 return 1;
2475 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2476 && info->symtab[i]->section == info->section)
2477 {
2478 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
1401d2fe 2479 if ((!micromips_p
1bbce132 2480 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
1401d2fe 2481 || (micromips_p
1bbce132
MR
2482 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2483 return 1;
2484 }
df58fc94
RS
2485
2486 return 0;
2487}
2488
47b0e7ad
NC
2489/* In an environment where we do not know the symbol type of the
2490 instruction we are forced to assume that the low order bit of the
2491 instructions' address may mark it as a mips16 instruction. If we
2492 are single stepping, or the pc is within the disassembled function,
2493 this works. Otherwise, we need a clue. Sometimes. */
2494
2495static int
2496_print_insn_mips (bfd_vma memaddr,
2497 struct disassemble_info *info,
2498 enum bfd_endian endianness)
2499{
2500 bfd_byte buffer[INSNLEN];
2501 int status;
2502
2503 set_default_mips_dis_options (info);
2504 parse_mips_dis_options (info->disassembler_options);
2505
df58fc94
RS
2506 if (info->mach == bfd_mach_mips16)
2507 return print_insn_mips16 (memaddr, info);
2508 if (info->mach == bfd_mach_mips_micromips)
2509 return print_insn_micromips (memaddr, info);
2510
47b0e7ad 2511#if 1
df58fc94 2512 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
2513 /* Only a few tools will work this way. */
2514 if (memaddr & 0x01)
1401d2fe
MR
2515 {
2516 if (micromips_ase)
2517 return print_insn_micromips (memaddr, info);
2518 else
2519 return print_insn_mips16 (memaddr, info);
2520 }
47b0e7ad
NC
2521#endif
2522
2523#if SYMTAB_AVAILABLE
1401d2fe
MR
2524 if (is_compressed_mode_p (info, TRUE))
2525 return print_insn_micromips (memaddr, info);
2526 if (is_compressed_mode_p (info, FALSE))
2527 return print_insn_mips16 (memaddr, info);
47b0e7ad
NC
2528#endif
2529
2530 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2531 if (status == 0)
2532 {
fc8c4fd1 2533 int insn;
47b0e7ad
NC
2534
2535 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 2536 insn = bfd_getb32 (buffer);
47b0e7ad 2537 else
fc8c4fd1 2538 insn = bfd_getl32 (buffer);
47b0e7ad
NC
2539
2540 return print_insn_mips (memaddr, insn, info);
2541 }
2542 else
2543 {
2544 (*info->memory_error_func) (status, memaddr, info);
2545 return -1;
2546 }
2547}
2548
2549int
2550print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2551{
2552 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2553}
2554
2555int
2556print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2557{
2558 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2559}
2560\f
471b9d15
MR
2561/* Indices into option argument vector for options accepting an argument.
2562 Use MIPS_OPTION_ARG_NONE for options accepting no argument. */
2563typedef enum
640c0ccd 2564{
471b9d15
MR
2565 MIPS_OPTION_ARG_NONE = -1,
2566 MIPS_OPTION_ARG_ABI,
2567 MIPS_OPTION_ARG_ARCH,
2568 MIPS_OPTION_ARG_SIZE
2569} mips_option_arg_t;
2570
2571/* Valid MIPS disassembler options. */
2572static struct
2573{
2574 const char *name;
2575 const char *description;
2576 mips_option_arg_t arg;
2577} mips_options[] =
2578{
2579 { "no-aliases", N_("Use canonical instruction forms.\n"),
2580 MIPS_OPTION_ARG_NONE },
2581 { "msa", N_("Recognize MSA instructions.\n"),
2582 MIPS_OPTION_ARG_NONE },
2583 { "virt", N_("Recognize the virtualization ASE instructions.\n"),
2584 MIPS_OPTION_ARG_NONE },
2585 { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\
2586 instructions.\n"),
2587 MIPS_OPTION_ARG_NONE },
2588 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2589 "instructions.\n"),
2590 MIPS_OPTION_ARG_NONE },
8095d2f7
CX
2591 { "loongson-mmi",
2592 N_("Recognize the Loongson MultiMedia extensions "
2593 "Instructions (MMI) ASE instructions.\n"),
2594 MIPS_OPTION_ARG_NONE },
471b9d15
MR
2595 { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
2596 Default: based on binary being disassembled.\n"),
2597 MIPS_OPTION_ARG_ABI },
2598 { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
2599 Default: numeric.\n"),
2600 MIPS_OPTION_ARG_ABI },
2601 { "cp0-names=", N_("Print CP0 register names according to specified "
2602 "architecture.\n\
2603 Default: based on binary being disassembled.\n"),
2604 MIPS_OPTION_ARG_ARCH },
2605 { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
2606 Default: based on binary being disassembled.\n"),
2607 MIPS_OPTION_ARG_ARCH },
2608 { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
2609 MIPS_OPTION_ARG_ABI },
2610 { "reg-names=", N_("Print CP0 register and HWR names according to "
2611 "specified\n\
2612 architecture."),
2613 MIPS_OPTION_ARG_ARCH }
2614};
0348fd79 2615
471b9d15
MR
2616/* Build the structure representing valid MIPS disassembler options.
2617 This is done dynamically for maintenance ease purpose; a static
2618 initializer would be unreadable. */
4edbb8e3 2619
471b9d15
MR
2620const disasm_options_and_args_t *
2621disassembler_options_mips (void)
2622{
2623 static disasm_options_and_args_t *opts_and_args;
b015e599 2624
471b9d15
MR
2625 if (opts_and_args == NULL)
2626 {
2627 size_t num_options = ARRAY_SIZE (mips_options);
2628 size_t num_args = MIPS_OPTION_ARG_SIZE;
2629 disasm_option_arg_t *args;
2630 disasm_options_t *opts;
2631 size_t i;
2632 size_t j;
2633
2634 args = XNEWVEC (disasm_option_arg_t, num_args + 1);
2635
2636 args[MIPS_OPTION_ARG_ABI].name = "ABI";
2637 args[MIPS_OPTION_ARG_ABI].values
2638 = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1);
2639 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2640 args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name;
2641 /* The array we return must be NULL terminated. */
2642 args[MIPS_OPTION_ARG_ABI].values[i] = NULL;
2643
2644 args[MIPS_OPTION_ARG_ARCH].name = "ARCH";
2645 args[MIPS_OPTION_ARG_ARCH].values
2646 = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1);
2647 for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2648 if (*mips_arch_choices[i].name != '\0')
2649 args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name;
2650 /* The array we return must be NULL terminated. */
2651 args[MIPS_OPTION_ARG_ARCH].values[j] = NULL;
2652
2653 /* The array we return must be NULL terminated. */
2654 args[MIPS_OPTION_ARG_SIZE].name = NULL;
2655 args[MIPS_OPTION_ARG_SIZE].values = NULL;
2656
2657 opts_and_args = XNEW (disasm_options_and_args_t);
2658 opts_and_args->args = args;
2659
2660 opts = &opts_and_args->options;
2661 opts->name = XNEWVEC (const char *, num_options + 1);
2662 opts->description = XNEWVEC (const char *, num_options + 1);
2663 opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
2664 for (i = 0; i < num_options; i++)
2665 {
2666 opts->name[i] = mips_options[i].name;
2667 opts->description[i] = _(mips_options[i].description);
2668 if (mips_options[i].arg != MIPS_OPTION_ARG_NONE)
2669 opts->arg[i] = &args[mips_options[i].arg];
2670 else
2671 opts->arg[i] = NULL;
2672 }
2673 /* The array we return must be NULL terminated. */
2674 opts->name[i] = NULL;
2675 opts->description[i] = NULL;
2676 opts->arg[i] = NULL;
2677 }
7d64c587 2678
471b9d15
MR
2679 return opts_and_args;
2680}
6f20c942 2681
471b9d15
MR
2682void
2683print_mips_disassembler_options (FILE *stream)
2684{
2685 const disasm_options_and_args_t *opts_and_args;
2686 const disasm_option_arg_t *args;
2687 const disasm_options_t *opts;
2688 size_t max_len = 0;
2689 size_t i;
2690 size_t j;
640c0ccd 2691
471b9d15
MR
2692 opts_and_args = disassembler_options_mips ();
2693 opts = &opts_and_args->options;
2694 args = opts_and_args->args;
640c0ccd
CD
2695
2696 fprintf (stream, _("\n\
471b9d15
MR
2697The following MIPS specific disassembler options are supported for use\n\
2698with the -M switch (multiple options should be separated by commas):\n\n"));
640c0ccd 2699
471b9d15
MR
2700 /* Compute the length of the longest option name. */
2701 for (i = 0; opts->name[i] != NULL; i++)
2702 {
2703 size_t len = strlen (opts->name[i]);
af7ee8bf 2704
471b9d15
MR
2705 if (opts->arg[i] != NULL)
2706 len += strlen (opts->arg[i]->name);
2707 if (max_len < len)
2708 max_len = len;
2709 }
640c0ccd 2710
471b9d15
MR
2711 for (i = 0, max_len++; opts->name[i] != NULL; i++)
2712 {
2713 fprintf (stream, " %s", opts->name[i]);
2714 if (opts->arg[i] != NULL)
2715 fprintf (stream, "%s", opts->arg[i]->name);
2716 if (opts->description[i] != NULL)
2717 {
2718 size_t len = strlen (opts->name[i]);
640c0ccd 2719
471b9d15
MR
2720 if (opts->arg[i] != NULL)
2721 len += strlen (opts->arg[i]->name);
2722 fprintf (stream,
2723 "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
2724 }
2725 fprintf (stream, _("\n"));
2726 }
640c0ccd 2727
471b9d15
MR
2728 for (i = 0; args[i].name != NULL; i++)
2729 {
2730 fprintf (stream, _("\n\
2731 For the options above, the following values are supported for \"%s\":\n "),
2732 args[i].name);
2733 for (j = 0; args[i].values[j] != NULL; j++)
2734 fprintf (stream, " %s", args[i].values[j]);
2735 fprintf (stream, _("\n"));
2736 }
640c0ccd
CD
2737
2738 fprintf (stream, _("\n"));
2739}
This page took 1.602499 seconds and 4 git commands to generate.