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