Add support to show the symbolic names of the MIPS CP1 registers.
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2012
4 Free Software Foundation, Inc.
5 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
6
7 This file is part of the GNU opcodes library.
8
9 This library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
13
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
23
24 #include "sysdep.h"
25 #include "dis-asm.h"
26 #include "libiberty.h"
27 #include "opcode/mips.h"
28 #include "opintl.h"
29
30 /* FIXME: These are needed to figure out if the code is mips16 or
31 not. The low bit of the address is often a good indicator. No
32 symbol table is available when this code runs out in an embedded
33 system as when it is used for disassembler support in a monitor. */
34
35 #if !defined(EMBEDDED_ENV)
36 #define SYMTAB_AVAILABLE 1
37 #include "elf-bfd.h"
38 #include "elf/mips.h"
39 #endif
40
41 /* Mips instructions are at maximum this many bytes long. */
42 #define INSNLEN 4
43
44 \f
45 /* 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_r3000[32] =
127 {
128 "c0_index", "c0_random", "c0_entrylo", "$3",
129 "c0_context", "$5", "$6", "$7",
130 "c0_badvaddr", "$9", "c0_entryhi", "$11",
131 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
132 "$16", "$17", "$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_r4000[32] =
139 {
140 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
141 "c0_context", "c0_pagemask", "c0_wired", "$7",
142 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
143 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
144 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
145 "c0_xcontext", "$21", "$22", "$23",
146 "$24", "$25", "c0_ecc", "c0_cacheerr",
147 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
148 };
149
150 static const char * const mips_cp0_names_r5900[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", "$17", "$18", "$19",
157 "$20", "$21", "$22", "c0_badpaddr",
158 "c0_depc", "c0_perfcnt", "$26", "$27",
159 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
160 };
161
162 static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900[] =
163 {
164 { 24, 2, "c0_iab" },
165 { 24, 3, "c0_iabm" },
166 { 24, 4, "c0_dab" },
167 { 24, 5, "c0_dabm" },
168 { 24, 6, "c0_dvb" },
169 { 24, 7, "c0_dvbm" },
170 { 25, 1, "c0_perfcnt,1" },
171 { 25, 2, "c0_perfcnt,2" }
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_mips3264[32] =
187 {
188 "c1_fir", "c1_ufr", "$2", "$3",
189 "c1_unfr", "$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", "c1_fccr", "c1_fexr", "$27",
195 "c1_fenr", "$29", "$30", "c1_fcsr"
196 };
197
198 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
199 {
200 { 16, 1, "c0_config1" },
201 { 16, 2, "c0_config2" },
202 { 16, 3, "c0_config3" },
203 { 18, 1, "c0_watchlo,1" },
204 { 18, 2, "c0_watchlo,2" },
205 { 18, 3, "c0_watchlo,3" },
206 { 18, 4, "c0_watchlo,4" },
207 { 18, 5, "c0_watchlo,5" },
208 { 18, 6, "c0_watchlo,6" },
209 { 18, 7, "c0_watchlo,7" },
210 { 19, 1, "c0_watchhi,1" },
211 { 19, 2, "c0_watchhi,2" },
212 { 19, 3, "c0_watchhi,3" },
213 { 19, 4, "c0_watchhi,4" },
214 { 19, 5, "c0_watchhi,5" },
215 { 19, 6, "c0_watchhi,6" },
216 { 19, 7, "c0_watchhi,7" },
217 { 25, 1, "c0_perfcnt,1" },
218 { 25, 2, "c0_perfcnt,2" },
219 { 25, 3, "c0_perfcnt,3" },
220 { 25, 4, "c0_perfcnt,4" },
221 { 25, 5, "c0_perfcnt,5" },
222 { 25, 6, "c0_perfcnt,6" },
223 { 25, 7, "c0_perfcnt,7" },
224 { 27, 1, "c0_cacheerr,1" },
225 { 27, 2, "c0_cacheerr,2" },
226 { 27, 3, "c0_cacheerr,3" },
227 { 28, 1, "c0_datalo" },
228 { 29, 1, "c0_datahi" }
229 };
230
231 static const char * const mips_cp0_names_mips3264r2[32] =
232 {
233 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
234 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
235 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
236 "c0_status", "c0_cause", "c0_epc", "c0_prid",
237 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
238 "c0_xcontext", "$21", "$22", "c0_debug",
239 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
240 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
241 };
242
243 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
244 {
245 { 4, 1, "c0_contextconfig" },
246 { 0, 1, "c0_mvpcontrol" },
247 { 0, 2, "c0_mvpconf0" },
248 { 0, 3, "c0_mvpconf1" },
249 { 1, 1, "c0_vpecontrol" },
250 { 1, 2, "c0_vpeconf0" },
251 { 1, 3, "c0_vpeconf1" },
252 { 1, 4, "c0_yqmask" },
253 { 1, 5, "c0_vpeschedule" },
254 { 1, 6, "c0_vpeschefback" },
255 { 2, 1, "c0_tcstatus" },
256 { 2, 2, "c0_tcbind" },
257 { 2, 3, "c0_tcrestart" },
258 { 2, 4, "c0_tchalt" },
259 { 2, 5, "c0_tccontext" },
260 { 2, 6, "c0_tcschedule" },
261 { 2, 7, "c0_tcschefback" },
262 { 5, 1, "c0_pagegrain" },
263 { 6, 1, "c0_srsconf0" },
264 { 6, 2, "c0_srsconf1" },
265 { 6, 3, "c0_srsconf2" },
266 { 6, 4, "c0_srsconf3" },
267 { 6, 5, "c0_srsconf4" },
268 { 12, 1, "c0_intctl" },
269 { 12, 2, "c0_srsctl" },
270 { 12, 3, "c0_srsmap" },
271 { 15, 1, "c0_ebase" },
272 { 16, 1, "c0_config1" },
273 { 16, 2, "c0_config2" },
274 { 16, 3, "c0_config3" },
275 { 18, 1, "c0_watchlo,1" },
276 { 18, 2, "c0_watchlo,2" },
277 { 18, 3, "c0_watchlo,3" },
278 { 18, 4, "c0_watchlo,4" },
279 { 18, 5, "c0_watchlo,5" },
280 { 18, 6, "c0_watchlo,6" },
281 { 18, 7, "c0_watchlo,7" },
282 { 19, 1, "c0_watchhi,1" },
283 { 19, 2, "c0_watchhi,2" },
284 { 19, 3, "c0_watchhi,3" },
285 { 19, 4, "c0_watchhi,4" },
286 { 19, 5, "c0_watchhi,5" },
287 { 19, 6, "c0_watchhi,6" },
288 { 19, 7, "c0_watchhi,7" },
289 { 23, 1, "c0_tracecontrol" },
290 { 23, 2, "c0_tracecontrol2" },
291 { 23, 3, "c0_usertracedata" },
292 { 23, 4, "c0_tracebpc" },
293 { 25, 1, "c0_perfcnt,1" },
294 { 25, 2, "c0_perfcnt,2" },
295 { 25, 3, "c0_perfcnt,3" },
296 { 25, 4, "c0_perfcnt,4" },
297 { 25, 5, "c0_perfcnt,5" },
298 { 25, 6, "c0_perfcnt,6" },
299 { 25, 7, "c0_perfcnt,7" },
300 { 27, 1, "c0_cacheerr,1" },
301 { 27, 2, "c0_cacheerr,2" },
302 { 27, 3, "c0_cacheerr,3" },
303 { 28, 1, "c0_datalo" },
304 { 28, 2, "c0_taglo1" },
305 { 28, 3, "c0_datalo1" },
306 { 28, 4, "c0_taglo2" },
307 { 28, 5, "c0_datalo2" },
308 { 28, 6, "c0_taglo3" },
309 { 28, 7, "c0_datalo3" },
310 { 29, 1, "c0_datahi" },
311 { 29, 2, "c0_taghi1" },
312 { 29, 3, "c0_datahi1" },
313 { 29, 4, "c0_taghi2" },
314 { 29, 5, "c0_datahi2" },
315 { 29, 6, "c0_taghi3" },
316 { 29, 7, "c0_datahi3" },
317 };
318
319 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
320 static const char * const mips_cp0_names_sb1[32] =
321 {
322 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
323 "c0_context", "c0_pagemask", "c0_wired", "$7",
324 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
325 "c0_status", "c0_cause", "c0_epc", "c0_prid",
326 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
327 "c0_xcontext", "$21", "$22", "c0_debug",
328 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
329 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
330 };
331
332 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
333 {
334 { 16, 1, "c0_config1" },
335 { 18, 1, "c0_watchlo,1" },
336 { 19, 1, "c0_watchhi,1" },
337 { 22, 0, "c0_perftrace" },
338 { 23, 3, "c0_edebug" },
339 { 25, 1, "c0_perfcnt,1" },
340 { 25, 2, "c0_perfcnt,2" },
341 { 25, 3, "c0_perfcnt,3" },
342 { 25, 4, "c0_perfcnt,4" },
343 { 25, 5, "c0_perfcnt,5" },
344 { 25, 6, "c0_perfcnt,6" },
345 { 25, 7, "c0_perfcnt,7" },
346 { 26, 1, "c0_buserr_pa" },
347 { 27, 1, "c0_cacheerr_d" },
348 { 27, 3, "c0_cacheerr_d_pa" },
349 { 28, 1, "c0_datalo_i" },
350 { 28, 2, "c0_taglo_d" },
351 { 28, 3, "c0_datalo_d" },
352 { 29, 1, "c0_datahi_i" },
353 { 29, 2, "c0_taghi_d" },
354 { 29, 3, "c0_datahi_d" },
355 };
356
357 /* Xlr cop0 register names. */
358 static const char * const mips_cp0_names_xlr[32] = {
359 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
360 "c0_context", "c0_pagemask", "c0_wired", "$7",
361 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
362 "c0_status", "c0_cause", "c0_epc", "c0_prid",
363 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
364 "c0_xcontext", "$21", "$22", "c0_debug",
365 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
366 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
367 };
368
369 /* XLR's CP0 Select Registers. */
370
371 static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
372 { 9, 6, "c0_extintreq" },
373 { 9, 7, "c0_extintmask" },
374 { 15, 1, "c0_ebase" },
375 { 16, 1, "c0_config1" },
376 { 16, 2, "c0_config2" },
377 { 16, 3, "c0_config3" },
378 { 16, 7, "c0_procid2" },
379 { 18, 1, "c0_watchlo,1" },
380 { 18, 2, "c0_watchlo,2" },
381 { 18, 3, "c0_watchlo,3" },
382 { 18, 4, "c0_watchlo,4" },
383 { 18, 5, "c0_watchlo,5" },
384 { 18, 6, "c0_watchlo,6" },
385 { 18, 7, "c0_watchlo,7" },
386 { 19, 1, "c0_watchhi,1" },
387 { 19, 2, "c0_watchhi,2" },
388 { 19, 3, "c0_watchhi,3" },
389 { 19, 4, "c0_watchhi,4" },
390 { 19, 5, "c0_watchhi,5" },
391 { 19, 6, "c0_watchhi,6" },
392 { 19, 7, "c0_watchhi,7" },
393 { 25, 1, "c0_perfcnt,1" },
394 { 25, 2, "c0_perfcnt,2" },
395 { 25, 3, "c0_perfcnt,3" },
396 { 25, 4, "c0_perfcnt,4" },
397 { 25, 5, "c0_perfcnt,5" },
398 { 25, 6, "c0_perfcnt,6" },
399 { 25, 7, "c0_perfcnt,7" },
400 { 27, 1, "c0_cacheerr,1" },
401 { 27, 2, "c0_cacheerr,2" },
402 { 27, 3, "c0_cacheerr,3" },
403 { 28, 1, "c0_datalo" },
404 { 29, 1, "c0_datahi" }
405 };
406
407 static const char * const mips_hwr_names_numeric[32] =
408 {
409 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
410 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
411 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
412 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
413 };
414
415 static const char * const mips_hwr_names_mips3264r2[32] =
416 {
417 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
418 "$4", "$5", "$6", "$7",
419 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
420 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
421 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
422 };
423
424 static const char * const msa_control_names[32] =
425 {
426 "msa_ir", "msa_csr", "msa_access", "msa_save",
427 "msa_modify", "msa_request", "msa_map", "msa_unmap",
428 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
429 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
430 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
431 };
432
433 struct mips_abi_choice
434 {
435 const char * name;
436 const char * const *gpr_names;
437 const char * const *fpr_names;
438 };
439
440 struct mips_abi_choice mips_abi_choices[] =
441 {
442 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
443 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
444 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
445 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
446 };
447
448 struct mips_arch_choice
449 {
450 const char *name;
451 int bfd_mach_valid;
452 unsigned long bfd_mach;
453 int processor;
454 int isa;
455 int ase;
456 const char * const *cp0_names;
457 const struct mips_cp0sel_name *cp0sel_names;
458 unsigned int cp0sel_names_len;
459 const char * const *cp1_names;
460 const char * const *hwr_names;
461 };
462
463 const struct mips_arch_choice mips_arch_choices[] =
464 {
465 { "numeric", 0, 0, 0, 0, 0,
466 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
467 mips_hwr_names_numeric },
468
469 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
470 mips_cp0_names_r3000, NULL, 0, mips_cp1_names_numeric,
471 mips_hwr_names_numeric },
472 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
473 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
474 mips_hwr_names_numeric },
475 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
476 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
477 mips_hwr_names_numeric },
478 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
479 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
480 mips_hwr_names_numeric },
481 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
482 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
483 mips_hwr_names_numeric },
484 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
485 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
486 mips_hwr_names_numeric },
487 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
488 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
489 mips_hwr_names_numeric },
490 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
491 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
492 mips_hwr_names_numeric },
493 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
494 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
495 mips_hwr_names_numeric },
496 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
497 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
498 mips_hwr_names_numeric },
499 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
500 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
501 mips_hwr_names_numeric },
502 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
503 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
504 mips_hwr_names_numeric },
505 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
506 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
507 mips_hwr_names_numeric },
508 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
509 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
510 mips_hwr_names_numeric },
511 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
512 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_numeric,
513 mips_hwr_names_numeric },
514 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
515 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
516 mips_hwr_names_numeric },
517 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
518 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
519 mips_hwr_names_numeric },
520 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
521 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
522 mips_hwr_names_numeric },
523 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
524 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
525 mips_hwr_names_numeric },
526 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
527 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
528 mips_hwr_names_numeric },
529 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
530 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
531 mips_hwr_names_numeric },
532 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
533 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
534 mips_hwr_names_numeric },
535 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
536 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
537 mips_hwr_names_numeric },
538 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
539 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
540 mips_hwr_names_numeric },
541
542 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
543 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
544 _MIPS32 Architecture For Programmers Volume I: Introduction to the
545 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
546 page 1. */
547 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
548 ISA_MIPS32, ASE_SMARTMIPS,
549 mips_cp0_names_mips3264,
550 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
551 mips_cp1_names_mips3264, mips_hwr_names_numeric },
552
553 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
554 ISA_MIPS32R2,
555 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
556 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA),
557 mips_cp0_names_mips3264r2,
558 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
559 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
560
561 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
562 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
563 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
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 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
569 ISA_MIPS64R2,
570 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
571 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64),
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 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
577 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
578 mips_cp0_names_sb1,
579 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
580 mips_cp1_names_mips3264, mips_hwr_names_numeric },
581
582 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
583 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
584 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
585
586 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
587 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
588 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
589
590 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
591 ISA_MIPS64 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
592 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
593
594 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
595 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
596 mips_cp1_names_mips3264, mips_hwr_names_numeric },
597
598 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
599 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
600 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
601
602 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
603 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
604 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
605
606 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
607 ISA_MIPS64 | INSN_XLR, 0,
608 mips_cp0_names_xlr,
609 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
610 mips_cp1_names_mips3264, mips_hwr_names_numeric },
611
612 /* XLP is mostly like XLR, with the prominent exception it is being
613 MIPS64R2. */
614 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
615 ISA_MIPS64R2 | INSN_XLR, 0,
616 mips_cp0_names_xlr,
617 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
618 mips_cp1_names_mips3264, mips_hwr_names_numeric },
619
620 /* This entry, mips16, is here only for ISA/processor selection; do
621 not print its name. */
622 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0,
623 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
624 mips_hwr_names_numeric },
625 };
626
627 /* ISA and processor type to disassemble for, and register names to use.
628 set_default_mips_dis_options and parse_mips_dis_options fill in these
629 values. */
630 static int mips_processor;
631 static int mips_isa;
632 static int mips_ase;
633 static int micromips_ase;
634 static const char * const *mips_gpr_names;
635 static const char * const *mips_fpr_names;
636 static const char * const *mips_cp0_names;
637 static const struct mips_cp0sel_name *mips_cp0sel_names;
638 static int mips_cp0sel_names_len;
639 static const char * const *mips_cp1_names;
640 static const char * const *mips_hwr_names;
641
642 /* Other options */
643 static int no_aliases; /* If set disassemble as most general inst. */
644 \f
645 static const struct mips_abi_choice *
646 choose_abi_by_name (const char *name, unsigned int namelen)
647 {
648 const struct mips_abi_choice *c;
649 unsigned int i;
650
651 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
652 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
653 && strlen (mips_abi_choices[i].name) == namelen)
654 c = &mips_abi_choices[i];
655
656 return c;
657 }
658
659 static const struct mips_arch_choice *
660 choose_arch_by_name (const char *name, unsigned int namelen)
661 {
662 const struct mips_arch_choice *c = NULL;
663 unsigned int i;
664
665 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
666 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
667 && strlen (mips_arch_choices[i].name) == namelen)
668 c = &mips_arch_choices[i];
669
670 return c;
671 }
672
673 static const struct mips_arch_choice *
674 choose_arch_by_number (unsigned long mach)
675 {
676 static unsigned long hint_bfd_mach;
677 static const struct mips_arch_choice *hint_arch_choice;
678 const struct mips_arch_choice *c;
679 unsigned int i;
680
681 /* We optimize this because even if the user specifies no
682 flags, this will be done for every instruction! */
683 if (hint_bfd_mach == mach
684 && hint_arch_choice != NULL
685 && hint_arch_choice->bfd_mach == hint_bfd_mach)
686 return hint_arch_choice;
687
688 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
689 {
690 if (mips_arch_choices[i].bfd_mach_valid
691 && mips_arch_choices[i].bfd_mach == mach)
692 {
693 c = &mips_arch_choices[i];
694 hint_bfd_mach = mach;
695 hint_arch_choice = c;
696 }
697 }
698 return c;
699 }
700
701 /* Check if the object uses NewABI conventions. */
702
703 static int
704 is_newabi (Elf_Internal_Ehdr *header)
705 {
706 /* There are no old-style ABIs which use 64-bit ELF. */
707 if (header->e_ident[EI_CLASS] == ELFCLASS64)
708 return 1;
709
710 /* If a 32-bit ELF file, n32 is a new-style ABI. */
711 if ((header->e_flags & EF_MIPS_ABI2) != 0)
712 return 1;
713
714 return 0;
715 }
716
717 /* Check if the object has microMIPS ASE code. */
718
719 static int
720 is_micromips (Elf_Internal_Ehdr *header)
721 {
722 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
723 return 1;
724
725 return 0;
726 }
727
728 static void
729 set_default_mips_dis_options (struct disassemble_info *info)
730 {
731 const struct mips_arch_choice *chosen_arch;
732
733 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
734 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
735 CP0 register, and HWR names. */
736 mips_isa = ISA_MIPS3;
737 mips_processor = CPU_R3000;
738 micromips_ase = 0;
739 mips_ase = 0;
740 mips_gpr_names = mips_gpr_names_oldabi;
741 mips_fpr_names = mips_fpr_names_numeric;
742 mips_cp0_names = mips_cp0_names_numeric;
743 mips_cp0sel_names = NULL;
744 mips_cp0sel_names_len = 0;
745 mips_cp1_names = mips_cp1_names_numeric;
746 mips_hwr_names = mips_hwr_names_numeric;
747 no_aliases = 0;
748
749 /* Update settings according to the ELF file header flags. */
750 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
751 {
752 Elf_Internal_Ehdr *header;
753
754 header = elf_elfheader (info->section->owner);
755 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
756 if (is_newabi (header))
757 mips_gpr_names = mips_gpr_names_newabi;
758 /* If a microMIPS binary, then don't use MIPS16 bindings. */
759 micromips_ase = is_micromips (header);
760 }
761
762 /* Set ISA, architecture, and cp0 register names as best we can. */
763 #if ! SYMTAB_AVAILABLE
764 /* This is running out on a target machine, not in a host tool.
765 FIXME: Where does mips_target_info come from? */
766 target_processor = mips_target_info.processor;
767 mips_isa = mips_target_info.isa;
768 mips_ase = mips_target_info.ase;
769 #else
770 chosen_arch = choose_arch_by_number (info->mach);
771 if (chosen_arch != NULL)
772 {
773 mips_processor = chosen_arch->processor;
774 mips_isa = chosen_arch->isa;
775 mips_ase = chosen_arch->ase;
776 mips_cp0_names = chosen_arch->cp0_names;
777 mips_cp0sel_names = chosen_arch->cp0sel_names;
778 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
779 mips_cp1_names = chosen_arch->cp1_names;
780 mips_hwr_names = chosen_arch->hwr_names;
781 }
782 #endif
783 }
784
785 static void
786 parse_mips_dis_option (const char *option, unsigned int len)
787 {
788 unsigned int i, optionlen, vallen;
789 const char *val;
790 const struct mips_abi_choice *chosen_abi;
791 const struct mips_arch_choice *chosen_arch;
792
793 /* Try to match options that are simple flags */
794 if (CONST_STRNEQ (option, "no-aliases"))
795 {
796 no_aliases = 1;
797 return;
798 }
799
800 if (CONST_STRNEQ (option, "msa"))
801 {
802 mips_ase |= ASE_MSA;
803 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2)
804 mips_ase |= ASE_MSA64;
805 return;
806 }
807
808 if (CONST_STRNEQ (option, "virt"))
809 {
810 mips_ase |= ASE_VIRT;
811 if (mips_isa & ISA_MIPS64R2)
812 mips_ase |= ASE_VIRT64;
813 return;
814 }
815
816 /* Look for the = that delimits the end of the option name. */
817 for (i = 0; i < len; i++)
818 if (option[i] == '=')
819 break;
820
821 if (i == 0) /* Invalid option: no name before '='. */
822 return;
823 if (i == len) /* Invalid option: no '='. */
824 return;
825 if (i == (len - 1)) /* Invalid option: no value after '='. */
826 return;
827
828 optionlen = i;
829 val = option + (optionlen + 1);
830 vallen = len - (optionlen + 1);
831
832 if (strncmp ("gpr-names", option, optionlen) == 0
833 && strlen ("gpr-names") == optionlen)
834 {
835 chosen_abi = choose_abi_by_name (val, vallen);
836 if (chosen_abi != NULL)
837 mips_gpr_names = chosen_abi->gpr_names;
838 return;
839 }
840
841 if (strncmp ("fpr-names", option, optionlen) == 0
842 && strlen ("fpr-names") == optionlen)
843 {
844 chosen_abi = choose_abi_by_name (val, vallen);
845 if (chosen_abi != NULL)
846 mips_fpr_names = chosen_abi->fpr_names;
847 return;
848 }
849
850 if (strncmp ("cp0-names", option, optionlen) == 0
851 && strlen ("cp0-names") == optionlen)
852 {
853 chosen_arch = choose_arch_by_name (val, vallen);
854 if (chosen_arch != NULL)
855 {
856 mips_cp0_names = chosen_arch->cp0_names;
857 mips_cp0sel_names = chosen_arch->cp0sel_names;
858 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
859 }
860 return;
861 }
862
863 if (strncmp ("cp1-names", option, optionlen) == 0
864 && strlen ("cp1-names") == optionlen)
865 {
866 chosen_arch = choose_arch_by_name (val, vallen);
867 if (chosen_arch != NULL)
868 mips_cp1_names = chosen_arch->cp1_names;
869 return;
870 }
871
872 if (strncmp ("hwr-names", option, optionlen) == 0
873 && strlen ("hwr-names") == optionlen)
874 {
875 chosen_arch = choose_arch_by_name (val, vallen);
876 if (chosen_arch != NULL)
877 mips_hwr_names = chosen_arch->hwr_names;
878 return;
879 }
880
881 if (strncmp ("reg-names", option, optionlen) == 0
882 && strlen ("reg-names") == optionlen)
883 {
884 /* We check both ABI and ARCH here unconditionally, so
885 that "numeric" will do the desirable thing: select
886 numeric register names for all registers. Other than
887 that, a given name probably won't match both. */
888 chosen_abi = choose_abi_by_name (val, vallen);
889 if (chosen_abi != NULL)
890 {
891 mips_gpr_names = chosen_abi->gpr_names;
892 mips_fpr_names = chosen_abi->fpr_names;
893 }
894 chosen_arch = choose_arch_by_name (val, vallen);
895 if (chosen_arch != NULL)
896 {
897 mips_cp0_names = chosen_arch->cp0_names;
898 mips_cp0sel_names = chosen_arch->cp0sel_names;
899 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
900 mips_cp1_names = chosen_arch->cp1_names;
901 mips_hwr_names = chosen_arch->hwr_names;
902 }
903 return;
904 }
905
906 /* Invalid option. */
907 }
908
909 static void
910 parse_mips_dis_options (const char *options)
911 {
912 const char *option_end;
913
914 if (options == NULL)
915 return;
916
917 while (*options != '\0')
918 {
919 /* Skip empty options. */
920 if (*options == ',')
921 {
922 options++;
923 continue;
924 }
925
926 /* We know that *options is neither NUL or a comma. */
927 option_end = options + 1;
928 while (*option_end != ',' && *option_end != '\0')
929 option_end++;
930
931 parse_mips_dis_option (options, option_end - options);
932
933 /* Go on to the next one. If option_end points to a comma, it
934 will be skipped above. */
935 options = option_end;
936 }
937 }
938
939 static const struct mips_cp0sel_name *
940 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
941 unsigned int len,
942 unsigned int cp0reg,
943 unsigned int sel)
944 {
945 unsigned int i;
946
947 for (i = 0; i < len; i++)
948 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
949 return &names[i];
950 return NULL;
951 }
952
953 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
954
955 static void
956 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
957 enum mips_reg_operand_type type, int regno)
958 {
959 switch (type)
960 {
961 case OP_REG_GP:
962 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
963 break;
964
965 case OP_REG_FP:
966 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
967 break;
968
969 case OP_REG_CCC:
970 if (opcode->pinfo & (FP_D | FP_S))
971 info->fprintf_func (info->stream, "$fcc%d", regno);
972 else
973 info->fprintf_func (info->stream, "$cc%d", regno);
974 break;
975
976 case OP_REG_VEC:
977 if (opcode->membership & INSN_5400)
978 info->fprintf_func (info->stream, "$f%d", regno);
979 else
980 info->fprintf_func (info->stream, "$v%d", regno);
981 break;
982
983 case OP_REG_ACC:
984 info->fprintf_func (info->stream, "$ac%d", regno);
985 break;
986
987 case OP_REG_COPRO:
988 if (opcode->name[strlen (opcode->name) - 1] == '0')
989 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
990 else if (opcode->name[strlen (opcode->name) - 1] == '1')
991 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
992 else
993 info->fprintf_func (info->stream, "$%d", regno);
994 break;
995
996 case OP_REG_HW:
997 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
998 break;
999
1000 case OP_REG_VF:
1001 info->fprintf_func (info->stream, "$vf%d", regno);
1002 break;
1003
1004 case OP_REG_VI:
1005 info->fprintf_func (info->stream, "$vi%d", regno);
1006 break;
1007
1008 case OP_REG_R5900_I:
1009 info->fprintf_func (info->stream, "$I");
1010 break;
1011
1012 case OP_REG_R5900_Q:
1013 info->fprintf_func (info->stream, "$Q");
1014 break;
1015
1016 case OP_REG_R5900_R:
1017 info->fprintf_func (info->stream, "$R");
1018 break;
1019
1020 case OP_REG_R5900_ACC:
1021 info->fprintf_func (info->stream, "$ACC");
1022 break;
1023
1024 case OP_REG_MSA:
1025 info->fprintf_func (info->stream, "$w%d", regno);
1026 break;
1027
1028 case OP_REG_MSA_CTRL:
1029 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1030 break;
1031
1032 }
1033 }
1034 \f
1035 /* Used to track the state carried over from previous operands in
1036 an instruction. */
1037 struct mips_print_arg_state {
1038 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1039 where the value is known to be unsigned and small. */
1040 unsigned int last_int;
1041
1042 /* The type and number of the last OP_REG seen. We only use this for
1043 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1044 enum mips_reg_operand_type last_reg_type;
1045 unsigned int last_regno;
1046 };
1047
1048 /* Initialize STATE for the start of an instruction. */
1049
1050 static inline void
1051 init_print_arg_state (struct mips_print_arg_state *state)
1052 {
1053 memset (state, 0, sizeof (*state));
1054 }
1055
1056 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1057 whose value is given by UVAL. */
1058
1059 static void
1060 print_vu0_channel (struct disassemble_info *info,
1061 const struct mips_operand *operand, unsigned int uval)
1062 {
1063 if (operand->size == 4)
1064 info->fprintf_func (info->stream, "%s%s%s%s",
1065 uval & 8 ? "x" : "",
1066 uval & 4 ? "y" : "",
1067 uval & 2 ? "z" : "",
1068 uval & 1 ? "w" : "");
1069 else if (operand->size == 2)
1070 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1071 else
1072 abort ();
1073 }
1074
1075 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1076 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1077 the base address for OP_PCREL operands. */
1078
1079 static void
1080 print_insn_arg (struct disassemble_info *info,
1081 struct mips_print_arg_state *state,
1082 const struct mips_opcode *opcode,
1083 const struct mips_operand *operand,
1084 bfd_vma base_pc,
1085 unsigned int uval)
1086 {
1087 const fprintf_ftype infprintf = info->fprintf_func;
1088 void *is = info->stream;
1089
1090 switch (operand->type)
1091 {
1092 case OP_INT:
1093 {
1094 const struct mips_int_operand *int_op;
1095
1096 int_op = (const struct mips_int_operand *) operand;
1097 uval = mips_decode_int_operand (int_op, uval);
1098 state->last_int = uval;
1099 if (int_op->print_hex)
1100 infprintf (is, "0x%x", uval);
1101 else
1102 infprintf (is, "%d", uval);
1103 }
1104 break;
1105
1106 case OP_MAPPED_INT:
1107 {
1108 const struct mips_mapped_int_operand *mint_op;
1109
1110 mint_op = (const struct mips_mapped_int_operand *) operand;
1111 uval = mint_op->int_map[uval];
1112 state->last_int = uval;
1113 if (mint_op->print_hex)
1114 infprintf (is, "0x%x", uval);
1115 else
1116 infprintf (is, "%d", uval);
1117 }
1118 break;
1119
1120 case OP_MSB:
1121 {
1122 const struct mips_msb_operand *msb_op;
1123
1124 msb_op = (const struct mips_msb_operand *) operand;
1125 uval += msb_op->bias;
1126 if (msb_op->add_lsb)
1127 uval -= state->last_int;
1128 infprintf (is, "0x%x", uval);
1129 }
1130 break;
1131
1132 case OP_REG:
1133 case OP_OPTIONAL_REG:
1134 {
1135 const struct mips_reg_operand *reg_op;
1136
1137 reg_op = (const struct mips_reg_operand *) operand;
1138 uval = mips_decode_reg_operand (reg_op, uval);
1139 print_reg (info, opcode, reg_op->reg_type, uval);
1140
1141 state->last_reg_type = reg_op->reg_type;
1142 state->last_regno = uval;
1143 }
1144 break;
1145
1146 case OP_REG_PAIR:
1147 {
1148 const struct mips_reg_pair_operand *pair_op;
1149
1150 pair_op = (const struct mips_reg_pair_operand *) operand;
1151 print_reg (info, opcode, pair_op->reg_type,
1152 pair_op->reg1_map[uval]);
1153 infprintf (is, ",");
1154 print_reg (info, opcode, pair_op->reg_type,
1155 pair_op->reg2_map[uval]);
1156 }
1157 break;
1158
1159 case OP_PCREL:
1160 {
1161 const struct mips_pcrel_operand *pcrel_op;
1162
1163 pcrel_op = (const struct mips_pcrel_operand *) operand;
1164 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1165
1166 /* Preserve the ISA bit for the GDB disassembler,
1167 otherwise clear it. */
1168 if (info->flavour != bfd_target_unknown_flavour)
1169 info->target &= -2;
1170
1171 (*info->print_address_func) (info->target, info);
1172 }
1173 break;
1174
1175 case OP_PERF_REG:
1176 infprintf (is, "%d", uval);
1177 break;
1178
1179 case OP_ADDIUSP_INT:
1180 {
1181 int sval;
1182
1183 sval = mips_signed_operand (operand, uval) * 4;
1184 if (sval >= -8 && sval < 8)
1185 sval ^= 0x400;
1186 infprintf (is, "%d", sval);
1187 break;
1188 }
1189
1190 case OP_CLO_CLZ_DEST:
1191 {
1192 unsigned int reg1, reg2;
1193
1194 reg1 = uval & 31;
1195 reg2 = uval >> 5;
1196 /* If one is zero use the other. */
1197 if (reg1 == reg2 || reg2 == 0)
1198 infprintf (is, "%s", mips_gpr_names[reg1]);
1199 else if (reg1 == 0)
1200 infprintf (is, "%s", mips_gpr_names[reg2]);
1201 else
1202 /* Bogus, result depends on processor. */
1203 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1204 mips_gpr_names[reg2]);
1205 }
1206 break;
1207
1208 case OP_LWM_SWM_LIST:
1209 if (operand->size == 2)
1210 {
1211 if (uval == 0)
1212 infprintf (is, "%s,%s",
1213 mips_gpr_names[16],
1214 mips_gpr_names[31]);
1215 else
1216 infprintf (is, "%s-%s,%s",
1217 mips_gpr_names[16],
1218 mips_gpr_names[16 + uval],
1219 mips_gpr_names[31]);
1220 }
1221 else
1222 {
1223 int s_reg_encode;
1224
1225 s_reg_encode = uval & 0xf;
1226 if (s_reg_encode != 0)
1227 {
1228 if (s_reg_encode == 1)
1229 infprintf (is, "%s", mips_gpr_names[16]);
1230 else if (s_reg_encode < 9)
1231 infprintf (is, "%s-%s",
1232 mips_gpr_names[16],
1233 mips_gpr_names[15 + s_reg_encode]);
1234 else if (s_reg_encode == 9)
1235 infprintf (is, "%s-%s,%s",
1236 mips_gpr_names[16],
1237 mips_gpr_names[23],
1238 mips_gpr_names[30]);
1239 else
1240 infprintf (is, "UNKNOWN");
1241 }
1242
1243 if (uval & 0x10) /* For ra. */
1244 {
1245 if (s_reg_encode == 0)
1246 infprintf (is, "%s", mips_gpr_names[31]);
1247 else
1248 infprintf (is, ",%s", mips_gpr_names[31]);
1249 }
1250 }
1251 break;
1252
1253 case OP_ENTRY_EXIT_LIST:
1254 {
1255 const char *sep;
1256 unsigned int amask, smask;
1257
1258 sep = "";
1259 amask = (uval >> 3) & 7;
1260 if (amask > 0 && amask < 5)
1261 {
1262 infprintf (is, "%s", mips_gpr_names[4]);
1263 if (amask > 1)
1264 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1265 sep = ",";
1266 }
1267
1268 smask = (uval >> 1) & 3;
1269 if (smask == 3)
1270 {
1271 infprintf (is, "%s??", sep);
1272 sep = ",";
1273 }
1274 else if (smask > 0)
1275 {
1276 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1277 if (smask > 1)
1278 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1279 sep = ",";
1280 }
1281
1282 if (uval & 1)
1283 {
1284 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1285 sep = ",";
1286 }
1287
1288 if (amask == 5 || amask == 6)
1289 {
1290 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1291 if (amask == 6)
1292 infprintf (is, "-%s", mips_fpr_names[1]);
1293 }
1294 }
1295 break;
1296
1297 case OP_SAVE_RESTORE_LIST:
1298 /* Should be handled by the caller due to extend behavior. */
1299 abort ();
1300
1301 case OP_MDMX_IMM_REG:
1302 {
1303 unsigned int vsel;
1304
1305 vsel = uval >> 5;
1306 uval &= 31;
1307 if ((vsel & 0x10) == 0)
1308 {
1309 int fmt;
1310
1311 vsel &= 0x0f;
1312 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1313 if ((vsel & 1) == 0)
1314 break;
1315 print_reg (info, opcode, OP_REG_VEC, uval);
1316 infprintf (is, "[%d]", vsel >> 1);
1317 }
1318 else if ((vsel & 0x08) == 0)
1319 print_reg (info, opcode, OP_REG_VEC, uval);
1320 else
1321 infprintf (is, "0x%x", uval);
1322 }
1323 break;
1324
1325 case OP_REPEAT_PREV_REG:
1326 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1327 break;
1328
1329 case OP_REPEAT_DEST_REG:
1330 /* Should always match OP_REPEAT_PREV_REG first. */
1331 abort ();
1332
1333 case OP_PC:
1334 infprintf (is, "$pc");
1335 break;
1336
1337 case OP_VU0_SUFFIX:
1338 case OP_VU0_MATCH_SUFFIX:
1339 print_vu0_channel (info, operand, uval);
1340 break;
1341
1342 case OP_IMM_INDEX:
1343 infprintf (is, "[%d]", uval);
1344 break;
1345
1346 case OP_REG_INDEX:
1347 infprintf (is, "[");
1348 print_reg (info, opcode, OP_REG_GP, uval);
1349 infprintf (is, "]");
1350 break;
1351 }
1352 }
1353
1354 /* Print the arguments for INSN, which is described by OPCODE.
1355 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1356 as the base of OP_PCREL operands. */
1357
1358 static void
1359 print_insn_args (struct disassemble_info *info,
1360 const struct mips_opcode *opcode,
1361 const struct mips_operand *(*decode_operand) (const char *),
1362 unsigned int insn, bfd_vma base_pc)
1363 {
1364 const fprintf_ftype infprintf = info->fprintf_func;
1365 void *is = info->stream;
1366 struct mips_print_arg_state state;
1367 const struct mips_operand *operand;
1368 const char *s;
1369
1370 init_print_arg_state (&state);
1371 for (s = opcode->args; *s; ++s)
1372 {
1373 switch (*s)
1374 {
1375 case ',':
1376 case '(':
1377 case ')':
1378 infprintf (is, "%c", *s);
1379 break;
1380
1381 case '#':
1382 ++s;
1383 infprintf (is, "%c%c", *s, *s);
1384 break;
1385
1386 default:
1387 operand = decode_operand (s);
1388 if (!operand)
1389 {
1390 /* xgettext:c-format */
1391 infprintf (is,
1392 _("# internal error, undefined operand in `%s %s'"),
1393 opcode->name, opcode->args);
1394 return;
1395 }
1396 if (operand->type == OP_REG
1397 && s[1] == ','
1398 && s[2] == 'H'
1399 && opcode->name[strlen (opcode->name) - 1] == '0')
1400 {
1401 /* Coprocessor register 0 with sel field (MT ASE). */
1402 const struct mips_cp0sel_name *n;
1403 unsigned int reg, sel;
1404
1405 reg = mips_extract_operand (operand, insn);
1406 s += 2;
1407 operand = decode_operand (s);
1408 sel = mips_extract_operand (operand, insn);
1409
1410 /* CP0 register including 'sel' code for mftc0, to be
1411 printed textually if known. If not known, print both
1412 CP0 register name and sel numerically since CP0 register
1413 with sel 0 may have a name unrelated to register being
1414 printed. */
1415 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1416 mips_cp0sel_names_len,
1417 reg, sel);
1418 if (n != NULL)
1419 infprintf (is, "%s", n->name);
1420 else
1421 infprintf (is, "$%d,%d", reg, sel);
1422 }
1423 else
1424 print_insn_arg (info, &state, opcode, operand, base_pc,
1425 mips_extract_operand (operand, insn));
1426 if (*s == 'm' || *s == '+')
1427 ++s;
1428 break;
1429 }
1430 }
1431 }
1432 \f
1433 /* Print the mips instruction at address MEMADDR in debugged memory,
1434 on using INFO. Returns length of the instruction, in bytes, which is
1435 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1436 this is little-endian code. */
1437
1438 static int
1439 print_insn_mips (bfd_vma memaddr,
1440 int word,
1441 struct disassemble_info *info)
1442 {
1443 #define GET_OP(insn, field) \
1444 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1445 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1446 const fprintf_ftype infprintf = info->fprintf_func;
1447 const struct mips_opcode *op;
1448 static bfd_boolean init = 0;
1449 void *is = info->stream;
1450
1451 /* Build a hash table to shorten the search time. */
1452 if (! init)
1453 {
1454 unsigned int i;
1455
1456 for (i = 0; i <= OP_MASK_OP; i++)
1457 {
1458 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1459 {
1460 if (op->pinfo == INSN_MACRO
1461 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1462 continue;
1463 if (i == GET_OP (op->match, OP))
1464 {
1465 mips_hash[i] = op;
1466 break;
1467 }
1468 }
1469 }
1470
1471 init = 1;
1472 }
1473
1474 info->bytes_per_chunk = INSNLEN;
1475 info->display_endian = info->endian;
1476 info->insn_info_valid = 1;
1477 info->branch_delay_insns = 0;
1478 info->data_size = 0;
1479 info->insn_type = dis_nonbranch;
1480 info->target = 0;
1481 info->target2 = 0;
1482
1483 op = mips_hash[GET_OP (word, OP)];
1484 if (op != NULL)
1485 {
1486 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1487 {
1488 if (op->pinfo != INSN_MACRO
1489 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1490 && (word & op->mask) == op->match)
1491 {
1492 /* We always allow to disassemble the jalx instruction. */
1493 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1494 && strcmp (op->name, "jalx"))
1495 continue;
1496
1497 /* Figure out instruction type and branch delay information. */
1498 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1499 {
1500 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
1501 info->insn_type = dis_jsr;
1502 else
1503 info->insn_type = dis_branch;
1504 info->branch_delay_insns = 1;
1505 }
1506 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1507 | INSN_COND_BRANCH_LIKELY)) != 0)
1508 {
1509 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1510 info->insn_type = dis_condjsr;
1511 else
1512 info->insn_type = dis_condbranch;
1513 info->branch_delay_insns = 1;
1514 }
1515 else if ((op->pinfo & (INSN_STORE_MEMORY
1516 | INSN_LOAD_MEMORY)) != 0)
1517 info->insn_type = dis_dref;
1518
1519 infprintf (is, "%s", op->name);
1520 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1521 {
1522 unsigned int uval;
1523
1524 infprintf (is, ".");
1525 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1526 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1527 }
1528
1529 if (op->args[0])
1530 {
1531 infprintf (is, "\t");
1532 print_insn_args (info, op, decode_mips_operand, word,
1533 memaddr + 4);
1534 }
1535
1536 return INSNLEN;
1537 }
1538 }
1539 }
1540 #undef GET_OP
1541
1542 /* Handle undefined instructions. */
1543 info->insn_type = dis_noninsn;
1544 infprintf (is, "0x%x", word);
1545 return INSNLEN;
1546 }
1547 \f
1548 /* Disassemble an operand for a mips16 instruction. */
1549
1550 static void
1551 print_mips16_insn_arg (struct disassemble_info *info,
1552 struct mips_print_arg_state *state,
1553 const struct mips_opcode *opcode,
1554 char type, bfd_vma memaddr,
1555 unsigned insn, bfd_boolean use_extend,
1556 unsigned extend, bfd_boolean is_offset)
1557 {
1558 const fprintf_ftype infprintf = info->fprintf_func;
1559 void *is = info->stream;
1560 const struct mips_operand *operand, *ext_operand;
1561 unsigned int uval;
1562 bfd_vma baseaddr;
1563
1564 if (!use_extend)
1565 extend = 0;
1566
1567 switch (type)
1568 {
1569 case ',':
1570 case '(':
1571 case ')':
1572 infprintf (is, "%c", type);
1573 break;
1574
1575 default:
1576 operand = decode_mips16_operand (type, FALSE);
1577 if (!operand)
1578 {
1579 /* xgettext:c-format */
1580 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1581 opcode->name, opcode->args);
1582 return;
1583 }
1584
1585 if (operand->type == OP_SAVE_RESTORE_LIST)
1586 {
1587 /* Handle this case here because of the complex interation
1588 with the EXTEND opcode. */
1589 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1590 const char *sep;
1591
1592 amask = extend & 0xf;
1593 if (amask == MIPS16_ALL_ARGS)
1594 {
1595 nargs = 4;
1596 nstatics = 0;
1597 }
1598 else if (amask == MIPS16_ALL_STATICS)
1599 {
1600 nargs = 0;
1601 nstatics = 4;
1602 }
1603 else
1604 {
1605 nargs = amask >> 2;
1606 nstatics = amask & 3;
1607 }
1608
1609 sep = "";
1610 if (nargs > 0)
1611 {
1612 infprintf (is, "%s", mips_gpr_names[4]);
1613 if (nargs > 1)
1614 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1615 sep = ",";
1616 }
1617
1618 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1619 if (frame_size == 0 && !use_extend)
1620 frame_size = 128;
1621 infprintf (is, "%s%d", sep, frame_size);
1622
1623 if (insn & 0x40) /* $ra */
1624 infprintf (is, ",%s", mips_gpr_names[31]);
1625
1626 nsreg = (extend >> 8) & 0x7;
1627 smask = 0;
1628 if (insn & 0x20) /* $s0 */
1629 smask |= 1 << 0;
1630 if (insn & 0x10) /* $s1 */
1631 smask |= 1 << 1;
1632 if (nsreg > 0) /* $s2-$s8 */
1633 smask |= ((1 << nsreg) - 1) << 2;
1634
1635 for (i = 0; i < 9; i++)
1636 if (smask & (1 << i))
1637 {
1638 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1639 /* Skip over string of set bits. */
1640 for (j = i; smask & (2 << j); j++)
1641 continue;
1642 if (j > i)
1643 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1644 i = j + 1;
1645 }
1646 /* Statics $ax - $a3. */
1647 if (nstatics == 1)
1648 infprintf (is, ",%s", mips_gpr_names[7]);
1649 else if (nstatics > 0)
1650 infprintf (is, ",%s-%s",
1651 mips_gpr_names[7 - nstatics + 1],
1652 mips_gpr_names[7]);
1653 break;
1654 }
1655
1656 if (is_offset && operand->type == OP_INT)
1657 {
1658 const struct mips_int_operand *int_op;
1659
1660 int_op = (const struct mips_int_operand *) operand;
1661 info->insn_type = dis_dref;
1662 info->data_size = 1 << int_op->shift;
1663 }
1664
1665 if (operand->size == 26)
1666 /* In this case INSN is the first two bytes of the instruction
1667 and EXTEND is the second two bytes. */
1668 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
1669 else
1670 {
1671 /* Calculate the full field value. */
1672 uval = mips_extract_operand (operand, insn);
1673 if (use_extend)
1674 {
1675 ext_operand = decode_mips16_operand (type, TRUE);
1676 if (ext_operand != operand)
1677 {
1678 operand = ext_operand;
1679 if (operand->size == 16)
1680 uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1681 else if (operand->size == 15)
1682 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1683 else
1684 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
1685 }
1686 }
1687 }
1688
1689 baseaddr = memaddr + 2;
1690 if (operand->type == OP_PCREL)
1691 {
1692 const struct mips_pcrel_operand *pcrel_op;
1693
1694 pcrel_op = (const struct mips_pcrel_operand *) operand;
1695 if (!pcrel_op->include_isa_bit && use_extend)
1696 baseaddr = memaddr - 2;
1697 else if (!pcrel_op->include_isa_bit)
1698 {
1699 bfd_byte buffer[2];
1700
1701 /* If this instruction is in the delay slot of a JR
1702 instruction, the base address is the address of the
1703 JR instruction. If it is in the delay slot of a JALR
1704 instruction, the base address is the address of the
1705 JALR instruction. This test is unreliable: we have
1706 no way of knowing whether the previous word is
1707 instruction or data. */
1708 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1709 && (((info->endian == BFD_ENDIAN_BIG
1710 ? bfd_getb16 (buffer)
1711 : bfd_getl16 (buffer))
1712 & 0xf800) == 0x1800))
1713 baseaddr = memaddr - 4;
1714 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1715 info) == 0
1716 && (((info->endian == BFD_ENDIAN_BIG
1717 ? bfd_getb16 (buffer)
1718 : bfd_getl16 (buffer))
1719 & 0xf81f) == 0xe800))
1720 baseaddr = memaddr - 2;
1721 else
1722 baseaddr = memaddr;
1723 }
1724 }
1725
1726 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
1727 break;
1728 }
1729 }
1730
1731
1732 /* Check if the given address is the last word of a MIPS16 PLT entry.
1733 This word is data and depending on the value it may interfere with
1734 disassembly of further PLT entries. We make use of the fact PLT
1735 symbols are marked BSF_SYNTHETIC. */
1736 static bfd_boolean
1737 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
1738 {
1739 if (info->symbols
1740 && info->symbols[0]
1741 && (info->symbols[0]->flags & BSF_SYNTHETIC)
1742 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
1743 return TRUE;
1744
1745 return FALSE;
1746 }
1747
1748 /* Disassemble mips16 instructions. */
1749
1750 static int
1751 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1752 {
1753 const fprintf_ftype infprintf = info->fprintf_func;
1754 int status;
1755 bfd_byte buffer[4];
1756 int length;
1757 int insn;
1758 bfd_boolean use_extend;
1759 int extend = 0;
1760 const struct mips_opcode *op, *opend;
1761 struct mips_print_arg_state state;
1762 void *is = info->stream;
1763
1764 info->bytes_per_chunk = 2;
1765 info->display_endian = info->endian;
1766 info->insn_info_valid = 1;
1767 info->branch_delay_insns = 0;
1768 info->data_size = 0;
1769 info->target = 0;
1770 info->target2 = 0;
1771
1772 #define GET_OP(insn, field) \
1773 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1774 /* Decode PLT entry's GOT slot address word. */
1775 if (is_mips16_plt_tail (info, memaddr))
1776 {
1777 info->insn_type = dis_noninsn;
1778 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
1779 if (status == 0)
1780 {
1781 unsigned int gotslot;
1782
1783 if (info->endian == BFD_ENDIAN_BIG)
1784 gotslot = bfd_getb32 (buffer);
1785 else
1786 gotslot = bfd_getl32 (buffer);
1787 infprintf (is, ".word\t0x%x", gotslot);
1788
1789 return 4;
1790 }
1791 }
1792 else
1793 {
1794 info->insn_type = dis_nonbranch;
1795 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1796 }
1797 if (status != 0)
1798 {
1799 (*info->memory_error_func) (status, memaddr, info);
1800 return -1;
1801 }
1802
1803 length = 2;
1804
1805 if (info->endian == BFD_ENDIAN_BIG)
1806 insn = bfd_getb16 (buffer);
1807 else
1808 insn = bfd_getl16 (buffer);
1809
1810 /* Handle the extend opcode specially. */
1811 use_extend = FALSE;
1812 if ((insn & 0xf800) == 0xf000)
1813 {
1814 use_extend = TRUE;
1815 extend = insn & 0x7ff;
1816
1817 memaddr += 2;
1818
1819 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1820 if (status != 0)
1821 {
1822 infprintf (is, "extend 0x%x", (unsigned int) extend);
1823 (*info->memory_error_func) (status, memaddr, info);
1824 return -1;
1825 }
1826
1827 if (info->endian == BFD_ENDIAN_BIG)
1828 insn = bfd_getb16 (buffer);
1829 else
1830 insn = bfd_getl16 (buffer);
1831
1832 /* Check for an extend opcode followed by an extend opcode. */
1833 if ((insn & 0xf800) == 0xf000)
1834 {
1835 infprintf (is, "extend 0x%x", (unsigned int) extend);
1836 info->insn_type = dis_noninsn;
1837 return length;
1838 }
1839
1840 length += 2;
1841 }
1842
1843 /* FIXME: Should probably use a hash table on the major opcode here. */
1844
1845 opend = mips16_opcodes + bfd_mips16_num_opcodes;
1846 for (op = mips16_opcodes; op < opend; op++)
1847 {
1848 if (op->pinfo != INSN_MACRO
1849 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1850 && (insn & op->mask) == op->match)
1851 {
1852 const char *s;
1853
1854 if (op->args[0] == 'a' || op->args[0] == 'i')
1855 {
1856 if (use_extend)
1857 {
1858 infprintf (is, "extend 0x%x", (unsigned int) extend);
1859 info->insn_type = dis_noninsn;
1860 return length - 2;
1861 }
1862
1863 use_extend = FALSE;
1864
1865 memaddr += 2;
1866
1867 status = (*info->read_memory_func) (memaddr, buffer, 2,
1868 info);
1869 if (status == 0)
1870 {
1871 use_extend = TRUE;
1872 if (info->endian == BFD_ENDIAN_BIG)
1873 extend = bfd_getb16 (buffer);
1874 else
1875 extend = bfd_getl16 (buffer);
1876 length += 2;
1877 }
1878 }
1879
1880 infprintf (is, "%s", op->name);
1881 if (op->args[0] != '\0')
1882 infprintf (is, "\t");
1883
1884 init_print_arg_state (&state);
1885 for (s = op->args; *s != '\0'; s++)
1886 {
1887 if (*s == ','
1888 && s[1] == 'w'
1889 && GET_OP (insn, RX) == GET_OP (insn, RY))
1890 {
1891 /* Skip the register and the comma. */
1892 ++s;
1893 continue;
1894 }
1895 if (*s == ','
1896 && s[1] == 'v'
1897 && GET_OP (insn, RZ) == GET_OP (insn, RX))
1898 {
1899 /* Skip the register and the comma. */
1900 ++s;
1901 continue;
1902 }
1903 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
1904 use_extend, extend, s[1] == '(');
1905 }
1906
1907 /* Figure out branch instruction type and delay slot information. */
1908 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1909 info->branch_delay_insns = 1;
1910 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
1911 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
1912 {
1913 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1914 info->insn_type = dis_jsr;
1915 else
1916 info->insn_type = dis_branch;
1917 }
1918 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
1919 info->insn_type = dis_condbranch;
1920
1921 return length;
1922 }
1923 }
1924 #undef GET_OP
1925
1926 if (use_extend)
1927 infprintf (is, "0x%x", extend | 0xf000);
1928 infprintf (is, "0x%x", insn);
1929 info->insn_type = dis_noninsn;
1930
1931 return length;
1932 }
1933
1934 /* Disassemble microMIPS instructions. */
1935
1936 static int
1937 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
1938 {
1939 const fprintf_ftype infprintf = info->fprintf_func;
1940 const struct mips_opcode *op, *opend;
1941 void *is = info->stream;
1942 bfd_byte buffer[2];
1943 unsigned int higher;
1944 unsigned int length;
1945 int status;
1946 unsigned int insn;
1947
1948 info->bytes_per_chunk = 2;
1949 info->display_endian = info->endian;
1950 info->insn_info_valid = 1;
1951 info->branch_delay_insns = 0;
1952 info->data_size = 0;
1953 info->insn_type = dis_nonbranch;
1954 info->target = 0;
1955 info->target2 = 0;
1956
1957 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1958 if (status != 0)
1959 {
1960 (*info->memory_error_func) (status, memaddr, info);
1961 return -1;
1962 }
1963
1964 length = 2;
1965
1966 if (info->endian == BFD_ENDIAN_BIG)
1967 insn = bfd_getb16 (buffer);
1968 else
1969 insn = bfd_getl16 (buffer);
1970
1971 if ((insn & 0xfc00) == 0x7c00)
1972 {
1973 /* This is a 48-bit microMIPS instruction. */
1974 higher = insn;
1975
1976 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
1977 if (status != 0)
1978 {
1979 infprintf (is, "micromips 0x%x", higher);
1980 (*info->memory_error_func) (status, memaddr + 2, info);
1981 return -1;
1982 }
1983 if (info->endian == BFD_ENDIAN_BIG)
1984 insn = bfd_getb16 (buffer);
1985 else
1986 insn = bfd_getl16 (buffer);
1987 higher = (higher << 16) | insn;
1988
1989 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
1990 if (status != 0)
1991 {
1992 infprintf (is, "micromips 0x%x", higher);
1993 (*info->memory_error_func) (status, memaddr + 4, info);
1994 return -1;
1995 }
1996 if (info->endian == BFD_ENDIAN_BIG)
1997 insn = bfd_getb16 (buffer);
1998 else
1999 insn = bfd_getl16 (buffer);
2000 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
2001
2002 info->insn_type = dis_noninsn;
2003 return 6;
2004 }
2005 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2006 {
2007 /* This is a 32-bit microMIPS instruction. */
2008 higher = insn;
2009
2010 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2011 if (status != 0)
2012 {
2013 infprintf (is, "micromips 0x%x", higher);
2014 (*info->memory_error_func) (status, memaddr + 2, info);
2015 return -1;
2016 }
2017
2018 if (info->endian == BFD_ENDIAN_BIG)
2019 insn = bfd_getb16 (buffer);
2020 else
2021 insn = bfd_getl16 (buffer);
2022
2023 insn = insn | (higher << 16);
2024
2025 length += 2;
2026 }
2027
2028 /* FIXME: Should probably use a hash table on the major opcode here. */
2029
2030 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2031 for (op = micromips_opcodes; op < opend; op++)
2032 {
2033 if (op->pinfo != INSN_MACRO
2034 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2035 && (insn & op->mask) == op->match
2036 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2037 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2038 {
2039 infprintf (is, "%s", op->name);
2040
2041 if (op->args[0])
2042 {
2043 infprintf (is, "\t");
2044 print_insn_args (info, op, decode_micromips_operand, insn,
2045 memaddr + length + 1);
2046 }
2047
2048 /* Figure out instruction type and branch delay information. */
2049 if ((op->pinfo
2050 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2051 info->branch_delay_insns = 1;
2052 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2053 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2054 {
2055 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2056 info->insn_type = dis_jsr;
2057 else
2058 info->insn_type = dis_branch;
2059 }
2060 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2061 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2062 {
2063 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2064 info->insn_type = dis_condjsr;
2065 else
2066 info->insn_type = dis_condbranch;
2067 }
2068 else if ((op->pinfo
2069 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2070 info->insn_type = dis_dref;
2071
2072 return length;
2073 }
2074 }
2075
2076 infprintf (is, "0x%x", insn);
2077 info->insn_type = dis_noninsn;
2078
2079 return length;
2080 }
2081
2082 /* Return 1 if a symbol associated with the location being disassembled
2083 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2084 all the symbols at the address being considered assuming if at least
2085 one of them indicates code compression, then such code has been
2086 genuinely produced here (other symbols could have been derived from
2087 function symbols defined elsewhere or could define data). Otherwise,
2088 return 0. */
2089
2090 static bfd_boolean
2091 is_compressed_mode_p (struct disassemble_info *info)
2092 {
2093 int i;
2094 int l;
2095
2096 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2097 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2098 && ((!micromips_ase
2099 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2100 || (micromips_ase
2101 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2102 return 1;
2103 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2104 && info->symtab[i]->section == info->section)
2105 {
2106 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2107 if ((!micromips_ase
2108 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2109 || (micromips_ase
2110 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2111 return 1;
2112 }
2113
2114 return 0;
2115 }
2116
2117 /* In an environment where we do not know the symbol type of the
2118 instruction we are forced to assume that the low order bit of the
2119 instructions' address may mark it as a mips16 instruction. If we
2120 are single stepping, or the pc is within the disassembled function,
2121 this works. Otherwise, we need a clue. Sometimes. */
2122
2123 static int
2124 _print_insn_mips (bfd_vma memaddr,
2125 struct disassemble_info *info,
2126 enum bfd_endian endianness)
2127 {
2128 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
2129 bfd_byte buffer[INSNLEN];
2130 int status;
2131
2132 set_default_mips_dis_options (info);
2133 parse_mips_dis_options (info->disassembler_options);
2134
2135 if (info->mach == bfd_mach_mips16)
2136 return print_insn_mips16 (memaddr, info);
2137 if (info->mach == bfd_mach_mips_micromips)
2138 return print_insn_micromips (memaddr, info);
2139
2140 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
2141
2142 #if 1
2143 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2144 /* Only a few tools will work this way. */
2145 if (memaddr & 0x01)
2146 return print_insn_compr (memaddr, info);
2147 #endif
2148
2149 #if SYMTAB_AVAILABLE
2150 if (is_compressed_mode_p (info))
2151 return print_insn_compr (memaddr, info);
2152 #endif
2153
2154 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2155 if (status == 0)
2156 {
2157 int insn;
2158
2159 if (endianness == BFD_ENDIAN_BIG)
2160 insn = bfd_getb32 (buffer);
2161 else
2162 insn = bfd_getl32 (buffer);
2163
2164 return print_insn_mips (memaddr, insn, info);
2165 }
2166 else
2167 {
2168 (*info->memory_error_func) (status, memaddr, info);
2169 return -1;
2170 }
2171 }
2172
2173 int
2174 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2175 {
2176 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2177 }
2178
2179 int
2180 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2181 {
2182 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2183 }
2184 \f
2185 void
2186 print_mips_disassembler_options (FILE *stream)
2187 {
2188 unsigned int i;
2189
2190 fprintf (stream, _("\n\
2191 The following MIPS specific disassembler options are supported for use\n\
2192 with the -M switch (multiple options should be separated by commas):\n"));
2193
2194 fprintf (stream, _("\n\
2195 msa Recognize MSA instructions.\n"));
2196
2197 fprintf (stream, _("\n\
2198 virt Recognize the virtualization ASE instructions.\n"));
2199
2200 fprintf (stream, _("\n\
2201 gpr-names=ABI Print GPR names according to specified ABI.\n\
2202 Default: based on binary being disassembled.\n"));
2203
2204 fprintf (stream, _("\n\
2205 fpr-names=ABI Print FPR names according to specified ABI.\n\
2206 Default: numeric.\n"));
2207
2208 fprintf (stream, _("\n\
2209 cp0-names=ARCH Print CP0 register names according to\n\
2210 specified architecture.\n\
2211 Default: based on binary being disassembled.\n"));
2212
2213 fprintf (stream, _("\n\
2214 hwr-names=ARCH Print HWR names according to specified \n\
2215 architecture.\n\
2216 Default: based on binary being disassembled.\n"));
2217
2218 fprintf (stream, _("\n\
2219 reg-names=ABI Print GPR and FPR names according to\n\
2220 specified ABI.\n"));
2221
2222 fprintf (stream, _("\n\
2223 reg-names=ARCH Print CP0 register and HWR names according to\n\
2224 specified architecture.\n"));
2225
2226 fprintf (stream, _("\n\
2227 For the options above, the following values are supported for \"ABI\":\n\
2228 "));
2229 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2230 fprintf (stream, " %s", mips_abi_choices[i].name);
2231 fprintf (stream, _("\n"));
2232
2233 fprintf (stream, _("\n\
2234 For the options above, The following values are supported for \"ARCH\":\n\
2235 "));
2236 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2237 if (*mips_arch_choices[i].name != '\0')
2238 fprintf (stream, " %s", mips_arch_choices[i].name);
2239 fprintf (stream, _("\n"));
2240
2241 fprintf (stream, _("\n"));
2242 }
This page took 0.115099 seconds and 5 git commands to generate.