MIPS16/GAS: Clean up invalid unextended operand handling
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
CommitLineData
252b5132 1/* Print mips instructions for GDB, the GNU debugger, or for objdump.
6f2750fe 2 Copyright (C) 1989-2016 Free Software Foundation, Inc.
252b5132
RH
3 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
4
9b201bb5 5 This file is part of the GNU opcodes library.
252b5132 6
9b201bb5 7 This library is free software; you can redistribute it and/or modify
47b0e7ad 8 it under the terms of the GNU General Public License as published by
9b201bb5
NC
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
252b5132 11
9b201bb5
NC
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
252b5132 16
47b0e7ad
NC
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
252b5132 21
252b5132
RH
22#include "sysdep.h"
23#include "dis-asm.h"
640c0ccd 24#include "libiberty.h"
252b5132
RH
25#include "opcode/mips.h"
26#include "opintl.h"
27
28/* FIXME: These are needed to figure out if the code is mips16 or
29 not. The low bit of the address is often a good indicator. No
30 symbol table is available when this code runs out in an embedded
7f6621cd 31 system as when it is used for disassembler support in a monitor. */
252b5132
RH
32
33#if !defined(EMBEDDED_ENV)
34#define SYMTAB_AVAILABLE 1
35#include "elf-bfd.h"
36#include "elf/mips.h"
37#endif
38
aa5f19f2
NC
39/* Mips instructions are at maximum this many bytes long. */
40#define INSNLEN 4
41
252b5132 42\f
aa5f19f2 43/* FIXME: These should be shared with gdb somehow. */
252b5132 44
47b0e7ad
NC
45struct mips_cp0sel_name
46{
47 unsigned int cp0reg;
48 unsigned int sel;
49 const char * const name;
bbcc0807
CD
50};
51
47b0e7ad
NC
52static const char * const mips_gpr_names_numeric[32] =
53{
640c0ccd
CD
54 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
55 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
56 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
57 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
aa5f19f2
NC
58};
59
47b0e7ad
NC
60static const char * const mips_gpr_names_oldabi[32] =
61{
640c0ccd
CD
62 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
63 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
64 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
65 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
aa5f19f2
NC
66};
67
47b0e7ad
NC
68static const char * const mips_gpr_names_newabi[32] =
69{
640c0ccd 70 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
0b14f26e 71 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
640c0ccd
CD
72 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
73 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
74};
75
47b0e7ad
NC
76static const char * const mips_fpr_names_numeric[32] =
77{
640c0ccd
CD
78 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
79 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
80 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
81 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
82};
83
47b0e7ad
NC
84static const char * const mips_fpr_names_32[32] =
85{
640c0ccd
CD
86 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
87 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
88 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
89 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
90};
91
47b0e7ad
NC
92static const char * const mips_fpr_names_n32[32] =
93{
640c0ccd
CD
94 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
95 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
96 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
97 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
98};
99
47b0e7ad
NC
100static const char * const mips_fpr_names_64[32] =
101{
640c0ccd
CD
102 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
103 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
104 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
105 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
106};
107
47b0e7ad
NC
108static const char * const mips_cp0_names_numeric[32] =
109{
640c0ccd
CD
110 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
111 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
112 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
113 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
114};
115
dc76d757
AB
116static const char * const mips_cp1_names_numeric[32] =
117{
118 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
119 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
120 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
121 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
122};
123
f409fd1e
MR
124static const char * const mips_cp0_names_r3000[32] =
125{
126 "c0_index", "c0_random", "c0_entrylo", "$3",
127 "c0_context", "$5", "$6", "$7",
128 "c0_badvaddr", "$9", "c0_entryhi", "$11",
129 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
130 "$16", "$17", "$18", "$19",
131 "$20", "$21", "$22", "$23",
132 "$24", "$25", "$26", "$27",
133 "$28", "$29", "$30", "$31",
134};
135
136static const char * const mips_cp0_names_r4000[32] =
137{
138 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
139 "c0_context", "c0_pagemask", "c0_wired", "$7",
140 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
141 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
142 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
143 "c0_xcontext", "$21", "$22", "$23",
144 "$24", "$25", "c0_ecc", "c0_cacheerr",
145 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
146};
147
e407c74b
NC
148static const char * const mips_cp0_names_r5900[32] =
149{
150 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
151 "c0_context", "c0_pagemask", "c0_wired", "$7",
152 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
153 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
154 "c0_config", "$17", "$18", "$19",
155 "$20", "$21", "$22", "c0_badpaddr",
156 "c0_depc", "c0_perfcnt", "$26", "$27",
157 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
158};
159
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
8f4f9071 566 | ASE_DSPR2 | ASE_DSPR3),
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
8f4f9071 605 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3),
7361da2c
AB
606 mips_cp0_names_mips3264r2,
607 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
608 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
609
640c0ccd 610 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
d301a56b 611 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
bbcc0807
CD
612 mips_cp0_names_sb1,
613 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
dc76d757 614 mips_cp1_names_mips3264, mips_hwr_names_numeric },
640c0ccd 615
350cc38d 616 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
d301a56b 617 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
dc76d757 618 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d
MS
619
620 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
d301a56b 621 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
dc76d757 622 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d 623
fd503541 624 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
4ba154f5 625 ISA_MIPS64R2 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
dc76d757 626 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
fd503541 627
57b592a3 628 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
d301a56b 629 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
dc76d757 630 mips_cp1_names_mips3264, mips_hwr_names_numeric },
57b592a3 631
dd6a37e7 632 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
d301a56b 633 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
dc76d757 634 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
432233b3
AP
635
636 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
d301a56b 637 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
dc76d757 638 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
dd6a37e7 639
2c629856
N
640 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
641 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
642 mips_cp0_names_numeric,
643 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
644
52b6b6b9 645 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 646 ISA_MIPS64 | INSN_XLR, 0,
52b6b6b9
JM
647 mips_cp0_names_xlr,
648 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 649 mips_cp1_names_mips3264, mips_hwr_names_numeric },
52b6b6b9 650
55a36193
MK
651 /* XLP is mostly like XLR, with the prominent exception it is being
652 MIPS64R2. */
653 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 654 ISA_MIPS64R2 | INSN_XLR, 0,
55a36193
MK
655 mips_cp0_names_xlr,
656 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 657 mips_cp1_names_mips3264, mips_hwr_names_numeric },
55a36193 658
640c0ccd
CD
659 /* This entry, mips16, is here only for ISA/processor selection; do
660 not print its name. */
11dd08e9 661 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64, 0,
dc76d757
AB
662 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
663 mips_hwr_names_numeric },
640c0ccd
CD
664};
665
666/* ISA and processor type to disassemble for, and register names to use.
667 set_default_mips_dis_options and parse_mips_dis_options fill in these
668 values. */
669static int mips_processor;
670static int mips_isa;
d301a56b 671static int mips_ase;
df58fc94 672static int micromips_ase;
640c0ccd
CD
673static const char * const *mips_gpr_names;
674static const char * const *mips_fpr_names;
675static const char * const *mips_cp0_names;
bbcc0807
CD
676static const struct mips_cp0sel_name *mips_cp0sel_names;
677static int mips_cp0sel_names_len;
dc76d757 678static const char * const *mips_cp1_names;
af7ee8bf 679static const char * const *mips_hwr_names;
640c0ccd 680
986e18a5 681/* Other options */
47b0e7ad 682static int no_aliases; /* If set disassemble as most general inst. */
640c0ccd
CD
683\f
684static const struct mips_abi_choice *
47b0e7ad 685choose_abi_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
686{
687 const struct mips_abi_choice *c;
688 unsigned int i;
689
690 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
47b0e7ad
NC
691 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
692 && strlen (mips_abi_choices[i].name) == namelen)
693 c = &mips_abi_choices[i];
694
640c0ccd
CD
695 return c;
696}
697
698static const struct mips_arch_choice *
47b0e7ad 699choose_arch_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
700{
701 const struct mips_arch_choice *c = NULL;
702 unsigned int i;
703
704 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
47b0e7ad
NC
705 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
706 && strlen (mips_arch_choices[i].name) == namelen)
707 c = &mips_arch_choices[i];
708
640c0ccd
CD
709 return c;
710}
711
712static const struct mips_arch_choice *
47b0e7ad 713choose_arch_by_number (unsigned long mach)
640c0ccd
CD
714{
715 static unsigned long hint_bfd_mach;
716 static const struct mips_arch_choice *hint_arch_choice;
717 const struct mips_arch_choice *c;
718 unsigned int i;
719
720 /* We optimize this because even if the user specifies no
721 flags, this will be done for every instruction! */
722 if (hint_bfd_mach == mach
723 && hint_arch_choice != NULL
724 && hint_arch_choice->bfd_mach == hint_bfd_mach)
725 return hint_arch_choice;
726
727 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
728 {
729 if (mips_arch_choices[i].bfd_mach_valid
730 && mips_arch_choices[i].bfd_mach == mach)
731 {
732 c = &mips_arch_choices[i];
733 hint_bfd_mach = mach;
734 hint_arch_choice = c;
735 }
736 }
737 return c;
738}
739
47b0e7ad
NC
740/* Check if the object uses NewABI conventions. */
741
742static int
743is_newabi (Elf_Internal_Ehdr *header)
744{
745 /* There are no old-style ABIs which use 64-bit ELF. */
746 if (header->e_ident[EI_CLASS] == ELFCLASS64)
747 return 1;
748
749 /* If a 32-bit ELF file, n32 is a new-style ABI. */
750 if ((header->e_flags & EF_MIPS_ABI2) != 0)
751 return 1;
752
753 return 0;
754}
755
df58fc94
RS
756/* Check if the object has microMIPS ASE code. */
757
758static int
759is_micromips (Elf_Internal_Ehdr *header)
760{
761 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
762 return 1;
763
764 return 0;
765}
766
5e7fc731
MR
767/* Convert ASE flags from .MIPS.abiflags to internal values. */
768
769static unsigned long
770mips_convert_abiflags_ases (unsigned long afl_ases)
771{
772 unsigned long opcode_ases = 0;
773
774 if (afl_ases & AFL_ASE_DSP)
775 opcode_ases |= ASE_DSP;
776 if (afl_ases & AFL_ASE_DSPR2)
777 opcode_ases |= ASE_DSPR2;
778 if (afl_ases & AFL_ASE_EVA)
779 opcode_ases |= ASE_EVA;
780 if (afl_ases & AFL_ASE_MCU)
781 opcode_ases |= ASE_MCU;
782 if (afl_ases & AFL_ASE_MDMX)
783 opcode_ases |= ASE_MDMX;
784 if (afl_ases & AFL_ASE_MIPS3D)
785 opcode_ases |= ASE_MIPS3D;
786 if (afl_ases & AFL_ASE_MT)
787 opcode_ases |= ASE_MT;
788 if (afl_ases & AFL_ASE_SMARTMIPS)
789 opcode_ases |= ASE_SMARTMIPS;
790 if (afl_ases & AFL_ASE_VIRT)
791 opcode_ases |= ASE_VIRT;
792 if (afl_ases & AFL_ASE_MSA)
793 opcode_ases |= ASE_MSA;
794 if (afl_ases & AFL_ASE_XPA)
795 opcode_ases |= ASE_XPA;
796 if (afl_ases & AFL_ASE_DSPR3)
797 opcode_ases |= ASE_DSPR3;
798 return opcode_ases;
799}
800
47b0e7ad
NC
801static void
802set_default_mips_dis_options (struct disassemble_info *info)
640c0ccd
CD
803{
804 const struct mips_arch_choice *chosen_arch;
805
df58fc94
RS
806 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
807 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
808 CP0 register, and HWR names. */
640c0ccd 809 mips_isa = ISA_MIPS3;
df58fc94
RS
810 mips_processor = CPU_R3000;
811 micromips_ase = 0;
d301a56b 812 mips_ase = 0;
640c0ccd
CD
813 mips_gpr_names = mips_gpr_names_oldabi;
814 mips_fpr_names = mips_fpr_names_numeric;
815 mips_cp0_names = mips_cp0_names_numeric;
bbcc0807
CD
816 mips_cp0sel_names = NULL;
817 mips_cp0sel_names_len = 0;
dc76d757 818 mips_cp1_names = mips_cp1_names_numeric;
af7ee8bf 819 mips_hwr_names = mips_hwr_names_numeric;
986e18a5 820 no_aliases = 0;
640c0ccd 821
640c0ccd
CD
822 /* Set ISA, architecture, and cp0 register names as best we can. */
823#if ! SYMTAB_AVAILABLE
824 /* This is running out on a target machine, not in a host tool.
825 FIXME: Where does mips_target_info come from? */
826 target_processor = mips_target_info.processor;
827 mips_isa = mips_target_info.isa;
d301a56b 828 mips_ase = mips_target_info.ase;
640c0ccd
CD
829#else
830 chosen_arch = choose_arch_by_number (info->mach);
831 if (chosen_arch != NULL)
832 {
833 mips_processor = chosen_arch->processor;
834 mips_isa = chosen_arch->isa;
d301a56b 835 mips_ase = chosen_arch->ase;
bbcc0807
CD
836 mips_cp0_names = chosen_arch->cp0_names;
837 mips_cp0sel_names = chosen_arch->cp0sel_names;
838 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 839 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 840 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd 841 }
8184783a
MR
842
843 /* Update settings according to the ELF file header flags. */
844 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
845 {
5e7fc731
MR
846 struct bfd *abfd = info->section->owner;
847 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
4df995c7
MR
848 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
849
9e76c212
MR
850 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
851 because we won't then have a MIPS/ELF BFD, however we need
852 to guard against a link error in a `--enable-targets=...'
853 configuration with a 32-bit host where the MIPS target is
854 a secondary, or with MIPS/ECOFF configurations. */
855#ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
4df995c7
MR
856 abiflags = bfd_mips_elf_get_abiflags (abfd);
857#endif
8184783a
MR
858 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
859 if (is_newabi (header))
860 mips_gpr_names = mips_gpr_names_newabi;
861 /* If a microMIPS binary, then don't use MIPS16 bindings. */
862 micromips_ase = is_micromips (header);
5e7fc731
MR
863 /* OR in any extra ASE flags set in ELF file structures. */
864 if (abiflags)
865 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
866 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
867 mips_ase |= ASE_MDMX;
8184783a 868 }
91068ec6 869#endif
640c0ccd
CD
870}
871
47b0e7ad
NC
872static void
873parse_mips_dis_option (const char *option, unsigned int len)
640c0ccd
CD
874{
875 unsigned int i, optionlen, vallen;
876 const char *val;
877 const struct mips_abi_choice *chosen_abi;
878 const struct mips_arch_choice *chosen_arch;
879
986e18a5 880 /* Try to match options that are simple flags */
0112cd26 881 if (CONST_STRNEQ (option, "no-aliases"))
986e18a5
FF
882 {
883 no_aliases = 1;
884 return;
885 }
b015e599 886
4edbb8e3
CF
887 if (CONST_STRNEQ (option, "msa"))
888 {
889 mips_ase |= ASE_MSA;
ae52f483
AB
890 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
891 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
7361da2c
AB
892 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
893 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
4edbb8e3
CF
894 mips_ase |= ASE_MSA64;
895 return;
896 }
897
b015e599
AP
898 if (CONST_STRNEQ (option, "virt"))
899 {
d301a56b 900 mips_ase |= ASE_VIRT;
ae52f483
AB
901 if (mips_isa & ISA_MIPS64R2
902 || mips_isa & ISA_MIPS64R3
7361da2c
AB
903 || mips_isa & ISA_MIPS64R5
904 || mips_isa & ISA_MIPS64R6)
d301a56b 905 mips_ase |= ASE_VIRT64;
b015e599
AP
906 return;
907 }
7d64c587
AB
908
909 if (CONST_STRNEQ (option, "xpa"))
910 {
911 mips_ase |= ASE_XPA;
912 return;
913 }
43e65147
L
914
915
640c0ccd
CD
916 /* Look for the = that delimits the end of the option name. */
917 for (i = 0; i < len; i++)
47b0e7ad
NC
918 if (option[i] == '=')
919 break;
920
640c0ccd
CD
921 if (i == 0) /* Invalid option: no name before '='. */
922 return;
923 if (i == len) /* Invalid option: no '='. */
924 return;
925 if (i == (len - 1)) /* Invalid option: no value after '='. */
926 return;
927
928 optionlen = i;
929 val = option + (optionlen + 1);
930 vallen = len - (optionlen + 1);
931
47b0e7ad
NC
932 if (strncmp ("gpr-names", option, optionlen) == 0
933 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
934 {
935 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 936 if (chosen_abi != NULL)
640c0ccd
CD
937 mips_gpr_names = chosen_abi->gpr_names;
938 return;
939 }
940
47b0e7ad
NC
941 if (strncmp ("fpr-names", option, optionlen) == 0
942 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
943 {
944 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 945 if (chosen_abi != NULL)
640c0ccd
CD
946 mips_fpr_names = chosen_abi->fpr_names;
947 return;
948 }
949
47b0e7ad
NC
950 if (strncmp ("cp0-names", option, optionlen) == 0
951 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
952 {
953 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
954 if (chosen_arch != NULL)
955 {
956 mips_cp0_names = chosen_arch->cp0_names;
957 mips_cp0sel_names = chosen_arch->cp0sel_names;
958 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
959 }
640c0ccd
CD
960 return;
961 }
962
dc76d757
AB
963 if (strncmp ("cp1-names", option, optionlen) == 0
964 && strlen ("cp1-names") == optionlen)
965 {
966 chosen_arch = choose_arch_by_name (val, vallen);
967 if (chosen_arch != NULL)
968 mips_cp1_names = chosen_arch->cp1_names;
969 return;
970 }
971
47b0e7ad
NC
972 if (strncmp ("hwr-names", option, optionlen) == 0
973 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
974 {
975 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 976 if (chosen_arch != NULL)
af7ee8bf
CD
977 mips_hwr_names = chosen_arch->hwr_names;
978 return;
979 }
980
47b0e7ad
NC
981 if (strncmp ("reg-names", option, optionlen) == 0
982 && strlen ("reg-names") == optionlen)
640c0ccd
CD
983 {
984 /* We check both ABI and ARCH here unconditionally, so
985 that "numeric" will do the desirable thing: select
986 numeric register names for all registers. Other than
987 that, a given name probably won't match both. */
988 chosen_abi = choose_abi_by_name (val, vallen);
989 if (chosen_abi != NULL)
990 {
bbcc0807
CD
991 mips_gpr_names = chosen_abi->gpr_names;
992 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
993 }
994 chosen_arch = choose_arch_by_name (val, vallen);
995 if (chosen_arch != NULL)
996 {
bbcc0807
CD
997 mips_cp0_names = chosen_arch->cp0_names;
998 mips_cp0sel_names = chosen_arch->cp0sel_names;
999 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 1000 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 1001 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
1002 }
1003 return;
1004 }
1005
1006 /* Invalid option. */
1007}
1008
47b0e7ad
NC
1009static void
1010parse_mips_dis_options (const char *options)
640c0ccd
CD
1011{
1012 const char *option_end;
1013
1014 if (options == NULL)
1015 return;
1016
1017 while (*options != '\0')
1018 {
1019 /* Skip empty options. */
1020 if (*options == ',')
1021 {
1022 options++;
1023 continue;
1024 }
1025
1026 /* We know that *options is neither NUL or a comma. */
1027 option_end = options + 1;
1028 while (*option_end != ',' && *option_end != '\0')
1029 option_end++;
1030
1031 parse_mips_dis_option (options, option_end - options);
1032
1033 /* Go on to the next one. If option_end points to a comma, it
1034 will be skipped above. */
1035 options = option_end;
1036 }
1037}
1038
bbcc0807 1039static const struct mips_cp0sel_name *
47b0e7ad
NC
1040lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1041 unsigned int len,
1042 unsigned int cp0reg,
1043 unsigned int sel)
bbcc0807
CD
1044{
1045 unsigned int i;
1046
1047 for (i = 0; i < len; i++)
1048 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1049 return &names[i];
1050 return NULL;
1051}
ab902481
RS
1052
1053/* Print register REGNO, of type TYPE, for instruction OPCODE. */
aa5f19f2 1054
794ac9d0 1055static void
ab902481
RS
1056print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1057 enum mips_reg_operand_type type, int regno)
252b5132 1058{
ab902481
RS
1059 switch (type)
1060 {
1061 case OP_REG_GP:
1062 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1063 break;
440cc0bc 1064
ab902481
RS
1065 case OP_REG_FP:
1066 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1067 break;
252b5132 1068
ab902481
RS
1069 case OP_REG_CCC:
1070 if (opcode->pinfo & (FP_D | FP_S))
1071 info->fprintf_func (info->stream, "$fcc%d", regno);
1072 else
1073 info->fprintf_func (info->stream, "$cc%d", regno);
1074 break;
794ac9d0 1075
ab902481
RS
1076 case OP_REG_VEC:
1077 if (opcode->membership & INSN_5400)
1078 info->fprintf_func (info->stream, "$f%d", regno);
1079 else
1080 info->fprintf_func (info->stream, "$v%d", regno);
1081 break;
794ac9d0 1082
ab902481
RS
1083 case OP_REG_ACC:
1084 info->fprintf_func (info->stream, "$ac%d", regno);
1085 break;
794ac9d0 1086
ab902481
RS
1087 case OP_REG_COPRO:
1088 if (opcode->name[strlen (opcode->name) - 1] == '0')
1089 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
dc76d757
AB
1090 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1091 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
ab902481
RS
1092 else
1093 info->fprintf_func (info->stream, "$%d", regno);
1094 break;
8b082fb1 1095
ab902481
RS
1096 case OP_REG_HW:
1097 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1098 break;
14daeee3
RS
1099
1100 case OP_REG_VF:
1101 info->fprintf_func (info->stream, "$vf%d", regno);
1102 break;
1103
1104 case OP_REG_VI:
1105 info->fprintf_func (info->stream, "$vi%d", regno);
1106 break;
1107
1108 case OP_REG_R5900_I:
1109 info->fprintf_func (info->stream, "$I");
1110 break;
1111
1112 case OP_REG_R5900_Q:
1113 info->fprintf_func (info->stream, "$Q");
1114 break;
1115
1116 case OP_REG_R5900_R:
1117 info->fprintf_func (info->stream, "$R");
1118 break;
1119
1120 case OP_REG_R5900_ACC:
1121 info->fprintf_func (info->stream, "$ACC");
1122 break;
4edbb8e3
CF
1123
1124 case OP_REG_MSA:
1125 info->fprintf_func (info->stream, "$w%d", regno);
1126 break;
1127
1128 case OP_REG_MSA_CTRL:
1129 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1130 break;
1131
ab902481
RS
1132 }
1133}
1134\f
1135/* Used to track the state carried over from previous operands in
1136 an instruction. */
1137struct mips_print_arg_state {
1138 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1139 where the value is known to be unsigned and small. */
1140 unsigned int last_int;
1141
1142 /* The type and number of the last OP_REG seen. We only use this for
1143 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1144 enum mips_reg_operand_type last_reg_type;
1145 unsigned int last_regno;
7361da2c
AB
1146 unsigned int dest_regno;
1147 unsigned int seen_dest;
ab902481 1148};
fd25c5a9 1149
ab902481 1150/* Initialize STATE for the start of an instruction. */
fd25c5a9 1151
ab902481
RS
1152static inline void
1153init_print_arg_state (struct mips_print_arg_state *state)
1154{
1155 memset (state, 0, sizeof (*state));
1156}
fd25c5a9 1157
14daeee3
RS
1158/* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1159 whose value is given by UVAL. */
1160
1161static void
1162print_vu0_channel (struct disassemble_info *info,
1163 const struct mips_operand *operand, unsigned int uval)
1164{
1165 if (operand->size == 4)
1166 info->fprintf_func (info->stream, "%s%s%s%s",
1167 uval & 8 ? "x" : "",
1168 uval & 4 ? "y" : "",
1169 uval & 2 ? "z" : "",
1170 uval & 1 ? "w" : "");
1171 else if (operand->size == 2)
1172 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1173 else
1174 abort ();
1175}
1176
7361da2c
AB
1177/* Record information about a register operand. */
1178
1179static void
1180mips_seen_register (struct mips_print_arg_state *state,
1181 unsigned int regno,
1182 enum mips_reg_operand_type reg_type)
1183{
1184 state->last_reg_type = reg_type;
1185 state->last_regno = regno;
1186
1187 if (!state->seen_dest)
1188 {
1189 state->seen_dest = 1;
1190 state->dest_regno = regno;
1191 }
1192}
1193
ab902481
RS
1194/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1195 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1196 the base address for OP_PCREL operands. */
fd25c5a9 1197
ab902481
RS
1198static void
1199print_insn_arg (struct disassemble_info *info,
1200 struct mips_print_arg_state *state,
1201 const struct mips_opcode *opcode,
1202 const struct mips_operand *operand,
1203 bfd_vma base_pc,
1204 unsigned int uval)
1205{
1206 const fprintf_ftype infprintf = info->fprintf_func;
1207 void *is = info->stream;
fd25c5a9 1208
ab902481
RS
1209 switch (operand->type)
1210 {
1211 case OP_INT:
1212 {
1213 const struct mips_int_operand *int_op;
fd25c5a9 1214
ab902481
RS
1215 int_op = (const struct mips_int_operand *) operand;
1216 uval = mips_decode_int_operand (int_op, uval);
1217 state->last_int = uval;
1218 if (int_op->print_hex)
1219 infprintf (is, "0x%x", uval);
1220 else
1221 infprintf (is, "%d", uval);
1222 }
1223 break;
fd25c5a9 1224
ab902481
RS
1225 case OP_MAPPED_INT:
1226 {
1227 const struct mips_mapped_int_operand *mint_op;
fd25c5a9 1228
ab902481
RS
1229 mint_op = (const struct mips_mapped_int_operand *) operand;
1230 uval = mint_op->int_map[uval];
1231 state->last_int = uval;
1232 if (mint_op->print_hex)
1233 infprintf (is, "0x%x", uval);
1234 else
1235 infprintf (is, "%d", uval);
1236 }
1237 break;
fd25c5a9 1238
ab902481
RS
1239 case OP_MSB:
1240 {
1241 const struct mips_msb_operand *msb_op;
dec0624d 1242
ab902481
RS
1243 msb_op = (const struct mips_msb_operand *) operand;
1244 uval += msb_op->bias;
1245 if (msb_op->add_lsb)
1246 uval -= state->last_int;
1247 infprintf (is, "0x%x", uval);
1248 }
1249 break;
dec0624d 1250
ab902481 1251 case OP_REG:
0f35dbc4 1252 case OP_OPTIONAL_REG:
ab902481
RS
1253 {
1254 const struct mips_reg_operand *reg_op;
fd25c5a9 1255
ab902481 1256 reg_op = (const struct mips_reg_operand *) operand;
fc76e730 1257 uval = mips_decode_reg_operand (reg_op, uval);
ab902481 1258 print_reg (info, opcode, reg_op->reg_type, uval);
fd25c5a9 1259
7361da2c 1260 mips_seen_register (state, uval, reg_op->reg_type);
ab902481
RS
1261 }
1262 break;
61cc0267 1263
ab902481
RS
1264 case OP_REG_PAIR:
1265 {
1266 const struct mips_reg_pair_operand *pair_op;
1267
1268 pair_op = (const struct mips_reg_pair_operand *) operand;
1269 print_reg (info, opcode, pair_op->reg_type,
1270 pair_op->reg1_map[uval]);
1271 infprintf (is, ",");
1272 print_reg (info, opcode, pair_op->reg_type,
1273 pair_op->reg2_map[uval]);
1274 }
1275 break;
61cc0267 1276
ab902481
RS
1277 case OP_PCREL:
1278 {
1279 const struct mips_pcrel_operand *pcrel_op;
61cc0267 1280
ab902481
RS
1281 pcrel_op = (const struct mips_pcrel_operand *) operand;
1282 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
61cc0267 1283
ab902481
RS
1284 /* Preserve the ISA bit for the GDB disassembler,
1285 otherwise clear it. */
1286 if (info->flavour != bfd_target_unknown_flavour)
1287 info->target &= -2;
61cc0267 1288
ab902481
RS
1289 (*info->print_address_func) (info->target, info);
1290 }
1291 break;
794ac9d0 1292
ab902481
RS
1293 case OP_PERF_REG:
1294 infprintf (is, "%d", uval);
1295 break;
794ac9d0 1296
ab902481
RS
1297 case OP_ADDIUSP_INT:
1298 {
1299 int sval;
794ac9d0 1300
ab902481
RS
1301 sval = mips_signed_operand (operand, uval) * 4;
1302 if (sval >= -8 && sval < 8)
1303 sval ^= 0x400;
1304 infprintf (is, "%d", sval);
1305 break;
1306 }
794ac9d0 1307
ab902481
RS
1308 case OP_CLO_CLZ_DEST:
1309 {
1310 unsigned int reg1, reg2;
1311
1312 reg1 = uval & 31;
1313 reg2 = uval >> 5;
1314 /* If one is zero use the other. */
1315 if (reg1 == reg2 || reg2 == 0)
1316 infprintf (is, "%s", mips_gpr_names[reg1]);
1317 else if (reg1 == 0)
1318 infprintf (is, "%s", mips_gpr_names[reg2]);
1319 else
1320 /* Bogus, result depends on processor. */
1321 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1322 mips_gpr_names[reg2]);
1323 }
1324 break;
794ac9d0 1325
7361da2c
AB
1326 case OP_SAME_RS_RT:
1327 case OP_CHECK_PREV:
1328 case OP_NON_ZERO_REG:
1329 {
1330 print_reg (info, opcode, OP_REG_GP, uval & 31);
1331 mips_seen_register (state, uval, OP_REG_GP);
1332 }
1333 break;
1334
ab902481
RS
1335 case OP_LWM_SWM_LIST:
1336 if (operand->size == 2)
1337 {
1338 if (uval == 0)
1339 infprintf (is, "%s,%s",
1340 mips_gpr_names[16],
1341 mips_gpr_names[31]);
1342 else
1343 infprintf (is, "%s-%s,%s",
1344 mips_gpr_names[16],
1345 mips_gpr_names[16 + uval],
1346 mips_gpr_names[31]);
1347 }
1348 else
1349 {
1350 int s_reg_encode;
794ac9d0 1351
ab902481
RS
1352 s_reg_encode = uval & 0xf;
1353 if (s_reg_encode != 0)
1354 {
1355 if (s_reg_encode == 1)
1356 infprintf (is, "%s", mips_gpr_names[16]);
1357 else if (s_reg_encode < 9)
1358 infprintf (is, "%s-%s",
1359 mips_gpr_names[16],
1360 mips_gpr_names[15 + s_reg_encode]);
1361 else if (s_reg_encode == 9)
1362 infprintf (is, "%s-%s,%s",
1363 mips_gpr_names[16],
1364 mips_gpr_names[23],
1365 mips_gpr_names[30]);
1366 else
1367 infprintf (is, "UNKNOWN");
1368 }
794ac9d0 1369
ab902481
RS
1370 if (uval & 0x10) /* For ra. */
1371 {
1372 if (s_reg_encode == 0)
1373 infprintf (is, "%s", mips_gpr_names[31]);
1374 else
1375 infprintf (is, ",%s", mips_gpr_names[31]);
1376 }
1377 }
1378 break;
794ac9d0 1379
c3c07478
RS
1380 case OP_ENTRY_EXIT_LIST:
1381 {
1382 const char *sep;
1383 unsigned int amask, smask;
1384
1385 sep = "";
1386 amask = (uval >> 3) & 7;
1387 if (amask > 0 && amask < 5)
1388 {
1389 infprintf (is, "%s", mips_gpr_names[4]);
1390 if (amask > 1)
1391 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1392 sep = ",";
1393 }
1394
1395 smask = (uval >> 1) & 3;
1396 if (smask == 3)
1397 {
1398 infprintf (is, "%s??", sep);
1399 sep = ",";
1400 }
1401 else if (smask > 0)
1402 {
1403 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1404 if (smask > 1)
1405 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1406 sep = ",";
1407 }
1408
1409 if (uval & 1)
1410 {
1411 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1412 sep = ",";
1413 }
1414
1415 if (amask == 5 || amask == 6)
1416 {
1417 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1418 if (amask == 6)
1419 infprintf (is, "-%s", mips_fpr_names[1]);
1420 }
1421 }
1422 break;
1423
1424 case OP_SAVE_RESTORE_LIST:
1425 /* Should be handled by the caller due to extend behavior. */
1426 abort ();
1427
ab902481
RS
1428 case OP_MDMX_IMM_REG:
1429 {
1430 unsigned int vsel;
794ac9d0 1431
ab902481
RS
1432 vsel = uval >> 5;
1433 uval &= 31;
1434 if ((vsel & 0x10) == 0)
794ac9d0 1435 {
ab902481
RS
1436 int fmt;
1437
1438 vsel &= 0x0f;
1439 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1440 if ((vsel & 1) == 0)
1441 break;
1442 print_reg (info, opcode, OP_REG_VEC, uval);
1443 infprintf (is, "[%d]", vsel >> 1);
794ac9d0 1444 }
ab902481
RS
1445 else if ((vsel & 0x08) == 0)
1446 print_reg (info, opcode, OP_REG_VEC, uval);
1447 else
1448 infprintf (is, "0x%x", uval);
1449 }
1450 break;
794ac9d0 1451
ab902481
RS
1452 case OP_REPEAT_PREV_REG:
1453 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1454 break;
794ac9d0 1455
ab902481 1456 case OP_REPEAT_DEST_REG:
7361da2c
AB
1457 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1458 break;
794ac9d0 1459
ab902481
RS
1460 case OP_PC:
1461 infprintf (is, "$pc");
1462 break;
14daeee3
RS
1463
1464 case OP_VU0_SUFFIX:
1465 case OP_VU0_MATCH_SUFFIX:
1466 print_vu0_channel (info, operand, uval);
1467 break;
4edbb8e3
CF
1468
1469 case OP_IMM_INDEX:
1470 infprintf (is, "[%d]", uval);
1471 break;
1472
1473 case OP_REG_INDEX:
1474 infprintf (is, "[");
1475 print_reg (info, opcode, OP_REG_GP, uval);
1476 infprintf (is, "]");
1477 break;
ab902481
RS
1478 }
1479}
794ac9d0 1480
7361da2c
AB
1481/* Validate the arguments for INSN, which is described by OPCODE.
1482 Use DECODE_OPERAND to get the encoding of each operand. */
1483
1484static bfd_boolean
1485validate_insn_args (const struct mips_opcode *opcode,
1486 const struct mips_operand *(*decode_operand) (const char *),
1487 unsigned int insn)
1488{
1489 struct mips_print_arg_state state;
1490 const struct mips_operand *operand;
1491 const char *s;
1492 unsigned int uval;
1493
1494 init_print_arg_state (&state);
1495 for (s = opcode->args; *s; ++s)
1496 {
1497 switch (*s)
1498 {
1499 case ',':
1500 case '(':
1501 case ')':
1502 break;
1503
1504 case '#':
1505 ++s;
1506 break;
1507
1508 default:
1509 operand = decode_operand (s);
1510
1511 if (operand)
1512 {
1513 uval = mips_extract_operand (operand, insn);
1514 switch (operand->type)
1515 {
1516 case OP_REG:
1517 case OP_OPTIONAL_REG:
1518 {
1519 const struct mips_reg_operand *reg_op;
1520
1521 reg_op = (const struct mips_reg_operand *) operand;
1522 uval = mips_decode_reg_operand (reg_op, uval);
1523 mips_seen_register (&state, uval, reg_op->reg_type);
1524 }
1525 break;
1526
1527 case OP_SAME_RS_RT:
1528 {
1529 unsigned int reg1, reg2;
1530
1531 reg1 = uval & 31;
1532 reg2 = uval >> 5;
1533
1534 if (reg1 != reg2 || reg1 == 0)
1535 return FALSE;
1536 }
1537 break;
1538
1539 case OP_CHECK_PREV:
1540 {
1541 const struct mips_check_prev_operand *prev_op;
1542
1543 prev_op = (const struct mips_check_prev_operand *) operand;
1544
1545 if (!prev_op->zero_ok && uval == 0)
1546 return FALSE;
1547
1548 if (((prev_op->less_than_ok && uval < state.last_regno)
1549 || (prev_op->greater_than_ok && uval > state.last_regno)
1550 || (prev_op->equal_ok && uval == state.last_regno)))
1551 break;
1552
1553 return FALSE;
1554 }
1555
1556 case OP_NON_ZERO_REG:
1557 {
1558 if (uval == 0)
1559 return FALSE;
1560 }
1561 break;
1562
1563 case OP_INT:
1564 case OP_MAPPED_INT:
1565 case OP_MSB:
1566 case OP_REG_PAIR:
1567 case OP_PCREL:
1568 case OP_PERF_REG:
1569 case OP_ADDIUSP_INT:
1570 case OP_CLO_CLZ_DEST:
1571 case OP_LWM_SWM_LIST:
1572 case OP_ENTRY_EXIT_LIST:
1573 case OP_MDMX_IMM_REG:
1574 case OP_REPEAT_PREV_REG:
1575 case OP_REPEAT_DEST_REG:
1576 case OP_PC:
1577 case OP_VU0_SUFFIX:
1578 case OP_VU0_MATCH_SUFFIX:
1579 case OP_IMM_INDEX:
1580 case OP_REG_INDEX:
1581 break;
1582
1583 case OP_SAVE_RESTORE_LIST:
1584 /* Should be handled by the caller due to extend behavior. */
1585 abort ();
1586 }
1587 }
1588 if (*s == 'm' || *s == '+' || *s == '-')
1589 ++s;
1590 }
1591 }
1592 return TRUE;
1593}
1594
ab902481
RS
1595/* Print the arguments for INSN, which is described by OPCODE.
1596 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
7361da2c
AB
1597 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1598 operand is for a branch or jump. */
af7ee8bf 1599
ab902481
RS
1600static void
1601print_insn_args (struct disassemble_info *info,
1602 const struct mips_opcode *opcode,
1603 const struct mips_operand *(*decode_operand) (const char *),
7361da2c 1604 unsigned int insn, bfd_vma insn_pc, unsigned int length)
ab902481
RS
1605{
1606 const fprintf_ftype infprintf = info->fprintf_func;
1607 void *is = info->stream;
1608 struct mips_print_arg_state state;
1609 const struct mips_operand *operand;
1610 const char *s;
794ac9d0 1611
ab902481
RS
1612 init_print_arg_state (&state);
1613 for (s = opcode->args; *s; ++s)
1614 {
1615 switch (*s)
1616 {
1617 case ',':
1618 case '(':
1619 case ')':
1620 infprintf (is, "%c", *s);
794ac9d0
CD
1621 break;
1622
14daeee3
RS
1623 case '#':
1624 ++s;
1625 infprintf (is, "%c%c", *s, *s);
1626 break;
1627
ab902481
RS
1628 default:
1629 operand = decode_operand (s);
1630 if (!operand)
fa7616a4 1631 {
ab902481
RS
1632 /* xgettext:c-format */
1633 infprintf (is,
1634 _("# internal error, undefined operand in `%s %s'"),
1635 opcode->name, opcode->args);
1636 return;
1637 }
1638 if (operand->type == OP_REG
1639 && s[1] == ','
1640 && s[2] == 'H'
1641 && opcode->name[strlen (opcode->name) - 1] == '0')
1642 {
1643 /* Coprocessor register 0 with sel field (MT ASE). */
1644 const struct mips_cp0sel_name *n;
1645 unsigned int reg, sel;
1646
1647 reg = mips_extract_operand (operand, insn);
1648 s += 2;
1649 operand = decode_operand (s);
1650 sel = mips_extract_operand (operand, insn);
1651
1652 /* CP0 register including 'sel' code for mftc0, to be
1653 printed textually if known. If not known, print both
1654 CP0 register name and sel numerically since CP0 register
1655 with sel 0 may have a name unrelated to register being
1656 printed. */
1657 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1658 mips_cp0sel_names_len,
1659 reg, sel);
1660 if (n != NULL)
1661 infprintf (is, "%s", n->name);
fa7616a4 1662 else
ab902481 1663 infprintf (is, "$%d,%d", reg, sel);
fa7616a4 1664 }
794ac9d0 1665 else
7361da2c
AB
1666 {
1667 bfd_vma base_pc = insn_pc;
1668
1669 /* Adjust the PC relative base so that branch/jump insns use
1670 the following PC as the base but genuinely PC relative
1671 operands use the current PC. */
1672 if (operand->type == OP_PCREL)
1673 {
1674 const struct mips_pcrel_operand *pcrel_op;
1675
1676 pcrel_op = (const struct mips_pcrel_operand *) operand;
1677 /* The include_isa_bit flag is sufficient to distinguish
1678 branch/jump from other PC relative operands. */
1679 if (pcrel_op->include_isa_bit)
1680 base_pc += length;
1681 }
1682
1683 print_insn_arg (info, &state, opcode, operand, base_pc,
1684 mips_extract_operand (operand, insn));
1685 }
1686 if (*s == 'm' || *s == '+' || *s == '-')
ab902481 1687 ++s;
794ac9d0 1688 break;
af7ee8bf 1689 }
252b5132
RH
1690 }
1691}
1692\f
252b5132
RH
1693/* Print the mips instruction at address MEMADDR in debugged memory,
1694 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1695 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1696 this is little-endian code. */
1697
1698static int
47b0e7ad 1699print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1700 int word,
47b0e7ad 1701 struct disassemble_info *info)
252b5132 1702{
ab902481
RS
1703#define GET_OP(insn, field) \
1704 (((insn) >> OP_SH_##field) & OP_MASK_##field)
fc8c4fd1
MR
1705 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1706 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1707 const struct mips_opcode *op;
b34976b6 1708 static bfd_boolean init = 0;
fc8c4fd1 1709 void *is = info->stream;
252b5132
RH
1710
1711 /* Build a hash table to shorten the search time. */
1712 if (! init)
1713 {
1714 unsigned int i;
1715
1716 for (i = 0; i <= OP_MASK_OP; i++)
1717 {
1718 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1719 {
986e18a5 1720 if (op->pinfo == INSN_MACRO
9e836e3d 1721 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1722 continue;
fc8c4fd1 1723 if (i == GET_OP (op->match, OP))
252b5132
RH
1724 {
1725 mips_hash[i] = op;
1726 break;
1727 }
1728 }
7f6621cd 1729 }
252b5132
RH
1730
1731 init = 1;
1732 }
1733
aa5f19f2 1734 info->bytes_per_chunk = INSNLEN;
252b5132 1735 info->display_endian = info->endian;
9bb28706
CD
1736 info->insn_info_valid = 1;
1737 info->branch_delay_insns = 0;
def7143b 1738 info->data_size = 0;
9bb28706
CD
1739 info->insn_type = dis_nonbranch;
1740 info->target = 0;
1741 info->target2 = 0;
252b5132 1742
fc8c4fd1 1743 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1744 if (op != NULL)
1745 {
1746 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1747 {
43e65147 1748 if (op->pinfo != INSN_MACRO
9e836e3d 1749 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1750 && (word & op->mask) == op->match)
252b5132 1751 {
7361da2c 1752 /* We always disassemble the jalx instruction, except for MIPS r6. */
d301a56b 1753 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
7361da2c
AB
1754 && (strcmp (op->name, "jalx")
1755 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1756 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
252b5132
RH
1757 continue;
1758
9bb28706
CD
1759 /* Figure out instruction type and branch delay information. */
1760 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1761 {
fc76e730 1762 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
9bb28706
CD
1763 info->insn_type = dis_jsr;
1764 else
1765 info->insn_type = dis_branch;
1766 info->branch_delay_insns = 1;
1767 }
1768 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1769 | INSN_COND_BRANCH_LIKELY)) != 0)
1770 {
c680e7f6 1771 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1772 info->insn_type = dis_condjsr;
1773 else
1774 info->insn_type = dis_condbranch;
1775 info->branch_delay_insns = 1;
1776 }
1777 else if ((op->pinfo & (INSN_STORE_MEMORY
67dc82bc 1778 | INSN_LOAD_MEMORY)) != 0)
9bb28706
CD
1779 info->insn_type = dis_dref;
1780
7361da2c
AB
1781 if (!validate_insn_args (op, decode_mips_operand, word))
1782 continue;
1783
fc8c4fd1 1784 infprintf (is, "%s", op->name);
14daeee3
RS
1785 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1786 {
1787 unsigned int uval;
1788
1789 infprintf (is, ".");
1790 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1791 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1792 }
252b5132 1793
ab902481 1794 if (op->args[0])
252b5132 1795 {
fc8c4fd1 1796 infprintf (is, "\t");
ab902481 1797 print_insn_args (info, op, decode_mips_operand, word,
7361da2c 1798 memaddr, 4);
252b5132
RH
1799 }
1800
aa5f19f2 1801 return INSNLEN;
252b5132
RH
1802 }
1803 }
1804 }
fc8c4fd1 1805#undef GET_OP
252b5132
RH
1806
1807 /* Handle undefined instructions. */
9bb28706 1808 info->insn_type = dis_noninsn;
fc8c4fd1 1809 infprintf (is, "0x%x", word);
aa5f19f2 1810 return INSNLEN;
252b5132 1811}
aa5f19f2 1812\f
252b5132
RH
1813/* Disassemble an operand for a mips16 instruction. */
1814
1815static void
c3c07478
RS
1816print_mips16_insn_arg (struct disassemble_info *info,
1817 struct mips_print_arg_state *state,
1818 const struct mips_opcode *opcode,
1819 char type, bfd_vma memaddr,
1820 unsigned insn, bfd_boolean use_extend,
1821 unsigned extend, bfd_boolean is_offset)
252b5132 1822{
fc8c4fd1
MR
1823 const fprintf_ftype infprintf = info->fprintf_func;
1824 void *is = info->stream;
c3c07478
RS
1825 const struct mips_operand *operand, *ext_operand;
1826 unsigned int uval;
1827 bfd_vma baseaddr;
1828
1829 if (!use_extend)
1830 extend = 0;
fc8c4fd1 1831
252b5132
RH
1832 switch (type)
1833 {
1834 case ',':
1835 case '(':
1836 case ')':
fc8c4fd1 1837 infprintf (is, "%c", type);
252b5132
RH
1838 break;
1839
c3c07478
RS
1840 default:
1841 operand = decode_mips16_operand (type, FALSE);
1842 if (!operand)
1843 {
1844 /* xgettext:c-format */
1845 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1846 opcode->name, opcode->args);
1847 return;
1848 }
252b5132 1849
c3c07478
RS
1850 if (operand->type == OP_SAVE_RESTORE_LIST)
1851 {
5f5c6e03 1852 /* Handle this case here because of the complex interaction
c3c07478
RS
1853 with the EXTEND opcode. */
1854 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1855 const char *sep;
252b5132 1856
c3c07478
RS
1857 amask = extend & 0xf;
1858 if (amask == MIPS16_ALL_ARGS)
1859 {
1860 nargs = 4;
1861 nstatics = 0;
1862 }
1863 else if (amask == MIPS16_ALL_STATICS)
1864 {
1865 nargs = 0;
1866 nstatics = 4;
1867 }
1868 else
1869 {
1870 nargs = amask >> 2;
1871 nstatics = amask & 3;
1872 }
252b5132 1873
c3c07478
RS
1874 sep = "";
1875 if (nargs > 0)
1876 {
1877 infprintf (is, "%s", mips_gpr_names[4]);
1878 if (nargs > 1)
1879 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1880 sep = ",";
1881 }
252b5132 1882
c3c07478
RS
1883 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1884 if (frame_size == 0 && !use_extend)
1885 frame_size = 128;
1886 infprintf (is, "%s%d", sep, frame_size);
1887
1888 if (insn & 0x40) /* $ra */
1889 infprintf (is, ",%s", mips_gpr_names[31]);
1890
1891 nsreg = (extend >> 8) & 0x7;
1892 smask = 0;
1893 if (insn & 0x20) /* $s0 */
1894 smask |= 1 << 0;
1895 if (insn & 0x10) /* $s1 */
1896 smask |= 1 << 1;
1897 if (nsreg > 0) /* $s2-$s8 */
1898 smask |= ((1 << nsreg) - 1) << 2;
1899
1900 for (i = 0; i < 9; i++)
1901 if (smask & (1 << i))
252b5132 1902 {
c3c07478
RS
1903 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1904 /* Skip over string of set bits. */
1905 for (j = i; smask & (2 << j); j++)
1906 continue;
1907 if (j > i)
1908 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1909 i = j + 1;
252b5132 1910 }
c3c07478
RS
1911 /* Statics $ax - $a3. */
1912 if (nstatics == 1)
1913 infprintf (is, ",%s", mips_gpr_names[7]);
1914 else if (nstatics > 0)
1915 infprintf (is, ",%s-%s",
1916 mips_gpr_names[7 - nstatics + 1],
1917 mips_gpr_names[7]);
1918 break;
1919 }
252b5132 1920
c3c07478
RS
1921 if (is_offset && operand->type == OP_INT)
1922 {
1923 const struct mips_int_operand *int_op;
252b5132 1924
c3c07478
RS
1925 int_op = (const struct mips_int_operand *) operand;
1926 info->insn_type = dis_dref;
1927 info->data_size = 1 << int_op->shift;
1928 }
252b5132 1929
c3c07478 1930 if (operand->size == 26)
7fd53920 1931 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
c3c07478
RS
1932 else
1933 {
1934 /* Calculate the full field value. */
7fd53920 1935 uval = mips_extract_operand (operand, (extend << 16) | insn);
c3c07478
RS
1936 if (use_extend)
1937 {
1938 ext_operand = decode_mips16_operand (type, TRUE);
1939 if (ext_operand != operand)
1940 {
1941 operand = ext_operand;
1942 if (operand->size == 16)
92708cec
MR
1943 uval = (((extend & 0x1f) << 11) | (extend & 0x7e0)
1944 | (uval & 0x1f));
c3c07478
RS
1945 else if (operand->size == 15)
1946 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1947 else
92708cec
MR
1948 uval = ((((extend >> 6) & 0x1f) | (extend & 0x20))
1949 & ((1U << operand->size) - 1));
c3c07478
RS
1950 }
1951 }
1952 }
1953
1954 baseaddr = memaddr + 2;
1955 if (operand->type == OP_PCREL)
1956 {
1957 const struct mips_pcrel_operand *pcrel_op;
1958
1959 pcrel_op = (const struct mips_pcrel_operand *) operand;
1960 if (!pcrel_op->include_isa_bit && use_extend)
1961 baseaddr = memaddr - 2;
1962 else if (!pcrel_op->include_isa_bit)
39f66f3a
MR
1963 {
1964 bfd_byte buffer[2];
1965
1966 /* If this instruction is in the delay slot of a JAL/JALX
1967 instruction, the base address is the address of the
1968 JAL/JALX instruction. If it is in the delay slot of
1969 a JR/JALR instruction, the base address is the address
1970 of the JR/JALR instruction. This test is unreliable:
1971 we have no way of knowing whether the previous word is
1972 instruction or data. */
1973 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1974 && (((info->endian == BFD_ENDIAN_BIG
1975 ? bfd_getb16 (buffer)
1976 : bfd_getl16 (buffer))
1977 & 0xf800) == 0x1800))
1978 baseaddr = memaddr - 4;
1979 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1980 info) == 0
1981 && (((info->endian == BFD_ENDIAN_BIG
1982 ? bfd_getb16 (buffer)
1983 : bfd_getl16 (buffer))
1984 & 0xf89f) == 0xe800)
1985 && (((info->endian == BFD_ENDIAN_BIG
1986 ? bfd_getb16 (buffer)
1987 : bfd_getl16 (buffer))
1988 & 0x0060) != 0x0060))
1989 baseaddr = memaddr - 2;
1990 else
1991 baseaddr = memaddr;
1992 }
c3c07478 1993 }
0499d65b 1994
6d075bce 1995 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
0499d65b 1996 break;
252b5132
RH
1997 }
1998}
640c0ccd 1999
1bbce132
MR
2000
2001/* Check if the given address is the last word of a MIPS16 PLT entry.
2002 This word is data and depending on the value it may interfere with
2003 disassembly of further PLT entries. We make use of the fact PLT
2004 symbols are marked BSF_SYNTHETIC. */
2005static bfd_boolean
2006is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2007{
2008 if (info->symbols
2009 && info->symbols[0]
2010 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2011 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2012 return TRUE;
2013
2014 return FALSE;
2015}
2016
7fd53920
MR
2017/* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2018
2019enum match_kind
2020{
2021 MATCH_NONE,
2022 MATCH_FULL,
2023 MATCH_SHORT
2024};
2025
47b0e7ad
NC
2026/* Disassemble mips16 instructions. */
2027
2028static int
2029print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2030{
fc8c4fd1 2031 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 2032 int status;
1bbce132 2033 bfd_byte buffer[4];
47b0e7ad 2034 const struct mips_opcode *op, *opend;
c3c07478 2035 struct mips_print_arg_state state;
fc8c4fd1 2036 void *is = info->stream;
7fd53920
MR
2037 bfd_boolean have_second;
2038 unsigned int second;
2039 unsigned int first;
2040 unsigned int full;
47b0e7ad
NC
2041
2042 info->bytes_per_chunk = 2;
2043 info->display_endian = info->endian;
2044 info->insn_info_valid = 1;
2045 info->branch_delay_insns = 0;
2046 info->data_size = 0;
47b0e7ad
NC
2047 info->target = 0;
2048 info->target2 = 0;
2049
c3c07478
RS
2050#define GET_OP(insn, field) \
2051 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1bbce132
MR
2052 /* Decode PLT entry's GOT slot address word. */
2053 if (is_mips16_plt_tail (info, memaddr))
2054 {
2055 info->insn_type = dis_noninsn;
2056 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2057 if (status == 0)
2058 {
2059 unsigned int gotslot;
2060
2061 if (info->endian == BFD_ENDIAN_BIG)
2062 gotslot = bfd_getb32 (buffer);
2063 else
2064 gotslot = bfd_getl32 (buffer);
2065 infprintf (is, ".word\t0x%x", gotslot);
2066
2067 return 4;
2068 }
2069 }
2070 else
2071 {
2072 info->insn_type = dis_nonbranch;
2073 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2074 }
47b0e7ad
NC
2075 if (status != 0)
2076 {
2077 (*info->memory_error_func) (status, memaddr, info);
2078 return -1;
2079 }
2080
47b0e7ad 2081 if (info->endian == BFD_ENDIAN_BIG)
7fd53920 2082 first = bfd_getb16 (buffer);
47b0e7ad 2083 else
7fd53920 2084 first = bfd_getl16 (buffer);
47b0e7ad 2085
7fd53920
MR
2086 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2087 if (status == 0)
47b0e7ad 2088 {
7fd53920 2089 have_second = TRUE;
47b0e7ad 2090 if (info->endian == BFD_ENDIAN_BIG)
7fd53920 2091 second = bfd_getb16 (buffer);
47b0e7ad 2092 else
7fd53920
MR
2093 second = bfd_getl16 (buffer);
2094 full = (first << 16) | second;
2095 }
2096 else
2097 {
2098 have_second = FALSE;
2099 second = 0;
2100 full = first;
47b0e7ad
NC
2101 }
2102
2103 /* FIXME: Should probably use a hash table on the major opcode here. */
2104
2105 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2106 for (op = mips16_opcodes; op < opend; op++)
2107 {
7fd53920 2108 enum match_kind match;
47b0e7ad 2109
11dd08e9
MR
2110 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2111 continue;
2112
7fd53920
MR
2113 if (op->pinfo == INSN_MACRO
2114 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2115 match = MATCH_NONE;
2116 else if (mips_opcode_32bit_p (op))
2117 {
2118 if (have_second
2119 && (full & op->mask) == op->match)
2120 match = MATCH_FULL;
2121 else
2122 match = MATCH_NONE;
2123 }
2124 else if ((first & op->mask) == op->match)
2125 {
2126 match = MATCH_SHORT;
2127 second = 0;
2128 full = first;
2129 }
2130 else if ((first & 0xf800) == 0xf000
2131 && have_second
0674ee5d 2132 && !(op->pinfo2 & INSN2_SHORT_ONLY)
7fd53920
MR
2133 && (second & op->mask) == op->match)
2134 match = MATCH_FULL;
2135 else
2136 match = MATCH_NONE;
47b0e7ad 2137
7fd53920
MR
2138 if (match != MATCH_NONE)
2139 {
2140 const char *s;
47b0e7ad 2141
fc8c4fd1 2142 infprintf (is, "%s", op->name);
47b0e7ad 2143 if (op->args[0] != '\0')
fc8c4fd1 2144 infprintf (is, "\t");
47b0e7ad 2145
c3c07478 2146 init_print_arg_state (&state);
47b0e7ad
NC
2147 for (s = op->args; *s != '\0'; s++)
2148 {
2149 if (*s == ','
2150 && s[1] == 'w'
7fd53920 2151 && GET_OP (full, RX) == GET_OP (full, RY))
47b0e7ad
NC
2152 {
2153 /* Skip the register and the comma. */
2154 ++s;
2155 continue;
2156 }
2157 if (*s == ','
2158 && s[1] == 'v'
7fd53920 2159 && GET_OP (full, RZ) == GET_OP (full, RX))
47b0e7ad
NC
2160 {
2161 /* Skip the register and the comma. */
2162 ++s;
2163 continue;
2164 }
7fd53920
MR
2165 switch (match)
2166 {
2167 case MATCH_FULL:
2168 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2169 second, TRUE, first, s[1] == '(');
2170 break;
2171 case MATCH_SHORT:
2172 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2173 first, FALSE, 0, s[1] == '(');
2174 break;
2175 case MATCH_NONE: /* Stop the compiler complaining. */
2176 break;
2177 }
47b0e7ad
NC
2178 }
2179
9a2c7088 2180 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 2181 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088 2182 info->branch_delay_insns = 1;
26545944
RS
2183 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2184 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
47b0e7ad 2185 {
9a2c7088
MR
2186 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2187 info->insn_type = dis_jsr;
2188 else
47b0e7ad
NC
2189 info->insn_type = dis_branch;
2190 }
26545944 2191 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
9a2c7088 2192 info->insn_type = dis_condbranch;
47b0e7ad 2193
7fd53920 2194 return match == MATCH_FULL ? 4 : 2;
47b0e7ad
NC
2195 }
2196 }
fc8c4fd1 2197#undef GET_OP
47b0e7ad 2198
7fd53920 2199 infprintf (is, "0x%x", first);
47b0e7ad
NC
2200 info->insn_type = dis_noninsn;
2201
7fd53920 2202 return 2;
47b0e7ad
NC
2203}
2204
df58fc94
RS
2205/* Disassemble microMIPS instructions. */
2206
2207static int
2208print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2209{
0c7533d3 2210 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94 2211 const struct mips_opcode *op, *opend;
df58fc94 2212 void *is = info->stream;
df58fc94 2213 bfd_byte buffer[2];
ab902481
RS
2214 unsigned int higher;
2215 unsigned int length;
df58fc94 2216 int status;
ab902481 2217 unsigned int insn;
df58fc94
RS
2218
2219 info->bytes_per_chunk = 2;
2220 info->display_endian = info->endian;
2221 info->insn_info_valid = 1;
2222 info->branch_delay_insns = 0;
2223 info->data_size = 0;
2224 info->insn_type = dis_nonbranch;
2225 info->target = 0;
2226 info->target2 = 0;
2227
2228 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2229 if (status != 0)
2230 {
2231 (*info->memory_error_func) (status, memaddr, info);
2232 return -1;
2233 }
2234
2235 length = 2;
2236
2237 if (info->endian == BFD_ENDIAN_BIG)
2238 insn = bfd_getb16 (buffer);
2239 else
2240 insn = bfd_getl16 (buffer);
2241
100b4f2e 2242 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
df58fc94
RS
2243 {
2244 /* This is a 32-bit microMIPS instruction. */
2245 higher = insn;
2246
2247 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2248 if (status != 0)
2249 {
0c7533d3 2250 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2251 (*info->memory_error_func) (status, memaddr + 2, info);
2252 return -1;
2253 }
2254
2255 if (info->endian == BFD_ENDIAN_BIG)
2256 insn = bfd_getb16 (buffer);
2257 else
2258 insn = bfd_getl16 (buffer);
2259
2260 insn = insn | (higher << 16);
2261
2262 length += 2;
2263 }
2264
2265 /* FIXME: Should probably use a hash table on the major opcode here. */
2266
df58fc94
RS
2267 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2268 for (op = micromips_opcodes; op < opend; op++)
2269 {
2270 if (op->pinfo != INSN_MACRO
2271 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2272 && (insn & op->mask) == op->match
2273 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2274 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2275 {
7361da2c
AB
2276 if (!validate_insn_args (op, decode_micromips_operand, insn))
2277 continue;
2278
0c7533d3 2279 infprintf (is, "%s", op->name);
df58fc94 2280
ab902481 2281 if (op->args[0])
df58fc94 2282 {
ab902481
RS
2283 infprintf (is, "\t");
2284 print_insn_args (info, op, decode_micromips_operand, insn,
7361da2c 2285 memaddr + 1, length);
df58fc94
RS
2286 }
2287
2288 /* Figure out instruction type and branch delay information. */
2289 if ((op->pinfo
2290 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2291 info->branch_delay_insns = 1;
2292 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2293 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2294 {
fc76e730 2295 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
df58fc94
RS
2296 info->insn_type = dis_jsr;
2297 else
2298 info->insn_type = dis_branch;
2299 }
2300 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2301 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2302 {
2303 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2304 info->insn_type = dis_condjsr;
2305 else
2306 info->insn_type = dis_condbranch;
2307 }
2308 else if ((op->pinfo
67dc82bc 2309 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
df58fc94
RS
2310 info->insn_type = dis_dref;
2311
2312 return length;
2313 }
2314 }
df58fc94 2315
0c7533d3 2316 infprintf (is, "0x%x", insn);
df58fc94
RS
2317 info->insn_type = dis_noninsn;
2318
2319 return length;
2320}
2321
2322/* Return 1 if a symbol associated with the location being disassembled
1401d2fe
MR
2323 indicates a compressed mode, either MIPS16 or microMIPS, according to
2324 MICROMIPS_P. We iterate over all the symbols at the address being
2325 considered assuming if at least one of them indicates code compression,
2326 then such code has been genuinely produced here (other symbols could
2327 have been derived from function symbols defined elsewhere or could
2328 define data). Otherwise, return 0. */
df58fc94
RS
2329
2330static bfd_boolean
1401d2fe 2331is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
df58fc94 2332{
df58fc94 2333 int i;
1bbce132
MR
2334 int l;
2335
2336 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2337 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
1401d2fe 2338 && ((!micromips_p
1bbce132 2339 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
1401d2fe 2340 || (micromips_p
1bbce132
MR
2341 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2342 return 1;
2343 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2344 && info->symtab[i]->section == info->section)
2345 {
2346 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
1401d2fe 2347 if ((!micromips_p
1bbce132 2348 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
1401d2fe 2349 || (micromips_p
1bbce132
MR
2350 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2351 return 1;
2352 }
df58fc94
RS
2353
2354 return 0;
2355}
2356
47b0e7ad
NC
2357/* In an environment where we do not know the symbol type of the
2358 instruction we are forced to assume that the low order bit of the
2359 instructions' address may mark it as a mips16 instruction. If we
2360 are single stepping, or the pc is within the disassembled function,
2361 this works. Otherwise, we need a clue. Sometimes. */
2362
2363static int
2364_print_insn_mips (bfd_vma memaddr,
2365 struct disassemble_info *info,
2366 enum bfd_endian endianness)
2367{
2368 bfd_byte buffer[INSNLEN];
2369 int status;
2370
2371 set_default_mips_dis_options (info);
2372 parse_mips_dis_options (info->disassembler_options);
2373
df58fc94
RS
2374 if (info->mach == bfd_mach_mips16)
2375 return print_insn_mips16 (memaddr, info);
2376 if (info->mach == bfd_mach_mips_micromips)
2377 return print_insn_micromips (memaddr, info);
2378
47b0e7ad 2379#if 1
df58fc94 2380 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
2381 /* Only a few tools will work this way. */
2382 if (memaddr & 0x01)
1401d2fe
MR
2383 {
2384 if (micromips_ase)
2385 return print_insn_micromips (memaddr, info);
2386 else
2387 return print_insn_mips16 (memaddr, info);
2388 }
47b0e7ad
NC
2389#endif
2390
2391#if SYMTAB_AVAILABLE
1401d2fe
MR
2392 if (is_compressed_mode_p (info, TRUE))
2393 return print_insn_micromips (memaddr, info);
2394 if (is_compressed_mode_p (info, FALSE))
2395 return print_insn_mips16 (memaddr, info);
47b0e7ad
NC
2396#endif
2397
2398 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2399 if (status == 0)
2400 {
fc8c4fd1 2401 int insn;
47b0e7ad
NC
2402
2403 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 2404 insn = bfd_getb32 (buffer);
47b0e7ad 2405 else
fc8c4fd1 2406 insn = bfd_getl32 (buffer);
47b0e7ad
NC
2407
2408 return print_insn_mips (memaddr, insn, info);
2409 }
2410 else
2411 {
2412 (*info->memory_error_func) (status, memaddr, info);
2413 return -1;
2414 }
2415}
2416
2417int
2418print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2419{
2420 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2421}
2422
2423int
2424print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2425{
2426 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2427}
2428\f
640c0ccd 2429void
47b0e7ad 2430print_mips_disassembler_options (FILE *stream)
640c0ccd 2431{
4a9a3c54 2432 unsigned int i;
640c0ccd
CD
2433
2434 fprintf (stream, _("\n\
2435The following MIPS specific disassembler options are supported for use\n\
2436with the -M switch (multiple options should be separated by commas):\n"));
2437
4edbb8e3 2438 fprintf (stream, _("\n\
6725647c 2439 msa Recognize MSA instructions.\n"));
4edbb8e3 2440
b015e599 2441 fprintf (stream, _("\n\
6725647c 2442 virt Recognize the virtualization ASE instructions.\n"));
b015e599 2443
7d64c587 2444 fprintf (stream, _("\n\
6725647c
MR
2445 xpa Recognize the eXtended Physical Address (XPA)\n\
2446 ASE instructions.\n"));
7d64c587 2447
640c0ccd 2448 fprintf (stream, _("\n\
6725647c 2449 gpr-names=ABI Print GPR names according to specified ABI.\n\
640c0ccd
CD
2450 Default: based on binary being disassembled.\n"));
2451
2452 fprintf (stream, _("\n\
2453 fpr-names=ABI Print FPR names according to specified ABI.\n\
2454 Default: numeric.\n"));
2455
2456 fprintf (stream, _("\n\
2457 cp0-names=ARCH Print CP0 register names according to\n\
2458 specified architecture.\n\
2459 Default: based on binary being disassembled.\n"));
2460
af7ee8bf
CD
2461 fprintf (stream, _("\n\
2462 hwr-names=ARCH Print HWR names according to specified \n\
6725647c 2463 architecture.\n\
af7ee8bf
CD
2464 Default: based on binary being disassembled.\n"));
2465
640c0ccd
CD
2466 fprintf (stream, _("\n\
2467 reg-names=ABI Print GPR and FPR names according to\n\
2468 specified ABI.\n"));
2469
2470 fprintf (stream, _("\n\
af7ee8bf 2471 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
2472 specified architecture.\n"));
2473
2474 fprintf (stream, _("\n\
2475 For the options above, the following values are supported for \"ABI\":\n\
2476 "));
4a9a3c54 2477 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
2478 fprintf (stream, " %s", mips_abi_choices[i].name);
2479 fprintf (stream, _("\n"));
2480
2481 fprintf (stream, _("\n\
2482 For the options above, The following values are supported for \"ARCH\":\n\
2483 "));
4a9a3c54 2484 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
2485 if (*mips_arch_choices[i].name != '\0')
2486 fprintf (stream, " %s", mips_arch_choices[i].name);
2487 fprintf (stream, _("\n"));
2488
2489 fprintf (stream, _("\n"));
2490}
This page took 1.086964 seconds and 4 git commands to generate.