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