]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/mips-dis.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / opcodes / mips-dis.c
CommitLineData
252b5132 1/* Print mips instructions for GDB, the GNU debugger, or for objdump.
219d1afa 2 Copyright (C) 1989-2018 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 22#include "sysdep.h"
6394c606 23#include "disassemble.h"
640c0ccd 24#include "libiberty.h"
252b5132
RH
25#include "opcode/mips.h"
26#include "opintl.h"
27
28/* FIXME: These are needed to figure out if the code is mips16 or
29 not. The low bit of the address is often a good indicator. No
30 symbol table is available when this code runs out in an embedded
7f6621cd 31 system as when it is used for disassembler support in a monitor. */
252b5132
RH
32
33#if !defined(EMBEDDED_ENV)
34#define SYMTAB_AVAILABLE 1
35#include "elf-bfd.h"
36#include "elf/mips.h"
37#endif
38
aa5f19f2
NC
39/* Mips instructions are at maximum this many bytes long. */
40#define INSNLEN 4
41
252b5132 42\f
aa5f19f2 43/* FIXME: These should be shared with gdb somehow. */
252b5132 44
47b0e7ad
NC
45struct mips_cp0sel_name
46{
47 unsigned int cp0reg;
48 unsigned int sel;
49 const char * const name;
bbcc0807
CD
50};
51
47b0e7ad
NC
52static const char * const mips_gpr_names_numeric[32] =
53{
640c0ccd
CD
54 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
55 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
56 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
57 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
aa5f19f2
NC
58};
59
47b0e7ad
NC
60static const char * const mips_gpr_names_oldabi[32] =
61{
640c0ccd
CD
62 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
63 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
64 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
65 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
aa5f19f2
NC
66};
67
47b0e7ad
NC
68static const char * const mips_gpr_names_newabi[32] =
69{
640c0ccd 70 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
0b14f26e 71 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
640c0ccd
CD
72 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
73 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
74};
75
47b0e7ad
NC
76static const char * const mips_fpr_names_numeric[32] =
77{
640c0ccd
CD
78 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
79 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
80 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
81 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
82};
83
47b0e7ad
NC
84static const char * const mips_fpr_names_32[32] =
85{
640c0ccd
CD
86 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
87 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
88 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
89 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
90};
91
47b0e7ad
NC
92static const char * const mips_fpr_names_n32[32] =
93{
640c0ccd
CD
94 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
95 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
96 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
97 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
98};
99
47b0e7ad
NC
100static const char * const mips_fpr_names_64[32] =
101{
640c0ccd
CD
102 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
103 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
104 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
105 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
106};
107
47b0e7ad
NC
108static const char * const mips_cp0_names_numeric[32] =
109{
640c0ccd
CD
110 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
111 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
112 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
113 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
114};
115
dc76d757
AB
116static const char * const mips_cp1_names_numeric[32] =
117{
118 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
119 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
120 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
121 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
122};
123
f409fd1e
MR
124static const char * const mips_cp0_names_r3000[32] =
125{
126 "c0_index", "c0_random", "c0_entrylo", "$3",
127 "c0_context", "$5", "$6", "$7",
128 "c0_badvaddr", "$9", "c0_entryhi", "$11",
129 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
130 "$16", "$17", "$18", "$19",
131 "$20", "$21", "$22", "$23",
132 "$24", "$25", "$26", "$27",
133 "$28", "$29", "$30", "$31",
134};
135
136static const char * const mips_cp0_names_r4000[32] =
137{
138 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
139 "c0_context", "c0_pagemask", "c0_wired", "$7",
140 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
141 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
142 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
143 "c0_xcontext", "$21", "$22", "$23",
144 "$24", "$25", "c0_ecc", "c0_cacheerr",
145 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
146};
147
e407c74b
NC
148static const char * const mips_cp0_names_r5900[32] =
149{
150 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
151 "c0_context", "c0_pagemask", "c0_wired", "$7",
152 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
153 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
154 "c0_config", "$17", "$18", "$19",
155 "$20", "$21", "$22", "c0_badpaddr",
156 "c0_depc", "c0_perfcnt", "$26", "$27",
157 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
158};
159
47b0e7ad
NC
160static const char * const mips_cp0_names_mips3264[32] =
161{
640c0ccd
CD
162 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
163 "c0_context", "c0_pagemask", "c0_wired", "$7",
164 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
165 "c0_status", "c0_cause", "c0_epc", "c0_prid",
166 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
167 "c0_xcontext", "$21", "$22", "c0_debug",
168 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
169 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
170};
171
dc76d757
AB
172static const char * const mips_cp1_names_mips3264[32] =
173{
174 "c1_fir", "c1_ufr", "$2", "$3",
175 "c1_unfr", "$5", "$6", "$7",
176 "$8", "$9", "$10", "$11",
177 "$12", "$13", "$14", "$15",
178 "$16", "$17", "$18", "$19",
179 "$20", "$21", "$22", "$23",
180 "$24", "c1_fccr", "c1_fexr", "$27",
181 "c1_fenr", "$29", "$30", "c1_fcsr"
182};
183
47b0e7ad
NC
184static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
185{
bbcc0807
CD
186 { 16, 1, "c0_config1" },
187 { 16, 2, "c0_config2" },
188 { 16, 3, "c0_config3" },
189 { 18, 1, "c0_watchlo,1" },
190 { 18, 2, "c0_watchlo,2" },
191 { 18, 3, "c0_watchlo,3" },
192 { 18, 4, "c0_watchlo,4" },
193 { 18, 5, "c0_watchlo,5" },
194 { 18, 6, "c0_watchlo,6" },
195 { 18, 7, "c0_watchlo,7" },
196 { 19, 1, "c0_watchhi,1" },
197 { 19, 2, "c0_watchhi,2" },
198 { 19, 3, "c0_watchhi,3" },
199 { 19, 4, "c0_watchhi,4" },
200 { 19, 5, "c0_watchhi,5" },
201 { 19, 6, "c0_watchhi,6" },
202 { 19, 7, "c0_watchhi,7" },
203 { 25, 1, "c0_perfcnt,1" },
204 { 25, 2, "c0_perfcnt,2" },
205 { 25, 3, "c0_perfcnt,3" },
206 { 25, 4, "c0_perfcnt,4" },
207 { 25, 5, "c0_perfcnt,5" },
208 { 25, 6, "c0_perfcnt,6" },
209 { 25, 7, "c0_perfcnt,7" },
210 { 27, 1, "c0_cacheerr,1" },
211 { 27, 2, "c0_cacheerr,2" },
212 { 27, 3, "c0_cacheerr,3" },
213 { 28, 1, "c0_datalo" },
214 { 29, 1, "c0_datahi" }
215};
216
47b0e7ad
NC
217static const char * const mips_cp0_names_mips3264r2[32] =
218{
af7ee8bf
CD
219 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
220 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
221 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
222 "c0_status", "c0_cause", "c0_epc", "c0_prid",
223 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
224 "c0_xcontext", "$21", "$22", "c0_debug",
225 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
226 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
227};
228
47b0e7ad
NC
229static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
230{
bbcc0807 231 { 4, 1, "c0_contextconfig" },
59c455b3
TS
232 { 0, 1, "c0_mvpcontrol" },
233 { 0, 2, "c0_mvpconf0" },
234 { 0, 3, "c0_mvpconf1" },
235 { 1, 1, "c0_vpecontrol" },
236 { 1, 2, "c0_vpeconf0" },
237 { 1, 3, "c0_vpeconf1" },
238 { 1, 4, "c0_yqmask" },
239 { 1, 5, "c0_vpeschedule" },
240 { 1, 6, "c0_vpeschefback" },
241 { 2, 1, "c0_tcstatus" },
242 { 2, 2, "c0_tcbind" },
243 { 2, 3, "c0_tcrestart" },
244 { 2, 4, "c0_tchalt" },
245 { 2, 5, "c0_tccontext" },
246 { 2, 6, "c0_tcschedule" },
247 { 2, 7, "c0_tcschefback" },
bbcc0807 248 { 5, 1, "c0_pagegrain" },
59c455b3
TS
249 { 6, 1, "c0_srsconf0" },
250 { 6, 2, "c0_srsconf1" },
251 { 6, 3, "c0_srsconf2" },
252 { 6, 4, "c0_srsconf3" },
253 { 6, 5, "c0_srsconf4" },
bbcc0807
CD
254 { 12, 1, "c0_intctl" },
255 { 12, 2, "c0_srsctl" },
256 { 12, 3, "c0_srsmap" },
257 { 15, 1, "c0_ebase" },
258 { 16, 1, "c0_config1" },
259 { 16, 2, "c0_config2" },
260 { 16, 3, "c0_config3" },
261 { 18, 1, "c0_watchlo,1" },
262 { 18, 2, "c0_watchlo,2" },
263 { 18, 3, "c0_watchlo,3" },
264 { 18, 4, "c0_watchlo,4" },
265 { 18, 5, "c0_watchlo,5" },
266 { 18, 6, "c0_watchlo,6" },
267 { 18, 7, "c0_watchlo,7" },
268 { 19, 1, "c0_watchhi,1" },
269 { 19, 2, "c0_watchhi,2" },
270 { 19, 3, "c0_watchhi,3" },
271 { 19, 4, "c0_watchhi,4" },
272 { 19, 5, "c0_watchhi,5" },
273 { 19, 6, "c0_watchhi,6" },
274 { 19, 7, "c0_watchhi,7" },
275 { 23, 1, "c0_tracecontrol" },
276 { 23, 2, "c0_tracecontrol2" },
277 { 23, 3, "c0_usertracedata" },
278 { 23, 4, "c0_tracebpc" },
279 { 25, 1, "c0_perfcnt,1" },
280 { 25, 2, "c0_perfcnt,2" },
281 { 25, 3, "c0_perfcnt,3" },
282 { 25, 4, "c0_perfcnt,4" },
283 { 25, 5, "c0_perfcnt,5" },
284 { 25, 6, "c0_perfcnt,6" },
285 { 25, 7, "c0_perfcnt,7" },
286 { 27, 1, "c0_cacheerr,1" },
287 { 27, 2, "c0_cacheerr,2" },
288 { 27, 3, "c0_cacheerr,3" },
289 { 28, 1, "c0_datalo" },
290 { 28, 2, "c0_taglo1" },
291 { 28, 3, "c0_datalo1" },
292 { 28, 4, "c0_taglo2" },
293 { 28, 5, "c0_datalo2" },
294 { 28, 6, "c0_taglo3" },
295 { 28, 7, "c0_datalo3" },
296 { 29, 1, "c0_datahi" },
297 { 29, 2, "c0_taghi1" },
298 { 29, 3, "c0_datahi1" },
299 { 29, 4, "c0_taghi2" },
300 { 29, 5, "c0_datahi2" },
301 { 29, 6, "c0_taghi3" },
302 { 29, 7, "c0_datahi3" },
303};
304
640c0ccd 305/* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
47b0e7ad
NC
306static const char * const mips_cp0_names_sb1[32] =
307{
640c0ccd
CD
308 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
309 "c0_context", "c0_pagemask", "c0_wired", "$7",
310 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
311 "c0_status", "c0_cause", "c0_epc", "c0_prid",
312 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
313 "c0_xcontext", "$21", "$22", "c0_debug",
314 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
315 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
316};
317
47b0e7ad
NC
318static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
319{
bbcc0807
CD
320 { 16, 1, "c0_config1" },
321 { 18, 1, "c0_watchlo,1" },
322 { 19, 1, "c0_watchhi,1" },
323 { 22, 0, "c0_perftrace" },
324 { 23, 3, "c0_edebug" },
325 { 25, 1, "c0_perfcnt,1" },
326 { 25, 2, "c0_perfcnt,2" },
327 { 25, 3, "c0_perfcnt,3" },
328 { 25, 4, "c0_perfcnt,4" },
329 { 25, 5, "c0_perfcnt,5" },
330 { 25, 6, "c0_perfcnt,6" },
331 { 25, 7, "c0_perfcnt,7" },
332 { 26, 1, "c0_buserr_pa" },
333 { 27, 1, "c0_cacheerr_d" },
334 { 27, 3, "c0_cacheerr_d_pa" },
335 { 28, 1, "c0_datalo_i" },
336 { 28, 2, "c0_taglo_d" },
337 { 28, 3, "c0_datalo_d" },
338 { 29, 1, "c0_datahi_i" },
339 { 29, 2, "c0_taghi_d" },
340 { 29, 3, "c0_datahi_d" },
341};
342
52b6b6b9
JM
343/* Xlr cop0 register names. */
344static const char * const mips_cp0_names_xlr[32] = {
345 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
346 "c0_context", "c0_pagemask", "c0_wired", "$7",
347 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
348 "c0_status", "c0_cause", "c0_epc", "c0_prid",
349 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
350 "c0_xcontext", "$21", "$22", "c0_debug",
351 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
352 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
353};
354
355/* XLR's CP0 Select Registers. */
356
357static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
358 { 9, 6, "c0_extintreq" },
359 { 9, 7, "c0_extintmask" },
360 { 15, 1, "c0_ebase" },
361 { 16, 1, "c0_config1" },
362 { 16, 2, "c0_config2" },
363 { 16, 3, "c0_config3" },
364 { 16, 7, "c0_procid2" },
365 { 18, 1, "c0_watchlo,1" },
366 { 18, 2, "c0_watchlo,2" },
367 { 18, 3, "c0_watchlo,3" },
368 { 18, 4, "c0_watchlo,4" },
369 { 18, 5, "c0_watchlo,5" },
370 { 18, 6, "c0_watchlo,6" },
371 { 18, 7, "c0_watchlo,7" },
372 { 19, 1, "c0_watchhi,1" },
373 { 19, 2, "c0_watchhi,2" },
374 { 19, 3, "c0_watchhi,3" },
375 { 19, 4, "c0_watchhi,4" },
376 { 19, 5, "c0_watchhi,5" },
377 { 19, 6, "c0_watchhi,6" },
378 { 19, 7, "c0_watchhi,7" },
379 { 25, 1, "c0_perfcnt,1" },
380 { 25, 2, "c0_perfcnt,2" },
381 { 25, 3, "c0_perfcnt,3" },
382 { 25, 4, "c0_perfcnt,4" },
383 { 25, 5, "c0_perfcnt,5" },
384 { 25, 6, "c0_perfcnt,6" },
385 { 25, 7, "c0_perfcnt,7" },
386 { 27, 1, "c0_cacheerr,1" },
387 { 27, 2, "c0_cacheerr,2" },
388 { 27, 3, "c0_cacheerr,3" },
389 { 28, 1, "c0_datalo" },
390 { 29, 1, "c0_datahi" }
391};
392
47b0e7ad
NC
393static const char * const mips_hwr_names_numeric[32] =
394{
af7ee8bf
CD
395 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
396 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
397 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
398 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
399};
400
47b0e7ad
NC
401static const char * const mips_hwr_names_mips3264r2[32] =
402{
af7ee8bf
CD
403 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
404 "$4", "$5", "$6", "$7",
405 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
406 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
407 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
408};
409
4edbb8e3
CF
410static const char * const msa_control_names[32] =
411{
412 "msa_ir", "msa_csr", "msa_access", "msa_save",
413 "msa_modify", "msa_request", "msa_map", "msa_unmap",
414 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
415 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
416 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
417};
418
47b0e7ad
NC
419struct mips_abi_choice
420{
421 const char * name;
640c0ccd
CD
422 const char * const *gpr_names;
423 const char * const *fpr_names;
424};
425
47b0e7ad
NC
426struct mips_abi_choice mips_abi_choices[] =
427{
640c0ccd
CD
428 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
429 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
430 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
431 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
432};
433
47b0e7ad
NC
434struct mips_arch_choice
435{
640c0ccd
CD
436 const char *name;
437 int bfd_mach_valid;
438 unsigned long bfd_mach;
439 int processor;
440 int isa;
d301a56b 441 int ase;
640c0ccd 442 const char * const *cp0_names;
bbcc0807
CD
443 const struct mips_cp0sel_name *cp0sel_names;
444 unsigned int cp0sel_names_len;
dc76d757 445 const char * const *cp1_names;
af7ee8bf 446 const char * const *hwr_names;
640c0ccd
CD
447};
448
47b0e7ad
NC
449const struct mips_arch_choice mips_arch_choices[] =
450{
d301a56b 451 { "numeric", 0, 0, 0, 0, 0,
dc76d757
AB
452 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
453 mips_hwr_names_numeric },
bbcc0807 454
d301a56b 455 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
dc76d757
AB
456 mips_cp0_names_r3000, NULL, 0, mips_cp1_names_numeric,
457 mips_hwr_names_numeric },
d301a56b 458 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
dc76d757
AB
459 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
460 mips_hwr_names_numeric },
d301a56b 461 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
dc76d757
AB
462 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
463 mips_hwr_names_numeric },
d301a56b 464 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
dc76d757
AB
465 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
466 mips_hwr_names_numeric },
d301a56b 467 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
dc76d757
AB
468 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
469 mips_hwr_names_numeric },
d301a56b 470 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
dc76d757
AB
471 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
472 mips_hwr_names_numeric },
d301a56b 473 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
dc76d757
AB
474 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
475 mips_hwr_names_numeric },
d301a56b 476 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
dc76d757
AB
477 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
478 mips_hwr_names_numeric },
d301a56b 479 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
dc76d757
AB
480 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
481 mips_hwr_names_numeric },
d301a56b 482 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
dc76d757
AB
483 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
484 mips_hwr_names_numeric },
d301a56b 485 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
dc76d757
AB
486 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
487 mips_hwr_names_numeric },
d301a56b 488 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
dc76d757
AB
489 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
490 mips_hwr_names_numeric },
d301a56b 491 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
dc76d757
AB
492 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
493 mips_hwr_names_numeric },
d301a56b 494 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
dc76d757
AB
495 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
496 mips_hwr_names_numeric },
d301a56b 497 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
dc76d757
AB
498 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_numeric,
499 mips_hwr_names_numeric },
d301a56b 500 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
dc76d757
AB
501 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
502 mips_hwr_names_numeric },
d301a56b 503 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
dc76d757
AB
504 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
505 mips_hwr_names_numeric },
d301a56b 506 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
dc76d757
AB
507 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
508 mips_hwr_names_numeric },
d301a56b 509 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
dc76d757
AB
510 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
511 mips_hwr_names_numeric },
d301a56b 512 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
dc76d757
AB
513 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
514 mips_hwr_names_numeric },
d301a56b 515 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
dc76d757
AB
516 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
517 mips_hwr_names_numeric },
d301a56b 518 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
dc76d757
AB
519 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
520 mips_hwr_names_numeric },
d301a56b 521 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
dc76d757
AB
522 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
523 mips_hwr_names_numeric },
d301a56b 524 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
dc76d757
AB
525 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
526 mips_hwr_names_numeric },
bbcc0807 527
640c0ccd
CD
528 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
529 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
530 _MIPS32 Architecture For Programmers Volume I: Introduction to the
531 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
532 page 1. */
533 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
d301a56b 534 ISA_MIPS32, ASE_SMARTMIPS,
bbcc0807
CD
535 mips_cp0_names_mips3264,
536 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
dc76d757 537 mips_cp1_names_mips3264, mips_hwr_names_numeric },
bbcc0807 538
af7ee8bf 539 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
d301a56b 540 ISA_MIPS32R2,
7f3c4072 541 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
7d64c587 542 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
bbcc0807
CD
543 mips_cp0_names_mips3264r2,
544 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
dc76d757 545 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
bbcc0807 546
ae52f483
AB
547 { "mips32r3", 1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
548 ISA_MIPS32R3,
549 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
550 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
551 mips_cp0_names_mips3264r2,
552 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
553 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
554
555 { "mips32r5", 1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
556 ISA_MIPS32R5,
557 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
558 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
559 mips_cp0_names_mips3264r2,
560 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
561 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
562
7361da2c
AB
563 { "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
564 ISA_MIPS32R6,
565 (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
8f4f9071 566 | ASE_DSPR2 | ASE_DSPR3),
7361da2c
AB
567 mips_cp0_names_mips3264r2,
568 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
569 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
570
640c0ccd
CD
571 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
572 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
d301a56b 573 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
bbcc0807
CD
574 mips_cp0_names_mips3264,
575 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
dc76d757 576 mips_cp1_names_mips3264, mips_hwr_names_numeric },
bbcc0807 577
5f74bc13 578 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
d301a56b 579 ISA_MIPS64R2,
7f3c4072 580 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
7d64c587 581 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
5f74bc13
CD
582 mips_cp0_names_mips3264r2,
583 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
dc76d757 584 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
5f74bc13 585
ae52f483
AB
586 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
587 ISA_MIPS64R3,
588 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
589 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
590 mips_cp0_names_mips3264r2,
591 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
592 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
593
594 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
595 ISA_MIPS64R5,
596 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
597 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
598 mips_cp0_names_mips3264r2,
599 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
600 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
601
7361da2c
AB
602 { "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
603 ISA_MIPS64R6,
604 (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
8f4f9071 605 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3),
7361da2c
AB
606 mips_cp0_names_mips3264r2,
607 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
608 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
609
38bf472a
MR
610 { "interaptiv-mr2", 1, bfd_mach_mips_interaptiv_mr2, CPU_INTERAPTIV_MR2,
611 ISA_MIPS32R3,
612 ASE_MT | ASE_EVA | ASE_DSP | ASE_DSPR2 | ASE_MIPS16E2 | ASE_MIPS16E2_MT,
613 mips_cp0_names_mips3264r2,
614 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
615 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
616
640c0ccd 617 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
d301a56b 618 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
bbcc0807
CD
619 mips_cp0_names_sb1,
620 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
dc76d757 621 mips_cp1_names_mips3264, mips_hwr_names_numeric },
640c0ccd 622
350cc38d 623 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
d301a56b 624 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
dc76d757 625 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d
MS
626
627 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
d301a56b 628 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
dc76d757 629 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
350cc38d 630
fd503541 631 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
4ba154f5 632 ISA_MIPS64R2 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
dc76d757 633 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
fd503541 634
57b592a3 635 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
d301a56b 636 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
dc76d757 637 mips_cp1_names_mips3264, mips_hwr_names_numeric },
57b592a3 638
dd6a37e7 639 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
d301a56b 640 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
dc76d757 641 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
432233b3
AP
642
643 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
d301a56b 644 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
dc76d757 645 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
dd6a37e7 646
2c629856
N
647 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
648 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
649 mips_cp0_names_numeric,
650 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
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. */
25499ac7
MR
668 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
669 ASE_MIPS16E2 | ASE_MIPS16E2_MT,
dc76d757
AB
670 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
671 mips_hwr_names_numeric },
640c0ccd
CD
672};
673
674/* ISA and processor type to disassemble for, and register names to use.
675 set_default_mips_dis_options and parse_mips_dis_options fill in these
676 values. */
677static int mips_processor;
678static int mips_isa;
d301a56b 679static int mips_ase;
df58fc94 680static int micromips_ase;
640c0ccd
CD
681static const char * const *mips_gpr_names;
682static const char * const *mips_fpr_names;
683static const char * const *mips_cp0_names;
bbcc0807
CD
684static const struct mips_cp0sel_name *mips_cp0sel_names;
685static int mips_cp0sel_names_len;
dc76d757 686static const char * const *mips_cp1_names;
af7ee8bf 687static const char * const *mips_hwr_names;
640c0ccd 688
986e18a5 689/* Other options */
47b0e7ad 690static int no_aliases; /* If set disassemble as most general inst. */
640c0ccd
CD
691\f
692static const struct mips_abi_choice *
47b0e7ad 693choose_abi_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
694{
695 const struct mips_abi_choice *c;
696 unsigned int i;
697
698 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
47b0e7ad
NC
699 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
700 && strlen (mips_abi_choices[i].name) == namelen)
701 c = &mips_abi_choices[i];
702
640c0ccd
CD
703 return c;
704}
705
706static const struct mips_arch_choice *
47b0e7ad 707choose_arch_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
708{
709 const struct mips_arch_choice *c = NULL;
710 unsigned int i;
711
712 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
47b0e7ad
NC
713 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
714 && strlen (mips_arch_choices[i].name) == namelen)
715 c = &mips_arch_choices[i];
716
640c0ccd
CD
717 return c;
718}
719
720static const struct mips_arch_choice *
47b0e7ad 721choose_arch_by_number (unsigned long mach)
640c0ccd
CD
722{
723 static unsigned long hint_bfd_mach;
724 static const struct mips_arch_choice *hint_arch_choice;
725 const struct mips_arch_choice *c;
726 unsigned int i;
727
728 /* We optimize this because even if the user specifies no
729 flags, this will be done for every instruction! */
730 if (hint_bfd_mach == mach
731 && hint_arch_choice != NULL
732 && hint_arch_choice->bfd_mach == hint_bfd_mach)
733 return hint_arch_choice;
734
735 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
736 {
737 if (mips_arch_choices[i].bfd_mach_valid
738 && mips_arch_choices[i].bfd_mach == mach)
739 {
740 c = &mips_arch_choices[i];
741 hint_bfd_mach = mach;
742 hint_arch_choice = c;
743 }
744 }
745 return c;
746}
747
47b0e7ad
NC
748/* Check if the object uses NewABI conventions. */
749
750static int
751is_newabi (Elf_Internal_Ehdr *header)
752{
753 /* There are no old-style ABIs which use 64-bit ELF. */
754 if (header->e_ident[EI_CLASS] == ELFCLASS64)
755 return 1;
756
757 /* If a 32-bit ELF file, n32 is a new-style ABI. */
758 if ((header->e_flags & EF_MIPS_ABI2) != 0)
759 return 1;
760
761 return 0;
762}
763
df58fc94
RS
764/* Check if the object has microMIPS ASE code. */
765
766static int
767is_micromips (Elf_Internal_Ehdr *header)
768{
769 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
770 return 1;
771
772 return 0;
773}
774
5e7fc731
MR
775/* Convert ASE flags from .MIPS.abiflags to internal values. */
776
777static unsigned long
778mips_convert_abiflags_ases (unsigned long afl_ases)
779{
780 unsigned long opcode_ases = 0;
781
782 if (afl_ases & AFL_ASE_DSP)
783 opcode_ases |= ASE_DSP;
784 if (afl_ases & AFL_ASE_DSPR2)
785 opcode_ases |= ASE_DSPR2;
786 if (afl_ases & AFL_ASE_EVA)
787 opcode_ases |= ASE_EVA;
788 if (afl_ases & AFL_ASE_MCU)
789 opcode_ases |= ASE_MCU;
790 if (afl_ases & AFL_ASE_MDMX)
791 opcode_ases |= ASE_MDMX;
792 if (afl_ases & AFL_ASE_MIPS3D)
793 opcode_ases |= ASE_MIPS3D;
794 if (afl_ases & AFL_ASE_MT)
795 opcode_ases |= ASE_MT;
796 if (afl_ases & AFL_ASE_SMARTMIPS)
797 opcode_ases |= ASE_SMARTMIPS;
798 if (afl_ases & AFL_ASE_VIRT)
799 opcode_ases |= ASE_VIRT;
800 if (afl_ases & AFL_ASE_MSA)
801 opcode_ases |= ASE_MSA;
802 if (afl_ases & AFL_ASE_XPA)
803 opcode_ases |= ASE_XPA;
804 if (afl_ases & AFL_ASE_DSPR3)
805 opcode_ases |= ASE_DSPR3;
25499ac7
MR
806 if (afl_ases & AFL_ASE_MIPS16E2)
807 opcode_ases |= ASE_MIPS16E2;
5e7fc731
MR
808 return opcode_ases;
809}
810
60804c53
MR
811/* Calculate combination ASE flags from regular ASE flags. */
812
813static unsigned long
814mips_calculate_combination_ases (unsigned long opcode_ases)
815{
816 unsigned long combination_ases = 0;
817
9785fc2a
MR
818 if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
819 combination_ases |= ASE_XPA_VIRT;
60804c53
MR
820 if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
821 combination_ases |= ASE_MIPS16E2_MT;
822 return combination_ases;
823}
824
47b0e7ad
NC
825static void
826set_default_mips_dis_options (struct disassemble_info *info)
640c0ccd
CD
827{
828 const struct mips_arch_choice *chosen_arch;
829
df58fc94
RS
830 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
831 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
832 CP0 register, and HWR names. */
640c0ccd 833 mips_isa = ISA_MIPS3;
df58fc94
RS
834 mips_processor = CPU_R3000;
835 micromips_ase = 0;
d301a56b 836 mips_ase = 0;
640c0ccd
CD
837 mips_gpr_names = mips_gpr_names_oldabi;
838 mips_fpr_names = mips_fpr_names_numeric;
839 mips_cp0_names = mips_cp0_names_numeric;
bbcc0807
CD
840 mips_cp0sel_names = NULL;
841 mips_cp0sel_names_len = 0;
dc76d757 842 mips_cp1_names = mips_cp1_names_numeric;
af7ee8bf 843 mips_hwr_names = mips_hwr_names_numeric;
986e18a5 844 no_aliases = 0;
640c0ccd 845
640c0ccd
CD
846 /* Set ISA, architecture, and cp0 register names as best we can. */
847#if ! SYMTAB_AVAILABLE
848 /* This is running out on a target machine, not in a host tool.
849 FIXME: Where does mips_target_info come from? */
850 target_processor = mips_target_info.processor;
851 mips_isa = mips_target_info.isa;
d301a56b 852 mips_ase = mips_target_info.ase;
640c0ccd
CD
853#else
854 chosen_arch = choose_arch_by_number (info->mach);
855 if (chosen_arch != NULL)
856 {
857 mips_processor = chosen_arch->processor;
858 mips_isa = chosen_arch->isa;
d301a56b 859 mips_ase = chosen_arch->ase;
bbcc0807
CD
860 mips_cp0_names = chosen_arch->cp0_names;
861 mips_cp0sel_names = chosen_arch->cp0sel_names;
862 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 863 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 864 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd 865 }
8184783a
MR
866
867 /* Update settings according to the ELF file header flags. */
868 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
869 {
5e7fc731
MR
870 struct bfd *abfd = info->section->owner;
871 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
4df995c7
MR
872 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
873
9e76c212
MR
874 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
875 because we won't then have a MIPS/ELF BFD, however we need
876 to guard against a link error in a `--enable-targets=...'
877 configuration with a 32-bit host where the MIPS target is
878 a secondary, or with MIPS/ECOFF configurations. */
879#ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
4df995c7
MR
880 abiflags = bfd_mips_elf_get_abiflags (abfd);
881#endif
8184783a
MR
882 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
883 if (is_newabi (header))
884 mips_gpr_names = mips_gpr_names_newabi;
885 /* If a microMIPS binary, then don't use MIPS16 bindings. */
886 micromips_ase = is_micromips (header);
5e7fc731
MR
887 /* OR in any extra ASE flags set in ELF file structures. */
888 if (abiflags)
889 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
890 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
891 mips_ase |= ASE_MDMX;
8184783a 892 }
91068ec6 893#endif
60804c53 894 mips_ase |= mips_calculate_combination_ases (mips_ase);
640c0ccd
CD
895}
896
9785fc2a
MR
897/* Parse an ASE disassembler option and set the corresponding global
898 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
b015e599 899
9785fc2a
MR
900static bfd_boolean
901parse_mips_ase_option (const char *option)
902{
4edbb8e3
CF
903 if (CONST_STRNEQ (option, "msa"))
904 {
905 mips_ase |= ASE_MSA;
ae52f483
AB
906 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
907 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
7361da2c
AB
908 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
909 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
4edbb8e3 910 mips_ase |= ASE_MSA64;
9785fc2a 911 return TRUE;
4edbb8e3
CF
912 }
913
b015e599
AP
914 if (CONST_STRNEQ (option, "virt"))
915 {
d301a56b 916 mips_ase |= ASE_VIRT;
ae52f483
AB
917 if (mips_isa & ISA_MIPS64R2
918 || mips_isa & ISA_MIPS64R3
7361da2c
AB
919 || mips_isa & ISA_MIPS64R5
920 || mips_isa & ISA_MIPS64R6)
d301a56b 921 mips_ase |= ASE_VIRT64;
9785fc2a 922 return TRUE;
b015e599 923 }
7d64c587
AB
924
925 if (CONST_STRNEQ (option, "xpa"))
926 {
927 mips_ase |= ASE_XPA;
9785fc2a
MR
928 return TRUE;
929 }
930
931 return FALSE;
932}
933
934static void
935parse_mips_dis_option (const char *option, unsigned int len)
936{
937 unsigned int i, optionlen, vallen;
938 const char *val;
939 const struct mips_abi_choice *chosen_abi;
940 const struct mips_arch_choice *chosen_arch;
941
942 /* Try to match options that are simple flags */
943 if (CONST_STRNEQ (option, "no-aliases"))
944 {
945 no_aliases = 1;
7d64c587
AB
946 return;
947 }
43e65147 948
9785fc2a
MR
949 if (parse_mips_ase_option (option))
950 {
951 mips_ase |= mips_calculate_combination_ases (mips_ase);
952 return;
953 }
43e65147 954
640c0ccd
CD
955 /* Look for the = that delimits the end of the option name. */
956 for (i = 0; i < len; i++)
47b0e7ad
NC
957 if (option[i] == '=')
958 break;
959
640c0ccd
CD
960 if (i == 0) /* Invalid option: no name before '='. */
961 return;
962 if (i == len) /* Invalid option: no '='. */
963 return;
964 if (i == (len - 1)) /* Invalid option: no value after '='. */
965 return;
966
967 optionlen = i;
968 val = option + (optionlen + 1);
969 vallen = len - (optionlen + 1);
970
47b0e7ad
NC
971 if (strncmp ("gpr-names", option, optionlen) == 0
972 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
973 {
974 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 975 if (chosen_abi != NULL)
640c0ccd
CD
976 mips_gpr_names = chosen_abi->gpr_names;
977 return;
978 }
979
47b0e7ad
NC
980 if (strncmp ("fpr-names", option, optionlen) == 0
981 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
982 {
983 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 984 if (chosen_abi != NULL)
640c0ccd
CD
985 mips_fpr_names = chosen_abi->fpr_names;
986 return;
987 }
988
47b0e7ad
NC
989 if (strncmp ("cp0-names", option, optionlen) == 0
990 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
991 {
992 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
993 if (chosen_arch != NULL)
994 {
995 mips_cp0_names = chosen_arch->cp0_names;
996 mips_cp0sel_names = chosen_arch->cp0sel_names;
997 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
998 }
640c0ccd
CD
999 return;
1000 }
1001
dc76d757
AB
1002 if (strncmp ("cp1-names", option, optionlen) == 0
1003 && strlen ("cp1-names") == optionlen)
1004 {
1005 chosen_arch = choose_arch_by_name (val, vallen);
1006 if (chosen_arch != NULL)
1007 mips_cp1_names = chosen_arch->cp1_names;
1008 return;
1009 }
1010
47b0e7ad
NC
1011 if (strncmp ("hwr-names", option, optionlen) == 0
1012 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
1013 {
1014 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 1015 if (chosen_arch != NULL)
af7ee8bf
CD
1016 mips_hwr_names = chosen_arch->hwr_names;
1017 return;
1018 }
1019
47b0e7ad
NC
1020 if (strncmp ("reg-names", option, optionlen) == 0
1021 && strlen ("reg-names") == optionlen)
640c0ccd
CD
1022 {
1023 /* We check both ABI and ARCH here unconditionally, so
1024 that "numeric" will do the desirable thing: select
1025 numeric register names for all registers. Other than
1026 that, a given name probably won't match both. */
1027 chosen_abi = choose_abi_by_name (val, vallen);
1028 if (chosen_abi != NULL)
1029 {
bbcc0807
CD
1030 mips_gpr_names = chosen_abi->gpr_names;
1031 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
1032 }
1033 chosen_arch = choose_arch_by_name (val, vallen);
1034 if (chosen_arch != NULL)
1035 {
bbcc0807
CD
1036 mips_cp0_names = chosen_arch->cp0_names;
1037 mips_cp0sel_names = chosen_arch->cp0sel_names;
1038 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
dc76d757 1039 mips_cp1_names = chosen_arch->cp1_names;
bbcc0807 1040 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
1041 }
1042 return;
1043 }
1044
1045 /* Invalid option. */
1046}
1047
47b0e7ad
NC
1048static void
1049parse_mips_dis_options (const char *options)
640c0ccd
CD
1050{
1051 const char *option_end;
1052
1053 if (options == NULL)
1054 return;
1055
1056 while (*options != '\0')
1057 {
1058 /* Skip empty options. */
1059 if (*options == ',')
1060 {
1061 options++;
1062 continue;
1063 }
1064
1065 /* We know that *options is neither NUL or a comma. */
1066 option_end = options + 1;
1067 while (*option_end != ',' && *option_end != '\0')
1068 option_end++;
1069
1070 parse_mips_dis_option (options, option_end - options);
1071
1072 /* Go on to the next one. If option_end points to a comma, it
1073 will be skipped above. */
1074 options = option_end;
1075 }
1076}
1077
bbcc0807 1078static const struct mips_cp0sel_name *
47b0e7ad
NC
1079lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1080 unsigned int len,
1081 unsigned int cp0reg,
1082 unsigned int sel)
bbcc0807
CD
1083{
1084 unsigned int i;
1085
1086 for (i = 0; i < len; i++)
1087 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1088 return &names[i];
1089 return NULL;
1090}
ab902481
RS
1091
1092/* Print register REGNO, of type TYPE, for instruction OPCODE. */
aa5f19f2 1093
794ac9d0 1094static void
ab902481
RS
1095print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1096 enum mips_reg_operand_type type, int regno)
252b5132 1097{
ab902481
RS
1098 switch (type)
1099 {
1100 case OP_REG_GP:
1101 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1102 break;
440cc0bc 1103
ab902481
RS
1104 case OP_REG_FP:
1105 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1106 break;
252b5132 1107
ab902481
RS
1108 case OP_REG_CCC:
1109 if (opcode->pinfo & (FP_D | FP_S))
1110 info->fprintf_func (info->stream, "$fcc%d", regno);
1111 else
1112 info->fprintf_func (info->stream, "$cc%d", regno);
1113 break;
794ac9d0 1114
ab902481
RS
1115 case OP_REG_VEC:
1116 if (opcode->membership & INSN_5400)
1117 info->fprintf_func (info->stream, "$f%d", regno);
1118 else
1119 info->fprintf_func (info->stream, "$v%d", regno);
1120 break;
794ac9d0 1121
ab902481
RS
1122 case OP_REG_ACC:
1123 info->fprintf_func (info->stream, "$ac%d", regno);
1124 break;
794ac9d0 1125
ab902481
RS
1126 case OP_REG_COPRO:
1127 if (opcode->name[strlen (opcode->name) - 1] == '0')
1128 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
dc76d757
AB
1129 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1130 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
ab902481
RS
1131 else
1132 info->fprintf_func (info->stream, "$%d", regno);
1133 break;
8b082fb1 1134
ab902481
RS
1135 case OP_REG_HW:
1136 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1137 break;
14daeee3
RS
1138
1139 case OP_REG_VF:
1140 info->fprintf_func (info->stream, "$vf%d", regno);
1141 break;
1142
1143 case OP_REG_VI:
1144 info->fprintf_func (info->stream, "$vi%d", regno);
1145 break;
1146
1147 case OP_REG_R5900_I:
1148 info->fprintf_func (info->stream, "$I");
1149 break;
1150
1151 case OP_REG_R5900_Q:
1152 info->fprintf_func (info->stream, "$Q");
1153 break;
1154
1155 case OP_REG_R5900_R:
1156 info->fprintf_func (info->stream, "$R");
1157 break;
1158
1159 case OP_REG_R5900_ACC:
1160 info->fprintf_func (info->stream, "$ACC");
1161 break;
4edbb8e3
CF
1162
1163 case OP_REG_MSA:
1164 info->fprintf_func (info->stream, "$w%d", regno);
1165 break;
1166
1167 case OP_REG_MSA_CTRL:
1168 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1169 break;
1170
ab902481
RS
1171 }
1172}
1173\f
1174/* Used to track the state carried over from previous operands in
1175 an instruction. */
1176struct mips_print_arg_state {
1177 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1178 where the value is known to be unsigned and small. */
1179 unsigned int last_int;
1180
1181 /* The type and number of the last OP_REG seen. We only use this for
1182 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1183 enum mips_reg_operand_type last_reg_type;
1184 unsigned int last_regno;
7361da2c
AB
1185 unsigned int dest_regno;
1186 unsigned int seen_dest;
ab902481 1187};
fd25c5a9 1188
ab902481 1189/* Initialize STATE for the start of an instruction. */
fd25c5a9 1190
ab902481
RS
1191static inline void
1192init_print_arg_state (struct mips_print_arg_state *state)
1193{
1194 memset (state, 0, sizeof (*state));
1195}
fd25c5a9 1196
14daeee3
RS
1197/* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1198 whose value is given by UVAL. */
1199
1200static void
1201print_vu0_channel (struct disassemble_info *info,
1202 const struct mips_operand *operand, unsigned int uval)
1203{
1204 if (operand->size == 4)
1205 info->fprintf_func (info->stream, "%s%s%s%s",
1206 uval & 8 ? "x" : "",
1207 uval & 4 ? "y" : "",
1208 uval & 2 ? "z" : "",
1209 uval & 1 ? "w" : "");
1210 else if (operand->size == 2)
1211 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1212 else
1213 abort ();
1214}
1215
7361da2c
AB
1216/* Record information about a register operand. */
1217
1218static void
1219mips_seen_register (struct mips_print_arg_state *state,
1220 unsigned int regno,
1221 enum mips_reg_operand_type reg_type)
1222{
1223 state->last_reg_type = reg_type;
1224 state->last_regno = regno;
1225
1226 if (!state->seen_dest)
1227 {
1228 state->seen_dest = 1;
1229 state->dest_regno = regno;
1230 }
1231}
1232
38bf472a
MR
1233/* Print SAVE/RESTORE instruction operands according to the argument
1234 register mask AMASK, the number of static registers saved NSREG,
1235 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1236 and the frame size FRAME_SIZE. */
1237
1238static void
1239mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
1240 unsigned int nsreg, unsigned int ra,
1241 unsigned int s0, unsigned int s1,
1242 unsigned int frame_size)
1243{
1244 const fprintf_ftype infprintf = info->fprintf_func;
1245 unsigned int nargs, nstatics, smask, i, j;
1246 void *is = info->stream;
1247 const char *sep;
1248
1249 if (amask == MIPS_SVRS_ALL_ARGS)
1250 {
1251 nargs = 4;
1252 nstatics = 0;
1253 }
1254 else if (amask == MIPS_SVRS_ALL_STATICS)
1255 {
1256 nargs = 0;
1257 nstatics = 4;
1258 }
1259 else
1260 {
1261 nargs = amask >> 2;
1262 nstatics = amask & 3;
1263 }
1264
1265 sep = "";
1266 if (nargs > 0)
1267 {
1268 infprintf (is, "%s", mips_gpr_names[4]);
1269 if (nargs > 1)
1270 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1271 sep = ",";
1272 }
1273
1274 infprintf (is, "%s%d", sep, frame_size);
1275
1276 if (ra) /* $ra */
1277 infprintf (is, ",%s", mips_gpr_names[31]);
1278
1279 smask = 0;
1280 if (s0) /* $s0 */
1281 smask |= 1 << 0;
1282 if (s1) /* $s1 */
1283 smask |= 1 << 1;
1284 if (nsreg > 0) /* $s2-$s8 */
1285 smask |= ((1 << nsreg) - 1) << 2;
1286
1287 for (i = 0; i < 9; i++)
1288 if (smask & (1 << i))
1289 {
1290 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1291 /* Skip over string of set bits. */
1292 for (j = i; smask & (2 << j); j++)
1293 continue;
1294 if (j > i)
1295 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1296 i = j + 1;
1297 }
1298 /* Statics $ax - $a3. */
1299 if (nstatics == 1)
1300 infprintf (is, ",%s", mips_gpr_names[7]);
1301 else if (nstatics > 0)
1302 infprintf (is, ",%s-%s",
1303 mips_gpr_names[7 - nstatics + 1],
1304 mips_gpr_names[7]);
1305}
1306
1307
ab902481
RS
1308/* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1309 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1310 the base address for OP_PCREL operands. */
fd25c5a9 1311
ab902481
RS
1312static void
1313print_insn_arg (struct disassemble_info *info,
1314 struct mips_print_arg_state *state,
1315 const struct mips_opcode *opcode,
1316 const struct mips_operand *operand,
1317 bfd_vma base_pc,
1318 unsigned int uval)
1319{
1320 const fprintf_ftype infprintf = info->fprintf_func;
1321 void *is = info->stream;
fd25c5a9 1322
ab902481
RS
1323 switch (operand->type)
1324 {
1325 case OP_INT:
1326 {
1327 const struct mips_int_operand *int_op;
fd25c5a9 1328
ab902481
RS
1329 int_op = (const struct mips_int_operand *) operand;
1330 uval = mips_decode_int_operand (int_op, uval);
1331 state->last_int = uval;
1332 if (int_op->print_hex)
1333 infprintf (is, "0x%x", uval);
1334 else
1335 infprintf (is, "%d", uval);
1336 }
1337 break;
fd25c5a9 1338
ab902481
RS
1339 case OP_MAPPED_INT:
1340 {
1341 const struct mips_mapped_int_operand *mint_op;
fd25c5a9 1342
ab902481
RS
1343 mint_op = (const struct mips_mapped_int_operand *) operand;
1344 uval = mint_op->int_map[uval];
1345 state->last_int = uval;
1346 if (mint_op->print_hex)
1347 infprintf (is, "0x%x", uval);
1348 else
1349 infprintf (is, "%d", uval);
1350 }
1351 break;
fd25c5a9 1352
ab902481
RS
1353 case OP_MSB:
1354 {
1355 const struct mips_msb_operand *msb_op;
dec0624d 1356
ab902481
RS
1357 msb_op = (const struct mips_msb_operand *) operand;
1358 uval += msb_op->bias;
1359 if (msb_op->add_lsb)
1360 uval -= state->last_int;
1361 infprintf (is, "0x%x", uval);
1362 }
1363 break;
dec0624d 1364
ab902481 1365 case OP_REG:
0f35dbc4 1366 case OP_OPTIONAL_REG:
ab902481
RS
1367 {
1368 const struct mips_reg_operand *reg_op;
fd25c5a9 1369
ab902481 1370 reg_op = (const struct mips_reg_operand *) operand;
fc76e730 1371 uval = mips_decode_reg_operand (reg_op, uval);
ab902481 1372 print_reg (info, opcode, reg_op->reg_type, uval);
fd25c5a9 1373
7361da2c 1374 mips_seen_register (state, uval, reg_op->reg_type);
ab902481
RS
1375 }
1376 break;
61cc0267 1377
ab902481
RS
1378 case OP_REG_PAIR:
1379 {
1380 const struct mips_reg_pair_operand *pair_op;
1381
1382 pair_op = (const struct mips_reg_pair_operand *) operand;
1383 print_reg (info, opcode, pair_op->reg_type,
1384 pair_op->reg1_map[uval]);
1385 infprintf (is, ",");
1386 print_reg (info, opcode, pair_op->reg_type,
1387 pair_op->reg2_map[uval]);
1388 }
1389 break;
61cc0267 1390
ab902481
RS
1391 case OP_PCREL:
1392 {
1393 const struct mips_pcrel_operand *pcrel_op;
61cc0267 1394
ab902481
RS
1395 pcrel_op = (const struct mips_pcrel_operand *) operand;
1396 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
61cc0267 1397
a4ddc54e
MR
1398 /* For jumps and branches clear the ISA bit except for
1399 the GDB disassembler. */
1400 if (pcrel_op->include_isa_bit
1401 && info->flavour != bfd_target_unknown_flavour)
ab902481 1402 info->target &= -2;
61cc0267 1403
ab902481
RS
1404 (*info->print_address_func) (info->target, info);
1405 }
1406 break;
794ac9d0 1407
ab902481
RS
1408 case OP_PERF_REG:
1409 infprintf (is, "%d", uval);
1410 break;
794ac9d0 1411
ab902481
RS
1412 case OP_ADDIUSP_INT:
1413 {
1414 int sval;
794ac9d0 1415
ab902481
RS
1416 sval = mips_signed_operand (operand, uval) * 4;
1417 if (sval >= -8 && sval < 8)
1418 sval ^= 0x400;
1419 infprintf (is, "%d", sval);
1420 break;
1421 }
794ac9d0 1422
ab902481
RS
1423 case OP_CLO_CLZ_DEST:
1424 {
1425 unsigned int reg1, reg2;
1426
1427 reg1 = uval & 31;
1428 reg2 = uval >> 5;
1429 /* If one is zero use the other. */
1430 if (reg1 == reg2 || reg2 == 0)
1431 infprintf (is, "%s", mips_gpr_names[reg1]);
1432 else if (reg1 == 0)
1433 infprintf (is, "%s", mips_gpr_names[reg2]);
1434 else
1435 /* Bogus, result depends on processor. */
1436 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1437 mips_gpr_names[reg2]);
1438 }
1439 break;
794ac9d0 1440
7361da2c
AB
1441 case OP_SAME_RS_RT:
1442 case OP_CHECK_PREV:
1443 case OP_NON_ZERO_REG:
1444 {
1445 print_reg (info, opcode, OP_REG_GP, uval & 31);
1446 mips_seen_register (state, uval, OP_REG_GP);
1447 }
1448 break;
1449
ab902481
RS
1450 case OP_LWM_SWM_LIST:
1451 if (operand->size == 2)
1452 {
1453 if (uval == 0)
1454 infprintf (is, "%s,%s",
1455 mips_gpr_names[16],
1456 mips_gpr_names[31]);
1457 else
1458 infprintf (is, "%s-%s,%s",
1459 mips_gpr_names[16],
1460 mips_gpr_names[16 + uval],
1461 mips_gpr_names[31]);
1462 }
1463 else
1464 {
1465 int s_reg_encode;
794ac9d0 1466
ab902481
RS
1467 s_reg_encode = uval & 0xf;
1468 if (s_reg_encode != 0)
1469 {
1470 if (s_reg_encode == 1)
1471 infprintf (is, "%s", mips_gpr_names[16]);
1472 else if (s_reg_encode < 9)
1473 infprintf (is, "%s-%s",
1474 mips_gpr_names[16],
1475 mips_gpr_names[15 + s_reg_encode]);
1476 else if (s_reg_encode == 9)
1477 infprintf (is, "%s-%s,%s",
1478 mips_gpr_names[16],
1479 mips_gpr_names[23],
1480 mips_gpr_names[30]);
1481 else
1482 infprintf (is, "UNKNOWN");
1483 }
794ac9d0 1484
ab902481
RS
1485 if (uval & 0x10) /* For ra. */
1486 {
1487 if (s_reg_encode == 0)
1488 infprintf (is, "%s", mips_gpr_names[31]);
1489 else
1490 infprintf (is, ",%s", mips_gpr_names[31]);
1491 }
1492 }
1493 break;
794ac9d0 1494
c3c07478
RS
1495 case OP_ENTRY_EXIT_LIST:
1496 {
1497 const char *sep;
1498 unsigned int amask, smask;
1499
1500 sep = "";
1501 amask = (uval >> 3) & 7;
1502 if (amask > 0 && amask < 5)
1503 {
1504 infprintf (is, "%s", mips_gpr_names[4]);
1505 if (amask > 1)
1506 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1507 sep = ",";
1508 }
1509
1510 smask = (uval >> 1) & 3;
1511 if (smask == 3)
1512 {
1513 infprintf (is, "%s??", sep);
1514 sep = ",";
1515 }
1516 else if (smask > 0)
1517 {
1518 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1519 if (smask > 1)
1520 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1521 sep = ",";
1522 }
1523
1524 if (uval & 1)
1525 {
1526 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1527 sep = ",";
1528 }
1529
1530 if (amask == 5 || amask == 6)
1531 {
1532 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1533 if (amask == 6)
1534 infprintf (is, "-%s", mips_fpr_names[1]);
1535 }
1536 }
1537 break;
1538
1539 case OP_SAVE_RESTORE_LIST:
38bf472a 1540 /* Should be handled by the caller due to complex behavior. */
c3c07478
RS
1541 abort ();
1542
ab902481
RS
1543 case OP_MDMX_IMM_REG:
1544 {
1545 unsigned int vsel;
794ac9d0 1546
ab902481
RS
1547 vsel = uval >> 5;
1548 uval &= 31;
1549 if ((vsel & 0x10) == 0)
794ac9d0 1550 {
ab902481
RS
1551 int fmt;
1552
1553 vsel &= 0x0f;
1554 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1555 if ((vsel & 1) == 0)
1556 break;
1557 print_reg (info, opcode, OP_REG_VEC, uval);
1558 infprintf (is, "[%d]", vsel >> 1);
794ac9d0 1559 }
ab902481
RS
1560 else if ((vsel & 0x08) == 0)
1561 print_reg (info, opcode, OP_REG_VEC, uval);
1562 else
1563 infprintf (is, "0x%x", uval);
1564 }
1565 break;
794ac9d0 1566
ab902481
RS
1567 case OP_REPEAT_PREV_REG:
1568 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1569 break;
794ac9d0 1570
ab902481 1571 case OP_REPEAT_DEST_REG:
7361da2c
AB
1572 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1573 break;
794ac9d0 1574
ab902481
RS
1575 case OP_PC:
1576 infprintf (is, "$pc");
1577 break;
14daeee3 1578
25499ac7
MR
1579 case OP_REG28:
1580 print_reg (info, opcode, OP_REG_GP, 28);
1581 break;
1582
14daeee3
RS
1583 case OP_VU0_SUFFIX:
1584 case OP_VU0_MATCH_SUFFIX:
1585 print_vu0_channel (info, operand, uval);
1586 break;
4edbb8e3
CF
1587
1588 case OP_IMM_INDEX:
1589 infprintf (is, "[%d]", uval);
1590 break;
1591
1592 case OP_REG_INDEX:
1593 infprintf (is, "[");
1594 print_reg (info, opcode, OP_REG_GP, uval);
1595 infprintf (is, "]");
1596 break;
ab902481
RS
1597 }
1598}
794ac9d0 1599
7361da2c
AB
1600/* Validate the arguments for INSN, which is described by OPCODE.
1601 Use DECODE_OPERAND to get the encoding of each operand. */
1602
1603static bfd_boolean
1604validate_insn_args (const struct mips_opcode *opcode,
1605 const struct mips_operand *(*decode_operand) (const char *),
1606 unsigned int insn)
1607{
1608 struct mips_print_arg_state state;
1609 const struct mips_operand *operand;
1610 const char *s;
1611 unsigned int uval;
1612
1613 init_print_arg_state (&state);
1614 for (s = opcode->args; *s; ++s)
1615 {
1616 switch (*s)
1617 {
1618 case ',':
1619 case '(':
1620 case ')':
1621 break;
1622
1623 case '#':
1624 ++s;
1625 break;
1626
1627 default:
1628 operand = decode_operand (s);
1629
1630 if (operand)
1631 {
1632 uval = mips_extract_operand (operand, insn);
1633 switch (operand->type)
1634 {
1635 case OP_REG:
1636 case OP_OPTIONAL_REG:
1637 {
1638 const struct mips_reg_operand *reg_op;
1639
1640 reg_op = (const struct mips_reg_operand *) operand;
1641 uval = mips_decode_reg_operand (reg_op, uval);
1642 mips_seen_register (&state, uval, reg_op->reg_type);
1643 }
1644 break;
1645
1646 case OP_SAME_RS_RT:
1647 {
1648 unsigned int reg1, reg2;
1649
1650 reg1 = uval & 31;
1651 reg2 = uval >> 5;
1652
1653 if (reg1 != reg2 || reg1 == 0)
1654 return FALSE;
1655 }
1656 break;
1657
1658 case OP_CHECK_PREV:
1659 {
1660 const struct mips_check_prev_operand *prev_op;
1661
1662 prev_op = (const struct mips_check_prev_operand *) operand;
1663
1664 if (!prev_op->zero_ok && uval == 0)
1665 return FALSE;
1666
1667 if (((prev_op->less_than_ok && uval < state.last_regno)
1668 || (prev_op->greater_than_ok && uval > state.last_regno)
1669 || (prev_op->equal_ok && uval == state.last_regno)))
1670 break;
1671
1672 return FALSE;
1673 }
1674
1675 case OP_NON_ZERO_REG:
1676 {
1677 if (uval == 0)
1678 return FALSE;
1679 }
1680 break;
1681
1682 case OP_INT:
1683 case OP_MAPPED_INT:
1684 case OP_MSB:
1685 case OP_REG_PAIR:
1686 case OP_PCREL:
1687 case OP_PERF_REG:
1688 case OP_ADDIUSP_INT:
1689 case OP_CLO_CLZ_DEST:
1690 case OP_LWM_SWM_LIST:
1691 case OP_ENTRY_EXIT_LIST:
1692 case OP_MDMX_IMM_REG:
1693 case OP_REPEAT_PREV_REG:
1694 case OP_REPEAT_DEST_REG:
1695 case OP_PC:
25499ac7 1696 case OP_REG28:
7361da2c
AB
1697 case OP_VU0_SUFFIX:
1698 case OP_VU0_MATCH_SUFFIX:
1699 case OP_IMM_INDEX:
1700 case OP_REG_INDEX:
7361da2c 1701 case OP_SAVE_RESTORE_LIST:
38bf472a 1702 break;
7361da2c
AB
1703 }
1704 }
1705 if (*s == 'm' || *s == '+' || *s == '-')
1706 ++s;
1707 }
1708 }
1709 return TRUE;
1710}
1711
ab902481
RS
1712/* Print the arguments for INSN, which is described by OPCODE.
1713 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
7361da2c
AB
1714 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1715 operand is for a branch or jump. */
af7ee8bf 1716
ab902481
RS
1717static void
1718print_insn_args (struct disassemble_info *info,
1719 const struct mips_opcode *opcode,
1720 const struct mips_operand *(*decode_operand) (const char *),
7361da2c 1721 unsigned int insn, bfd_vma insn_pc, unsigned int length)
ab902481
RS
1722{
1723 const fprintf_ftype infprintf = info->fprintf_func;
1724 void *is = info->stream;
1725 struct mips_print_arg_state state;
1726 const struct mips_operand *operand;
1727 const char *s;
794ac9d0 1728
ab902481
RS
1729 init_print_arg_state (&state);
1730 for (s = opcode->args; *s; ++s)
1731 {
1732 switch (*s)
1733 {
1734 case ',':
1735 case '(':
1736 case ')':
1737 infprintf (is, "%c", *s);
794ac9d0
CD
1738 break;
1739
14daeee3
RS
1740 case '#':
1741 ++s;
1742 infprintf (is, "%c%c", *s, *s);
1743 break;
1744
ab902481
RS
1745 default:
1746 operand = decode_operand (s);
1747 if (!operand)
fa7616a4 1748 {
ab902481
RS
1749 /* xgettext:c-format */
1750 infprintf (is,
1751 _("# internal error, undefined operand in `%s %s'"),
1752 opcode->name, opcode->args);
1753 return;
1754 }
38bf472a
MR
1755
1756 if (operand->type == OP_SAVE_RESTORE_LIST)
1757 {
1758 /* Handle this case here because of the complex behavior. */
1759 unsigned int amask = (insn >> 15) & 0xf;
1760 unsigned int nsreg = (insn >> 23) & 0x7;
1761 unsigned int ra = insn & 0x1000; /* $ra */
1762 unsigned int s0 = insn & 0x800; /* $s0 */
1763 unsigned int s1 = insn & 0x400; /* $s1 */
1764 unsigned int frame_size = (((insn >> 15) & 0xf0)
1765 | ((insn >> 6) & 0x0f)) * 8;
1766 mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1767 frame_size);
1768 }
1769 else if (operand->type == OP_REG
1770 && s[1] == ','
1771 && s[2] == 'H'
1772 && opcode->name[strlen (opcode->name) - 1] == '0')
ab902481 1773 {
fdfb4752 1774 /* Coprocessor register 0 with sel field. */
ab902481
RS
1775 const struct mips_cp0sel_name *n;
1776 unsigned int reg, sel;
1777
1778 reg = mips_extract_operand (operand, insn);
1779 s += 2;
1780 operand = decode_operand (s);
1781 sel = mips_extract_operand (operand, insn);
1782
1783 /* CP0 register including 'sel' code for mftc0, to be
1784 printed textually if known. If not known, print both
1785 CP0 register name and sel numerically since CP0 register
1786 with sel 0 may have a name unrelated to register being
1787 printed. */
1788 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1789 mips_cp0sel_names_len,
1790 reg, sel);
1791 if (n != NULL)
1792 infprintf (is, "%s", n->name);
fa7616a4 1793 else
ab902481 1794 infprintf (is, "$%d,%d", reg, sel);
fa7616a4 1795 }
794ac9d0 1796 else
7361da2c
AB
1797 {
1798 bfd_vma base_pc = insn_pc;
1799
1800 /* Adjust the PC relative base so that branch/jump insns use
1801 the following PC as the base but genuinely PC relative
1802 operands use the current PC. */
1803 if (operand->type == OP_PCREL)
1804 {
1805 const struct mips_pcrel_operand *pcrel_op;
1806
1807 pcrel_op = (const struct mips_pcrel_operand *) operand;
1808 /* The include_isa_bit flag is sufficient to distinguish
1809 branch/jump from other PC relative operands. */
1810 if (pcrel_op->include_isa_bit)
1811 base_pc += length;
1812 }
1813
1814 print_insn_arg (info, &state, opcode, operand, base_pc,
1815 mips_extract_operand (operand, insn));
1816 }
1817 if (*s == 'm' || *s == '+' || *s == '-')
ab902481 1818 ++s;
794ac9d0 1819 break;
af7ee8bf 1820 }
252b5132
RH
1821 }
1822}
1823\f
252b5132
RH
1824/* Print the mips instruction at address MEMADDR in debugged memory,
1825 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1826 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1827 this is little-endian code. */
1828
1829static int
47b0e7ad 1830print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1831 int word,
47b0e7ad 1832 struct disassemble_info *info)
252b5132 1833{
ab902481
RS
1834#define GET_OP(insn, field) \
1835 (((insn) >> OP_SH_##field) & OP_MASK_##field)
fc8c4fd1
MR
1836 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1837 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1838 const struct mips_opcode *op;
b34976b6 1839 static bfd_boolean init = 0;
fc8c4fd1 1840 void *is = info->stream;
252b5132
RH
1841
1842 /* Build a hash table to shorten the search time. */
1843 if (! init)
1844 {
1845 unsigned int i;
1846
1847 for (i = 0; i <= OP_MASK_OP; i++)
1848 {
1849 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1850 {
986e18a5 1851 if (op->pinfo == INSN_MACRO
9e836e3d 1852 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1853 continue;
fc8c4fd1 1854 if (i == GET_OP (op->match, OP))
252b5132
RH
1855 {
1856 mips_hash[i] = op;
1857 break;
1858 }
1859 }
7f6621cd 1860 }
252b5132
RH
1861
1862 init = 1;
1863 }
1864
aa5f19f2 1865 info->bytes_per_chunk = INSNLEN;
252b5132 1866 info->display_endian = info->endian;
9bb28706
CD
1867 info->insn_info_valid = 1;
1868 info->branch_delay_insns = 0;
def7143b 1869 info->data_size = 0;
9bb28706
CD
1870 info->insn_type = dis_nonbranch;
1871 info->target = 0;
1872 info->target2 = 0;
252b5132 1873
fc8c4fd1 1874 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1875 if (op != NULL)
1876 {
1877 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1878 {
43e65147 1879 if (op->pinfo != INSN_MACRO
9e836e3d 1880 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1881 && (word & op->mask) == op->match)
252b5132 1882 {
7361da2c 1883 /* We always disassemble the jalx instruction, except for MIPS r6. */
d301a56b 1884 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
7361da2c
AB
1885 && (strcmp (op->name, "jalx")
1886 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1887 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
252b5132
RH
1888 continue;
1889
9bb28706
CD
1890 /* Figure out instruction type and branch delay information. */
1891 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1892 {
fc76e730 1893 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
9bb28706
CD
1894 info->insn_type = dis_jsr;
1895 else
1896 info->insn_type = dis_branch;
1897 info->branch_delay_insns = 1;
1898 }
1899 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1900 | INSN_COND_BRANCH_LIKELY)) != 0)
1901 {
c680e7f6 1902 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1903 info->insn_type = dis_condjsr;
1904 else
1905 info->insn_type = dis_condbranch;
1906 info->branch_delay_insns = 1;
1907 }
1908 else if ((op->pinfo & (INSN_STORE_MEMORY
67dc82bc 1909 | INSN_LOAD_MEMORY)) != 0)
9bb28706
CD
1910 info->insn_type = dis_dref;
1911
7361da2c
AB
1912 if (!validate_insn_args (op, decode_mips_operand, word))
1913 continue;
1914
fc8c4fd1 1915 infprintf (is, "%s", op->name);
14daeee3
RS
1916 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1917 {
1918 unsigned int uval;
1919
1920 infprintf (is, ".");
1921 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1922 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1923 }
252b5132 1924
ab902481 1925 if (op->args[0])
252b5132 1926 {
fc8c4fd1 1927 infprintf (is, "\t");
ab902481 1928 print_insn_args (info, op, decode_mips_operand, word,
7361da2c 1929 memaddr, 4);
252b5132
RH
1930 }
1931
aa5f19f2 1932 return INSNLEN;
252b5132
RH
1933 }
1934 }
1935 }
fc8c4fd1 1936#undef GET_OP
252b5132
RH
1937
1938 /* Handle undefined instructions. */
9bb28706 1939 info->insn_type = dis_noninsn;
fc8c4fd1 1940 infprintf (is, "0x%x", word);
aa5f19f2 1941 return INSNLEN;
252b5132 1942}
aa5f19f2 1943\f
252b5132
RH
1944/* Disassemble an operand for a mips16 instruction. */
1945
1946static void
c3c07478
RS
1947print_mips16_insn_arg (struct disassemble_info *info,
1948 struct mips_print_arg_state *state,
1949 const struct mips_opcode *opcode,
1950 char type, bfd_vma memaddr,
1951 unsigned insn, bfd_boolean use_extend,
1952 unsigned extend, bfd_boolean is_offset)
252b5132 1953{
fc8c4fd1
MR
1954 const fprintf_ftype infprintf = info->fprintf_func;
1955 void *is = info->stream;
c3c07478 1956 const struct mips_operand *operand, *ext_operand;
bdd15286 1957 unsigned short ext_size;
c3c07478
RS
1958 unsigned int uval;
1959 bfd_vma baseaddr;
1960
1961 if (!use_extend)
1962 extend = 0;
fc8c4fd1 1963
252b5132
RH
1964 switch (type)
1965 {
1966 case ',':
1967 case '(':
1968 case ')':
fc8c4fd1 1969 infprintf (is, "%c", type);
252b5132
RH
1970 break;
1971
c3c07478
RS
1972 default:
1973 operand = decode_mips16_operand (type, FALSE);
1974 if (!operand)
1975 {
1976 /* xgettext:c-format */
1977 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1978 opcode->name, opcode->args);
1979 return;
1980 }
252b5132 1981
c3c07478
RS
1982 if (operand->type == OP_SAVE_RESTORE_LIST)
1983 {
5f5c6e03 1984 /* Handle this case here because of the complex interaction
c3c07478 1985 with the EXTEND opcode. */
38bf472a
MR
1986 unsigned int amask = extend & 0xf;
1987 unsigned int nsreg = (extend >> 8) & 0x7;
1988 unsigned int ra = insn & 0x40; /* $ra */
1989 unsigned int s0 = insn & 0x20; /* $s0 */
1990 unsigned int s1 = insn & 0x10; /* $s1 */
1991 unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
c3c07478
RS
1992 if (frame_size == 0 && !use_extend)
1993 frame_size = 128;
38bf472a 1994 mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
c3c07478
RS
1995 break;
1996 }
252b5132 1997
c3c07478
RS
1998 if (is_offset && operand->type == OP_INT)
1999 {
2000 const struct mips_int_operand *int_op;
252b5132 2001
c3c07478
RS
2002 int_op = (const struct mips_int_operand *) operand;
2003 info->insn_type = dis_dref;
2004 info->data_size = 1 << int_op->shift;
2005 }
252b5132 2006
bdd15286
MR
2007 ext_size = 0;
2008 if (use_extend)
c3c07478 2009 {
bdd15286 2010 ext_operand = decode_mips16_operand (type, TRUE);
25499ac7
MR
2011 if (ext_operand != operand
2012 || (operand->type == OP_INT && operand->lsb == 0
2013 && mips_opcode_32bit_p (opcode)))
c3c07478 2014 {
bdd15286
MR
2015 ext_size = ext_operand->size;
2016 operand = ext_operand;
c3c07478
RS
2017 }
2018 }
bdd15286
MR
2019 if (operand->size == 26)
2020 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
25499ac7 2021 else if (ext_size == 16 || ext_size == 9)
bdd15286
MR
2022 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2023 else if (ext_size == 15)
2024 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2025 else if (ext_size == 6)
2026 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2027 else
2028 uval = mips_extract_operand (operand, (extend << 16) | insn);
25499ac7
MR
2029 if (ext_size == 9)
2030 uval &= (1U << ext_size) - 1;
c3c07478
RS
2031
2032 baseaddr = memaddr + 2;
2033 if (operand->type == OP_PCREL)
2034 {
2035 const struct mips_pcrel_operand *pcrel_op;
2036
2037 pcrel_op = (const struct mips_pcrel_operand *) operand;
2038 if (!pcrel_op->include_isa_bit && use_extend)
2039 baseaddr = memaddr - 2;
2040 else if (!pcrel_op->include_isa_bit)
39f66f3a
MR
2041 {
2042 bfd_byte buffer[2];
2043
2044 /* If this instruction is in the delay slot of a JAL/JALX
2045 instruction, the base address is the address of the
2046 JAL/JALX instruction. If it is in the delay slot of
2047 a JR/JALR instruction, the base address is the address
2048 of the JR/JALR instruction. This test is unreliable:
2049 we have no way of knowing whether the previous word is
2050 instruction or data. */
2051 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2052 && (((info->endian == BFD_ENDIAN_BIG
2053 ? bfd_getb16 (buffer)
2054 : bfd_getl16 (buffer))
2055 & 0xf800) == 0x1800))
2056 baseaddr = memaddr - 4;
2057 else if (info->read_memory_func (memaddr - 2, buffer, 2,
2058 info) == 0
2059 && (((info->endian == BFD_ENDIAN_BIG
2060 ? bfd_getb16 (buffer)
2061 : bfd_getl16 (buffer))
2062 & 0xf89f) == 0xe800)
2063 && (((info->endian == BFD_ENDIAN_BIG
2064 ? bfd_getb16 (buffer)
2065 : bfd_getl16 (buffer))
2066 & 0x0060) != 0x0060))
2067 baseaddr = memaddr - 2;
2068 else
2069 baseaddr = memaddr;
2070 }
c3c07478 2071 }
0499d65b 2072
6d075bce 2073 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
0499d65b 2074 break;
252b5132
RH
2075 }
2076}
640c0ccd 2077
1bbce132
MR
2078
2079/* Check if the given address is the last word of a MIPS16 PLT entry.
2080 This word is data and depending on the value it may interfere with
2081 disassembly of further PLT entries. We make use of the fact PLT
2082 symbols are marked BSF_SYNTHETIC. */
2083static bfd_boolean
2084is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2085{
2086 if (info->symbols
2087 && info->symbols[0]
2088 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2089 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2090 return TRUE;
2091
2092 return FALSE;
2093}
2094
7fd53920
MR
2095/* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2096
2097enum match_kind
2098{
2099 MATCH_NONE,
2100 MATCH_FULL,
2101 MATCH_SHORT
2102};
2103
47b0e7ad
NC
2104/* Disassemble mips16 instructions. */
2105
2106static int
2107print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2108{
fc8c4fd1 2109 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 2110 int status;
1bbce132 2111 bfd_byte buffer[4];
47b0e7ad 2112 const struct mips_opcode *op, *opend;
c3c07478 2113 struct mips_print_arg_state state;
fc8c4fd1 2114 void *is = info->stream;
7fd53920 2115 bfd_boolean have_second;
25499ac7 2116 bfd_boolean extend_only;
7fd53920
MR
2117 unsigned int second;
2118 unsigned int first;
2119 unsigned int full;
47b0e7ad
NC
2120
2121 info->bytes_per_chunk = 2;
2122 info->display_endian = info->endian;
2123 info->insn_info_valid = 1;
2124 info->branch_delay_insns = 0;
2125 info->data_size = 0;
47b0e7ad
NC
2126 info->target = 0;
2127 info->target2 = 0;
2128
c3c07478
RS
2129#define GET_OP(insn, field) \
2130 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1bbce132
MR
2131 /* Decode PLT entry's GOT slot address word. */
2132 if (is_mips16_plt_tail (info, memaddr))
2133 {
2134 info->insn_type = dis_noninsn;
2135 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2136 if (status == 0)
2137 {
2138 unsigned int gotslot;
2139
2140 if (info->endian == BFD_ENDIAN_BIG)
2141 gotslot = bfd_getb32 (buffer);
2142 else
2143 gotslot = bfd_getl32 (buffer);
2144 infprintf (is, ".word\t0x%x", gotslot);
2145
2146 return 4;
2147 }
2148 }
2149 else
2150 {
2151 info->insn_type = dis_nonbranch;
2152 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2153 }
47b0e7ad
NC
2154 if (status != 0)
2155 {
2156 (*info->memory_error_func) (status, memaddr, info);
2157 return -1;
2158 }
2159
25499ac7
MR
2160 extend_only = FALSE;
2161
47b0e7ad 2162 if (info->endian == BFD_ENDIAN_BIG)
7fd53920 2163 first = bfd_getb16 (buffer);
47b0e7ad 2164 else
7fd53920 2165 first = bfd_getl16 (buffer);
47b0e7ad 2166
7fd53920
MR
2167 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2168 if (status == 0)
47b0e7ad 2169 {
7fd53920 2170 have_second = TRUE;
47b0e7ad 2171 if (info->endian == BFD_ENDIAN_BIG)
7fd53920 2172 second = bfd_getb16 (buffer);
47b0e7ad 2173 else
7fd53920
MR
2174 second = bfd_getl16 (buffer);
2175 full = (first << 16) | second;
2176 }
2177 else
2178 {
2179 have_second = FALSE;
2180 second = 0;
2181 full = first;
47b0e7ad
NC
2182 }
2183
2184 /* FIXME: Should probably use a hash table on the major opcode here. */
2185
2186 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2187 for (op = mips16_opcodes; op < opend; op++)
2188 {
7fd53920 2189 enum match_kind match;
47b0e7ad 2190
11dd08e9
MR
2191 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2192 continue;
2193
7fd53920
MR
2194 if (op->pinfo == INSN_MACRO
2195 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2196 match = MATCH_NONE;
2197 else if (mips_opcode_32bit_p (op))
2198 {
2199 if (have_second
2200 && (full & op->mask) == op->match)
2201 match = MATCH_FULL;
2202 else
2203 match = MATCH_NONE;
2204 }
2205 else if ((first & op->mask) == op->match)
2206 {
2207 match = MATCH_SHORT;
2208 second = 0;
2209 full = first;
2210 }
2211 else if ((first & 0xf800) == 0xf000
2212 && have_second
25499ac7 2213 && !extend_only
7fd53920 2214 && (second & op->mask) == op->match)
25499ac7
MR
2215 {
2216 if (op->pinfo2 & INSN2_SHORT_ONLY)
2217 {
2218 match = MATCH_NONE;
2219 extend_only = TRUE;
2220 }
2221 else
2222 match = MATCH_FULL;
2223 }
7fd53920
MR
2224 else
2225 match = MATCH_NONE;
47b0e7ad 2226
7fd53920
MR
2227 if (match != MATCH_NONE)
2228 {
2229 const char *s;
47b0e7ad 2230
fc8c4fd1 2231 infprintf (is, "%s", op->name);
47b0e7ad 2232 if (op->args[0] != '\0')
fc8c4fd1 2233 infprintf (is, "\t");
47b0e7ad 2234
c3c07478 2235 init_print_arg_state (&state);
47b0e7ad
NC
2236 for (s = op->args; *s != '\0'; s++)
2237 {
2238 if (*s == ','
2239 && s[1] == 'w'
7fd53920 2240 && GET_OP (full, RX) == GET_OP (full, RY))
47b0e7ad
NC
2241 {
2242 /* Skip the register and the comma. */
2243 ++s;
2244 continue;
2245 }
2246 if (*s == ','
2247 && s[1] == 'v'
7fd53920 2248 && GET_OP (full, RZ) == GET_OP (full, RX))
47b0e7ad
NC
2249 {
2250 /* Skip the register and the comma. */
2251 ++s;
2252 continue;
2253 }
25499ac7
MR
2254 if (s[0] == 'N'
2255 && s[1] == ','
2256 && s[2] == 'O'
2257 && op->name[strlen (op->name) - 1] == '0')
7fd53920 2258 {
25499ac7
MR
2259 /* Coprocessor register 0 with sel field. */
2260 const struct mips_cp0sel_name *n;
2261 const struct mips_operand *operand;
2262 unsigned int reg, sel;
2263
2264 operand = decode_mips16_operand (*s, TRUE);
2265 reg = mips_extract_operand (operand, (first << 16) | second);
2266 s += 2;
2267 operand = decode_mips16_operand (*s, TRUE);
2268 sel = mips_extract_operand (operand, (first << 16) | second);
2269
2270 /* CP0 register including 'sel' code for mftc0, to be
2271 printed textually if known. If not known, print both
2272 CP0 register name and sel numerically since CP0 register
2273 with sel 0 may have a name unrelated to register being
2274 printed. */
2275 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2276 mips_cp0sel_names_len,
2277 reg, sel);
2278 if (n != NULL)
2279 infprintf (is, "%s", n->name);
2280 else
2281 infprintf (is, "$%d,%d", reg, sel);
7fd53920 2282 }
25499ac7
MR
2283 else
2284 switch (match)
2285 {
2286 case MATCH_FULL:
2287 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2288 second, TRUE, first, s[1] == '(');
2289 break;
2290 case MATCH_SHORT:
2291 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2292 first, FALSE, 0, s[1] == '(');
2293 break;
2294 case MATCH_NONE: /* Stop the compiler complaining. */
2295 break;
2296 }
47b0e7ad
NC
2297 }
2298
9a2c7088 2299 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 2300 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088 2301 info->branch_delay_insns = 1;
26545944
RS
2302 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2303 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
47b0e7ad 2304 {
9a2c7088
MR
2305 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2306 info->insn_type = dis_jsr;
2307 else
47b0e7ad
NC
2308 info->insn_type = dis_branch;
2309 }
26545944 2310 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
9a2c7088 2311 info->insn_type = dis_condbranch;
47b0e7ad 2312
7fd53920 2313 return match == MATCH_FULL ? 4 : 2;
47b0e7ad
NC
2314 }
2315 }
fc8c4fd1 2316#undef GET_OP
47b0e7ad 2317
7fd53920 2318 infprintf (is, "0x%x", first);
47b0e7ad
NC
2319 info->insn_type = dis_noninsn;
2320
7fd53920 2321 return 2;
47b0e7ad
NC
2322}
2323
df58fc94
RS
2324/* Disassemble microMIPS instructions. */
2325
2326static int
2327print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2328{
0c7533d3 2329 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94 2330 const struct mips_opcode *op, *opend;
df58fc94 2331 void *is = info->stream;
df58fc94 2332 bfd_byte buffer[2];
ab902481
RS
2333 unsigned int higher;
2334 unsigned int length;
df58fc94 2335 int status;
ab902481 2336 unsigned int insn;
df58fc94
RS
2337
2338 info->bytes_per_chunk = 2;
2339 info->display_endian = info->endian;
2340 info->insn_info_valid = 1;
2341 info->branch_delay_insns = 0;
2342 info->data_size = 0;
2343 info->insn_type = dis_nonbranch;
2344 info->target = 0;
2345 info->target2 = 0;
2346
2347 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2348 if (status != 0)
2349 {
2350 (*info->memory_error_func) (status, memaddr, info);
2351 return -1;
2352 }
2353
2354 length = 2;
2355
2356 if (info->endian == BFD_ENDIAN_BIG)
2357 insn = bfd_getb16 (buffer);
2358 else
2359 insn = bfd_getl16 (buffer);
2360
100b4f2e 2361 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
df58fc94
RS
2362 {
2363 /* This is a 32-bit microMIPS instruction. */
2364 higher = insn;
2365
2366 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2367 if (status != 0)
2368 {
0c7533d3 2369 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2370 (*info->memory_error_func) (status, memaddr + 2, info);
2371 return -1;
2372 }
2373
2374 if (info->endian == BFD_ENDIAN_BIG)
2375 insn = bfd_getb16 (buffer);
2376 else
2377 insn = bfd_getl16 (buffer);
2378
2379 insn = insn | (higher << 16);
2380
2381 length += 2;
2382 }
2383
2384 /* FIXME: Should probably use a hash table on the major opcode here. */
2385
df58fc94
RS
2386 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2387 for (op = micromips_opcodes; op < opend; op++)
2388 {
2389 if (op->pinfo != INSN_MACRO
2390 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2391 && (insn & op->mask) == op->match
2392 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2393 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2394 {
7361da2c
AB
2395 if (!validate_insn_args (op, decode_micromips_operand, insn))
2396 continue;
2397
0c7533d3 2398 infprintf (is, "%s", op->name);
df58fc94 2399
ab902481 2400 if (op->args[0])
df58fc94 2401 {
ab902481
RS
2402 infprintf (is, "\t");
2403 print_insn_args (info, op, decode_micromips_operand, insn,
7361da2c 2404 memaddr + 1, length);
df58fc94
RS
2405 }
2406
2407 /* Figure out instruction type and branch delay information. */
2408 if ((op->pinfo
2409 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2410 info->branch_delay_insns = 1;
2411 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2412 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2413 {
fc76e730 2414 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
df58fc94
RS
2415 info->insn_type = dis_jsr;
2416 else
2417 info->insn_type = dis_branch;
2418 }
2419 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2420 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2421 {
2422 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2423 info->insn_type = dis_condjsr;
2424 else
2425 info->insn_type = dis_condbranch;
2426 }
2427 else if ((op->pinfo
67dc82bc 2428 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
df58fc94
RS
2429 info->insn_type = dis_dref;
2430
2431 return length;
2432 }
2433 }
df58fc94 2434
0c7533d3 2435 infprintf (is, "0x%x", insn);
df58fc94
RS
2436 info->insn_type = dis_noninsn;
2437
2438 return length;
2439}
2440
2441/* Return 1 if a symbol associated with the location being disassembled
1401d2fe
MR
2442 indicates a compressed mode, either MIPS16 or microMIPS, according to
2443 MICROMIPS_P. We iterate over all the symbols at the address being
2444 considered assuming if at least one of them indicates code compression,
2445 then such code has been genuinely produced here (other symbols could
2446 have been derived from function symbols defined elsewhere or could
2447 define data). Otherwise, return 0. */
df58fc94
RS
2448
2449static bfd_boolean
1401d2fe 2450is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
df58fc94 2451{
df58fc94 2452 int i;
1bbce132
MR
2453 int l;
2454
2455 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2456 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
1401d2fe 2457 && ((!micromips_p
1bbce132 2458 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
1401d2fe 2459 || (micromips_p
1bbce132
MR
2460 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2461 return 1;
2462 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2463 && info->symtab[i]->section == info->section)
2464 {
2465 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
1401d2fe 2466 if ((!micromips_p
1bbce132 2467 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
1401d2fe 2468 || (micromips_p
1bbce132
MR
2469 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2470 return 1;
2471 }
df58fc94
RS
2472
2473 return 0;
2474}
2475
47b0e7ad
NC
2476/* In an environment where we do not know the symbol type of the
2477 instruction we are forced to assume that the low order bit of the
2478 instructions' address may mark it as a mips16 instruction. If we
2479 are single stepping, or the pc is within the disassembled function,
2480 this works. Otherwise, we need a clue. Sometimes. */
2481
2482static int
2483_print_insn_mips (bfd_vma memaddr,
2484 struct disassemble_info *info,
2485 enum bfd_endian endianness)
2486{
2487 bfd_byte buffer[INSNLEN];
2488 int status;
2489
2490 set_default_mips_dis_options (info);
2491 parse_mips_dis_options (info->disassembler_options);
2492
df58fc94
RS
2493 if (info->mach == bfd_mach_mips16)
2494 return print_insn_mips16 (memaddr, info);
2495 if (info->mach == bfd_mach_mips_micromips)
2496 return print_insn_micromips (memaddr, info);
2497
47b0e7ad 2498#if 1
df58fc94 2499 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
2500 /* Only a few tools will work this way. */
2501 if (memaddr & 0x01)
1401d2fe
MR
2502 {
2503 if (micromips_ase)
2504 return print_insn_micromips (memaddr, info);
2505 else
2506 return print_insn_mips16 (memaddr, info);
2507 }
47b0e7ad
NC
2508#endif
2509
2510#if SYMTAB_AVAILABLE
1401d2fe
MR
2511 if (is_compressed_mode_p (info, TRUE))
2512 return print_insn_micromips (memaddr, info);
2513 if (is_compressed_mode_p (info, FALSE))
2514 return print_insn_mips16 (memaddr, info);
47b0e7ad
NC
2515#endif
2516
2517 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2518 if (status == 0)
2519 {
fc8c4fd1 2520 int insn;
47b0e7ad
NC
2521
2522 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 2523 insn = bfd_getb32 (buffer);
47b0e7ad 2524 else
fc8c4fd1 2525 insn = bfd_getl32 (buffer);
47b0e7ad
NC
2526
2527 return print_insn_mips (memaddr, insn, info);
2528 }
2529 else
2530 {
2531 (*info->memory_error_func) (status, memaddr, info);
2532 return -1;
2533 }
2534}
2535
2536int
2537print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2538{
2539 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2540}
2541
2542int
2543print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2544{
2545 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2546}
2547\f
640c0ccd 2548void
47b0e7ad 2549print_mips_disassembler_options (FILE *stream)
640c0ccd 2550{
4a9a3c54 2551 unsigned int i;
640c0ccd
CD
2552
2553 fprintf (stream, _("\n\
2554The following MIPS specific disassembler options are supported for use\n\
2555with the -M switch (multiple options should be separated by commas):\n"));
2556
0348fd79
MR
2557 fprintf (stream, _("\n\
2558 no-aliases Use canonical instruction forms.\n"));
2559
4edbb8e3 2560 fprintf (stream, _("\n\
6725647c 2561 msa Recognize MSA instructions.\n"));
4edbb8e3 2562
b015e599 2563 fprintf (stream, _("\n\
6725647c 2564 virt Recognize the virtualization ASE instructions.\n"));
b015e599 2565
7d64c587 2566 fprintf (stream, _("\n\
6725647c
MR
2567 xpa Recognize the eXtended Physical Address (XPA)\n\
2568 ASE instructions.\n"));
7d64c587 2569
640c0ccd 2570 fprintf (stream, _("\n\
6725647c 2571 gpr-names=ABI Print GPR names according to specified ABI.\n\
640c0ccd
CD
2572 Default: based on binary being disassembled.\n"));
2573
2574 fprintf (stream, _("\n\
2575 fpr-names=ABI Print FPR names according to specified ABI.\n\
2576 Default: numeric.\n"));
2577
2578 fprintf (stream, _("\n\
2579 cp0-names=ARCH Print CP0 register names according to\n\
2580 specified architecture.\n\
2581 Default: based on binary being disassembled.\n"));
2582
af7ee8bf
CD
2583 fprintf (stream, _("\n\
2584 hwr-names=ARCH Print HWR names according to specified \n\
6725647c 2585 architecture.\n\
af7ee8bf
CD
2586 Default: based on binary being disassembled.\n"));
2587
640c0ccd
CD
2588 fprintf (stream, _("\n\
2589 reg-names=ABI Print GPR and FPR names according to\n\
2590 specified ABI.\n"));
2591
2592 fprintf (stream, _("\n\
af7ee8bf 2593 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
2594 specified architecture.\n"));
2595
2596 fprintf (stream, _("\n\
2597 For the options above, the following values are supported for \"ABI\":\n\
2598 "));
4a9a3c54 2599 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
2600 fprintf (stream, " %s", mips_abi_choices[i].name);
2601 fprintf (stream, _("\n"));
2602
2603 fprintf (stream, _("\n\
2604 For the options above, The following values are supported for \"ARCH\":\n\
2605 "));
4a9a3c54 2606 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
2607 if (*mips_arch_choices[i].name != '\0')
2608 fprintf (stream, " %s", mips_arch_choices[i].name);
2609 fprintf (stream, _("\n"));
2610
2611 fprintf (stream, _("\n"));
2612}