PR ld/16787, stale dwarf2 stash
[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
4edbb8e3 554 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA),
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
640c0ccd
CD
559 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
560 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
d301a56b 561 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
bbcc0807
CD
562 mips_cp0_names_mips3264,
563 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
dc76d757 564 mips_cp1_names_mips3264, mips_hwr_names_numeric },
bbcc0807 565
5f74bc13 566 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
d301a56b 567 ISA_MIPS64R2,
7f3c4072 568 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
4edbb8e3 569 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64),
5f74bc13
CD
570 mips_cp0_names_mips3264r2,
571 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
dc76d757 572 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
5f74bc13 573
640c0ccd 574 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
d301a56b 575 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
bbcc0807
CD
576 mips_cp0_names_sb1,
577 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
dc76d757 578 mips_cp1_names_mips3264, mips_hwr_names_numeric },
640c0ccd 579
350cc38d 580 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
d301a56b 581 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
dc76d757 582 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d
MS
583
584 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
d301a56b 585 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
dc76d757 586 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d 587
fd503541 588 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
4ba154f5 589 ISA_MIPS64R2 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
dc76d757 590 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
fd503541 591
57b592a3 592 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
d301a56b 593 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
dc76d757 594 mips_cp1_names_mips3264, mips_hwr_names_numeric },
57b592a3 595
dd6a37e7 596 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
d301a56b 597 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
dc76d757 598 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
432233b3
AP
599
600 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
d301a56b 601 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
dc76d757 602 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
dd6a37e7 603
52b6b6b9 604 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 605 ISA_MIPS64 | INSN_XLR, 0,
52b6b6b9
JM
606 mips_cp0_names_xlr,
607 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 608 mips_cp1_names_mips3264, mips_hwr_names_numeric },
52b6b6b9 609
55a36193
MK
610 /* XLP is mostly like XLR, with the prominent exception it is being
611 MIPS64R2. */
612 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 613 ISA_MIPS64R2 | INSN_XLR, 0,
55a36193
MK
614 mips_cp0_names_xlr,
615 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
dc76d757 616 mips_cp1_names_mips3264, mips_hwr_names_numeric },
55a36193 617
640c0ccd
CD
618 /* This entry, mips16, is here only for ISA/processor selection; do
619 not print its name. */
d301a56b 620 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0,
dc76d757
AB
621 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
622 mips_hwr_names_numeric },
640c0ccd
CD
623};
624
625/* ISA and processor type to disassemble for, and register names to use.
626 set_default_mips_dis_options and parse_mips_dis_options fill in these
627 values. */
628static int mips_processor;
629static int mips_isa;
d301a56b 630static int mips_ase;
df58fc94 631static int micromips_ase;
640c0ccd
CD
632static const char * const *mips_gpr_names;
633static const char * const *mips_fpr_names;
634static const char * const *mips_cp0_names;
bbcc0807
CD
635static const struct mips_cp0sel_name *mips_cp0sel_names;
636static int mips_cp0sel_names_len;
dc76d757 637static const char * const *mips_cp1_names;
af7ee8bf 638static const char * const *mips_hwr_names;
640c0ccd 639
986e18a5 640/* Other options */
47b0e7ad 641static int no_aliases; /* If set disassemble as most general inst. */
640c0ccd
CD
642\f
643static const struct mips_abi_choice *
47b0e7ad 644choose_abi_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
645{
646 const struct mips_abi_choice *c;
647 unsigned int i;
648
649 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
47b0e7ad
NC
650 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
651 && strlen (mips_abi_choices[i].name) == namelen)
652 c = &mips_abi_choices[i];
653
640c0ccd
CD
654 return c;
655}
656
657static const struct mips_arch_choice *
47b0e7ad 658choose_arch_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
659{
660 const struct mips_arch_choice *c = NULL;
661 unsigned int i;
662
663 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
47b0e7ad
NC
664 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
665 && strlen (mips_arch_choices[i].name) == namelen)
666 c = &mips_arch_choices[i];
667
640c0ccd
CD
668 return c;
669}
670
671static const struct mips_arch_choice *
47b0e7ad 672choose_arch_by_number (unsigned long mach)
640c0ccd
CD
673{
674 static unsigned long hint_bfd_mach;
675 static const struct mips_arch_choice *hint_arch_choice;
676 const struct mips_arch_choice *c;
677 unsigned int i;
678
679 /* We optimize this because even if the user specifies no
680 flags, this will be done for every instruction! */
681 if (hint_bfd_mach == mach
682 && hint_arch_choice != NULL
683 && hint_arch_choice->bfd_mach == hint_bfd_mach)
684 return hint_arch_choice;
685
686 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
687 {
688 if (mips_arch_choices[i].bfd_mach_valid
689 && mips_arch_choices[i].bfd_mach == mach)
690 {
691 c = &mips_arch_choices[i];
692 hint_bfd_mach = mach;
693 hint_arch_choice = c;
694 }
695 }
696 return c;
697}
698
47b0e7ad
NC
699/* Check if the object uses NewABI conventions. */
700
701static int
702is_newabi (Elf_Internal_Ehdr *header)
703{
704 /* There are no old-style ABIs which use 64-bit ELF. */
705 if (header->e_ident[EI_CLASS] == ELFCLASS64)
706 return 1;
707
708 /* If a 32-bit ELF file, n32 is a new-style ABI. */
709 if ((header->e_flags & EF_MIPS_ABI2) != 0)
710 return 1;
711
712 return 0;
713}
714
df58fc94
RS
715/* Check if the object has microMIPS ASE code. */
716
717static int
718is_micromips (Elf_Internal_Ehdr *header)
719{
720 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
721 return 1;
722
723 return 0;
724}
725
47b0e7ad
NC
726static void
727set_default_mips_dis_options (struct disassemble_info *info)
640c0ccd
CD
728{
729 const struct mips_arch_choice *chosen_arch;
730
df58fc94
RS
731 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
732 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
733 CP0 register, and HWR names. */
640c0ccd 734 mips_isa = ISA_MIPS3;
df58fc94
RS
735 mips_processor = CPU_R3000;
736 micromips_ase = 0;
d301a56b 737 mips_ase = 0;
640c0ccd
CD
738 mips_gpr_names = mips_gpr_names_oldabi;
739 mips_fpr_names = mips_fpr_names_numeric;
740 mips_cp0_names = mips_cp0_names_numeric;
bbcc0807
CD
741 mips_cp0sel_names = NULL;
742 mips_cp0sel_names_len = 0;
dc76d757 743 mips_cp1_names = mips_cp1_names_numeric;
af7ee8bf 744 mips_hwr_names = mips_hwr_names_numeric;
986e18a5 745 no_aliases = 0;
640c0ccd 746
df58fc94 747 /* Update settings according to the ELF file header flags. */
fec06546 748 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
640c0ccd
CD
749 {
750 Elf_Internal_Ehdr *header;
751
fec06546 752 header = elf_elfheader (info->section->owner);
df58fc94 753 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
640c0ccd
CD
754 if (is_newabi (header))
755 mips_gpr_names = mips_gpr_names_newabi;
df58fc94
RS
756 /* If a microMIPS binary, then don't use MIPS16 bindings. */
757 micromips_ase = is_micromips (header);
640c0ccd
CD
758 }
759
760 /* Set ISA, architecture, and cp0 register names as best we can. */
761#if ! SYMTAB_AVAILABLE
762 /* This is running out on a target machine, not in a host tool.
763 FIXME: Where does mips_target_info come from? */
764 target_processor = mips_target_info.processor;
765 mips_isa = mips_target_info.isa;
d301a56b 766 mips_ase = mips_target_info.ase;
640c0ccd
CD
767#else
768 chosen_arch = choose_arch_by_number (info->mach);
769 if (chosen_arch != NULL)
770 {
771 mips_processor = chosen_arch->processor;
772 mips_isa = chosen_arch->isa;
d301a56b 773 mips_ase = chosen_arch->ase;
bbcc0807
CD
774 mips_cp0_names = chosen_arch->cp0_names;
775 mips_cp0sel_names = chosen_arch->cp0sel_names;
776 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 777 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 778 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
779 }
780#endif
781}
782
47b0e7ad
NC
783static void
784parse_mips_dis_option (const char *option, unsigned int len)
640c0ccd
CD
785{
786 unsigned int i, optionlen, vallen;
787 const char *val;
788 const struct mips_abi_choice *chosen_abi;
789 const struct mips_arch_choice *chosen_arch;
790
986e18a5 791 /* Try to match options that are simple flags */
0112cd26 792 if (CONST_STRNEQ (option, "no-aliases"))
986e18a5
FF
793 {
794 no_aliases = 1;
795 return;
796 }
b015e599 797
4edbb8e3
CF
798 if (CONST_STRNEQ (option, "msa"))
799 {
800 mips_ase |= ASE_MSA;
801 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2)
802 mips_ase |= ASE_MSA64;
803 return;
804 }
805
b015e599
AP
806 if (CONST_STRNEQ (option, "virt"))
807 {
d301a56b 808 mips_ase |= ASE_VIRT;
b015e599 809 if (mips_isa & ISA_MIPS64R2)
d301a56b 810 mips_ase |= ASE_VIRT64;
b015e599
AP
811 return;
812 }
986e18a5 813
640c0ccd
CD
814 /* Look for the = that delimits the end of the option name. */
815 for (i = 0; i < len; i++)
47b0e7ad
NC
816 if (option[i] == '=')
817 break;
818
640c0ccd
CD
819 if (i == 0) /* Invalid option: no name before '='. */
820 return;
821 if (i == len) /* Invalid option: no '='. */
822 return;
823 if (i == (len - 1)) /* Invalid option: no value after '='. */
824 return;
825
826 optionlen = i;
827 val = option + (optionlen + 1);
828 vallen = len - (optionlen + 1);
829
47b0e7ad
NC
830 if (strncmp ("gpr-names", option, optionlen) == 0
831 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
832 {
833 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 834 if (chosen_abi != NULL)
640c0ccd
CD
835 mips_gpr_names = chosen_abi->gpr_names;
836 return;
837 }
838
47b0e7ad
NC
839 if (strncmp ("fpr-names", option, optionlen) == 0
840 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
841 {
842 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 843 if (chosen_abi != NULL)
640c0ccd
CD
844 mips_fpr_names = chosen_abi->fpr_names;
845 return;
846 }
847
47b0e7ad
NC
848 if (strncmp ("cp0-names", option, optionlen) == 0
849 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
850 {
851 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
852 if (chosen_arch != NULL)
853 {
854 mips_cp0_names = chosen_arch->cp0_names;
855 mips_cp0sel_names = chosen_arch->cp0sel_names;
856 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
857 }
640c0ccd
CD
858 return;
859 }
860
dc76d757
AB
861 if (strncmp ("cp1-names", option, optionlen) == 0
862 && strlen ("cp1-names") == optionlen)
863 {
864 chosen_arch = choose_arch_by_name (val, vallen);
865 if (chosen_arch != NULL)
866 mips_cp1_names = chosen_arch->cp1_names;
867 return;
868 }
869
47b0e7ad
NC
870 if (strncmp ("hwr-names", option, optionlen) == 0
871 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
872 {
873 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 874 if (chosen_arch != NULL)
af7ee8bf
CD
875 mips_hwr_names = chosen_arch->hwr_names;
876 return;
877 }
878
47b0e7ad
NC
879 if (strncmp ("reg-names", option, optionlen) == 0
880 && strlen ("reg-names") == optionlen)
640c0ccd
CD
881 {
882 /* We check both ABI and ARCH here unconditionally, so
883 that "numeric" will do the desirable thing: select
884 numeric register names for all registers. Other than
885 that, a given name probably won't match both. */
886 chosen_abi = choose_abi_by_name (val, vallen);
887 if (chosen_abi != NULL)
888 {
bbcc0807
CD
889 mips_gpr_names = chosen_abi->gpr_names;
890 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
891 }
892 chosen_arch = choose_arch_by_name (val, vallen);
893 if (chosen_arch != NULL)
894 {
bbcc0807
CD
895 mips_cp0_names = chosen_arch->cp0_names;
896 mips_cp0sel_names = chosen_arch->cp0sel_names;
897 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 898 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 899 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
900 }
901 return;
902 }
903
904 /* Invalid option. */
905}
906
47b0e7ad
NC
907static void
908parse_mips_dis_options (const char *options)
640c0ccd
CD
909{
910 const char *option_end;
911
912 if (options == NULL)
913 return;
914
915 while (*options != '\0')
916 {
917 /* Skip empty options. */
918 if (*options == ',')
919 {
920 options++;
921 continue;
922 }
923
924 /* We know that *options is neither NUL or a comma. */
925 option_end = options + 1;
926 while (*option_end != ',' && *option_end != '\0')
927 option_end++;
928
929 parse_mips_dis_option (options, option_end - options);
930
931 /* Go on to the next one. If option_end points to a comma, it
932 will be skipped above. */
933 options = option_end;
934 }
935}
936
bbcc0807 937static const struct mips_cp0sel_name *
47b0e7ad
NC
938lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
939 unsigned int len,
940 unsigned int cp0reg,
941 unsigned int sel)
bbcc0807
CD
942{
943 unsigned int i;
944
945 for (i = 0; i < len; i++)
946 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
947 return &names[i];
948 return NULL;
949}
ab902481
RS
950
951/* Print register REGNO, of type TYPE, for instruction OPCODE. */
aa5f19f2 952
794ac9d0 953static void
ab902481
RS
954print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
955 enum mips_reg_operand_type type, int regno)
252b5132 956{
ab902481
RS
957 switch (type)
958 {
959 case OP_REG_GP:
960 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
961 break;
440cc0bc 962
ab902481
RS
963 case OP_REG_FP:
964 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
965 break;
252b5132 966
ab902481
RS
967 case OP_REG_CCC:
968 if (opcode->pinfo & (FP_D | FP_S))
969 info->fprintf_func (info->stream, "$fcc%d", regno);
970 else
971 info->fprintf_func (info->stream, "$cc%d", regno);
972 break;
794ac9d0 973
ab902481
RS
974 case OP_REG_VEC:
975 if (opcode->membership & INSN_5400)
976 info->fprintf_func (info->stream, "$f%d", regno);
977 else
978 info->fprintf_func (info->stream, "$v%d", regno);
979 break;
794ac9d0 980
ab902481
RS
981 case OP_REG_ACC:
982 info->fprintf_func (info->stream, "$ac%d", regno);
983 break;
794ac9d0 984
ab902481
RS
985 case OP_REG_COPRO:
986 if (opcode->name[strlen (opcode->name) - 1] == '0')
987 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
dc76d757
AB
988 else if (opcode->name[strlen (opcode->name) - 1] == '1')
989 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
ab902481
RS
990 else
991 info->fprintf_func (info->stream, "$%d", regno);
992 break;
8b082fb1 993
ab902481
RS
994 case OP_REG_HW:
995 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
996 break;
14daeee3
RS
997
998 case OP_REG_VF:
999 info->fprintf_func (info->stream, "$vf%d", regno);
1000 break;
1001
1002 case OP_REG_VI:
1003 info->fprintf_func (info->stream, "$vi%d", regno);
1004 break;
1005
1006 case OP_REG_R5900_I:
1007 info->fprintf_func (info->stream, "$I");
1008 break;
1009
1010 case OP_REG_R5900_Q:
1011 info->fprintf_func (info->stream, "$Q");
1012 break;
1013
1014 case OP_REG_R5900_R:
1015 info->fprintf_func (info->stream, "$R");
1016 break;
1017
1018 case OP_REG_R5900_ACC:
1019 info->fprintf_func (info->stream, "$ACC");
1020 break;
4edbb8e3
CF
1021
1022 case OP_REG_MSA:
1023 info->fprintf_func (info->stream, "$w%d", regno);
1024 break;
1025
1026 case OP_REG_MSA_CTRL:
1027 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1028 break;
1029
ab902481
RS
1030 }
1031}
1032\f
1033/* Used to track the state carried over from previous operands in
1034 an instruction. */
1035struct mips_print_arg_state {
1036 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1037 where the value is known to be unsigned and small. */
1038 unsigned int last_int;
1039
1040 /* The type and number of the last OP_REG seen. We only use this for
1041 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1042 enum mips_reg_operand_type last_reg_type;
1043 unsigned int last_regno;
1044};
fd25c5a9 1045
ab902481 1046/* Initialize STATE for the start of an instruction. */
fd25c5a9 1047
ab902481
RS
1048static inline void
1049init_print_arg_state (struct mips_print_arg_state *state)
1050{
1051 memset (state, 0, sizeof (*state));
1052}
fd25c5a9 1053
14daeee3
RS
1054/* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1055 whose value is given by UVAL. */
1056
1057static void
1058print_vu0_channel (struct disassemble_info *info,
1059 const struct mips_operand *operand, unsigned int uval)
1060{
1061 if (operand->size == 4)
1062 info->fprintf_func (info->stream, "%s%s%s%s",
1063 uval & 8 ? "x" : "",
1064 uval & 4 ? "y" : "",
1065 uval & 2 ? "z" : "",
1066 uval & 1 ? "w" : "");
1067 else if (operand->size == 2)
1068 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1069 else
1070 abort ();
1071}
1072
ab902481
RS
1073/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1074 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1075 the base address for OP_PCREL operands. */
fd25c5a9 1076
ab902481
RS
1077static void
1078print_insn_arg (struct disassemble_info *info,
1079 struct mips_print_arg_state *state,
1080 const struct mips_opcode *opcode,
1081 const struct mips_operand *operand,
1082 bfd_vma base_pc,
1083 unsigned int uval)
1084{
1085 const fprintf_ftype infprintf = info->fprintf_func;
1086 void *is = info->stream;
fd25c5a9 1087
ab902481
RS
1088 switch (operand->type)
1089 {
1090 case OP_INT:
1091 {
1092 const struct mips_int_operand *int_op;
fd25c5a9 1093
ab902481
RS
1094 int_op = (const struct mips_int_operand *) operand;
1095 uval = mips_decode_int_operand (int_op, uval);
1096 state->last_int = uval;
1097 if (int_op->print_hex)
1098 infprintf (is, "0x%x", uval);
1099 else
1100 infprintf (is, "%d", uval);
1101 }
1102 break;
fd25c5a9 1103
ab902481
RS
1104 case OP_MAPPED_INT:
1105 {
1106 const struct mips_mapped_int_operand *mint_op;
fd25c5a9 1107
ab902481
RS
1108 mint_op = (const struct mips_mapped_int_operand *) operand;
1109 uval = mint_op->int_map[uval];
1110 state->last_int = uval;
1111 if (mint_op->print_hex)
1112 infprintf (is, "0x%x", uval);
1113 else
1114 infprintf (is, "%d", uval);
1115 }
1116 break;
fd25c5a9 1117
ab902481
RS
1118 case OP_MSB:
1119 {
1120 const struct mips_msb_operand *msb_op;
dec0624d 1121
ab902481
RS
1122 msb_op = (const struct mips_msb_operand *) operand;
1123 uval += msb_op->bias;
1124 if (msb_op->add_lsb)
1125 uval -= state->last_int;
1126 infprintf (is, "0x%x", uval);
1127 }
1128 break;
dec0624d 1129
ab902481 1130 case OP_REG:
0f35dbc4 1131 case OP_OPTIONAL_REG:
ab902481
RS
1132 {
1133 const struct mips_reg_operand *reg_op;
fd25c5a9 1134
ab902481 1135 reg_op = (const struct mips_reg_operand *) operand;
fc76e730 1136 uval = mips_decode_reg_operand (reg_op, uval);
ab902481 1137 print_reg (info, opcode, reg_op->reg_type, uval);
fd25c5a9 1138
ab902481
RS
1139 state->last_reg_type = reg_op->reg_type;
1140 state->last_regno = uval;
1141 }
1142 break;
61cc0267 1143
ab902481
RS
1144 case OP_REG_PAIR:
1145 {
1146 const struct mips_reg_pair_operand *pair_op;
1147
1148 pair_op = (const struct mips_reg_pair_operand *) operand;
1149 print_reg (info, opcode, pair_op->reg_type,
1150 pair_op->reg1_map[uval]);
1151 infprintf (is, ",");
1152 print_reg (info, opcode, pair_op->reg_type,
1153 pair_op->reg2_map[uval]);
1154 }
1155 break;
61cc0267 1156
ab902481
RS
1157 case OP_PCREL:
1158 {
1159 const struct mips_pcrel_operand *pcrel_op;
61cc0267 1160
ab902481
RS
1161 pcrel_op = (const struct mips_pcrel_operand *) operand;
1162 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
61cc0267 1163
ab902481
RS
1164 /* Preserve the ISA bit for the GDB disassembler,
1165 otherwise clear it. */
1166 if (info->flavour != bfd_target_unknown_flavour)
1167 info->target &= -2;
61cc0267 1168
ab902481
RS
1169 (*info->print_address_func) (info->target, info);
1170 }
1171 break;
794ac9d0 1172
ab902481
RS
1173 case OP_PERF_REG:
1174 infprintf (is, "%d", uval);
1175 break;
794ac9d0 1176
ab902481
RS
1177 case OP_ADDIUSP_INT:
1178 {
1179 int sval;
794ac9d0 1180
ab902481
RS
1181 sval = mips_signed_operand (operand, uval) * 4;
1182 if (sval >= -8 && sval < 8)
1183 sval ^= 0x400;
1184 infprintf (is, "%d", sval);
1185 break;
1186 }
794ac9d0 1187
ab902481
RS
1188 case OP_CLO_CLZ_DEST:
1189 {
1190 unsigned int reg1, reg2;
1191
1192 reg1 = uval & 31;
1193 reg2 = uval >> 5;
1194 /* If one is zero use the other. */
1195 if (reg1 == reg2 || reg2 == 0)
1196 infprintf (is, "%s", mips_gpr_names[reg1]);
1197 else if (reg1 == 0)
1198 infprintf (is, "%s", mips_gpr_names[reg2]);
1199 else
1200 /* Bogus, result depends on processor. */
1201 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1202 mips_gpr_names[reg2]);
1203 }
1204 break;
794ac9d0 1205
ab902481
RS
1206 case OP_LWM_SWM_LIST:
1207 if (operand->size == 2)
1208 {
1209 if (uval == 0)
1210 infprintf (is, "%s,%s",
1211 mips_gpr_names[16],
1212 mips_gpr_names[31]);
1213 else
1214 infprintf (is, "%s-%s,%s",
1215 mips_gpr_names[16],
1216 mips_gpr_names[16 + uval],
1217 mips_gpr_names[31]);
1218 }
1219 else
1220 {
1221 int s_reg_encode;
794ac9d0 1222
ab902481
RS
1223 s_reg_encode = uval & 0xf;
1224 if (s_reg_encode != 0)
1225 {
1226 if (s_reg_encode == 1)
1227 infprintf (is, "%s", mips_gpr_names[16]);
1228 else if (s_reg_encode < 9)
1229 infprintf (is, "%s-%s",
1230 mips_gpr_names[16],
1231 mips_gpr_names[15 + s_reg_encode]);
1232 else if (s_reg_encode == 9)
1233 infprintf (is, "%s-%s,%s",
1234 mips_gpr_names[16],
1235 mips_gpr_names[23],
1236 mips_gpr_names[30]);
1237 else
1238 infprintf (is, "UNKNOWN");
1239 }
794ac9d0 1240
ab902481
RS
1241 if (uval & 0x10) /* For ra. */
1242 {
1243 if (s_reg_encode == 0)
1244 infprintf (is, "%s", mips_gpr_names[31]);
1245 else
1246 infprintf (is, ",%s", mips_gpr_names[31]);
1247 }
1248 }
1249 break;
794ac9d0 1250
c3c07478
RS
1251 case OP_ENTRY_EXIT_LIST:
1252 {
1253 const char *sep;
1254 unsigned int amask, smask;
1255
1256 sep = "";
1257 amask = (uval >> 3) & 7;
1258 if (amask > 0 && amask < 5)
1259 {
1260 infprintf (is, "%s", mips_gpr_names[4]);
1261 if (amask > 1)
1262 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1263 sep = ",";
1264 }
1265
1266 smask = (uval >> 1) & 3;
1267 if (smask == 3)
1268 {
1269 infprintf (is, "%s??", sep);
1270 sep = ",";
1271 }
1272 else if (smask > 0)
1273 {
1274 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1275 if (smask > 1)
1276 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1277 sep = ",";
1278 }
1279
1280 if (uval & 1)
1281 {
1282 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1283 sep = ",";
1284 }
1285
1286 if (amask == 5 || amask == 6)
1287 {
1288 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1289 if (amask == 6)
1290 infprintf (is, "-%s", mips_fpr_names[1]);
1291 }
1292 }
1293 break;
1294
1295 case OP_SAVE_RESTORE_LIST:
1296 /* Should be handled by the caller due to extend behavior. */
1297 abort ();
1298
ab902481
RS
1299 case OP_MDMX_IMM_REG:
1300 {
1301 unsigned int vsel;
794ac9d0 1302
ab902481
RS
1303 vsel = uval >> 5;
1304 uval &= 31;
1305 if ((vsel & 0x10) == 0)
794ac9d0 1306 {
ab902481
RS
1307 int fmt;
1308
1309 vsel &= 0x0f;
1310 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1311 if ((vsel & 1) == 0)
1312 break;
1313 print_reg (info, opcode, OP_REG_VEC, uval);
1314 infprintf (is, "[%d]", vsel >> 1);
794ac9d0 1315 }
ab902481
RS
1316 else if ((vsel & 0x08) == 0)
1317 print_reg (info, opcode, OP_REG_VEC, uval);
1318 else
1319 infprintf (is, "0x%x", uval);
1320 }
1321 break;
794ac9d0 1322
ab902481
RS
1323 case OP_REPEAT_PREV_REG:
1324 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1325 break;
794ac9d0 1326
ab902481
RS
1327 case OP_REPEAT_DEST_REG:
1328 /* Should always match OP_REPEAT_PREV_REG first. */
1329 abort ();
794ac9d0 1330
ab902481
RS
1331 case OP_PC:
1332 infprintf (is, "$pc");
1333 break;
14daeee3
RS
1334
1335 case OP_VU0_SUFFIX:
1336 case OP_VU0_MATCH_SUFFIX:
1337 print_vu0_channel (info, operand, uval);
1338 break;
4edbb8e3
CF
1339
1340 case OP_IMM_INDEX:
1341 infprintf (is, "[%d]", uval);
1342 break;
1343
1344 case OP_REG_INDEX:
1345 infprintf (is, "[");
1346 print_reg (info, opcode, OP_REG_GP, uval);
1347 infprintf (is, "]");
1348 break;
ab902481
RS
1349 }
1350}
794ac9d0 1351
ab902481
RS
1352/* Print the arguments for INSN, which is described by OPCODE.
1353 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1354 as the base of OP_PCREL operands. */
af7ee8bf 1355
ab902481
RS
1356static void
1357print_insn_args (struct disassemble_info *info,
1358 const struct mips_opcode *opcode,
1359 const struct mips_operand *(*decode_operand) (const char *),
1360 unsigned int insn, bfd_vma base_pc)
1361{
1362 const fprintf_ftype infprintf = info->fprintf_func;
1363 void *is = info->stream;
1364 struct mips_print_arg_state state;
1365 const struct mips_operand *operand;
1366 const char *s;
794ac9d0 1367
ab902481
RS
1368 init_print_arg_state (&state);
1369 for (s = opcode->args; *s; ++s)
1370 {
1371 switch (*s)
1372 {
1373 case ',':
1374 case '(':
1375 case ')':
1376 infprintf (is, "%c", *s);
794ac9d0
CD
1377 break;
1378
14daeee3
RS
1379 case '#':
1380 ++s;
1381 infprintf (is, "%c%c", *s, *s);
1382 break;
1383
ab902481
RS
1384 default:
1385 operand = decode_operand (s);
1386 if (!operand)
fa7616a4 1387 {
ab902481
RS
1388 /* xgettext:c-format */
1389 infprintf (is,
1390 _("# internal error, undefined operand in `%s %s'"),
1391 opcode->name, opcode->args);
1392 return;
1393 }
1394 if (operand->type == OP_REG
1395 && s[1] == ','
1396 && s[2] == 'H'
1397 && opcode->name[strlen (opcode->name) - 1] == '0')
1398 {
1399 /* Coprocessor register 0 with sel field (MT ASE). */
1400 const struct mips_cp0sel_name *n;
1401 unsigned int reg, sel;
1402
1403 reg = mips_extract_operand (operand, insn);
1404 s += 2;
1405 operand = decode_operand (s);
1406 sel = mips_extract_operand (operand, insn);
1407
1408 /* CP0 register including 'sel' code for mftc0, to be
1409 printed textually if known. If not known, print both
1410 CP0 register name and sel numerically since CP0 register
1411 with sel 0 may have a name unrelated to register being
1412 printed. */
1413 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1414 mips_cp0sel_names_len,
1415 reg, sel);
1416 if (n != NULL)
1417 infprintf (is, "%s", n->name);
fa7616a4 1418 else
ab902481 1419 infprintf (is, "$%d,%d", reg, sel);
fa7616a4 1420 }
794ac9d0 1421 else
ab902481
RS
1422 print_insn_arg (info, &state, opcode, operand, base_pc,
1423 mips_extract_operand (operand, insn));
1424 if (*s == 'm' || *s == '+')
1425 ++s;
794ac9d0 1426 break;
af7ee8bf 1427 }
252b5132
RH
1428 }
1429}
1430\f
252b5132
RH
1431/* Print the mips instruction at address MEMADDR in debugged memory,
1432 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1433 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1434 this is little-endian code. */
1435
1436static int
47b0e7ad 1437print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1438 int word,
47b0e7ad 1439 struct disassemble_info *info)
252b5132 1440{
ab902481
RS
1441#define GET_OP(insn, field) \
1442 (((insn) >> OP_SH_##field) & OP_MASK_##field)
fc8c4fd1
MR
1443 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1444 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1445 const struct mips_opcode *op;
b34976b6 1446 static bfd_boolean init = 0;
fc8c4fd1 1447 void *is = info->stream;
252b5132
RH
1448
1449 /* Build a hash table to shorten the search time. */
1450 if (! init)
1451 {
1452 unsigned int i;
1453
1454 for (i = 0; i <= OP_MASK_OP; i++)
1455 {
1456 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1457 {
986e18a5 1458 if (op->pinfo == INSN_MACRO
9e836e3d 1459 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1460 continue;
fc8c4fd1 1461 if (i == GET_OP (op->match, OP))
252b5132
RH
1462 {
1463 mips_hash[i] = op;
1464 break;
1465 }
1466 }
7f6621cd 1467 }
252b5132
RH
1468
1469 init = 1;
1470 }
1471
aa5f19f2 1472 info->bytes_per_chunk = INSNLEN;
252b5132 1473 info->display_endian = info->endian;
9bb28706
CD
1474 info->insn_info_valid = 1;
1475 info->branch_delay_insns = 0;
def7143b 1476 info->data_size = 0;
9bb28706
CD
1477 info->insn_type = dis_nonbranch;
1478 info->target = 0;
1479 info->target2 = 0;
252b5132 1480
fc8c4fd1 1481 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1482 if (op != NULL)
1483 {
1484 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1485 {
986e18a5 1486 if (op->pinfo != INSN_MACRO
9e836e3d 1487 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1488 && (word & op->mask) == op->match)
252b5132 1489 {
3396de36 1490 /* We always allow to disassemble the jalx instruction. */
d301a56b 1491 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
3396de36 1492 && strcmp (op->name, "jalx"))
252b5132
RH
1493 continue;
1494
9bb28706
CD
1495 /* Figure out instruction type and branch delay information. */
1496 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1497 {
fc76e730 1498 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
9bb28706
CD
1499 info->insn_type = dis_jsr;
1500 else
1501 info->insn_type = dis_branch;
1502 info->branch_delay_insns = 1;
1503 }
1504 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1505 | INSN_COND_BRANCH_LIKELY)) != 0)
1506 {
c680e7f6 1507 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1508 info->insn_type = dis_condjsr;
1509 else
1510 info->insn_type = dis_condbranch;
1511 info->branch_delay_insns = 1;
1512 }
1513 else if ((op->pinfo & (INSN_STORE_MEMORY
67dc82bc 1514 | INSN_LOAD_MEMORY)) != 0)
9bb28706
CD
1515 info->insn_type = dis_dref;
1516
fc8c4fd1 1517 infprintf (is, "%s", op->name);
14daeee3
RS
1518 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1519 {
1520 unsigned int uval;
1521
1522 infprintf (is, ".");
1523 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1524 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1525 }
252b5132 1526
ab902481 1527 if (op->args[0])
252b5132 1528 {
fc8c4fd1 1529 infprintf (is, "\t");
ab902481
RS
1530 print_insn_args (info, op, decode_mips_operand, word,
1531 memaddr + 4);
252b5132
RH
1532 }
1533
aa5f19f2 1534 return INSNLEN;
252b5132
RH
1535 }
1536 }
1537 }
fc8c4fd1 1538#undef GET_OP
252b5132
RH
1539
1540 /* Handle undefined instructions. */
9bb28706 1541 info->insn_type = dis_noninsn;
fc8c4fd1 1542 infprintf (is, "0x%x", word);
aa5f19f2 1543 return INSNLEN;
252b5132 1544}
aa5f19f2 1545\f
252b5132
RH
1546/* Disassemble an operand for a mips16 instruction. */
1547
1548static void
c3c07478
RS
1549print_mips16_insn_arg (struct disassemble_info *info,
1550 struct mips_print_arg_state *state,
1551 const struct mips_opcode *opcode,
1552 char type, bfd_vma memaddr,
1553 unsigned insn, bfd_boolean use_extend,
1554 unsigned extend, bfd_boolean is_offset)
252b5132 1555{
fc8c4fd1
MR
1556 const fprintf_ftype infprintf = info->fprintf_func;
1557 void *is = info->stream;
c3c07478
RS
1558 const struct mips_operand *operand, *ext_operand;
1559 unsigned int uval;
1560 bfd_vma baseaddr;
1561
1562 if (!use_extend)
1563 extend = 0;
fc8c4fd1 1564
252b5132
RH
1565 switch (type)
1566 {
1567 case ',':
1568 case '(':
1569 case ')':
fc8c4fd1 1570 infprintf (is, "%c", type);
252b5132
RH
1571 break;
1572
c3c07478
RS
1573 default:
1574 operand = decode_mips16_operand (type, FALSE);
1575 if (!operand)
1576 {
1577 /* xgettext:c-format */
1578 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1579 opcode->name, opcode->args);
1580 return;
1581 }
252b5132 1582
c3c07478
RS
1583 if (operand->type == OP_SAVE_RESTORE_LIST)
1584 {
1585 /* Handle this case here because of the complex interation
1586 with the EXTEND opcode. */
1587 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1588 const char *sep;
252b5132 1589
c3c07478
RS
1590 amask = extend & 0xf;
1591 if (amask == MIPS16_ALL_ARGS)
1592 {
1593 nargs = 4;
1594 nstatics = 0;
1595 }
1596 else if (amask == MIPS16_ALL_STATICS)
1597 {
1598 nargs = 0;
1599 nstatics = 4;
1600 }
1601 else
1602 {
1603 nargs = amask >> 2;
1604 nstatics = amask & 3;
1605 }
252b5132 1606
c3c07478
RS
1607 sep = "";
1608 if (nargs > 0)
1609 {
1610 infprintf (is, "%s", mips_gpr_names[4]);
1611 if (nargs > 1)
1612 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1613 sep = ",";
1614 }
252b5132 1615
c3c07478
RS
1616 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1617 if (frame_size == 0 && !use_extend)
1618 frame_size = 128;
1619 infprintf (is, "%s%d", sep, frame_size);
1620
1621 if (insn & 0x40) /* $ra */
1622 infprintf (is, ",%s", mips_gpr_names[31]);
1623
1624 nsreg = (extend >> 8) & 0x7;
1625 smask = 0;
1626 if (insn & 0x20) /* $s0 */
1627 smask |= 1 << 0;
1628 if (insn & 0x10) /* $s1 */
1629 smask |= 1 << 1;
1630 if (nsreg > 0) /* $s2-$s8 */
1631 smask |= ((1 << nsreg) - 1) << 2;
1632
1633 for (i = 0; i < 9; i++)
1634 if (smask & (1 << i))
252b5132 1635 {
c3c07478
RS
1636 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1637 /* Skip over string of set bits. */
1638 for (j = i; smask & (2 << j); j++)
1639 continue;
1640 if (j > i)
1641 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1642 i = j + 1;
252b5132 1643 }
c3c07478
RS
1644 /* Statics $ax - $a3. */
1645 if (nstatics == 1)
1646 infprintf (is, ",%s", mips_gpr_names[7]);
1647 else if (nstatics > 0)
1648 infprintf (is, ",%s-%s",
1649 mips_gpr_names[7 - nstatics + 1],
1650 mips_gpr_names[7]);
1651 break;
1652 }
252b5132 1653
c3c07478
RS
1654 if (is_offset && operand->type == OP_INT)
1655 {
1656 const struct mips_int_operand *int_op;
252b5132 1657
c3c07478
RS
1658 int_op = (const struct mips_int_operand *) operand;
1659 info->insn_type = dis_dref;
1660 info->data_size = 1 << int_op->shift;
1661 }
252b5132 1662
c3c07478
RS
1663 if (operand->size == 26)
1664 /* In this case INSN is the first two bytes of the instruction
1665 and EXTEND is the second two bytes. */
1666 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
1667 else
1668 {
1669 /* Calculate the full field value. */
1670 uval = mips_extract_operand (operand, insn);
1671 if (use_extend)
1672 {
1673 ext_operand = decode_mips16_operand (type, TRUE);
1674 if (ext_operand != operand)
1675 {
1676 operand = ext_operand;
1677 if (operand->size == 16)
1678 uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1679 else if (operand->size == 15)
1680 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1681 else
1682 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
1683 }
1684 }
1685 }
1686
1687 baseaddr = memaddr + 2;
1688 if (operand->type == OP_PCREL)
1689 {
1690 const struct mips_pcrel_operand *pcrel_op;
1691
1692 pcrel_op = (const struct mips_pcrel_operand *) operand;
1693 if (!pcrel_op->include_isa_bit && use_extend)
1694 baseaddr = memaddr - 2;
1695 else if (!pcrel_op->include_isa_bit)
1696 {
1697 bfd_byte buffer[2];
1698
1699 /* If this instruction is in the delay slot of a JR
1700 instruction, the base address is the address of the
1701 JR instruction. If it is in the delay slot of a JALR
1702 instruction, the base address is the address of the
1703 JALR instruction. This test is unreliable: we have
1704 no way of knowing whether the previous word is
1705 instruction or data. */
1706 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1707 && (((info->endian == BFD_ENDIAN_BIG
1708 ? bfd_getb16 (buffer)
1709 : bfd_getl16 (buffer))
1710 & 0xf800) == 0x1800))
1711 baseaddr = memaddr - 4;
1712 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1713 info) == 0
252b5132
RH
1714 && (((info->endian == BFD_ENDIAN_BIG
1715 ? bfd_getb16 (buffer)
1716 : bfd_getl16 (buffer))
1717 & 0xf81f) == 0xe800))
c3c07478
RS
1718 baseaddr = memaddr - 2;
1719 else
1720 baseaddr = memaddr;
1721 }
1722 }
0499d65b 1723
6d075bce 1724 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
0499d65b 1725 break;
252b5132
RH
1726 }
1727}
640c0ccd 1728
1bbce132
MR
1729
1730/* Check if the given address is the last word of a MIPS16 PLT entry.
1731 This word is data and depending on the value it may interfere with
1732 disassembly of further PLT entries. We make use of the fact PLT
1733 symbols are marked BSF_SYNTHETIC. */
1734static bfd_boolean
1735is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
1736{
1737 if (info->symbols
1738 && info->symbols[0]
1739 && (info->symbols[0]->flags & BSF_SYNTHETIC)
1740 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
1741 return TRUE;
1742
1743 return FALSE;
1744}
1745
47b0e7ad
NC
1746/* Disassemble mips16 instructions. */
1747
1748static int
1749print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1750{
fc8c4fd1 1751 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1752 int status;
1bbce132 1753 bfd_byte buffer[4];
47b0e7ad
NC
1754 int length;
1755 int insn;
1756 bfd_boolean use_extend;
1757 int extend = 0;
1758 const struct mips_opcode *op, *opend;
c3c07478 1759 struct mips_print_arg_state state;
fc8c4fd1 1760 void *is = info->stream;
47b0e7ad
NC
1761
1762 info->bytes_per_chunk = 2;
1763 info->display_endian = info->endian;
1764 info->insn_info_valid = 1;
1765 info->branch_delay_insns = 0;
1766 info->data_size = 0;
47b0e7ad
NC
1767 info->target = 0;
1768 info->target2 = 0;
1769
c3c07478
RS
1770#define GET_OP(insn, field) \
1771 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1bbce132
MR
1772 /* Decode PLT entry's GOT slot address word. */
1773 if (is_mips16_plt_tail (info, memaddr))
1774 {
1775 info->insn_type = dis_noninsn;
1776 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
1777 if (status == 0)
1778 {
1779 unsigned int gotslot;
1780
1781 if (info->endian == BFD_ENDIAN_BIG)
1782 gotslot = bfd_getb32 (buffer);
1783 else
1784 gotslot = bfd_getl32 (buffer);
1785 infprintf (is, ".word\t0x%x", gotslot);
1786
1787 return 4;
1788 }
1789 }
1790 else
1791 {
1792 info->insn_type = dis_nonbranch;
1793 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1794 }
47b0e7ad
NC
1795 if (status != 0)
1796 {
1797 (*info->memory_error_func) (status, memaddr, info);
1798 return -1;
1799 }
1800
1801 length = 2;
1802
1803 if (info->endian == BFD_ENDIAN_BIG)
1804 insn = bfd_getb16 (buffer);
1805 else
1806 insn = bfd_getl16 (buffer);
1807
1808 /* Handle the extend opcode specially. */
1809 use_extend = FALSE;
1810 if ((insn & 0xf800) == 0xf000)
1811 {
1812 use_extend = TRUE;
1813 extend = insn & 0x7ff;
1814
1815 memaddr += 2;
1816
1817 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1818 if (status != 0)
1819 {
fc8c4fd1 1820 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1821 (*info->memory_error_func) (status, memaddr, info);
1822 return -1;
1823 }
1824
1825 if (info->endian == BFD_ENDIAN_BIG)
1826 insn = bfd_getb16 (buffer);
1827 else
1828 insn = bfd_getl16 (buffer);
1829
1830 /* Check for an extend opcode followed by an extend opcode. */
1831 if ((insn & 0xf800) == 0xf000)
1832 {
fc8c4fd1 1833 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1834 info->insn_type = dis_noninsn;
1835 return length;
1836 }
1837
1838 length += 2;
1839 }
1840
1841 /* FIXME: Should probably use a hash table on the major opcode here. */
1842
1843 opend = mips16_opcodes + bfd_mips16_num_opcodes;
1844 for (op = mips16_opcodes; op < opend; op++)
1845 {
1846 if (op->pinfo != INSN_MACRO
1847 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1848 && (insn & op->mask) == op->match)
1849 {
1850 const char *s;
1851
27c5c572 1852 if (op->args[0] == 'a' || op->args[0] == 'i')
47b0e7ad
NC
1853 {
1854 if (use_extend)
1855 {
fc8c4fd1 1856 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
1857 info->insn_type = dis_noninsn;
1858 return length - 2;
1859 }
1860
1861 use_extend = FALSE;
1862
1863 memaddr += 2;
1864
1865 status = (*info->read_memory_func) (memaddr, buffer, 2,
1866 info);
1867 if (status == 0)
1868 {
1869 use_extend = TRUE;
1870 if (info->endian == BFD_ENDIAN_BIG)
1871 extend = bfd_getb16 (buffer);
1872 else
1873 extend = bfd_getl16 (buffer);
1874 length += 2;
1875 }
1876 }
1877
fc8c4fd1 1878 infprintf (is, "%s", op->name);
47b0e7ad 1879 if (op->args[0] != '\0')
fc8c4fd1 1880 infprintf (is, "\t");
47b0e7ad 1881
c3c07478 1882 init_print_arg_state (&state);
47b0e7ad
NC
1883 for (s = op->args; *s != '\0'; s++)
1884 {
1885 if (*s == ','
1886 && s[1] == 'w'
fc8c4fd1 1887 && GET_OP (insn, RX) == GET_OP (insn, RY))
47b0e7ad
NC
1888 {
1889 /* Skip the register and the comma. */
1890 ++s;
1891 continue;
1892 }
1893 if (*s == ','
1894 && s[1] == 'v'
fc8c4fd1 1895 && GET_OP (insn, RZ) == GET_OP (insn, RX))
47b0e7ad
NC
1896 {
1897 /* Skip the register and the comma. */
1898 ++s;
1899 continue;
1900 }
c3c07478
RS
1901 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
1902 use_extend, extend, s[1] == '(');
47b0e7ad
NC
1903 }
1904
9a2c7088 1905 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 1906 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088 1907 info->branch_delay_insns = 1;
26545944
RS
1908 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
1909 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
47b0e7ad 1910 {
9a2c7088
MR
1911 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1912 info->insn_type = dis_jsr;
1913 else
47b0e7ad
NC
1914 info->insn_type = dis_branch;
1915 }
26545944 1916 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
9a2c7088 1917 info->insn_type = dis_condbranch;
47b0e7ad
NC
1918
1919 return length;
1920 }
1921 }
fc8c4fd1 1922#undef GET_OP
47b0e7ad
NC
1923
1924 if (use_extend)
fc8c4fd1
MR
1925 infprintf (is, "0x%x", extend | 0xf000);
1926 infprintf (is, "0x%x", insn);
47b0e7ad
NC
1927 info->insn_type = dis_noninsn;
1928
1929 return length;
1930}
1931
df58fc94
RS
1932/* Disassemble microMIPS instructions. */
1933
1934static int
1935print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
1936{
0c7533d3 1937 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94 1938 const struct mips_opcode *op, *opend;
df58fc94 1939 void *is = info->stream;
df58fc94 1940 bfd_byte buffer[2];
ab902481
RS
1941 unsigned int higher;
1942 unsigned int length;
df58fc94 1943 int status;
ab902481 1944 unsigned int insn;
df58fc94
RS
1945
1946 info->bytes_per_chunk = 2;
1947 info->display_endian = info->endian;
1948 info->insn_info_valid = 1;
1949 info->branch_delay_insns = 0;
1950 info->data_size = 0;
1951 info->insn_type = dis_nonbranch;
1952 info->target = 0;
1953 info->target2 = 0;
1954
1955 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1956 if (status != 0)
1957 {
1958 (*info->memory_error_func) (status, memaddr, info);
1959 return -1;
1960 }
1961
1962 length = 2;
1963
1964 if (info->endian == BFD_ENDIAN_BIG)
1965 insn = bfd_getb16 (buffer);
1966 else
1967 insn = bfd_getl16 (buffer);
1968
1969 if ((insn & 0xfc00) == 0x7c00)
1970 {
1971 /* This is a 48-bit microMIPS instruction. */
1972 higher = insn;
1973
1974 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
1975 if (status != 0)
1976 {
0c7533d3 1977 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
1978 (*info->memory_error_func) (status, memaddr + 2, info);
1979 return -1;
1980 }
1981 if (info->endian == BFD_ENDIAN_BIG)
1982 insn = bfd_getb16 (buffer);
1983 else
1984 insn = bfd_getl16 (buffer);
1985 higher = (higher << 16) | insn;
1986
1987 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
1988 if (status != 0)
1989 {
0c7533d3 1990 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
1991 (*info->memory_error_func) (status, memaddr + 4, info);
1992 return -1;
1993 }
1994 if (info->endian == BFD_ENDIAN_BIG)
1995 insn = bfd_getb16 (buffer);
1996 else
1997 insn = bfd_getl16 (buffer);
0c7533d3 1998 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
df58fc94
RS
1999
2000 info->insn_type = dis_noninsn;
2001 return 6;
2002 }
2003 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2004 {
2005 /* This is a 32-bit microMIPS instruction. */
2006 higher = insn;
2007
2008 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2009 if (status != 0)
2010 {
0c7533d3 2011 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2012 (*info->memory_error_func) (status, memaddr + 2, info);
2013 return -1;
2014 }
2015
2016 if (info->endian == BFD_ENDIAN_BIG)
2017 insn = bfd_getb16 (buffer);
2018 else
2019 insn = bfd_getl16 (buffer);
2020
2021 insn = insn | (higher << 16);
2022
2023 length += 2;
2024 }
2025
2026 /* FIXME: Should probably use a hash table on the major opcode here. */
2027
df58fc94
RS
2028 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2029 for (op = micromips_opcodes; op < opend; op++)
2030 {
2031 if (op->pinfo != INSN_MACRO
2032 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2033 && (insn & op->mask) == op->match
2034 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2035 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2036 {
0c7533d3 2037 infprintf (is, "%s", op->name);
df58fc94 2038
ab902481 2039 if (op->args[0])
df58fc94 2040 {
ab902481
RS
2041 infprintf (is, "\t");
2042 print_insn_args (info, op, decode_micromips_operand, insn,
2043 memaddr + length + 1);
df58fc94
RS
2044 }
2045
2046 /* Figure out instruction type and branch delay information. */
2047 if ((op->pinfo
2048 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2049 info->branch_delay_insns = 1;
2050 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2051 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2052 {
fc76e730 2053 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
df58fc94
RS
2054 info->insn_type = dis_jsr;
2055 else
2056 info->insn_type = dis_branch;
2057 }
2058 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2059 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2060 {
2061 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2062 info->insn_type = dis_condjsr;
2063 else
2064 info->insn_type = dis_condbranch;
2065 }
2066 else if ((op->pinfo
67dc82bc 2067 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
df58fc94
RS
2068 info->insn_type = dis_dref;
2069
2070 return length;
2071 }
2072 }
df58fc94 2073
0c7533d3 2074 infprintf (is, "0x%x", insn);
df58fc94
RS
2075 info->insn_type = dis_noninsn;
2076
2077 return length;
2078}
2079
2080/* Return 1 if a symbol associated with the location being disassembled
2081 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2082 all the symbols at the address being considered assuming if at least
2083 one of them indicates code compression, then such code has been
2084 genuinely produced here (other symbols could have been derived from
2085 function symbols defined elsewhere or could define data). Otherwise,
2086 return 0. */
2087
2088static bfd_boolean
2089is_compressed_mode_p (struct disassemble_info *info)
2090{
df58fc94 2091 int i;
1bbce132
MR
2092 int l;
2093
2094 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2095 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2096 && ((!micromips_ase
2097 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2098 || (micromips_ase
2099 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2100 return 1;
2101 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2102 && info->symtab[i]->section == info->section)
2103 {
2104 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2105 if ((!micromips_ase
2106 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2107 || (micromips_ase
2108 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2109 return 1;
2110 }
df58fc94
RS
2111
2112 return 0;
2113}
2114
47b0e7ad
NC
2115/* In an environment where we do not know the symbol type of the
2116 instruction we are forced to assume that the low order bit of the
2117 instructions' address may mark it as a mips16 instruction. If we
2118 are single stepping, or the pc is within the disassembled function,
2119 this works. Otherwise, we need a clue. Sometimes. */
2120
2121static int
2122_print_insn_mips (bfd_vma memaddr,
2123 struct disassemble_info *info,
2124 enum bfd_endian endianness)
2125{
df58fc94 2126 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
47b0e7ad
NC
2127 bfd_byte buffer[INSNLEN];
2128 int status;
2129
2130 set_default_mips_dis_options (info);
2131 parse_mips_dis_options (info->disassembler_options);
2132
df58fc94
RS
2133 if (info->mach == bfd_mach_mips16)
2134 return print_insn_mips16 (memaddr, info);
2135 if (info->mach == bfd_mach_mips_micromips)
2136 return print_insn_micromips (memaddr, info);
2137
2138 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
2139
47b0e7ad 2140#if 1
df58fc94 2141 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
2142 /* Only a few tools will work this way. */
2143 if (memaddr & 0x01)
df58fc94 2144 return print_insn_compr (memaddr, info);
47b0e7ad
NC
2145#endif
2146
2147#if SYMTAB_AVAILABLE
df58fc94
RS
2148 if (is_compressed_mode_p (info))
2149 return print_insn_compr (memaddr, info);
47b0e7ad
NC
2150#endif
2151
2152 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2153 if (status == 0)
2154 {
fc8c4fd1 2155 int insn;
47b0e7ad
NC
2156
2157 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 2158 insn = bfd_getb32 (buffer);
47b0e7ad 2159 else
fc8c4fd1 2160 insn = bfd_getl32 (buffer);
47b0e7ad
NC
2161
2162 return print_insn_mips (memaddr, insn, info);
2163 }
2164 else
2165 {
2166 (*info->memory_error_func) (status, memaddr, info);
2167 return -1;
2168 }
2169}
2170
2171int
2172print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2173{
2174 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2175}
2176
2177int
2178print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2179{
2180 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2181}
2182\f
640c0ccd 2183void
47b0e7ad 2184print_mips_disassembler_options (FILE *stream)
640c0ccd 2185{
4a9a3c54 2186 unsigned int i;
640c0ccd
CD
2187
2188 fprintf (stream, _("\n\
2189The following MIPS specific disassembler options are supported for use\n\
2190with the -M switch (multiple options should be separated by commas):\n"));
2191
4edbb8e3
CF
2192 fprintf (stream, _("\n\
2193 msa Recognize MSA instructions.\n"));
2194
b015e599
AP
2195 fprintf (stream, _("\n\
2196 virt Recognize the virtualization ASE instructions.\n"));
2197
640c0ccd
CD
2198 fprintf (stream, _("\n\
2199 gpr-names=ABI Print GPR names according to specified ABI.\n\
2200 Default: based on binary being disassembled.\n"));
2201
2202 fprintf (stream, _("\n\
2203 fpr-names=ABI Print FPR names according to specified ABI.\n\
2204 Default: numeric.\n"));
2205
2206 fprintf (stream, _("\n\
2207 cp0-names=ARCH Print CP0 register names according to\n\
2208 specified architecture.\n\
2209 Default: based on binary being disassembled.\n"));
2210
af7ee8bf
CD
2211 fprintf (stream, _("\n\
2212 hwr-names=ARCH Print HWR names according to specified \n\
2213 architecture.\n\
2214 Default: based on binary being disassembled.\n"));
2215
640c0ccd
CD
2216 fprintf (stream, _("\n\
2217 reg-names=ABI Print GPR and FPR names according to\n\
2218 specified ABI.\n"));
2219
2220 fprintf (stream, _("\n\
af7ee8bf 2221 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
2222 specified architecture.\n"));
2223
2224 fprintf (stream, _("\n\
2225 For the options above, the following values are supported for \"ABI\":\n\
2226 "));
4a9a3c54 2227 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
2228 fprintf (stream, " %s", mips_abi_choices[i].name);
2229 fprintf (stream, _("\n"));
2230
2231 fprintf (stream, _("\n\
2232 For the options above, The following values are supported for \"ARCH\":\n\
2233 "));
4a9a3c54 2234 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
2235 if (*mips_arch_choices[i].name != '\0')
2236 fprintf (stream, " %s", mips_arch_choices[i].name);
2237 fprintf (stream, _("\n"));
2238
2239 fprintf (stream, _("\n"));
2240}
This page took 0.745324 seconds and 4 git commands to generate.