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