Ensure softfloat and singlefloat take precedence in consistency checks
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
CommitLineData
252b5132 1/* Print mips instructions for GDB, the GNU debugger, or for objdump.
4b95cf5c 2 Copyright (C) 1989-2014 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
160static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900[] =
161{
162 { 24, 2, "c0_iab" },
163 { 24, 3, "c0_iabm" },
164 { 24, 4, "c0_dab" },
165 { 24, 5, "c0_dabm" },
166 { 24, 6, "c0_dvb" },
167 { 24, 7, "c0_dvbm" },
168 { 25, 1, "c0_perfcnt,1" },
169 { 25, 2, "c0_perfcnt,2" }
170};
171
47b0e7ad
NC
172static const char * const mips_cp0_names_mips3264[32] =
173{
640c0ccd
CD
174 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
175 "c0_context", "c0_pagemask", "c0_wired", "$7",
176 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
177 "c0_status", "c0_cause", "c0_epc", "c0_prid",
178 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
179 "c0_xcontext", "$21", "$22", "c0_debug",
180 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
181 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
182};
183
dc76d757
AB
184static const char * const mips_cp1_names_mips3264[32] =
185{
186 "c1_fir", "c1_ufr", "$2", "$3",
187 "c1_unfr", "$5", "$6", "$7",
188 "$8", "$9", "$10", "$11",
189 "$12", "$13", "$14", "$15",
190 "$16", "$17", "$18", "$19",
191 "$20", "$21", "$22", "$23",
192 "$24", "c1_fccr", "c1_fexr", "$27",
193 "c1_fenr", "$29", "$30", "c1_fcsr"
194};
195
47b0e7ad
NC
196static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
197{
bbcc0807
CD
198 { 16, 1, "c0_config1" },
199 { 16, 2, "c0_config2" },
200 { 16, 3, "c0_config3" },
201 { 18, 1, "c0_watchlo,1" },
202 { 18, 2, "c0_watchlo,2" },
203 { 18, 3, "c0_watchlo,3" },
204 { 18, 4, "c0_watchlo,4" },
205 { 18, 5, "c0_watchlo,5" },
206 { 18, 6, "c0_watchlo,6" },
207 { 18, 7, "c0_watchlo,7" },
208 { 19, 1, "c0_watchhi,1" },
209 { 19, 2, "c0_watchhi,2" },
210 { 19, 3, "c0_watchhi,3" },
211 { 19, 4, "c0_watchhi,4" },
212 { 19, 5, "c0_watchhi,5" },
213 { 19, 6, "c0_watchhi,6" },
214 { 19, 7, "c0_watchhi,7" },
215 { 25, 1, "c0_perfcnt,1" },
216 { 25, 2, "c0_perfcnt,2" },
217 { 25, 3, "c0_perfcnt,3" },
218 { 25, 4, "c0_perfcnt,4" },
219 { 25, 5, "c0_perfcnt,5" },
220 { 25, 6, "c0_perfcnt,6" },
221 { 25, 7, "c0_perfcnt,7" },
222 { 27, 1, "c0_cacheerr,1" },
223 { 27, 2, "c0_cacheerr,2" },
224 { 27, 3, "c0_cacheerr,3" },
225 { 28, 1, "c0_datalo" },
226 { 29, 1, "c0_datahi" }
227};
228
47b0e7ad
NC
229static const char * const mips_cp0_names_mips3264r2[32] =
230{
af7ee8bf
CD
231 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
232 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
233 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
234 "c0_status", "c0_cause", "c0_epc", "c0_prid",
235 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
236 "c0_xcontext", "$21", "$22", "c0_debug",
237 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
238 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
239};
240
47b0e7ad
NC
241static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
242{
bbcc0807 243 { 4, 1, "c0_contextconfig" },
59c455b3
TS
244 { 0, 1, "c0_mvpcontrol" },
245 { 0, 2, "c0_mvpconf0" },
246 { 0, 3, "c0_mvpconf1" },
247 { 1, 1, "c0_vpecontrol" },
248 { 1, 2, "c0_vpeconf0" },
249 { 1, 3, "c0_vpeconf1" },
250 { 1, 4, "c0_yqmask" },
251 { 1, 5, "c0_vpeschedule" },
252 { 1, 6, "c0_vpeschefback" },
253 { 2, 1, "c0_tcstatus" },
254 { 2, 2, "c0_tcbind" },
255 { 2, 3, "c0_tcrestart" },
256 { 2, 4, "c0_tchalt" },
257 { 2, 5, "c0_tccontext" },
258 { 2, 6, "c0_tcschedule" },
259 { 2, 7, "c0_tcschefback" },
bbcc0807 260 { 5, 1, "c0_pagegrain" },
59c455b3
TS
261 { 6, 1, "c0_srsconf0" },
262 { 6, 2, "c0_srsconf1" },
263 { 6, 3, "c0_srsconf2" },
264 { 6, 4, "c0_srsconf3" },
265 { 6, 5, "c0_srsconf4" },
bbcc0807
CD
266 { 12, 1, "c0_intctl" },
267 { 12, 2, "c0_srsctl" },
268 { 12, 3, "c0_srsmap" },
269 { 15, 1, "c0_ebase" },
270 { 16, 1, "c0_config1" },
271 { 16, 2, "c0_config2" },
272 { 16, 3, "c0_config3" },
273 { 18, 1, "c0_watchlo,1" },
274 { 18, 2, "c0_watchlo,2" },
275 { 18, 3, "c0_watchlo,3" },
276 { 18, 4, "c0_watchlo,4" },
277 { 18, 5, "c0_watchlo,5" },
278 { 18, 6, "c0_watchlo,6" },
279 { 18, 7, "c0_watchlo,7" },
280 { 19, 1, "c0_watchhi,1" },
281 { 19, 2, "c0_watchhi,2" },
282 { 19, 3, "c0_watchhi,3" },
283 { 19, 4, "c0_watchhi,4" },
284 { 19, 5, "c0_watchhi,5" },
285 { 19, 6, "c0_watchhi,6" },
286 { 19, 7, "c0_watchhi,7" },
287 { 23, 1, "c0_tracecontrol" },
288 { 23, 2, "c0_tracecontrol2" },
289 { 23, 3, "c0_usertracedata" },
290 { 23, 4, "c0_tracebpc" },
291 { 25, 1, "c0_perfcnt,1" },
292 { 25, 2, "c0_perfcnt,2" },
293 { 25, 3, "c0_perfcnt,3" },
294 { 25, 4, "c0_perfcnt,4" },
295 { 25, 5, "c0_perfcnt,5" },
296 { 25, 6, "c0_perfcnt,6" },
297 { 25, 7, "c0_perfcnt,7" },
298 { 27, 1, "c0_cacheerr,1" },
299 { 27, 2, "c0_cacheerr,2" },
300 { 27, 3, "c0_cacheerr,3" },
301 { 28, 1, "c0_datalo" },
302 { 28, 2, "c0_taglo1" },
303 { 28, 3, "c0_datalo1" },
304 { 28, 4, "c0_taglo2" },
305 { 28, 5, "c0_datalo2" },
306 { 28, 6, "c0_taglo3" },
307 { 28, 7, "c0_datalo3" },
308 { 29, 1, "c0_datahi" },
309 { 29, 2, "c0_taghi1" },
310 { 29, 3, "c0_datahi1" },
311 { 29, 4, "c0_taghi2" },
312 { 29, 5, "c0_datahi2" },
313 { 29, 6, "c0_taghi3" },
314 { 29, 7, "c0_datahi3" },
315};
316
640c0ccd 317/* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
47b0e7ad
NC
318static const char * const mips_cp0_names_sb1[32] =
319{
640c0ccd
CD
320 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
321 "c0_context", "c0_pagemask", "c0_wired", "$7",
322 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
323 "c0_status", "c0_cause", "c0_epc", "c0_prid",
324 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
325 "c0_xcontext", "$21", "$22", "c0_debug",
326 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
327 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
328};
329
47b0e7ad
NC
330static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
331{
bbcc0807
CD
332 { 16, 1, "c0_config1" },
333 { 18, 1, "c0_watchlo,1" },
334 { 19, 1, "c0_watchhi,1" },
335 { 22, 0, "c0_perftrace" },
336 { 23, 3, "c0_edebug" },
337 { 25, 1, "c0_perfcnt,1" },
338 { 25, 2, "c0_perfcnt,2" },
339 { 25, 3, "c0_perfcnt,3" },
340 { 25, 4, "c0_perfcnt,4" },
341 { 25, 5, "c0_perfcnt,5" },
342 { 25, 6, "c0_perfcnt,6" },
343 { 25, 7, "c0_perfcnt,7" },
344 { 26, 1, "c0_buserr_pa" },
345 { 27, 1, "c0_cacheerr_d" },
346 { 27, 3, "c0_cacheerr_d_pa" },
347 { 28, 1, "c0_datalo_i" },
348 { 28, 2, "c0_taglo_d" },
349 { 28, 3, "c0_datalo_d" },
350 { 29, 1, "c0_datahi_i" },
351 { 29, 2, "c0_taghi_d" },
352 { 29, 3, "c0_datahi_d" },
353};
354
52b6b6b9
JM
355/* Xlr cop0 register names. */
356static const char * const mips_cp0_names_xlr[32] = {
357 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
358 "c0_context", "c0_pagemask", "c0_wired", "$7",
359 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
360 "c0_status", "c0_cause", "c0_epc", "c0_prid",
361 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
362 "c0_xcontext", "$21", "$22", "c0_debug",
363 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
364 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
365};
366
367/* XLR's CP0 Select Registers. */
368
369static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
370 { 9, 6, "c0_extintreq" },
371 { 9, 7, "c0_extintmask" },
372 { 15, 1, "c0_ebase" },
373 { 16, 1, "c0_config1" },
374 { 16, 2, "c0_config2" },
375 { 16, 3, "c0_config3" },
376 { 16, 7, "c0_procid2" },
377 { 18, 1, "c0_watchlo,1" },
378 { 18, 2, "c0_watchlo,2" },
379 { 18, 3, "c0_watchlo,3" },
380 { 18, 4, "c0_watchlo,4" },
381 { 18, 5, "c0_watchlo,5" },
382 { 18, 6, "c0_watchlo,6" },
383 { 18, 7, "c0_watchlo,7" },
384 { 19, 1, "c0_watchhi,1" },
385 { 19, 2, "c0_watchhi,2" },
386 { 19, 3, "c0_watchhi,3" },
387 { 19, 4, "c0_watchhi,4" },
388 { 19, 5, "c0_watchhi,5" },
389 { 19, 6, "c0_watchhi,6" },
390 { 19, 7, "c0_watchhi,7" },
391 { 25, 1, "c0_perfcnt,1" },
392 { 25, 2, "c0_perfcnt,2" },
393 { 25, 3, "c0_perfcnt,3" },
394 { 25, 4, "c0_perfcnt,4" },
395 { 25, 5, "c0_perfcnt,5" },
396 { 25, 6, "c0_perfcnt,6" },
397 { 25, 7, "c0_perfcnt,7" },
398 { 27, 1, "c0_cacheerr,1" },
399 { 27, 2, "c0_cacheerr,2" },
400 { 27, 3, "c0_cacheerr,3" },
401 { 28, 1, "c0_datalo" },
402 { 29, 1, "c0_datahi" }
403};
404
47b0e7ad
NC
405static const char * const mips_hwr_names_numeric[32] =
406{
af7ee8bf
CD
407 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
408 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
409 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
410 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
411};
412
47b0e7ad
NC
413static const char * const mips_hwr_names_mips3264r2[32] =
414{
af7ee8bf
CD
415 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
416 "$4", "$5", "$6", "$7",
417 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
418 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
419 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
420};
421
4edbb8e3
CF
422static const char * const msa_control_names[32] =
423{
424 "msa_ir", "msa_csr", "msa_access", "msa_save",
425 "msa_modify", "msa_request", "msa_map", "msa_unmap",
426 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
427 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
428 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
429};
430
47b0e7ad
NC
431struct mips_abi_choice
432{
433 const char * name;
640c0ccd
CD
434 const char * const *gpr_names;
435 const char * const *fpr_names;
436};
437
47b0e7ad
NC
438struct mips_abi_choice mips_abi_choices[] =
439{
640c0ccd
CD
440 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
441 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
442 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
443 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
444};
445
47b0e7ad
NC
446struct mips_arch_choice
447{
640c0ccd
CD
448 const char *name;
449 int bfd_mach_valid;
450 unsigned long bfd_mach;
451 int processor;
452 int isa;
d301a56b 453 int ase;
640c0ccd 454 const char * const *cp0_names;
bbcc0807
CD
455 const struct mips_cp0sel_name *cp0sel_names;
456 unsigned int cp0sel_names_len;
dc76d757 457 const char * const *cp1_names;
af7ee8bf 458 const char * const *hwr_names;
640c0ccd
CD
459};
460
47b0e7ad
NC
461const struct mips_arch_choice mips_arch_choices[] =
462{
d301a56b 463 { "numeric", 0, 0, 0, 0, 0,
dc76d757
AB
464 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
465 mips_hwr_names_numeric },
bbcc0807 466
d301a56b 467 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
dc76d757
AB
468 mips_cp0_names_r3000, NULL, 0, mips_cp1_names_numeric,
469 mips_hwr_names_numeric },
d301a56b 470 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
dc76d757
AB
471 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
472 mips_hwr_names_numeric },
d301a56b 473 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
dc76d757
AB
474 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
475 mips_hwr_names_numeric },
d301a56b 476 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
dc76d757
AB
477 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
478 mips_hwr_names_numeric },
d301a56b 479 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
dc76d757
AB
480 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
481 mips_hwr_names_numeric },
d301a56b 482 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
dc76d757
AB
483 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
484 mips_hwr_names_numeric },
d301a56b 485 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
dc76d757
AB
486 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
487 mips_hwr_names_numeric },
d301a56b 488 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
dc76d757
AB
489 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
490 mips_hwr_names_numeric },
d301a56b 491 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
dc76d757
AB
492 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
493 mips_hwr_names_numeric },
d301a56b 494 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
dc76d757
AB
495 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
496 mips_hwr_names_numeric },
d301a56b 497 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
dc76d757
AB
498 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
499 mips_hwr_names_numeric },
d301a56b 500 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
dc76d757
AB
501 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
502 mips_hwr_names_numeric },
d301a56b 503 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
dc76d757
AB
504 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
505 mips_hwr_names_numeric },
d301a56b 506 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
dc76d757
AB
507 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
508 mips_hwr_names_numeric },
d301a56b 509 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
dc76d757
AB
510 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_numeric,
511 mips_hwr_names_numeric },
d301a56b 512 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
dc76d757
AB
513 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
514 mips_hwr_names_numeric },
d301a56b 515 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
dc76d757
AB
516 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
517 mips_hwr_names_numeric },
d301a56b 518 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
dc76d757
AB
519 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
520 mips_hwr_names_numeric },
d301a56b 521 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
dc76d757
AB
522 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
523 mips_hwr_names_numeric },
d301a56b 524 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
dc76d757
AB
525 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
526 mips_hwr_names_numeric },
d301a56b 527 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
dc76d757
AB
528 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
529 mips_hwr_names_numeric },
d301a56b 530 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
dc76d757
AB
531 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
532 mips_hwr_names_numeric },
d301a56b 533 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
dc76d757
AB
534 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
535 mips_hwr_names_numeric },
d301a56b 536 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
dc76d757
AB
537 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
538 mips_hwr_names_numeric },
bbcc0807 539
640c0ccd
CD
540 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
541 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
542 _MIPS32 Architecture For Programmers Volume I: Introduction to the
543 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
544 page 1. */
545 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
d301a56b 546 ISA_MIPS32, ASE_SMARTMIPS,
bbcc0807
CD
547 mips_cp0_names_mips3264,
548 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
dc76d757 549 mips_cp1_names_mips3264, mips_hwr_names_numeric },
bbcc0807 550
af7ee8bf 551 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
d301a56b 552 ISA_MIPS32R2,
7f3c4072 553 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
7d64c587 554 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
bbcc0807
CD
555 mips_cp0_names_mips3264r2,
556 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
dc76d757 557 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
bbcc0807 558
ae52f483
AB
559 { "mips32r3", 1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
560 ISA_MIPS32R3,
561 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
562 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
563 mips_cp0_names_mips3264r2,
564 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
565 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
566
567 { "mips32r5", 1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
568 ISA_MIPS32R5,
569 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
570 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
571 mips_cp0_names_mips3264r2,
572 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
573 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
574
640c0ccd
CD
575 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
576 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
d301a56b 577 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
bbcc0807
CD
578 mips_cp0_names_mips3264,
579 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
dc76d757 580 mips_cp1_names_mips3264, mips_hwr_names_numeric },
bbcc0807 581
5f74bc13 582 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
d301a56b 583 ISA_MIPS64R2,
7f3c4072 584 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
7d64c587 585 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
5f74bc13
CD
586 mips_cp0_names_mips3264r2,
587 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
dc76d757 588 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
5f74bc13 589
ae52f483
AB
590 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
591 ISA_MIPS64R3,
592 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
593 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
594 mips_cp0_names_mips3264r2,
595 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
596 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
597
598 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
599 ISA_MIPS64R5,
600 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
601 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
602 mips_cp0_names_mips3264r2,
603 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
604 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
605
640c0ccd 606 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
d301a56b 607 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
bbcc0807
CD
608 mips_cp0_names_sb1,
609 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
dc76d757 610 mips_cp1_names_mips3264, mips_hwr_names_numeric },
640c0ccd 611
350cc38d 612 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
d301a56b 613 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
dc76d757 614 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d
MS
615
616 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
d301a56b 617 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
dc76d757 618 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d 619
fd503541 620 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
4ba154f5 621 ISA_MIPS64R2 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
dc76d757 622 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
fd503541 623
57b592a3 624 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
d301a56b 625 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
dc76d757 626 mips_cp1_names_mips3264, mips_hwr_names_numeric },
57b592a3 627
dd6a37e7 628 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
d301a56b 629 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
dc76d757 630 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
432233b3
AP
631
632 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
d301a56b 633 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
dc76d757 634 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
dd6a37e7 635
52b6b6b9 636 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 637 ISA_MIPS64 | INSN_XLR, 0,
52b6b6b9
JM
638 mips_cp0_names_xlr,
639 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 640 mips_cp1_names_mips3264, mips_hwr_names_numeric },
52b6b6b9 641
55a36193
MK
642 /* XLP is mostly like XLR, with the prominent exception it is being
643 MIPS64R2. */
644 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 645 ISA_MIPS64R2 | INSN_XLR, 0,
55a36193
MK
646 mips_cp0_names_xlr,
647 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 648 mips_cp1_names_mips3264, mips_hwr_names_numeric },
55a36193 649
640c0ccd
CD
650 /* This entry, mips16, is here only for ISA/processor selection; do
651 not print its name. */
d301a56b 652 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0,
dc76d757
AB
653 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
654 mips_hwr_names_numeric },
640c0ccd
CD
655};
656
657/* ISA and processor type to disassemble for, and register names to use.
658 set_default_mips_dis_options and parse_mips_dis_options fill in these
659 values. */
660static int mips_processor;
661static int mips_isa;
d301a56b 662static int mips_ase;
df58fc94 663static int micromips_ase;
640c0ccd
CD
664static const char * const *mips_gpr_names;
665static const char * const *mips_fpr_names;
666static const char * const *mips_cp0_names;
bbcc0807
CD
667static const struct mips_cp0sel_name *mips_cp0sel_names;
668static int mips_cp0sel_names_len;
dc76d757 669static const char * const *mips_cp1_names;
af7ee8bf 670static const char * const *mips_hwr_names;
640c0ccd 671
986e18a5 672/* Other options */
47b0e7ad 673static int no_aliases; /* If set disassemble as most general inst. */
640c0ccd
CD
674\f
675static const struct mips_abi_choice *
47b0e7ad 676choose_abi_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
677{
678 const struct mips_abi_choice *c;
679 unsigned int i;
680
681 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
47b0e7ad
NC
682 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
683 && strlen (mips_abi_choices[i].name) == namelen)
684 c = &mips_abi_choices[i];
685
640c0ccd
CD
686 return c;
687}
688
689static const struct mips_arch_choice *
47b0e7ad 690choose_arch_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
691{
692 const struct mips_arch_choice *c = NULL;
693 unsigned int i;
694
695 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
47b0e7ad
NC
696 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
697 && strlen (mips_arch_choices[i].name) == namelen)
698 c = &mips_arch_choices[i];
699
640c0ccd
CD
700 return c;
701}
702
703static const struct mips_arch_choice *
47b0e7ad 704choose_arch_by_number (unsigned long mach)
640c0ccd
CD
705{
706 static unsigned long hint_bfd_mach;
707 static const struct mips_arch_choice *hint_arch_choice;
708 const struct mips_arch_choice *c;
709 unsigned int i;
710
711 /* We optimize this because even if the user specifies no
712 flags, this will be done for every instruction! */
713 if (hint_bfd_mach == mach
714 && hint_arch_choice != NULL
715 && hint_arch_choice->bfd_mach == hint_bfd_mach)
716 return hint_arch_choice;
717
718 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
719 {
720 if (mips_arch_choices[i].bfd_mach_valid
721 && mips_arch_choices[i].bfd_mach == mach)
722 {
723 c = &mips_arch_choices[i];
724 hint_bfd_mach = mach;
725 hint_arch_choice = c;
726 }
727 }
728 return c;
729}
730
47b0e7ad
NC
731/* Check if the object uses NewABI conventions. */
732
733static int
734is_newabi (Elf_Internal_Ehdr *header)
735{
736 /* There are no old-style ABIs which use 64-bit ELF. */
737 if (header->e_ident[EI_CLASS] == ELFCLASS64)
738 return 1;
739
740 /* If a 32-bit ELF file, n32 is a new-style ABI. */
741 if ((header->e_flags & EF_MIPS_ABI2) != 0)
742 return 1;
743
744 return 0;
745}
746
df58fc94
RS
747/* Check if the object has microMIPS ASE code. */
748
749static int
750is_micromips (Elf_Internal_Ehdr *header)
751{
752 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
753 return 1;
754
755 return 0;
756}
757
47b0e7ad
NC
758static void
759set_default_mips_dis_options (struct disassemble_info *info)
640c0ccd
CD
760{
761 const struct mips_arch_choice *chosen_arch;
762
df58fc94
RS
763 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
764 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
765 CP0 register, and HWR names. */
640c0ccd 766 mips_isa = ISA_MIPS3;
df58fc94
RS
767 mips_processor = CPU_R3000;
768 micromips_ase = 0;
d301a56b 769 mips_ase = 0;
640c0ccd
CD
770 mips_gpr_names = mips_gpr_names_oldabi;
771 mips_fpr_names = mips_fpr_names_numeric;
772 mips_cp0_names = mips_cp0_names_numeric;
bbcc0807
CD
773 mips_cp0sel_names = NULL;
774 mips_cp0sel_names_len = 0;
dc76d757 775 mips_cp1_names = mips_cp1_names_numeric;
af7ee8bf 776 mips_hwr_names = mips_hwr_names_numeric;
986e18a5 777 no_aliases = 0;
640c0ccd 778
df58fc94 779 /* Update settings according to the ELF file header flags. */
fec06546 780 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
640c0ccd
CD
781 {
782 Elf_Internal_Ehdr *header;
783
fec06546 784 header = elf_elfheader (info->section->owner);
df58fc94 785 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
640c0ccd
CD
786 if (is_newabi (header))
787 mips_gpr_names = mips_gpr_names_newabi;
df58fc94
RS
788 /* If a microMIPS binary, then don't use MIPS16 bindings. */
789 micromips_ase = is_micromips (header);
640c0ccd
CD
790 }
791
792 /* Set ISA, architecture, and cp0 register names as best we can. */
793#if ! SYMTAB_AVAILABLE
794 /* This is running out on a target machine, not in a host tool.
795 FIXME: Where does mips_target_info come from? */
796 target_processor = mips_target_info.processor;
797 mips_isa = mips_target_info.isa;
d301a56b 798 mips_ase = mips_target_info.ase;
640c0ccd
CD
799#else
800 chosen_arch = choose_arch_by_number (info->mach);
801 if (chosen_arch != NULL)
802 {
803 mips_processor = chosen_arch->processor;
804 mips_isa = chosen_arch->isa;
d301a56b 805 mips_ase = chosen_arch->ase;
bbcc0807
CD
806 mips_cp0_names = chosen_arch->cp0_names;
807 mips_cp0sel_names = chosen_arch->cp0sel_names;
808 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 809 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 810 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
811 }
812#endif
813}
814
47b0e7ad
NC
815static void
816parse_mips_dis_option (const char *option, unsigned int len)
640c0ccd
CD
817{
818 unsigned int i, optionlen, vallen;
819 const char *val;
820 const struct mips_abi_choice *chosen_abi;
821 const struct mips_arch_choice *chosen_arch;
822
986e18a5 823 /* Try to match options that are simple flags */
0112cd26 824 if (CONST_STRNEQ (option, "no-aliases"))
986e18a5
FF
825 {
826 no_aliases = 1;
827 return;
828 }
b015e599 829
4edbb8e3
CF
830 if (CONST_STRNEQ (option, "msa"))
831 {
832 mips_ase |= ASE_MSA;
ae52f483
AB
833 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
834 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
835 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5)
4edbb8e3
CF
836 mips_ase |= ASE_MSA64;
837 return;
838 }
839
b015e599
AP
840 if (CONST_STRNEQ (option, "virt"))
841 {
d301a56b 842 mips_ase |= ASE_VIRT;
ae52f483
AB
843 if (mips_isa & ISA_MIPS64R2
844 || mips_isa & ISA_MIPS64R3
845 || mips_isa & ISA_MIPS64R5)
d301a56b 846 mips_ase |= ASE_VIRT64;
b015e599
AP
847 return;
848 }
7d64c587
AB
849
850 if (CONST_STRNEQ (option, "xpa"))
851 {
852 mips_ase |= ASE_XPA;
853 return;
854 }
855
986e18a5 856
640c0ccd
CD
857 /* Look for the = that delimits the end of the option name. */
858 for (i = 0; i < len; i++)
47b0e7ad
NC
859 if (option[i] == '=')
860 break;
861
640c0ccd
CD
862 if (i == 0) /* Invalid option: no name before '='. */
863 return;
864 if (i == len) /* Invalid option: no '='. */
865 return;
866 if (i == (len - 1)) /* Invalid option: no value after '='. */
867 return;
868
869 optionlen = i;
870 val = option + (optionlen + 1);
871 vallen = len - (optionlen + 1);
872
47b0e7ad
NC
873 if (strncmp ("gpr-names", option, optionlen) == 0
874 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
875 {
876 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 877 if (chosen_abi != NULL)
640c0ccd
CD
878 mips_gpr_names = chosen_abi->gpr_names;
879 return;
880 }
881
47b0e7ad
NC
882 if (strncmp ("fpr-names", option, optionlen) == 0
883 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
884 {
885 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 886 if (chosen_abi != NULL)
640c0ccd
CD
887 mips_fpr_names = chosen_abi->fpr_names;
888 return;
889 }
890
47b0e7ad
NC
891 if (strncmp ("cp0-names", option, optionlen) == 0
892 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
893 {
894 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
895 if (chosen_arch != NULL)
896 {
897 mips_cp0_names = chosen_arch->cp0_names;
898 mips_cp0sel_names = chosen_arch->cp0sel_names;
899 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
900 }
640c0ccd
CD
901 return;
902 }
903
dc76d757
AB
904 if (strncmp ("cp1-names", option, optionlen) == 0
905 && strlen ("cp1-names") == optionlen)
906 {
907 chosen_arch = choose_arch_by_name (val, vallen);
908 if (chosen_arch != NULL)
909 mips_cp1_names = chosen_arch->cp1_names;
910 return;
911 }
912
47b0e7ad
NC
913 if (strncmp ("hwr-names", option, optionlen) == 0
914 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
915 {
916 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 917 if (chosen_arch != NULL)
af7ee8bf
CD
918 mips_hwr_names = chosen_arch->hwr_names;
919 return;
920 }
921
47b0e7ad
NC
922 if (strncmp ("reg-names", option, optionlen) == 0
923 && strlen ("reg-names") == optionlen)
640c0ccd
CD
924 {
925 /* We check both ABI and ARCH here unconditionally, so
926 that "numeric" will do the desirable thing: select
927 numeric register names for all registers. Other than
928 that, a given name probably won't match both. */
929 chosen_abi = choose_abi_by_name (val, vallen);
930 if (chosen_abi != NULL)
931 {
bbcc0807
CD
932 mips_gpr_names = chosen_abi->gpr_names;
933 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
934 }
935 chosen_arch = choose_arch_by_name (val, vallen);
936 if (chosen_arch != NULL)
937 {
bbcc0807
CD
938 mips_cp0_names = chosen_arch->cp0_names;
939 mips_cp0sel_names = chosen_arch->cp0sel_names;
940 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 941 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 942 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
943 }
944 return;
945 }
946
947 /* Invalid option. */
948}
949
47b0e7ad
NC
950static void
951parse_mips_dis_options (const char *options)
640c0ccd
CD
952{
953 const char *option_end;
954
955 if (options == NULL)
956 return;
957
958 while (*options != '\0')
959 {
960 /* Skip empty options. */
961 if (*options == ',')
962 {
963 options++;
964 continue;
965 }
966
967 /* We know that *options is neither NUL or a comma. */
968 option_end = options + 1;
969 while (*option_end != ',' && *option_end != '\0')
970 option_end++;
971
972 parse_mips_dis_option (options, option_end - options);
973
974 /* Go on to the next one. If option_end points to a comma, it
975 will be skipped above. */
976 options = option_end;
977 }
978}
979
bbcc0807 980static const struct mips_cp0sel_name *
47b0e7ad
NC
981lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
982 unsigned int len,
983 unsigned int cp0reg,
984 unsigned int sel)
bbcc0807
CD
985{
986 unsigned int i;
987
988 for (i = 0; i < len; i++)
989 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
990 return &names[i];
991 return NULL;
992}
ab902481
RS
993
994/* Print register REGNO, of type TYPE, for instruction OPCODE. */
aa5f19f2 995
794ac9d0 996static void
ab902481
RS
997print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
998 enum mips_reg_operand_type type, int regno)
252b5132 999{
ab902481
RS
1000 switch (type)
1001 {
1002 case OP_REG_GP:
1003 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1004 break;
440cc0bc 1005
ab902481
RS
1006 case OP_REG_FP:
1007 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1008 break;
252b5132 1009
ab902481
RS
1010 case OP_REG_CCC:
1011 if (opcode->pinfo & (FP_D | FP_S))
1012 info->fprintf_func (info->stream, "$fcc%d", regno);
1013 else
1014 info->fprintf_func (info->stream, "$cc%d", regno);
1015 break;
794ac9d0 1016
ab902481
RS
1017 case OP_REG_VEC:
1018 if (opcode->membership & INSN_5400)
1019 info->fprintf_func (info->stream, "$f%d", regno);
1020 else
1021 info->fprintf_func (info->stream, "$v%d", regno);
1022 break;
794ac9d0 1023
ab902481
RS
1024 case OP_REG_ACC:
1025 info->fprintf_func (info->stream, "$ac%d", regno);
1026 break;
794ac9d0 1027
ab902481
RS
1028 case OP_REG_COPRO:
1029 if (opcode->name[strlen (opcode->name) - 1] == '0')
1030 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
dc76d757
AB
1031 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1032 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
ab902481
RS
1033 else
1034 info->fprintf_func (info->stream, "$%d", regno);
1035 break;
8b082fb1 1036
ab902481
RS
1037 case OP_REG_HW:
1038 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1039 break;
14daeee3
RS
1040
1041 case OP_REG_VF:
1042 info->fprintf_func (info->stream, "$vf%d", regno);
1043 break;
1044
1045 case OP_REG_VI:
1046 info->fprintf_func (info->stream, "$vi%d", regno);
1047 break;
1048
1049 case OP_REG_R5900_I:
1050 info->fprintf_func (info->stream, "$I");
1051 break;
1052
1053 case OP_REG_R5900_Q:
1054 info->fprintf_func (info->stream, "$Q");
1055 break;
1056
1057 case OP_REG_R5900_R:
1058 info->fprintf_func (info->stream, "$R");
1059 break;
1060
1061 case OP_REG_R5900_ACC:
1062 info->fprintf_func (info->stream, "$ACC");
1063 break;
4edbb8e3
CF
1064
1065 case OP_REG_MSA:
1066 info->fprintf_func (info->stream, "$w%d", regno);
1067 break;
1068
1069 case OP_REG_MSA_CTRL:
1070 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1071 break;
1072
ab902481
RS
1073 }
1074}
1075\f
1076/* Used to track the state carried over from previous operands in
1077 an instruction. */
1078struct mips_print_arg_state {
1079 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1080 where the value is known to be unsigned and small. */
1081 unsigned int last_int;
1082
1083 /* The type and number of the last OP_REG seen. We only use this for
1084 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1085 enum mips_reg_operand_type last_reg_type;
1086 unsigned int last_regno;
1087};
fd25c5a9 1088
ab902481 1089/* Initialize STATE for the start of an instruction. */
fd25c5a9 1090
ab902481
RS
1091static inline void
1092init_print_arg_state (struct mips_print_arg_state *state)
1093{
1094 memset (state, 0, sizeof (*state));
1095}
fd25c5a9 1096
14daeee3
RS
1097/* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1098 whose value is given by UVAL. */
1099
1100static void
1101print_vu0_channel (struct disassemble_info *info,
1102 const struct mips_operand *operand, unsigned int uval)
1103{
1104 if (operand->size == 4)
1105 info->fprintf_func (info->stream, "%s%s%s%s",
1106 uval & 8 ? "x" : "",
1107 uval & 4 ? "y" : "",
1108 uval & 2 ? "z" : "",
1109 uval & 1 ? "w" : "");
1110 else if (operand->size == 2)
1111 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1112 else
1113 abort ();
1114}
1115
ab902481
RS
1116/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1117 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1118 the base address for OP_PCREL operands. */
fd25c5a9 1119
ab902481
RS
1120static void
1121print_insn_arg (struct disassemble_info *info,
1122 struct mips_print_arg_state *state,
1123 const struct mips_opcode *opcode,
1124 const struct mips_operand *operand,
1125 bfd_vma base_pc,
1126 unsigned int uval)
1127{
1128 const fprintf_ftype infprintf = info->fprintf_func;
1129 void *is = info->stream;
fd25c5a9 1130
ab902481
RS
1131 switch (operand->type)
1132 {
1133 case OP_INT:
1134 {
1135 const struct mips_int_operand *int_op;
fd25c5a9 1136
ab902481
RS
1137 int_op = (const struct mips_int_operand *) operand;
1138 uval = mips_decode_int_operand (int_op, uval);
1139 state->last_int = uval;
1140 if (int_op->print_hex)
1141 infprintf (is, "0x%x", uval);
1142 else
1143 infprintf (is, "%d", uval);
1144 }
1145 break;
fd25c5a9 1146
ab902481
RS
1147 case OP_MAPPED_INT:
1148 {
1149 const struct mips_mapped_int_operand *mint_op;
fd25c5a9 1150
ab902481
RS
1151 mint_op = (const struct mips_mapped_int_operand *) operand;
1152 uval = mint_op->int_map[uval];
1153 state->last_int = uval;
1154 if (mint_op->print_hex)
1155 infprintf (is, "0x%x", uval);
1156 else
1157 infprintf (is, "%d", uval);
1158 }
1159 break;
fd25c5a9 1160
ab902481
RS
1161 case OP_MSB:
1162 {
1163 const struct mips_msb_operand *msb_op;
dec0624d 1164
ab902481
RS
1165 msb_op = (const struct mips_msb_operand *) operand;
1166 uval += msb_op->bias;
1167 if (msb_op->add_lsb)
1168 uval -= state->last_int;
1169 infprintf (is, "0x%x", uval);
1170 }
1171 break;
dec0624d 1172
ab902481 1173 case OP_REG:
0f35dbc4 1174 case OP_OPTIONAL_REG:
ab902481
RS
1175 {
1176 const struct mips_reg_operand *reg_op;
fd25c5a9 1177
ab902481 1178 reg_op = (const struct mips_reg_operand *) operand;
fc76e730 1179 uval = mips_decode_reg_operand (reg_op, uval);
ab902481 1180 print_reg (info, opcode, reg_op->reg_type, uval);
fd25c5a9 1181
ab902481
RS
1182 state->last_reg_type = reg_op->reg_type;
1183 state->last_regno = uval;
1184 }
1185 break;
61cc0267 1186
ab902481
RS
1187 case OP_REG_PAIR:
1188 {
1189 const struct mips_reg_pair_operand *pair_op;
1190
1191 pair_op = (const struct mips_reg_pair_operand *) operand;
1192 print_reg (info, opcode, pair_op->reg_type,
1193 pair_op->reg1_map[uval]);
1194 infprintf (is, ",");
1195 print_reg (info, opcode, pair_op->reg_type,
1196 pair_op->reg2_map[uval]);
1197 }
1198 break;
61cc0267 1199
ab902481
RS
1200 case OP_PCREL:
1201 {
1202 const struct mips_pcrel_operand *pcrel_op;
61cc0267 1203
ab902481
RS
1204 pcrel_op = (const struct mips_pcrel_operand *) operand;
1205 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
61cc0267 1206
ab902481
RS
1207 /* Preserve the ISA bit for the GDB disassembler,
1208 otherwise clear it. */
1209 if (info->flavour != bfd_target_unknown_flavour)
1210 info->target &= -2;
61cc0267 1211
ab902481
RS
1212 (*info->print_address_func) (info->target, info);
1213 }
1214 break;
794ac9d0 1215
ab902481
RS
1216 case OP_PERF_REG:
1217 infprintf (is, "%d", uval);
1218 break;
794ac9d0 1219
ab902481
RS
1220 case OP_ADDIUSP_INT:
1221 {
1222 int sval;
794ac9d0 1223
ab902481
RS
1224 sval = mips_signed_operand (operand, uval) * 4;
1225 if (sval >= -8 && sval < 8)
1226 sval ^= 0x400;
1227 infprintf (is, "%d", sval);
1228 break;
1229 }
794ac9d0 1230
ab902481
RS
1231 case OP_CLO_CLZ_DEST:
1232 {
1233 unsigned int reg1, reg2;
1234
1235 reg1 = uval & 31;
1236 reg2 = uval >> 5;
1237 /* If one is zero use the other. */
1238 if (reg1 == reg2 || reg2 == 0)
1239 infprintf (is, "%s", mips_gpr_names[reg1]);
1240 else if (reg1 == 0)
1241 infprintf (is, "%s", mips_gpr_names[reg2]);
1242 else
1243 /* Bogus, result depends on processor. */
1244 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1245 mips_gpr_names[reg2]);
1246 }
1247 break;
794ac9d0 1248
ab902481
RS
1249 case OP_LWM_SWM_LIST:
1250 if (operand->size == 2)
1251 {
1252 if (uval == 0)
1253 infprintf (is, "%s,%s",
1254 mips_gpr_names[16],
1255 mips_gpr_names[31]);
1256 else
1257 infprintf (is, "%s-%s,%s",
1258 mips_gpr_names[16],
1259 mips_gpr_names[16 + uval],
1260 mips_gpr_names[31]);
1261 }
1262 else
1263 {
1264 int s_reg_encode;
794ac9d0 1265
ab902481
RS
1266 s_reg_encode = uval & 0xf;
1267 if (s_reg_encode != 0)
1268 {
1269 if (s_reg_encode == 1)
1270 infprintf (is, "%s", mips_gpr_names[16]);
1271 else if (s_reg_encode < 9)
1272 infprintf (is, "%s-%s",
1273 mips_gpr_names[16],
1274 mips_gpr_names[15 + s_reg_encode]);
1275 else if (s_reg_encode == 9)
1276 infprintf (is, "%s-%s,%s",
1277 mips_gpr_names[16],
1278 mips_gpr_names[23],
1279 mips_gpr_names[30]);
1280 else
1281 infprintf (is, "UNKNOWN");
1282 }
794ac9d0 1283
ab902481
RS
1284 if (uval & 0x10) /* For ra. */
1285 {
1286 if (s_reg_encode == 0)
1287 infprintf (is, "%s", mips_gpr_names[31]);
1288 else
1289 infprintf (is, ",%s", mips_gpr_names[31]);
1290 }
1291 }
1292 break;
794ac9d0 1293
c3c07478
RS
1294 case OP_ENTRY_EXIT_LIST:
1295 {
1296 const char *sep;
1297 unsigned int amask, smask;
1298
1299 sep = "";
1300 amask = (uval >> 3) & 7;
1301 if (amask > 0 && amask < 5)
1302 {
1303 infprintf (is, "%s", mips_gpr_names[4]);
1304 if (amask > 1)
1305 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1306 sep = ",";
1307 }
1308
1309 smask = (uval >> 1) & 3;
1310 if (smask == 3)
1311 {
1312 infprintf (is, "%s??", sep);
1313 sep = ",";
1314 }
1315 else if (smask > 0)
1316 {
1317 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1318 if (smask > 1)
1319 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1320 sep = ",";
1321 }
1322
1323 if (uval & 1)
1324 {
1325 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1326 sep = ",";
1327 }
1328
1329 if (amask == 5 || amask == 6)
1330 {
1331 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1332 if (amask == 6)
1333 infprintf (is, "-%s", mips_fpr_names[1]);
1334 }
1335 }
1336 break;
1337
1338 case OP_SAVE_RESTORE_LIST:
1339 /* Should be handled by the caller due to extend behavior. */
1340 abort ();
1341
ab902481
RS
1342 case OP_MDMX_IMM_REG:
1343 {
1344 unsigned int vsel;
794ac9d0 1345
ab902481
RS
1346 vsel = uval >> 5;
1347 uval &= 31;
1348 if ((vsel & 0x10) == 0)
794ac9d0 1349 {
ab902481
RS
1350 int fmt;
1351
1352 vsel &= 0x0f;
1353 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1354 if ((vsel & 1) == 0)
1355 break;
1356 print_reg (info, opcode, OP_REG_VEC, uval);
1357 infprintf (is, "[%d]", vsel >> 1);
794ac9d0 1358 }
ab902481
RS
1359 else if ((vsel & 0x08) == 0)
1360 print_reg (info, opcode, OP_REG_VEC, uval);
1361 else
1362 infprintf (is, "0x%x", uval);
1363 }
1364 break;
794ac9d0 1365
ab902481
RS
1366 case OP_REPEAT_PREV_REG:
1367 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1368 break;
794ac9d0 1369
ab902481
RS
1370 case OP_REPEAT_DEST_REG:
1371 /* Should always match OP_REPEAT_PREV_REG first. */
1372 abort ();
794ac9d0 1373
ab902481
RS
1374 case OP_PC:
1375 infprintf (is, "$pc");
1376 break;
14daeee3
RS
1377
1378 case OP_VU0_SUFFIX:
1379 case OP_VU0_MATCH_SUFFIX:
1380 print_vu0_channel (info, operand, uval);
1381 break;
4edbb8e3
CF
1382
1383 case OP_IMM_INDEX:
1384 infprintf (is, "[%d]", uval);
1385 break;
1386
1387 case OP_REG_INDEX:
1388 infprintf (is, "[");
1389 print_reg (info, opcode, OP_REG_GP, uval);
1390 infprintf (is, "]");
1391 break;
ab902481
RS
1392 }
1393}
794ac9d0 1394
ab902481
RS
1395/* Print the arguments for INSN, which is described by OPCODE.
1396 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1397 as the base of OP_PCREL operands. */
af7ee8bf 1398
ab902481
RS
1399static void
1400print_insn_args (struct disassemble_info *info,
1401 const struct mips_opcode *opcode,
1402 const struct mips_operand *(*decode_operand) (const char *),
1403 unsigned int insn, bfd_vma base_pc)
1404{
1405 const fprintf_ftype infprintf = info->fprintf_func;
1406 void *is = info->stream;
1407 struct mips_print_arg_state state;
1408 const struct mips_operand *operand;
1409 const char *s;
794ac9d0 1410
ab902481
RS
1411 init_print_arg_state (&state);
1412 for (s = opcode->args; *s; ++s)
1413 {
1414 switch (*s)
1415 {
1416 case ',':
1417 case '(':
1418 case ')':
1419 infprintf (is, "%c", *s);
794ac9d0
CD
1420 break;
1421
14daeee3
RS
1422 case '#':
1423 ++s;
1424 infprintf (is, "%c%c", *s, *s);
1425 break;
1426
ab902481
RS
1427 default:
1428 operand = decode_operand (s);
1429 if (!operand)
fa7616a4 1430 {
ab902481
RS
1431 /* xgettext:c-format */
1432 infprintf (is,
1433 _("# internal error, undefined operand in `%s %s'"),
1434 opcode->name, opcode->args);
1435 return;
1436 }
1437 if (operand->type == OP_REG
1438 && s[1] == ','
1439 && s[2] == 'H'
1440 && opcode->name[strlen (opcode->name) - 1] == '0')
1441 {
1442 /* Coprocessor register 0 with sel field (MT ASE). */
1443 const struct mips_cp0sel_name *n;
1444 unsigned int reg, sel;
1445
1446 reg = mips_extract_operand (operand, insn);
1447 s += 2;
1448 operand = decode_operand (s);
1449 sel = mips_extract_operand (operand, insn);
1450
1451 /* CP0 register including 'sel' code for mftc0, to be
1452 printed textually if known. If not known, print both
1453 CP0 register name and sel numerically since CP0 register
1454 with sel 0 may have a name unrelated to register being
1455 printed. */
1456 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1457 mips_cp0sel_names_len,
1458 reg, sel);
1459 if (n != NULL)
1460 infprintf (is, "%s", n->name);
fa7616a4 1461 else
ab902481 1462 infprintf (is, "$%d,%d", reg, sel);
fa7616a4 1463 }
794ac9d0 1464 else
ab902481
RS
1465 print_insn_arg (info, &state, opcode, operand, base_pc,
1466 mips_extract_operand (operand, insn));
1467 if (*s == 'm' || *s == '+')
1468 ++s;
794ac9d0 1469 break;
af7ee8bf 1470 }
252b5132
RH
1471 }
1472}
1473\f
252b5132
RH
1474/* Print the mips instruction at address MEMADDR in debugged memory,
1475 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1476 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1477 this is little-endian code. */
1478
1479static int
47b0e7ad 1480print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1481 int word,
47b0e7ad 1482 struct disassemble_info *info)
252b5132 1483{
ab902481
RS
1484#define GET_OP(insn, field) \
1485 (((insn) >> OP_SH_##field) & OP_MASK_##field)
fc8c4fd1
MR
1486 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1487 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1488 const struct mips_opcode *op;
b34976b6 1489 static bfd_boolean init = 0;
fc8c4fd1 1490 void *is = info->stream;
252b5132
RH
1491
1492 /* Build a hash table to shorten the search time. */
1493 if (! init)
1494 {
1495 unsigned int i;
1496
1497 for (i = 0; i <= OP_MASK_OP; i++)
1498 {
1499 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1500 {
986e18a5 1501 if (op->pinfo == INSN_MACRO
9e836e3d 1502 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1503 continue;
fc8c4fd1 1504 if (i == GET_OP (op->match, OP))
252b5132
RH
1505 {
1506 mips_hash[i] = op;
1507 break;
1508 }
1509 }
7f6621cd 1510 }
252b5132
RH
1511
1512 init = 1;
1513 }
1514
aa5f19f2 1515 info->bytes_per_chunk = INSNLEN;
252b5132 1516 info->display_endian = info->endian;
9bb28706
CD
1517 info->insn_info_valid = 1;
1518 info->branch_delay_insns = 0;
def7143b 1519 info->data_size = 0;
9bb28706
CD
1520 info->insn_type = dis_nonbranch;
1521 info->target = 0;
1522 info->target2 = 0;
252b5132 1523
fc8c4fd1 1524 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1525 if (op != NULL)
1526 {
1527 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1528 {
986e18a5 1529 if (op->pinfo != INSN_MACRO
9e836e3d 1530 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1531 && (word & op->mask) == op->match)
252b5132 1532 {
3396de36 1533 /* We always allow to disassemble the jalx instruction. */
d301a56b 1534 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
3396de36 1535 && strcmp (op->name, "jalx"))
252b5132
RH
1536 continue;
1537
9bb28706
CD
1538 /* Figure out instruction type and branch delay information. */
1539 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1540 {
fc76e730 1541 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
9bb28706
CD
1542 info->insn_type = dis_jsr;
1543 else
1544 info->insn_type = dis_branch;
1545 info->branch_delay_insns = 1;
1546 }
1547 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1548 | INSN_COND_BRANCH_LIKELY)) != 0)
1549 {
c680e7f6 1550 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1551 info->insn_type = dis_condjsr;
1552 else
1553 info->insn_type = dis_condbranch;
1554 info->branch_delay_insns = 1;
1555 }
1556 else if ((op->pinfo & (INSN_STORE_MEMORY
67dc82bc 1557 | INSN_LOAD_MEMORY)) != 0)
9bb28706
CD
1558 info->insn_type = dis_dref;
1559
fc8c4fd1 1560 infprintf (is, "%s", op->name);
14daeee3
RS
1561 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1562 {
1563 unsigned int uval;
1564
1565 infprintf (is, ".");
1566 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1567 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1568 }
252b5132 1569
ab902481 1570 if (op->args[0])
252b5132 1571 {
fc8c4fd1 1572 infprintf (is, "\t");
ab902481
RS
1573 print_insn_args (info, op, decode_mips_operand, word,
1574 memaddr + 4);
252b5132
RH
1575 }
1576
aa5f19f2 1577 return INSNLEN;
252b5132
RH
1578 }
1579 }
1580 }
fc8c4fd1 1581#undef GET_OP
252b5132
RH
1582
1583 /* Handle undefined instructions. */
9bb28706 1584 info->insn_type = dis_noninsn;
fc8c4fd1 1585 infprintf (is, "0x%x", word);
aa5f19f2 1586 return INSNLEN;
252b5132 1587}
aa5f19f2 1588\f
252b5132
RH
1589/* Disassemble an operand for a mips16 instruction. */
1590
1591static void
c3c07478
RS
1592print_mips16_insn_arg (struct disassemble_info *info,
1593 struct mips_print_arg_state *state,
1594 const struct mips_opcode *opcode,
1595 char type, bfd_vma memaddr,
1596 unsigned insn, bfd_boolean use_extend,
1597 unsigned extend, bfd_boolean is_offset)
252b5132 1598{
fc8c4fd1
MR
1599 const fprintf_ftype infprintf = info->fprintf_func;
1600 void *is = info->stream;
c3c07478
RS
1601 const struct mips_operand *operand, *ext_operand;
1602 unsigned int uval;
1603 bfd_vma baseaddr;
1604
1605 if (!use_extend)
1606 extend = 0;
fc8c4fd1 1607
252b5132
RH
1608 switch (type)
1609 {
1610 case ',':
1611 case '(':
1612 case ')':
fc8c4fd1 1613 infprintf (is, "%c", type);
252b5132
RH
1614 break;
1615
c3c07478
RS
1616 default:
1617 operand = decode_mips16_operand (type, FALSE);
1618 if (!operand)
1619 {
1620 /* xgettext:c-format */
1621 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1622 opcode->name, opcode->args);
1623 return;
1624 }
252b5132 1625
c3c07478
RS
1626 if (operand->type == OP_SAVE_RESTORE_LIST)
1627 {
1628 /* Handle this case here because of the complex interation
1629 with the EXTEND opcode. */
1630 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1631 const char *sep;
252b5132 1632
c3c07478
RS
1633 amask = extend & 0xf;
1634 if (amask == MIPS16_ALL_ARGS)
1635 {
1636 nargs = 4;
1637 nstatics = 0;
1638 }
1639 else if (amask == MIPS16_ALL_STATICS)
1640 {
1641 nargs = 0;
1642 nstatics = 4;
1643 }
1644 else
1645 {
1646 nargs = amask >> 2;
1647 nstatics = amask & 3;
1648 }
252b5132 1649
c3c07478
RS
1650 sep = "";
1651 if (nargs > 0)
1652 {
1653 infprintf (is, "%s", mips_gpr_names[4]);
1654 if (nargs > 1)
1655 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1656 sep = ",";
1657 }
252b5132 1658
c3c07478
RS
1659 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1660 if (frame_size == 0 && !use_extend)
1661 frame_size = 128;
1662 infprintf (is, "%s%d", sep, frame_size);
1663
1664 if (insn & 0x40) /* $ra */
1665 infprintf (is, ",%s", mips_gpr_names[31]);
1666
1667 nsreg = (extend >> 8) & 0x7;
1668 smask = 0;
1669 if (insn & 0x20) /* $s0 */
1670 smask |= 1 << 0;
1671 if (insn & 0x10) /* $s1 */
1672 smask |= 1 << 1;
1673 if (nsreg > 0) /* $s2-$s8 */
1674 smask |= ((1 << nsreg) - 1) << 2;
1675
1676 for (i = 0; i < 9; i++)
1677 if (smask & (1 << i))
252b5132 1678 {
c3c07478
RS
1679 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1680 /* Skip over string of set bits. */
1681 for (j = i; smask & (2 << j); j++)
1682 continue;
1683 if (j > i)
1684 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1685 i = j + 1;
252b5132 1686 }
c3c07478
RS
1687 /* Statics $ax - $a3. */
1688 if (nstatics == 1)
1689 infprintf (is, ",%s", mips_gpr_names[7]);
1690 else if (nstatics > 0)
1691 infprintf (is, ",%s-%s",
1692 mips_gpr_names[7 - nstatics + 1],
1693 mips_gpr_names[7]);
1694 break;
1695 }
252b5132 1696
c3c07478
RS
1697 if (is_offset && operand->type == OP_INT)
1698 {
1699 const struct mips_int_operand *int_op;
252b5132 1700
c3c07478
RS
1701 int_op = (const struct mips_int_operand *) operand;
1702 info->insn_type = dis_dref;
1703 info->data_size = 1 << int_op->shift;
1704 }
252b5132 1705
c3c07478
RS
1706 if (operand->size == 26)
1707 /* In this case INSN is the first two bytes of the instruction
1708 and EXTEND is the second two bytes. */
1709 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
1710 else
1711 {
1712 /* Calculate the full field value. */
1713 uval = mips_extract_operand (operand, insn);
1714 if (use_extend)
1715 {
1716 ext_operand = decode_mips16_operand (type, TRUE);
1717 if (ext_operand != operand)
1718 {
1719 operand = ext_operand;
1720 if (operand->size == 16)
1721 uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1722 else if (operand->size == 15)
1723 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1724 else
1725 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
1726 }
1727 }
1728 }
1729
1730 baseaddr = memaddr + 2;
1731 if (operand->type == OP_PCREL)
1732 {
1733 const struct mips_pcrel_operand *pcrel_op;
1734
1735 pcrel_op = (const struct mips_pcrel_operand *) operand;
1736 if (!pcrel_op->include_isa_bit && use_extend)
1737 baseaddr = memaddr - 2;
1738 else if (!pcrel_op->include_isa_bit)
1739 {
1740 bfd_byte buffer[2];
1741
1742 /* If this instruction is in the delay slot of a JR
1743 instruction, the base address is the address of the
1744 JR instruction. If it is in the delay slot of a JALR
1745 instruction, the base address is the address of the
1746 JALR instruction. This test is unreliable: we have
1747 no way of knowing whether the previous word is
1748 instruction or data. */
1749 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1750 && (((info->endian == BFD_ENDIAN_BIG
1751 ? bfd_getb16 (buffer)
1752 : bfd_getl16 (buffer))
1753 & 0xf800) == 0x1800))
1754 baseaddr = memaddr - 4;
1755 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1756 info) == 0
252b5132
RH
1757 && (((info->endian == BFD_ENDIAN_BIG
1758 ? bfd_getb16 (buffer)
1759 : bfd_getl16 (buffer))
1760 & 0xf81f) == 0xe800))
c3c07478
RS
1761 baseaddr = memaddr - 2;
1762 else
1763 baseaddr = memaddr;
1764 }
1765 }
0499d65b 1766
6d075bce 1767 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
0499d65b 1768 break;
252b5132
RH
1769 }
1770}
640c0ccd 1771
1bbce132
MR
1772
1773/* Check if the given address is the last word of a MIPS16 PLT entry.
1774 This word is data and depending on the value it may interfere with
1775 disassembly of further PLT entries. We make use of the fact PLT
1776 symbols are marked BSF_SYNTHETIC. */
1777static bfd_boolean
1778is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
1779{
1780 if (info->symbols
1781 && info->symbols[0]
1782 && (info->symbols[0]->flags & BSF_SYNTHETIC)
1783 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
1784 return TRUE;
1785
1786 return FALSE;
1787}
1788
47b0e7ad
NC
1789/* Disassemble mips16 instructions. */
1790
1791static int
1792print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1793{
fc8c4fd1 1794 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1795 int status;
1bbce132 1796 bfd_byte buffer[4];
47b0e7ad
NC
1797 int length;
1798 int insn;
1799 bfd_boolean use_extend;
1800 int extend = 0;
1801 const struct mips_opcode *op, *opend;
c3c07478 1802 struct mips_print_arg_state state;
fc8c4fd1 1803 void *is = info->stream;
47b0e7ad
NC
1804
1805 info->bytes_per_chunk = 2;
1806 info->display_endian = info->endian;
1807 info->insn_info_valid = 1;
1808 info->branch_delay_insns = 0;
1809 info->data_size = 0;
47b0e7ad
NC
1810 info->target = 0;
1811 info->target2 = 0;
1812
c3c07478
RS
1813#define GET_OP(insn, field) \
1814 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1bbce132
MR
1815 /* Decode PLT entry's GOT slot address word. */
1816 if (is_mips16_plt_tail (info, memaddr))
1817 {
1818 info->insn_type = dis_noninsn;
1819 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
1820 if (status == 0)
1821 {
1822 unsigned int gotslot;
1823
1824 if (info->endian == BFD_ENDIAN_BIG)
1825 gotslot = bfd_getb32 (buffer);
1826 else
1827 gotslot = bfd_getl32 (buffer);
1828 infprintf (is, ".word\t0x%x", gotslot);
1829
1830 return 4;
1831 }
1832 }
1833 else
1834 {
1835 info->insn_type = dis_nonbranch;
1836 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1837 }
47b0e7ad
NC
1838 if (status != 0)
1839 {
1840 (*info->memory_error_func) (status, memaddr, info);
1841 return -1;
1842 }
1843
1844 length = 2;
1845
1846 if (info->endian == BFD_ENDIAN_BIG)
1847 insn = bfd_getb16 (buffer);
1848 else
1849 insn = bfd_getl16 (buffer);
1850
1851 /* Handle the extend opcode specially. */
1852 use_extend = FALSE;
1853 if ((insn & 0xf800) == 0xf000)
1854 {
1855 use_extend = TRUE;
1856 extend = insn & 0x7ff;
1857
1858 memaddr += 2;
1859
1860 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1861 if (status != 0)
1862 {
fc8c4fd1 1863 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1864 (*info->memory_error_func) (status, memaddr, info);
1865 return -1;
1866 }
1867
1868 if (info->endian == BFD_ENDIAN_BIG)
1869 insn = bfd_getb16 (buffer);
1870 else
1871 insn = bfd_getl16 (buffer);
1872
1873 /* Check for an extend opcode followed by an extend opcode. */
1874 if ((insn & 0xf800) == 0xf000)
1875 {
fc8c4fd1 1876 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1877 info->insn_type = dis_noninsn;
1878 return length;
1879 }
1880
1881 length += 2;
1882 }
1883
1884 /* FIXME: Should probably use a hash table on the major opcode here. */
1885
1886 opend = mips16_opcodes + bfd_mips16_num_opcodes;
1887 for (op = mips16_opcodes; op < opend; op++)
1888 {
1889 if (op->pinfo != INSN_MACRO
1890 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1891 && (insn & op->mask) == op->match)
1892 {
1893 const char *s;
1894
27c5c572 1895 if (op->args[0] == 'a' || op->args[0] == 'i')
47b0e7ad
NC
1896 {
1897 if (use_extend)
1898 {
fc8c4fd1 1899 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1900 info->insn_type = dis_noninsn;
1901 return length - 2;
1902 }
1903
1904 use_extend = FALSE;
1905
1906 memaddr += 2;
1907
1908 status = (*info->read_memory_func) (memaddr, buffer, 2,
1909 info);
1910 if (status == 0)
1911 {
1912 use_extend = TRUE;
1913 if (info->endian == BFD_ENDIAN_BIG)
1914 extend = bfd_getb16 (buffer);
1915 else
1916 extend = bfd_getl16 (buffer);
1917 length += 2;
1918 }
1919 }
1920
fc8c4fd1 1921 infprintf (is, "%s", op->name);
47b0e7ad 1922 if (op->args[0] != '\0')
fc8c4fd1 1923 infprintf (is, "\t");
47b0e7ad 1924
c3c07478 1925 init_print_arg_state (&state);
47b0e7ad
NC
1926 for (s = op->args; *s != '\0'; s++)
1927 {
1928 if (*s == ','
1929 && s[1] == 'w'
fc8c4fd1 1930 && GET_OP (insn, RX) == GET_OP (insn, RY))
47b0e7ad
NC
1931 {
1932 /* Skip the register and the comma. */
1933 ++s;
1934 continue;
1935 }
1936 if (*s == ','
1937 && s[1] == 'v'
fc8c4fd1 1938 && GET_OP (insn, RZ) == GET_OP (insn, RX))
47b0e7ad
NC
1939 {
1940 /* Skip the register and the comma. */
1941 ++s;
1942 continue;
1943 }
c3c07478
RS
1944 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
1945 use_extend, extend, s[1] == '(');
47b0e7ad
NC
1946 }
1947
9a2c7088 1948 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 1949 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088 1950 info->branch_delay_insns = 1;
26545944
RS
1951 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
1952 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
47b0e7ad 1953 {
9a2c7088
MR
1954 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1955 info->insn_type = dis_jsr;
1956 else
47b0e7ad
NC
1957 info->insn_type = dis_branch;
1958 }
26545944 1959 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
9a2c7088 1960 info->insn_type = dis_condbranch;
47b0e7ad
NC
1961
1962 return length;
1963 }
1964 }
fc8c4fd1 1965#undef GET_OP
47b0e7ad
NC
1966
1967 if (use_extend)
fc8c4fd1
MR
1968 infprintf (is, "0x%x", extend | 0xf000);
1969 infprintf (is, "0x%x", insn);
47b0e7ad
NC
1970 info->insn_type = dis_noninsn;
1971
1972 return length;
1973}
1974
df58fc94
RS
1975/* Disassemble microMIPS instructions. */
1976
1977static int
1978print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
1979{
0c7533d3 1980 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94 1981 const struct mips_opcode *op, *opend;
df58fc94 1982 void *is = info->stream;
df58fc94 1983 bfd_byte buffer[2];
ab902481
RS
1984 unsigned int higher;
1985 unsigned int length;
df58fc94 1986 int status;
ab902481 1987 unsigned int insn;
df58fc94
RS
1988
1989 info->bytes_per_chunk = 2;
1990 info->display_endian = info->endian;
1991 info->insn_info_valid = 1;
1992 info->branch_delay_insns = 0;
1993 info->data_size = 0;
1994 info->insn_type = dis_nonbranch;
1995 info->target = 0;
1996 info->target2 = 0;
1997
1998 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1999 if (status != 0)
2000 {
2001 (*info->memory_error_func) (status, memaddr, info);
2002 return -1;
2003 }
2004
2005 length = 2;
2006
2007 if (info->endian == BFD_ENDIAN_BIG)
2008 insn = bfd_getb16 (buffer);
2009 else
2010 insn = bfd_getl16 (buffer);
2011
2012 if ((insn & 0xfc00) == 0x7c00)
2013 {
2014 /* This is a 48-bit microMIPS instruction. */
2015 higher = insn;
2016
2017 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2018 if (status != 0)
2019 {
0c7533d3 2020 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2021 (*info->memory_error_func) (status, memaddr + 2, info);
2022 return -1;
2023 }
2024 if (info->endian == BFD_ENDIAN_BIG)
2025 insn = bfd_getb16 (buffer);
2026 else
2027 insn = bfd_getl16 (buffer);
2028 higher = (higher << 16) | insn;
2029
2030 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
2031 if (status != 0)
2032 {
0c7533d3 2033 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2034 (*info->memory_error_func) (status, memaddr + 4, info);
2035 return -1;
2036 }
2037 if (info->endian == BFD_ENDIAN_BIG)
2038 insn = bfd_getb16 (buffer);
2039 else
2040 insn = bfd_getl16 (buffer);
0c7533d3 2041 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
df58fc94
RS
2042
2043 info->insn_type = dis_noninsn;
2044 return 6;
2045 }
2046 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2047 {
2048 /* This is a 32-bit microMIPS instruction. */
2049 higher = insn;
2050
2051 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2052 if (status != 0)
2053 {
0c7533d3 2054 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2055 (*info->memory_error_func) (status, memaddr + 2, info);
2056 return -1;
2057 }
2058
2059 if (info->endian == BFD_ENDIAN_BIG)
2060 insn = bfd_getb16 (buffer);
2061 else
2062 insn = bfd_getl16 (buffer);
2063
2064 insn = insn | (higher << 16);
2065
2066 length += 2;
2067 }
2068
2069 /* FIXME: Should probably use a hash table on the major opcode here. */
2070
df58fc94
RS
2071 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2072 for (op = micromips_opcodes; op < opend; op++)
2073 {
2074 if (op->pinfo != INSN_MACRO
2075 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2076 && (insn & op->mask) == op->match
2077 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2078 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2079 {
0c7533d3 2080 infprintf (is, "%s", op->name);
df58fc94 2081
ab902481 2082 if (op->args[0])
df58fc94 2083 {
ab902481
RS
2084 infprintf (is, "\t");
2085 print_insn_args (info, op, decode_micromips_operand, insn,
2086 memaddr + length + 1);
df58fc94
RS
2087 }
2088
2089 /* Figure out instruction type and branch delay information. */
2090 if ((op->pinfo
2091 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2092 info->branch_delay_insns = 1;
2093 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2094 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2095 {
fc76e730 2096 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
df58fc94
RS
2097 info->insn_type = dis_jsr;
2098 else
2099 info->insn_type = dis_branch;
2100 }
2101 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2102 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2103 {
2104 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2105 info->insn_type = dis_condjsr;
2106 else
2107 info->insn_type = dis_condbranch;
2108 }
2109 else if ((op->pinfo
67dc82bc 2110 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
df58fc94
RS
2111 info->insn_type = dis_dref;
2112
2113 return length;
2114 }
2115 }
df58fc94 2116
0c7533d3 2117 infprintf (is, "0x%x", insn);
df58fc94
RS
2118 info->insn_type = dis_noninsn;
2119
2120 return length;
2121}
2122
2123/* Return 1 if a symbol associated with the location being disassembled
2124 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2125 all the symbols at the address being considered assuming if at least
2126 one of them indicates code compression, then such code has been
2127 genuinely produced here (other symbols could have been derived from
2128 function symbols defined elsewhere or could define data). Otherwise,
2129 return 0. */
2130
2131static bfd_boolean
2132is_compressed_mode_p (struct disassemble_info *info)
2133{
df58fc94 2134 int i;
1bbce132
MR
2135 int l;
2136
2137 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2138 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2139 && ((!micromips_ase
2140 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2141 || (micromips_ase
2142 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2143 return 1;
2144 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2145 && info->symtab[i]->section == info->section)
2146 {
2147 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2148 if ((!micromips_ase
2149 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2150 || (micromips_ase
2151 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2152 return 1;
2153 }
df58fc94
RS
2154
2155 return 0;
2156}
2157
47b0e7ad
NC
2158/* In an environment where we do not know the symbol type of the
2159 instruction we are forced to assume that the low order bit of the
2160 instructions' address may mark it as a mips16 instruction. If we
2161 are single stepping, or the pc is within the disassembled function,
2162 this works. Otherwise, we need a clue. Sometimes. */
2163
2164static int
2165_print_insn_mips (bfd_vma memaddr,
2166 struct disassemble_info *info,
2167 enum bfd_endian endianness)
2168{
df58fc94 2169 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
47b0e7ad
NC
2170 bfd_byte buffer[INSNLEN];
2171 int status;
2172
2173 set_default_mips_dis_options (info);
2174 parse_mips_dis_options (info->disassembler_options);
2175
df58fc94
RS
2176 if (info->mach == bfd_mach_mips16)
2177 return print_insn_mips16 (memaddr, info);
2178 if (info->mach == bfd_mach_mips_micromips)
2179 return print_insn_micromips (memaddr, info);
2180
2181 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
2182
47b0e7ad 2183#if 1
df58fc94 2184 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
2185 /* Only a few tools will work this way. */
2186 if (memaddr & 0x01)
df58fc94 2187 return print_insn_compr (memaddr, info);
47b0e7ad
NC
2188#endif
2189
2190#if SYMTAB_AVAILABLE
df58fc94
RS
2191 if (is_compressed_mode_p (info))
2192 return print_insn_compr (memaddr, info);
47b0e7ad
NC
2193#endif
2194
2195 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2196 if (status == 0)
2197 {
fc8c4fd1 2198 int insn;
47b0e7ad
NC
2199
2200 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 2201 insn = bfd_getb32 (buffer);
47b0e7ad 2202 else
fc8c4fd1 2203 insn = bfd_getl32 (buffer);
47b0e7ad
NC
2204
2205 return print_insn_mips (memaddr, insn, info);
2206 }
2207 else
2208 {
2209 (*info->memory_error_func) (status, memaddr, info);
2210 return -1;
2211 }
2212}
2213
2214int
2215print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2216{
2217 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2218}
2219
2220int
2221print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2222{
2223 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2224}
2225\f
640c0ccd 2226void
47b0e7ad 2227print_mips_disassembler_options (FILE *stream)
640c0ccd 2228{
4a9a3c54 2229 unsigned int i;
640c0ccd
CD
2230
2231 fprintf (stream, _("\n\
2232The following MIPS specific disassembler options are supported for use\n\
2233with the -M switch (multiple options should be separated by commas):\n"));
2234
4edbb8e3
CF
2235 fprintf (stream, _("\n\
2236 msa Recognize MSA instructions.\n"));
2237
b015e599
AP
2238 fprintf (stream, _("\n\
2239 virt Recognize the virtualization ASE instructions.\n"));
2240
7d64c587
AB
2241 fprintf (stream, _("\n\
2242 xpa Recognize the eXtended Physical Address (XPA) ASE instructions.\n"));
2243
640c0ccd
CD
2244 fprintf (stream, _("\n\
2245 gpr-names=ABI Print GPR names according to specified ABI.\n\
2246 Default: based on binary being disassembled.\n"));
2247
2248 fprintf (stream, _("\n\
2249 fpr-names=ABI Print FPR names according to specified ABI.\n\
2250 Default: numeric.\n"));
2251
2252 fprintf (stream, _("\n\
2253 cp0-names=ARCH Print CP0 register names according to\n\
2254 specified architecture.\n\
2255 Default: based on binary being disassembled.\n"));
2256
af7ee8bf
CD
2257 fprintf (stream, _("\n\
2258 hwr-names=ARCH Print HWR names according to specified \n\
2259 architecture.\n\
2260 Default: based on binary being disassembled.\n"));
2261
640c0ccd
CD
2262 fprintf (stream, _("\n\
2263 reg-names=ABI Print GPR and FPR names according to\n\
2264 specified ABI.\n"));
2265
2266 fprintf (stream, _("\n\
af7ee8bf 2267 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
2268 specified architecture.\n"));
2269
2270 fprintf (stream, _("\n\
2271 For the options above, the following values are supported for \"ABI\":\n\
2272 "));
4a9a3c54 2273 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
2274 fprintf (stream, " %s", mips_abi_choices[i].name);
2275 fprintf (stream, _("\n"));
2276
2277 fprintf (stream, _("\n\
2278 For the options above, The following values are supported for \"ARCH\":\n\
2279 "));
4a9a3c54 2280 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
2281 if (*mips_arch_choices[i].name != '\0')
2282 fprintf (stream, " %s", mips_arch_choices[i].name);
2283 fprintf (stream, _("\n"));
2284
2285 fprintf (stream, _("\n"));
2286}
This page took 0.876604 seconds and 4 git commands to generate.