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