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