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