Automatic date update in version.in
[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. */
d301a56b 661 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 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
CD
841 }
842#endif
8184783a
MR
843
844 /* Update settings according to the ELF file header flags. */
845 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
846 {
5e7fc731
MR
847 struct bfd *abfd = info->section->owner;
848 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
849 Elf_Internal_ABIFlags_v0 *abiflags = bfd_mips_elf_get_abiflags (abfd);
8184783a 850
8184783a
MR
851 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
852 if (is_newabi (header))
853 mips_gpr_names = mips_gpr_names_newabi;
854 /* If a microMIPS binary, then don't use MIPS16 bindings. */
855 micromips_ase = is_micromips (header);
5e7fc731
MR
856 /* OR in any extra ASE flags set in ELF file structures. */
857 if (abiflags)
858 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
859 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
860 mips_ase |= ASE_MDMX;
8184783a 861 }
640c0ccd
CD
862}
863
47b0e7ad
NC
864static void
865parse_mips_dis_option (const char *option, unsigned int len)
640c0ccd
CD
866{
867 unsigned int i, optionlen, vallen;
868 const char *val;
869 const struct mips_abi_choice *chosen_abi;
870 const struct mips_arch_choice *chosen_arch;
871
986e18a5 872 /* Try to match options that are simple flags */
0112cd26 873 if (CONST_STRNEQ (option, "no-aliases"))
986e18a5
FF
874 {
875 no_aliases = 1;
876 return;
877 }
b015e599 878
4edbb8e3
CF
879 if (CONST_STRNEQ (option, "msa"))
880 {
881 mips_ase |= ASE_MSA;
ae52f483
AB
882 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
883 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
7361da2c
AB
884 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
885 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
4edbb8e3
CF
886 mips_ase |= ASE_MSA64;
887 return;
888 }
889
b015e599
AP
890 if (CONST_STRNEQ (option, "virt"))
891 {
d301a56b 892 mips_ase |= ASE_VIRT;
ae52f483
AB
893 if (mips_isa & ISA_MIPS64R2
894 || mips_isa & ISA_MIPS64R3
7361da2c
AB
895 || mips_isa & ISA_MIPS64R5
896 || mips_isa & ISA_MIPS64R6)
d301a56b 897 mips_ase |= ASE_VIRT64;
b015e599
AP
898 return;
899 }
7d64c587
AB
900
901 if (CONST_STRNEQ (option, "xpa"))
902 {
903 mips_ase |= ASE_XPA;
904 return;
905 }
43e65147
L
906
907
640c0ccd
CD
908 /* Look for the = that delimits the end of the option name. */
909 for (i = 0; i < len; i++)
47b0e7ad
NC
910 if (option[i] == '=')
911 break;
912
640c0ccd
CD
913 if (i == 0) /* Invalid option: no name before '='. */
914 return;
915 if (i == len) /* Invalid option: no '='. */
916 return;
917 if (i == (len - 1)) /* Invalid option: no value after '='. */
918 return;
919
920 optionlen = i;
921 val = option + (optionlen + 1);
922 vallen = len - (optionlen + 1);
923
47b0e7ad
NC
924 if (strncmp ("gpr-names", option, optionlen) == 0
925 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
926 {
927 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 928 if (chosen_abi != NULL)
640c0ccd
CD
929 mips_gpr_names = chosen_abi->gpr_names;
930 return;
931 }
932
47b0e7ad
NC
933 if (strncmp ("fpr-names", option, optionlen) == 0
934 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
935 {
936 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 937 if (chosen_abi != NULL)
640c0ccd
CD
938 mips_fpr_names = chosen_abi->fpr_names;
939 return;
940 }
941
47b0e7ad
NC
942 if (strncmp ("cp0-names", option, optionlen) == 0
943 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
944 {
945 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
946 if (chosen_arch != NULL)
947 {
948 mips_cp0_names = chosen_arch->cp0_names;
949 mips_cp0sel_names = chosen_arch->cp0sel_names;
950 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
951 }
640c0ccd
CD
952 return;
953 }
954
dc76d757
AB
955 if (strncmp ("cp1-names", option, optionlen) == 0
956 && strlen ("cp1-names") == optionlen)
957 {
958 chosen_arch = choose_arch_by_name (val, vallen);
959 if (chosen_arch != NULL)
960 mips_cp1_names = chosen_arch->cp1_names;
961 return;
962 }
963
47b0e7ad
NC
964 if (strncmp ("hwr-names", option, optionlen) == 0
965 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
966 {
967 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 968 if (chosen_arch != NULL)
af7ee8bf
CD
969 mips_hwr_names = chosen_arch->hwr_names;
970 return;
971 }
972
47b0e7ad
NC
973 if (strncmp ("reg-names", option, optionlen) == 0
974 && strlen ("reg-names") == optionlen)
640c0ccd
CD
975 {
976 /* We check both ABI and ARCH here unconditionally, so
977 that "numeric" will do the desirable thing: select
978 numeric register names for all registers. Other than
979 that, a given name probably won't match both. */
980 chosen_abi = choose_abi_by_name (val, vallen);
981 if (chosen_abi != NULL)
982 {
bbcc0807
CD
983 mips_gpr_names = chosen_abi->gpr_names;
984 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
985 }
986 chosen_arch = choose_arch_by_name (val, vallen);
987 if (chosen_arch != NULL)
988 {
bbcc0807
CD
989 mips_cp0_names = chosen_arch->cp0_names;
990 mips_cp0sel_names = chosen_arch->cp0sel_names;
991 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 992 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 993 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
994 }
995 return;
996 }
997
998 /* Invalid option. */
999}
1000
47b0e7ad
NC
1001static void
1002parse_mips_dis_options (const char *options)
640c0ccd
CD
1003{
1004 const char *option_end;
1005
1006 if (options == NULL)
1007 return;
1008
1009 while (*options != '\0')
1010 {
1011 /* Skip empty options. */
1012 if (*options == ',')
1013 {
1014 options++;
1015 continue;
1016 }
1017
1018 /* We know that *options is neither NUL or a comma. */
1019 option_end = options + 1;
1020 while (*option_end != ',' && *option_end != '\0')
1021 option_end++;
1022
1023 parse_mips_dis_option (options, option_end - options);
1024
1025 /* Go on to the next one. If option_end points to a comma, it
1026 will be skipped above. */
1027 options = option_end;
1028 }
1029}
1030
bbcc0807 1031static const struct mips_cp0sel_name *
47b0e7ad
NC
1032lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1033 unsigned int len,
1034 unsigned int cp0reg,
1035 unsigned int sel)
bbcc0807
CD
1036{
1037 unsigned int i;
1038
1039 for (i = 0; i < len; i++)
1040 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1041 return &names[i];
1042 return NULL;
1043}
ab902481
RS
1044
1045/* Print register REGNO, of type TYPE, for instruction OPCODE. */
aa5f19f2 1046
794ac9d0 1047static void
ab902481
RS
1048print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1049 enum mips_reg_operand_type type, int regno)
252b5132 1050{
ab902481
RS
1051 switch (type)
1052 {
1053 case OP_REG_GP:
1054 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1055 break;
440cc0bc 1056
ab902481
RS
1057 case OP_REG_FP:
1058 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1059 break;
252b5132 1060
ab902481
RS
1061 case OP_REG_CCC:
1062 if (opcode->pinfo & (FP_D | FP_S))
1063 info->fprintf_func (info->stream, "$fcc%d", regno);
1064 else
1065 info->fprintf_func (info->stream, "$cc%d", regno);
1066 break;
794ac9d0 1067
ab902481
RS
1068 case OP_REG_VEC:
1069 if (opcode->membership & INSN_5400)
1070 info->fprintf_func (info->stream, "$f%d", regno);
1071 else
1072 info->fprintf_func (info->stream, "$v%d", regno);
1073 break;
794ac9d0 1074
ab902481
RS
1075 case OP_REG_ACC:
1076 info->fprintf_func (info->stream, "$ac%d", regno);
1077 break;
794ac9d0 1078
ab902481
RS
1079 case OP_REG_COPRO:
1080 if (opcode->name[strlen (opcode->name) - 1] == '0')
1081 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
dc76d757
AB
1082 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1083 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
ab902481
RS
1084 else
1085 info->fprintf_func (info->stream, "$%d", regno);
1086 break;
8b082fb1 1087
ab902481
RS
1088 case OP_REG_HW:
1089 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1090 break;
14daeee3
RS
1091
1092 case OP_REG_VF:
1093 info->fprintf_func (info->stream, "$vf%d", regno);
1094 break;
1095
1096 case OP_REG_VI:
1097 info->fprintf_func (info->stream, "$vi%d", regno);
1098 break;
1099
1100 case OP_REG_R5900_I:
1101 info->fprintf_func (info->stream, "$I");
1102 break;
1103
1104 case OP_REG_R5900_Q:
1105 info->fprintf_func (info->stream, "$Q");
1106 break;
1107
1108 case OP_REG_R5900_R:
1109 info->fprintf_func (info->stream, "$R");
1110 break;
1111
1112 case OP_REG_R5900_ACC:
1113 info->fprintf_func (info->stream, "$ACC");
1114 break;
4edbb8e3
CF
1115
1116 case OP_REG_MSA:
1117 info->fprintf_func (info->stream, "$w%d", regno);
1118 break;
1119
1120 case OP_REG_MSA_CTRL:
1121 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1122 break;
1123
ab902481
RS
1124 }
1125}
1126\f
1127/* Used to track the state carried over from previous operands in
1128 an instruction. */
1129struct mips_print_arg_state {
1130 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1131 where the value is known to be unsigned and small. */
1132 unsigned int last_int;
1133
1134 /* The type and number of the last OP_REG seen. We only use this for
1135 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1136 enum mips_reg_operand_type last_reg_type;
1137 unsigned int last_regno;
7361da2c
AB
1138 unsigned int dest_regno;
1139 unsigned int seen_dest;
ab902481 1140};
fd25c5a9 1141
ab902481 1142/* Initialize STATE for the start of an instruction. */
fd25c5a9 1143
ab902481
RS
1144static inline void
1145init_print_arg_state (struct mips_print_arg_state *state)
1146{
1147 memset (state, 0, sizeof (*state));
1148}
fd25c5a9 1149
14daeee3
RS
1150/* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1151 whose value is given by UVAL. */
1152
1153static void
1154print_vu0_channel (struct disassemble_info *info,
1155 const struct mips_operand *operand, unsigned int uval)
1156{
1157 if (operand->size == 4)
1158 info->fprintf_func (info->stream, "%s%s%s%s",
1159 uval & 8 ? "x" : "",
1160 uval & 4 ? "y" : "",
1161 uval & 2 ? "z" : "",
1162 uval & 1 ? "w" : "");
1163 else if (operand->size == 2)
1164 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1165 else
1166 abort ();
1167}
1168
7361da2c
AB
1169/* Record information about a register operand. */
1170
1171static void
1172mips_seen_register (struct mips_print_arg_state *state,
1173 unsigned int regno,
1174 enum mips_reg_operand_type reg_type)
1175{
1176 state->last_reg_type = reg_type;
1177 state->last_regno = regno;
1178
1179 if (!state->seen_dest)
1180 {
1181 state->seen_dest = 1;
1182 state->dest_regno = regno;
1183 }
1184}
1185
ab902481
RS
1186/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1187 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1188 the base address for OP_PCREL operands. */
fd25c5a9 1189
ab902481
RS
1190static void
1191print_insn_arg (struct disassemble_info *info,
1192 struct mips_print_arg_state *state,
1193 const struct mips_opcode *opcode,
1194 const struct mips_operand *operand,
1195 bfd_vma base_pc,
1196 unsigned int uval)
1197{
1198 const fprintf_ftype infprintf = info->fprintf_func;
1199 void *is = info->stream;
fd25c5a9 1200
ab902481
RS
1201 switch (operand->type)
1202 {
1203 case OP_INT:
1204 {
1205 const struct mips_int_operand *int_op;
fd25c5a9 1206
ab902481
RS
1207 int_op = (const struct mips_int_operand *) operand;
1208 uval = mips_decode_int_operand (int_op, uval);
1209 state->last_int = uval;
1210 if (int_op->print_hex)
1211 infprintf (is, "0x%x", uval);
1212 else
1213 infprintf (is, "%d", uval);
1214 }
1215 break;
fd25c5a9 1216
ab902481
RS
1217 case OP_MAPPED_INT:
1218 {
1219 const struct mips_mapped_int_operand *mint_op;
fd25c5a9 1220
ab902481
RS
1221 mint_op = (const struct mips_mapped_int_operand *) operand;
1222 uval = mint_op->int_map[uval];
1223 state->last_int = uval;
1224 if (mint_op->print_hex)
1225 infprintf (is, "0x%x", uval);
1226 else
1227 infprintf (is, "%d", uval);
1228 }
1229 break;
fd25c5a9 1230
ab902481
RS
1231 case OP_MSB:
1232 {
1233 const struct mips_msb_operand *msb_op;
dec0624d 1234
ab902481
RS
1235 msb_op = (const struct mips_msb_operand *) operand;
1236 uval += msb_op->bias;
1237 if (msb_op->add_lsb)
1238 uval -= state->last_int;
1239 infprintf (is, "0x%x", uval);
1240 }
1241 break;
dec0624d 1242
ab902481 1243 case OP_REG:
0f35dbc4 1244 case OP_OPTIONAL_REG:
ab902481
RS
1245 {
1246 const struct mips_reg_operand *reg_op;
fd25c5a9 1247
ab902481 1248 reg_op = (const struct mips_reg_operand *) operand;
fc76e730 1249 uval = mips_decode_reg_operand (reg_op, uval);
ab902481 1250 print_reg (info, opcode, reg_op->reg_type, uval);
fd25c5a9 1251
7361da2c 1252 mips_seen_register (state, uval, reg_op->reg_type);
ab902481
RS
1253 }
1254 break;
61cc0267 1255
ab902481
RS
1256 case OP_REG_PAIR:
1257 {
1258 const struct mips_reg_pair_operand *pair_op;
1259
1260 pair_op = (const struct mips_reg_pair_operand *) operand;
1261 print_reg (info, opcode, pair_op->reg_type,
1262 pair_op->reg1_map[uval]);
1263 infprintf (is, ",");
1264 print_reg (info, opcode, pair_op->reg_type,
1265 pair_op->reg2_map[uval]);
1266 }
1267 break;
61cc0267 1268
ab902481
RS
1269 case OP_PCREL:
1270 {
1271 const struct mips_pcrel_operand *pcrel_op;
61cc0267 1272
ab902481
RS
1273 pcrel_op = (const struct mips_pcrel_operand *) operand;
1274 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
61cc0267 1275
ab902481
RS
1276 /* Preserve the ISA bit for the GDB disassembler,
1277 otherwise clear it. */
1278 if (info->flavour != bfd_target_unknown_flavour)
1279 info->target &= -2;
61cc0267 1280
ab902481
RS
1281 (*info->print_address_func) (info->target, info);
1282 }
1283 break;
794ac9d0 1284
ab902481
RS
1285 case OP_PERF_REG:
1286 infprintf (is, "%d", uval);
1287 break;
794ac9d0 1288
ab902481
RS
1289 case OP_ADDIUSP_INT:
1290 {
1291 int sval;
794ac9d0 1292
ab902481
RS
1293 sval = mips_signed_operand (operand, uval) * 4;
1294 if (sval >= -8 && sval < 8)
1295 sval ^= 0x400;
1296 infprintf (is, "%d", sval);
1297 break;
1298 }
794ac9d0 1299
ab902481
RS
1300 case OP_CLO_CLZ_DEST:
1301 {
1302 unsigned int reg1, reg2;
1303
1304 reg1 = uval & 31;
1305 reg2 = uval >> 5;
1306 /* If one is zero use the other. */
1307 if (reg1 == reg2 || reg2 == 0)
1308 infprintf (is, "%s", mips_gpr_names[reg1]);
1309 else if (reg1 == 0)
1310 infprintf (is, "%s", mips_gpr_names[reg2]);
1311 else
1312 /* Bogus, result depends on processor. */
1313 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1314 mips_gpr_names[reg2]);
1315 }
1316 break;
794ac9d0 1317
7361da2c
AB
1318 case OP_SAME_RS_RT:
1319 case OP_CHECK_PREV:
1320 case OP_NON_ZERO_REG:
1321 {
1322 print_reg (info, opcode, OP_REG_GP, uval & 31);
1323 mips_seen_register (state, uval, OP_REG_GP);
1324 }
1325 break;
1326
ab902481
RS
1327 case OP_LWM_SWM_LIST:
1328 if (operand->size == 2)
1329 {
1330 if (uval == 0)
1331 infprintf (is, "%s,%s",
1332 mips_gpr_names[16],
1333 mips_gpr_names[31]);
1334 else
1335 infprintf (is, "%s-%s,%s",
1336 mips_gpr_names[16],
1337 mips_gpr_names[16 + uval],
1338 mips_gpr_names[31]);
1339 }
1340 else
1341 {
1342 int s_reg_encode;
794ac9d0 1343
ab902481
RS
1344 s_reg_encode = uval & 0xf;
1345 if (s_reg_encode != 0)
1346 {
1347 if (s_reg_encode == 1)
1348 infprintf (is, "%s", mips_gpr_names[16]);
1349 else if (s_reg_encode < 9)
1350 infprintf (is, "%s-%s",
1351 mips_gpr_names[16],
1352 mips_gpr_names[15 + s_reg_encode]);
1353 else if (s_reg_encode == 9)
1354 infprintf (is, "%s-%s,%s",
1355 mips_gpr_names[16],
1356 mips_gpr_names[23],
1357 mips_gpr_names[30]);
1358 else
1359 infprintf (is, "UNKNOWN");
1360 }
794ac9d0 1361
ab902481
RS
1362 if (uval & 0x10) /* For ra. */
1363 {
1364 if (s_reg_encode == 0)
1365 infprintf (is, "%s", mips_gpr_names[31]);
1366 else
1367 infprintf (is, ",%s", mips_gpr_names[31]);
1368 }
1369 }
1370 break;
794ac9d0 1371
c3c07478
RS
1372 case OP_ENTRY_EXIT_LIST:
1373 {
1374 const char *sep;
1375 unsigned int amask, smask;
1376
1377 sep = "";
1378 amask = (uval >> 3) & 7;
1379 if (amask > 0 && amask < 5)
1380 {
1381 infprintf (is, "%s", mips_gpr_names[4]);
1382 if (amask > 1)
1383 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1384 sep = ",";
1385 }
1386
1387 smask = (uval >> 1) & 3;
1388 if (smask == 3)
1389 {
1390 infprintf (is, "%s??", sep);
1391 sep = ",";
1392 }
1393 else if (smask > 0)
1394 {
1395 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1396 if (smask > 1)
1397 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1398 sep = ",";
1399 }
1400
1401 if (uval & 1)
1402 {
1403 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1404 sep = ",";
1405 }
1406
1407 if (amask == 5 || amask == 6)
1408 {
1409 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1410 if (amask == 6)
1411 infprintf (is, "-%s", mips_fpr_names[1]);
1412 }
1413 }
1414 break;
1415
1416 case OP_SAVE_RESTORE_LIST:
1417 /* Should be handled by the caller due to extend behavior. */
1418 abort ();
1419
ab902481
RS
1420 case OP_MDMX_IMM_REG:
1421 {
1422 unsigned int vsel;
794ac9d0 1423
ab902481
RS
1424 vsel = uval >> 5;
1425 uval &= 31;
1426 if ((vsel & 0x10) == 0)
794ac9d0 1427 {
ab902481
RS
1428 int fmt;
1429
1430 vsel &= 0x0f;
1431 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1432 if ((vsel & 1) == 0)
1433 break;
1434 print_reg (info, opcode, OP_REG_VEC, uval);
1435 infprintf (is, "[%d]", vsel >> 1);
794ac9d0 1436 }
ab902481
RS
1437 else if ((vsel & 0x08) == 0)
1438 print_reg (info, opcode, OP_REG_VEC, uval);
1439 else
1440 infprintf (is, "0x%x", uval);
1441 }
1442 break;
794ac9d0 1443
ab902481
RS
1444 case OP_REPEAT_PREV_REG:
1445 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1446 break;
794ac9d0 1447
ab902481 1448 case OP_REPEAT_DEST_REG:
7361da2c
AB
1449 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1450 break;
794ac9d0 1451
ab902481
RS
1452 case OP_PC:
1453 infprintf (is, "$pc");
1454 break;
14daeee3
RS
1455
1456 case OP_VU0_SUFFIX:
1457 case OP_VU0_MATCH_SUFFIX:
1458 print_vu0_channel (info, operand, uval);
1459 break;
4edbb8e3
CF
1460
1461 case OP_IMM_INDEX:
1462 infprintf (is, "[%d]", uval);
1463 break;
1464
1465 case OP_REG_INDEX:
1466 infprintf (is, "[");
1467 print_reg (info, opcode, OP_REG_GP, uval);
1468 infprintf (is, "]");
1469 break;
ab902481
RS
1470 }
1471}
794ac9d0 1472
7361da2c
AB
1473/* Validate the arguments for INSN, which is described by OPCODE.
1474 Use DECODE_OPERAND to get the encoding of each operand. */
1475
1476static bfd_boolean
1477validate_insn_args (const struct mips_opcode *opcode,
1478 const struct mips_operand *(*decode_operand) (const char *),
1479 unsigned int insn)
1480{
1481 struct mips_print_arg_state state;
1482 const struct mips_operand *operand;
1483 const char *s;
1484 unsigned int uval;
1485
1486 init_print_arg_state (&state);
1487 for (s = opcode->args; *s; ++s)
1488 {
1489 switch (*s)
1490 {
1491 case ',':
1492 case '(':
1493 case ')':
1494 break;
1495
1496 case '#':
1497 ++s;
1498 break;
1499
1500 default:
1501 operand = decode_operand (s);
1502
1503 if (operand)
1504 {
1505 uval = mips_extract_operand (operand, insn);
1506 switch (operand->type)
1507 {
1508 case OP_REG:
1509 case OP_OPTIONAL_REG:
1510 {
1511 const struct mips_reg_operand *reg_op;
1512
1513 reg_op = (const struct mips_reg_operand *) operand;
1514 uval = mips_decode_reg_operand (reg_op, uval);
1515 mips_seen_register (&state, uval, reg_op->reg_type);
1516 }
1517 break;
1518
1519 case OP_SAME_RS_RT:
1520 {
1521 unsigned int reg1, reg2;
1522
1523 reg1 = uval & 31;
1524 reg2 = uval >> 5;
1525
1526 if (reg1 != reg2 || reg1 == 0)
1527 return FALSE;
1528 }
1529 break;
1530
1531 case OP_CHECK_PREV:
1532 {
1533 const struct mips_check_prev_operand *prev_op;
1534
1535 prev_op = (const struct mips_check_prev_operand *) operand;
1536
1537 if (!prev_op->zero_ok && uval == 0)
1538 return FALSE;
1539
1540 if (((prev_op->less_than_ok && uval < state.last_regno)
1541 || (prev_op->greater_than_ok && uval > state.last_regno)
1542 || (prev_op->equal_ok && uval == state.last_regno)))
1543 break;
1544
1545 return FALSE;
1546 }
1547
1548 case OP_NON_ZERO_REG:
1549 {
1550 if (uval == 0)
1551 return FALSE;
1552 }
1553 break;
1554
1555 case OP_INT:
1556 case OP_MAPPED_INT:
1557 case OP_MSB:
1558 case OP_REG_PAIR:
1559 case OP_PCREL:
1560 case OP_PERF_REG:
1561 case OP_ADDIUSP_INT:
1562 case OP_CLO_CLZ_DEST:
1563 case OP_LWM_SWM_LIST:
1564 case OP_ENTRY_EXIT_LIST:
1565 case OP_MDMX_IMM_REG:
1566 case OP_REPEAT_PREV_REG:
1567 case OP_REPEAT_DEST_REG:
1568 case OP_PC:
1569 case OP_VU0_SUFFIX:
1570 case OP_VU0_MATCH_SUFFIX:
1571 case OP_IMM_INDEX:
1572 case OP_REG_INDEX:
1573 break;
1574
1575 case OP_SAVE_RESTORE_LIST:
1576 /* Should be handled by the caller due to extend behavior. */
1577 abort ();
1578 }
1579 }
1580 if (*s == 'm' || *s == '+' || *s == '-')
1581 ++s;
1582 }
1583 }
1584 return TRUE;
1585}
1586
ab902481
RS
1587/* Print the arguments for INSN, which is described by OPCODE.
1588 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
7361da2c
AB
1589 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1590 operand is for a branch or jump. */
af7ee8bf 1591
ab902481
RS
1592static void
1593print_insn_args (struct disassemble_info *info,
1594 const struct mips_opcode *opcode,
1595 const struct mips_operand *(*decode_operand) (const char *),
7361da2c 1596 unsigned int insn, bfd_vma insn_pc, unsigned int length)
ab902481
RS
1597{
1598 const fprintf_ftype infprintf = info->fprintf_func;
1599 void *is = info->stream;
1600 struct mips_print_arg_state state;
1601 const struct mips_operand *operand;
1602 const char *s;
794ac9d0 1603
ab902481
RS
1604 init_print_arg_state (&state);
1605 for (s = opcode->args; *s; ++s)
1606 {
1607 switch (*s)
1608 {
1609 case ',':
1610 case '(':
1611 case ')':
1612 infprintf (is, "%c", *s);
794ac9d0
CD
1613 break;
1614
14daeee3
RS
1615 case '#':
1616 ++s;
1617 infprintf (is, "%c%c", *s, *s);
1618 break;
1619
ab902481
RS
1620 default:
1621 operand = decode_operand (s);
1622 if (!operand)
fa7616a4 1623 {
ab902481
RS
1624 /* xgettext:c-format */
1625 infprintf (is,
1626 _("# internal error, undefined operand in `%s %s'"),
1627 opcode->name, opcode->args);
1628 return;
1629 }
1630 if (operand->type == OP_REG
1631 && s[1] == ','
1632 && s[2] == 'H'
1633 && opcode->name[strlen (opcode->name) - 1] == '0')
1634 {
1635 /* Coprocessor register 0 with sel field (MT ASE). */
1636 const struct mips_cp0sel_name *n;
1637 unsigned int reg, sel;
1638
1639 reg = mips_extract_operand (operand, insn);
1640 s += 2;
1641 operand = decode_operand (s);
1642 sel = mips_extract_operand (operand, insn);
1643
1644 /* CP0 register including 'sel' code for mftc0, to be
1645 printed textually if known. If not known, print both
1646 CP0 register name and sel numerically since CP0 register
1647 with sel 0 may have a name unrelated to register being
1648 printed. */
1649 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1650 mips_cp0sel_names_len,
1651 reg, sel);
1652 if (n != NULL)
1653 infprintf (is, "%s", n->name);
fa7616a4 1654 else
ab902481 1655 infprintf (is, "$%d,%d", reg, sel);
fa7616a4 1656 }
794ac9d0 1657 else
7361da2c
AB
1658 {
1659 bfd_vma base_pc = insn_pc;
1660
1661 /* Adjust the PC relative base so that branch/jump insns use
1662 the following PC as the base but genuinely PC relative
1663 operands use the current PC. */
1664 if (operand->type == OP_PCREL)
1665 {
1666 const struct mips_pcrel_operand *pcrel_op;
1667
1668 pcrel_op = (const struct mips_pcrel_operand *) operand;
1669 /* The include_isa_bit flag is sufficient to distinguish
1670 branch/jump from other PC relative operands. */
1671 if (pcrel_op->include_isa_bit)
1672 base_pc += length;
1673 }
1674
1675 print_insn_arg (info, &state, opcode, operand, base_pc,
1676 mips_extract_operand (operand, insn));
1677 }
1678 if (*s == 'm' || *s == '+' || *s == '-')
ab902481 1679 ++s;
794ac9d0 1680 break;
af7ee8bf 1681 }
252b5132
RH
1682 }
1683}
1684\f
252b5132
RH
1685/* Print the mips instruction at address MEMADDR in debugged memory,
1686 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1687 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1688 this is little-endian code. */
1689
1690static int
47b0e7ad 1691print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1692 int word,
47b0e7ad 1693 struct disassemble_info *info)
252b5132 1694{
ab902481
RS
1695#define GET_OP(insn, field) \
1696 (((insn) >> OP_SH_##field) & OP_MASK_##field)
fc8c4fd1
MR
1697 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1698 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1699 const struct mips_opcode *op;
b34976b6 1700 static bfd_boolean init = 0;
fc8c4fd1 1701 void *is = info->stream;
252b5132
RH
1702
1703 /* Build a hash table to shorten the search time. */
1704 if (! init)
1705 {
1706 unsigned int i;
1707
1708 for (i = 0; i <= OP_MASK_OP; i++)
1709 {
1710 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1711 {
986e18a5 1712 if (op->pinfo == INSN_MACRO
9e836e3d 1713 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1714 continue;
fc8c4fd1 1715 if (i == GET_OP (op->match, OP))
252b5132
RH
1716 {
1717 mips_hash[i] = op;
1718 break;
1719 }
1720 }
7f6621cd 1721 }
252b5132
RH
1722
1723 init = 1;
1724 }
1725
aa5f19f2 1726 info->bytes_per_chunk = INSNLEN;
252b5132 1727 info->display_endian = info->endian;
9bb28706
CD
1728 info->insn_info_valid = 1;
1729 info->branch_delay_insns = 0;
def7143b 1730 info->data_size = 0;
9bb28706
CD
1731 info->insn_type = dis_nonbranch;
1732 info->target = 0;
1733 info->target2 = 0;
252b5132 1734
fc8c4fd1 1735 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1736 if (op != NULL)
1737 {
1738 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1739 {
43e65147 1740 if (op->pinfo != INSN_MACRO
9e836e3d 1741 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1742 && (word & op->mask) == op->match)
252b5132 1743 {
7361da2c 1744 /* We always disassemble the jalx instruction, except for MIPS r6. */
d301a56b 1745 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
7361da2c
AB
1746 && (strcmp (op->name, "jalx")
1747 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1748 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
252b5132
RH
1749 continue;
1750
9bb28706
CD
1751 /* Figure out instruction type and branch delay information. */
1752 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1753 {
fc76e730 1754 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
9bb28706
CD
1755 info->insn_type = dis_jsr;
1756 else
1757 info->insn_type = dis_branch;
1758 info->branch_delay_insns = 1;
1759 }
1760 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1761 | INSN_COND_BRANCH_LIKELY)) != 0)
1762 {
c680e7f6 1763 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1764 info->insn_type = dis_condjsr;
1765 else
1766 info->insn_type = dis_condbranch;
1767 info->branch_delay_insns = 1;
1768 }
1769 else if ((op->pinfo & (INSN_STORE_MEMORY
67dc82bc 1770 | INSN_LOAD_MEMORY)) != 0)
9bb28706
CD
1771 info->insn_type = dis_dref;
1772
7361da2c
AB
1773 if (!validate_insn_args (op, decode_mips_operand, word))
1774 continue;
1775
fc8c4fd1 1776 infprintf (is, "%s", op->name);
14daeee3
RS
1777 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1778 {
1779 unsigned int uval;
1780
1781 infprintf (is, ".");
1782 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1783 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1784 }
252b5132 1785
ab902481 1786 if (op->args[0])
252b5132 1787 {
fc8c4fd1 1788 infprintf (is, "\t");
ab902481 1789 print_insn_args (info, op, decode_mips_operand, word,
7361da2c 1790 memaddr, 4);
252b5132
RH
1791 }
1792
aa5f19f2 1793 return INSNLEN;
252b5132
RH
1794 }
1795 }
1796 }
fc8c4fd1 1797#undef GET_OP
252b5132
RH
1798
1799 /* Handle undefined instructions. */
9bb28706 1800 info->insn_type = dis_noninsn;
fc8c4fd1 1801 infprintf (is, "0x%x", word);
aa5f19f2 1802 return INSNLEN;
252b5132 1803}
aa5f19f2 1804\f
252b5132
RH
1805/* Disassemble an operand for a mips16 instruction. */
1806
1807static void
c3c07478
RS
1808print_mips16_insn_arg (struct disassemble_info *info,
1809 struct mips_print_arg_state *state,
1810 const struct mips_opcode *opcode,
1811 char type, bfd_vma memaddr,
1812 unsigned insn, bfd_boolean use_extend,
1813 unsigned extend, bfd_boolean is_offset)
252b5132 1814{
fc8c4fd1
MR
1815 const fprintf_ftype infprintf = info->fprintf_func;
1816 void *is = info->stream;
c3c07478
RS
1817 const struct mips_operand *operand, *ext_operand;
1818 unsigned int uval;
1819 bfd_vma baseaddr;
1820
1821 if (!use_extend)
1822 extend = 0;
fc8c4fd1 1823
252b5132
RH
1824 switch (type)
1825 {
1826 case ',':
1827 case '(':
1828 case ')':
fc8c4fd1 1829 infprintf (is, "%c", type);
252b5132
RH
1830 break;
1831
c3c07478
RS
1832 default:
1833 operand = decode_mips16_operand (type, FALSE);
1834 if (!operand)
1835 {
1836 /* xgettext:c-format */
1837 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1838 opcode->name, opcode->args);
1839 return;
1840 }
252b5132 1841
c3c07478
RS
1842 if (operand->type == OP_SAVE_RESTORE_LIST)
1843 {
5f5c6e03 1844 /* Handle this case here because of the complex interaction
c3c07478
RS
1845 with the EXTEND opcode. */
1846 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1847 const char *sep;
252b5132 1848
c3c07478
RS
1849 amask = extend & 0xf;
1850 if (amask == MIPS16_ALL_ARGS)
1851 {
1852 nargs = 4;
1853 nstatics = 0;
1854 }
1855 else if (amask == MIPS16_ALL_STATICS)
1856 {
1857 nargs = 0;
1858 nstatics = 4;
1859 }
1860 else
1861 {
1862 nargs = amask >> 2;
1863 nstatics = amask & 3;
1864 }
252b5132 1865
c3c07478
RS
1866 sep = "";
1867 if (nargs > 0)
1868 {
1869 infprintf (is, "%s", mips_gpr_names[4]);
1870 if (nargs > 1)
1871 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1872 sep = ",";
1873 }
252b5132 1874
c3c07478
RS
1875 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1876 if (frame_size == 0 && !use_extend)
1877 frame_size = 128;
1878 infprintf (is, "%s%d", sep, frame_size);
1879
1880 if (insn & 0x40) /* $ra */
1881 infprintf (is, ",%s", mips_gpr_names[31]);
1882
1883 nsreg = (extend >> 8) & 0x7;
1884 smask = 0;
1885 if (insn & 0x20) /* $s0 */
1886 smask |= 1 << 0;
1887 if (insn & 0x10) /* $s1 */
1888 smask |= 1 << 1;
1889 if (nsreg > 0) /* $s2-$s8 */
1890 smask |= ((1 << nsreg) - 1) << 2;
1891
1892 for (i = 0; i < 9; i++)
1893 if (smask & (1 << i))
252b5132 1894 {
c3c07478
RS
1895 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1896 /* Skip over string of set bits. */
1897 for (j = i; smask & (2 << j); j++)
1898 continue;
1899 if (j > i)
1900 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1901 i = j + 1;
252b5132 1902 }
c3c07478
RS
1903 /* Statics $ax - $a3. */
1904 if (nstatics == 1)
1905 infprintf (is, ",%s", mips_gpr_names[7]);
1906 else if (nstatics > 0)
1907 infprintf (is, ",%s-%s",
1908 mips_gpr_names[7 - nstatics + 1],
1909 mips_gpr_names[7]);
1910 break;
1911 }
252b5132 1912
c3c07478
RS
1913 if (is_offset && operand->type == OP_INT)
1914 {
1915 const struct mips_int_operand *int_op;
252b5132 1916
c3c07478
RS
1917 int_op = (const struct mips_int_operand *) operand;
1918 info->insn_type = dis_dref;
1919 info->data_size = 1 << int_op->shift;
1920 }
252b5132 1921
c3c07478
RS
1922 if (operand->size == 26)
1923 /* In this case INSN is the first two bytes of the instruction
1924 and EXTEND is the second two bytes. */
1925 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
1926 else
1927 {
1928 /* Calculate the full field value. */
1929 uval = mips_extract_operand (operand, insn);
1930 if (use_extend)
1931 {
1932 ext_operand = decode_mips16_operand (type, TRUE);
1933 if (ext_operand != operand)
1934 {
1935 operand = ext_operand;
1936 if (operand->size == 16)
92708cec
MR
1937 uval = (((extend & 0x1f) << 11) | (extend & 0x7e0)
1938 | (uval & 0x1f));
c3c07478
RS
1939 else if (operand->size == 15)
1940 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1941 else
92708cec
MR
1942 uval = ((((extend >> 6) & 0x1f) | (extend & 0x20))
1943 & ((1U << operand->size) - 1));
c3c07478
RS
1944 }
1945 }
1946 }
1947
1948 baseaddr = memaddr + 2;
1949 if (operand->type == OP_PCREL)
1950 {
1951 const struct mips_pcrel_operand *pcrel_op;
1952
1953 pcrel_op = (const struct mips_pcrel_operand *) operand;
1954 if (!pcrel_op->include_isa_bit && use_extend)
1955 baseaddr = memaddr - 2;
1956 else if (!pcrel_op->include_isa_bit)
39f66f3a
MR
1957 {
1958 bfd_byte buffer[2];
1959
1960 /* If this instruction is in the delay slot of a JAL/JALX
1961 instruction, the base address is the address of the
1962 JAL/JALX instruction. If it is in the delay slot of
1963 a JR/JALR instruction, the base address is the address
1964 of the JR/JALR instruction. This test is unreliable:
1965 we have no way of knowing whether the previous word is
1966 instruction or data. */
1967 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1968 && (((info->endian == BFD_ENDIAN_BIG
1969 ? bfd_getb16 (buffer)
1970 : bfd_getl16 (buffer))
1971 & 0xf800) == 0x1800))
1972 baseaddr = memaddr - 4;
1973 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1974 info) == 0
1975 && (((info->endian == BFD_ENDIAN_BIG
1976 ? bfd_getb16 (buffer)
1977 : bfd_getl16 (buffer))
1978 & 0xf89f) == 0xe800)
1979 && (((info->endian == BFD_ENDIAN_BIG
1980 ? bfd_getb16 (buffer)
1981 : bfd_getl16 (buffer))
1982 & 0x0060) != 0x0060))
1983 baseaddr = memaddr - 2;
1984 else
1985 baseaddr = memaddr;
1986 }
c3c07478 1987 }
0499d65b 1988
6d075bce 1989 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
0499d65b 1990 break;
252b5132
RH
1991 }
1992}
640c0ccd 1993
1bbce132
MR
1994
1995/* Check if the given address is the last word of a MIPS16 PLT entry.
1996 This word is data and depending on the value it may interfere with
1997 disassembly of further PLT entries. We make use of the fact PLT
1998 symbols are marked BSF_SYNTHETIC. */
1999static bfd_boolean
2000is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2001{
2002 if (info->symbols
2003 && info->symbols[0]
2004 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2005 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2006 return TRUE;
2007
2008 return FALSE;
2009}
2010
47b0e7ad
NC
2011/* Disassemble mips16 instructions. */
2012
2013static int
2014print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2015{
fc8c4fd1 2016 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 2017 int status;
1bbce132 2018 bfd_byte buffer[4];
47b0e7ad
NC
2019 int length;
2020 int insn;
2021 bfd_boolean use_extend;
2022 int extend = 0;
2023 const struct mips_opcode *op, *opend;
c3c07478 2024 struct mips_print_arg_state state;
fc8c4fd1 2025 void *is = info->stream;
47b0e7ad
NC
2026
2027 info->bytes_per_chunk = 2;
2028 info->display_endian = info->endian;
2029 info->insn_info_valid = 1;
2030 info->branch_delay_insns = 0;
2031 info->data_size = 0;
47b0e7ad
NC
2032 info->target = 0;
2033 info->target2 = 0;
2034
c3c07478
RS
2035#define GET_OP(insn, field) \
2036 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1bbce132
MR
2037 /* Decode PLT entry's GOT slot address word. */
2038 if (is_mips16_plt_tail (info, memaddr))
2039 {
2040 info->insn_type = dis_noninsn;
2041 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2042 if (status == 0)
2043 {
2044 unsigned int gotslot;
2045
2046 if (info->endian == BFD_ENDIAN_BIG)
2047 gotslot = bfd_getb32 (buffer);
2048 else
2049 gotslot = bfd_getl32 (buffer);
2050 infprintf (is, ".word\t0x%x", gotslot);
2051
2052 return 4;
2053 }
2054 }
2055 else
2056 {
2057 info->insn_type = dis_nonbranch;
2058 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2059 }
47b0e7ad
NC
2060 if (status != 0)
2061 {
2062 (*info->memory_error_func) (status, memaddr, info);
2063 return -1;
2064 }
2065
2066 length = 2;
2067
2068 if (info->endian == BFD_ENDIAN_BIG)
2069 insn = bfd_getb16 (buffer);
2070 else
2071 insn = bfd_getl16 (buffer);
2072
2073 /* Handle the extend opcode specially. */
2074 use_extend = FALSE;
2075 if ((insn & 0xf800) == 0xf000)
2076 {
2077 use_extend = TRUE;
2078 extend = insn & 0x7ff;
2079
2080 memaddr += 2;
2081
2082 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2083 if (status != 0)
2084 {
55af4784 2085 infprintf (is, "extend\t0x%x", (unsigned int) extend);
47b0e7ad
NC
2086 (*info->memory_error_func) (status, memaddr, info);
2087 return -1;
2088 }
2089
2090 if (info->endian == BFD_ENDIAN_BIG)
2091 insn = bfd_getb16 (buffer);
2092 else
2093 insn = bfd_getl16 (buffer);
2094
2095 /* Check for an extend opcode followed by an extend opcode. */
2096 if ((insn & 0xf800) == 0xf000)
2097 {
55af4784 2098 infprintf (is, "extend\t0x%x", (unsigned int) extend);
47b0e7ad
NC
2099 info->insn_type = dis_noninsn;
2100 return length;
2101 }
2102
2103 length += 2;
2104 }
2105
2106 /* FIXME: Should probably use a hash table on the major opcode here. */
2107
2108 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2109 for (op = mips16_opcodes; op < opend; op++)
2110 {
2111 if (op->pinfo != INSN_MACRO
2112 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2113 && (insn & op->mask) == op->match)
2114 {
2115 const char *s;
2116
27c5c572 2117 if (op->args[0] == 'a' || op->args[0] == 'i')
47b0e7ad
NC
2118 {
2119 if (use_extend)
2120 {
55af4784 2121 infprintf (is, "extend\t0x%x", (unsigned int) extend);
47b0e7ad
NC
2122 info->insn_type = dis_noninsn;
2123 return length - 2;
2124 }
2125
2126 use_extend = FALSE;
2127
2128 memaddr += 2;
2129
2130 status = (*info->read_memory_func) (memaddr, buffer, 2,
2131 info);
2132 if (status == 0)
2133 {
2134 use_extend = TRUE;
2135 if (info->endian == BFD_ENDIAN_BIG)
2136 extend = bfd_getb16 (buffer);
2137 else
2138 extend = bfd_getl16 (buffer);
2139 length += 2;
2140 }
2141 }
2142
fc8c4fd1 2143 infprintf (is, "%s", op->name);
47b0e7ad 2144 if (op->args[0] != '\0')
fc8c4fd1 2145 infprintf (is, "\t");
47b0e7ad 2146
c3c07478 2147 init_print_arg_state (&state);
47b0e7ad
NC
2148 for (s = op->args; *s != '\0'; s++)
2149 {
2150 if (*s == ','
2151 && s[1] == 'w'
fc8c4fd1 2152 && GET_OP (insn, RX) == GET_OP (insn, RY))
47b0e7ad
NC
2153 {
2154 /* Skip the register and the comma. */
2155 ++s;
2156 continue;
2157 }
2158 if (*s == ','
2159 && s[1] == 'v'
fc8c4fd1 2160 && GET_OP (insn, RZ) == GET_OP (insn, RX))
47b0e7ad
NC
2161 {
2162 /* Skip the register and the comma. */
2163 ++s;
2164 continue;
2165 }
c3c07478
RS
2166 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
2167 use_extend, extend, s[1] == '(');
47b0e7ad
NC
2168 }
2169
9a2c7088 2170 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 2171 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088 2172 info->branch_delay_insns = 1;
26545944
RS
2173 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2174 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
47b0e7ad 2175 {
9a2c7088
MR
2176 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2177 info->insn_type = dis_jsr;
2178 else
47b0e7ad
NC
2179 info->insn_type = dis_branch;
2180 }
26545944 2181 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
9a2c7088 2182 info->insn_type = dis_condbranch;
47b0e7ad
NC
2183
2184 return length;
2185 }
2186 }
fc8c4fd1 2187#undef GET_OP
47b0e7ad
NC
2188
2189 if (use_extend)
55af4784 2190 infprintf (is, "0x%x ", extend | 0xf000);
fc8c4fd1 2191 infprintf (is, "0x%x", insn);
47b0e7ad
NC
2192 info->insn_type = dis_noninsn;
2193
2194 return length;
2195}
2196
df58fc94
RS
2197/* Disassemble microMIPS instructions. */
2198
2199static int
2200print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2201{
0c7533d3 2202 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94 2203 const struct mips_opcode *op, *opend;
df58fc94 2204 void *is = info->stream;
df58fc94 2205 bfd_byte buffer[2];
ab902481
RS
2206 unsigned int higher;
2207 unsigned int length;
df58fc94 2208 int status;
ab902481 2209 unsigned int insn;
df58fc94
RS
2210
2211 info->bytes_per_chunk = 2;
2212 info->display_endian = info->endian;
2213 info->insn_info_valid = 1;
2214 info->branch_delay_insns = 0;
2215 info->data_size = 0;
2216 info->insn_type = dis_nonbranch;
2217 info->target = 0;
2218 info->target2 = 0;
2219
2220 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2221 if (status != 0)
2222 {
2223 (*info->memory_error_func) (status, memaddr, info);
2224 return -1;
2225 }
2226
2227 length = 2;
2228
2229 if (info->endian == BFD_ENDIAN_BIG)
2230 insn = bfd_getb16 (buffer);
2231 else
2232 insn = bfd_getl16 (buffer);
2233
100b4f2e 2234 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
df58fc94
RS
2235 {
2236 /* This is a 32-bit microMIPS instruction. */
2237 higher = insn;
2238
2239 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2240 if (status != 0)
2241 {
0c7533d3 2242 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2243 (*info->memory_error_func) (status, memaddr + 2, info);
2244 return -1;
2245 }
2246
2247 if (info->endian == BFD_ENDIAN_BIG)
2248 insn = bfd_getb16 (buffer);
2249 else
2250 insn = bfd_getl16 (buffer);
2251
2252 insn = insn | (higher << 16);
2253
2254 length += 2;
2255 }
2256
2257 /* FIXME: Should probably use a hash table on the major opcode here. */
2258
df58fc94
RS
2259 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2260 for (op = micromips_opcodes; op < opend; op++)
2261 {
2262 if (op->pinfo != INSN_MACRO
2263 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2264 && (insn & op->mask) == op->match
2265 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2266 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2267 {
7361da2c
AB
2268 if (!validate_insn_args (op, decode_micromips_operand, insn))
2269 continue;
2270
0c7533d3 2271 infprintf (is, "%s", op->name);
df58fc94 2272
ab902481 2273 if (op->args[0])
df58fc94 2274 {
ab902481
RS
2275 infprintf (is, "\t");
2276 print_insn_args (info, op, decode_micromips_operand, insn,
7361da2c 2277 memaddr + 1, length);
df58fc94
RS
2278 }
2279
2280 /* Figure out instruction type and branch delay information. */
2281 if ((op->pinfo
2282 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2283 info->branch_delay_insns = 1;
2284 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2285 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2286 {
fc76e730 2287 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
df58fc94
RS
2288 info->insn_type = dis_jsr;
2289 else
2290 info->insn_type = dis_branch;
2291 }
2292 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2293 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2294 {
2295 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2296 info->insn_type = dis_condjsr;
2297 else
2298 info->insn_type = dis_condbranch;
2299 }
2300 else if ((op->pinfo
67dc82bc 2301 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
df58fc94
RS
2302 info->insn_type = dis_dref;
2303
2304 return length;
2305 }
2306 }
df58fc94 2307
0c7533d3 2308 infprintf (is, "0x%x", insn);
df58fc94
RS
2309 info->insn_type = dis_noninsn;
2310
2311 return length;
2312}
2313
2314/* Return 1 if a symbol associated with the location being disassembled
1401d2fe
MR
2315 indicates a compressed mode, either MIPS16 or microMIPS, according to
2316 MICROMIPS_P. We iterate over all the symbols at the address being
2317 considered assuming if at least one of them indicates code compression,
2318 then such code has been genuinely produced here (other symbols could
2319 have been derived from function symbols defined elsewhere or could
2320 define data). Otherwise, return 0. */
df58fc94
RS
2321
2322static bfd_boolean
1401d2fe 2323is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
df58fc94 2324{
df58fc94 2325 int i;
1bbce132
MR
2326 int l;
2327
2328 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2329 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
1401d2fe 2330 && ((!micromips_p
1bbce132 2331 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
1401d2fe 2332 || (micromips_p
1bbce132
MR
2333 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2334 return 1;
2335 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2336 && info->symtab[i]->section == info->section)
2337 {
2338 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
1401d2fe 2339 if ((!micromips_p
1bbce132 2340 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
1401d2fe 2341 || (micromips_p
1bbce132
MR
2342 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2343 return 1;
2344 }
df58fc94
RS
2345
2346 return 0;
2347}
2348
47b0e7ad
NC
2349/* In an environment where we do not know the symbol type of the
2350 instruction we are forced to assume that the low order bit of the
2351 instructions' address may mark it as a mips16 instruction. If we
2352 are single stepping, or the pc is within the disassembled function,
2353 this works. Otherwise, we need a clue. Sometimes. */
2354
2355static int
2356_print_insn_mips (bfd_vma memaddr,
2357 struct disassemble_info *info,
2358 enum bfd_endian endianness)
2359{
2360 bfd_byte buffer[INSNLEN];
2361 int status;
2362
2363 set_default_mips_dis_options (info);
2364 parse_mips_dis_options (info->disassembler_options);
2365
df58fc94
RS
2366 if (info->mach == bfd_mach_mips16)
2367 return print_insn_mips16 (memaddr, info);
2368 if (info->mach == bfd_mach_mips_micromips)
2369 return print_insn_micromips (memaddr, info);
2370
47b0e7ad 2371#if 1
df58fc94 2372 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
2373 /* Only a few tools will work this way. */
2374 if (memaddr & 0x01)
1401d2fe
MR
2375 {
2376 if (micromips_ase)
2377 return print_insn_micromips (memaddr, info);
2378 else
2379 return print_insn_mips16 (memaddr, info);
2380 }
47b0e7ad
NC
2381#endif
2382
2383#if SYMTAB_AVAILABLE
1401d2fe
MR
2384 if (is_compressed_mode_p (info, TRUE))
2385 return print_insn_micromips (memaddr, info);
2386 if (is_compressed_mode_p (info, FALSE))
2387 return print_insn_mips16 (memaddr, info);
47b0e7ad
NC
2388#endif
2389
2390 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2391 if (status == 0)
2392 {
fc8c4fd1 2393 int insn;
47b0e7ad
NC
2394
2395 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 2396 insn = bfd_getb32 (buffer);
47b0e7ad 2397 else
fc8c4fd1 2398 insn = bfd_getl32 (buffer);
47b0e7ad
NC
2399
2400 return print_insn_mips (memaddr, insn, info);
2401 }
2402 else
2403 {
2404 (*info->memory_error_func) (status, memaddr, info);
2405 return -1;
2406 }
2407}
2408
2409int
2410print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2411{
2412 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2413}
2414
2415int
2416print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2417{
2418 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2419}
2420\f
640c0ccd 2421void
47b0e7ad 2422print_mips_disassembler_options (FILE *stream)
640c0ccd 2423{
4a9a3c54 2424 unsigned int i;
640c0ccd
CD
2425
2426 fprintf (stream, _("\n\
2427The following MIPS specific disassembler options are supported for use\n\
2428with the -M switch (multiple options should be separated by commas):\n"));
2429
4edbb8e3 2430 fprintf (stream, _("\n\
6725647c 2431 msa Recognize MSA instructions.\n"));
4edbb8e3 2432
b015e599 2433 fprintf (stream, _("\n\
6725647c 2434 virt Recognize the virtualization ASE instructions.\n"));
b015e599 2435
7d64c587 2436 fprintf (stream, _("\n\
6725647c
MR
2437 xpa Recognize the eXtended Physical Address (XPA)\n\
2438 ASE instructions.\n"));
7d64c587 2439
640c0ccd 2440 fprintf (stream, _("\n\
6725647c 2441 gpr-names=ABI Print GPR names according to specified ABI.\n\
640c0ccd
CD
2442 Default: based on binary being disassembled.\n"));
2443
2444 fprintf (stream, _("\n\
2445 fpr-names=ABI Print FPR names according to specified ABI.\n\
2446 Default: numeric.\n"));
2447
2448 fprintf (stream, _("\n\
2449 cp0-names=ARCH Print CP0 register names according to\n\
2450 specified architecture.\n\
2451 Default: based on binary being disassembled.\n"));
2452
af7ee8bf
CD
2453 fprintf (stream, _("\n\
2454 hwr-names=ARCH Print HWR names according to specified \n\
6725647c 2455 architecture.\n\
af7ee8bf
CD
2456 Default: based on binary being disassembled.\n"));
2457
640c0ccd
CD
2458 fprintf (stream, _("\n\
2459 reg-names=ABI Print GPR and FPR names according to\n\
2460 specified ABI.\n"));
2461
2462 fprintf (stream, _("\n\
af7ee8bf 2463 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
2464 specified architecture.\n"));
2465
2466 fprintf (stream, _("\n\
2467 For the options above, the following values are supported for \"ABI\":\n\
2468 "));
4a9a3c54 2469 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
2470 fprintf (stream, " %s", mips_abi_choices[i].name);
2471 fprintf (stream, _("\n"));
2472
2473 fprintf (stream, _("\n\
2474 For the options above, The following values are supported for \"ARCH\":\n\
2475 "));
4a9a3c54 2476 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
2477 if (*mips_arch_choices[i].name != '\0')
2478 fprintf (stream, " %s", mips_arch_choices[i].name);
2479 fprintf (stream, _("\n"));
2480
2481 fprintf (stream, _("\n"));
2482}
This page took 0.933213 seconds and 4 git commands to generate.