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