1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2017 Free Software Foundation, Inc.
3 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
5 This file is part of the GNU opcodes library.
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)
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.
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. */
23 #include "disassemble.h"
24 #include "libiberty.h"
25 #include "opcode/mips.h"
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. */
33 #if !defined(EMBEDDED_ENV)
34 #define SYMTAB_AVAILABLE 1
39 /* Mips instructions are at maximum this many bytes long. */
43 /* FIXME: These should be shared with gdb somehow. */
45 struct mips_cp0sel_name
49 const char * const name
;
52 static const char * const mips_gpr_names_numeric
[32] =
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"
60 static const char * const mips_gpr_names_oldabi
[32] =
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"
68 static const char * const mips_gpr_names_newabi
[32] =
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"
76 static const char * const mips_fpr_names_numeric
[32] =
78 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
79 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
80 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
81 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
84 static const char * const mips_fpr_names_32
[32] =
86 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
87 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
88 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
89 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
92 static const char * const mips_fpr_names_n32
[32] =
94 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
95 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
96 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
97 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
100 static const char * const mips_fpr_names_64
[32] =
102 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
103 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
104 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
105 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
108 static const char * const mips_cp0_names_numeric
[32] =
110 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
111 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
112 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
113 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
116 static const char * const mips_cp1_names_numeric
[32] =
118 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
119 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
120 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
121 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
124 static const char * const mips_cp0_names_r3000
[32] =
126 "c0_index", "c0_random", "c0_entrylo", "$3",
127 "c0_context", "$5", "$6", "$7",
128 "c0_badvaddr", "$9", "c0_entryhi", "$11",
129 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
130 "$16", "$17", "$18", "$19",
131 "$20", "$21", "$22", "$23",
132 "$24", "$25", "$26", "$27",
133 "$28", "$29", "$30", "$31",
136 static const char * const mips_cp0_names_r4000
[32] =
138 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
139 "c0_context", "c0_pagemask", "c0_wired", "$7",
140 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
141 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
142 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
143 "c0_xcontext", "$21", "$22", "$23",
144 "$24", "$25", "c0_ecc", "c0_cacheerr",
145 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
148 static const char * const mips_cp0_names_r5900
[32] =
150 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
151 "c0_context", "c0_pagemask", "c0_wired", "$7",
152 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
153 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
154 "c0_config", "$17", "$18", "$19",
155 "$20", "$21", "$22", "c0_badpaddr",
156 "c0_depc", "c0_perfcnt", "$26", "$27",
157 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
160 static const char * const mips_cp0_names_mips3264
[32] =
162 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
163 "c0_context", "c0_pagemask", "c0_wired", "$7",
164 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
165 "c0_status", "c0_cause", "c0_epc", "c0_prid",
166 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
167 "c0_xcontext", "$21", "$22", "c0_debug",
168 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
169 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
172 static const char * const mips_cp1_names_mips3264
[32] =
174 "c1_fir", "c1_ufr", "$2", "$3",
175 "c1_unfr", "$5", "$6", "$7",
176 "$8", "$9", "$10", "$11",
177 "$12", "$13", "$14", "$15",
178 "$16", "$17", "$18", "$19",
179 "$20", "$21", "$22", "$23",
180 "$24", "c1_fccr", "c1_fexr", "$27",
181 "c1_fenr", "$29", "$30", "c1_fcsr"
184 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] =
186 { 16, 1, "c0_config1" },
187 { 16, 2, "c0_config2" },
188 { 16, 3, "c0_config3" },
189 { 18, 1, "c0_watchlo,1" },
190 { 18, 2, "c0_watchlo,2" },
191 { 18, 3, "c0_watchlo,3" },
192 { 18, 4, "c0_watchlo,4" },
193 { 18, 5, "c0_watchlo,5" },
194 { 18, 6, "c0_watchlo,6" },
195 { 18, 7, "c0_watchlo,7" },
196 { 19, 1, "c0_watchhi,1" },
197 { 19, 2, "c0_watchhi,2" },
198 { 19, 3, "c0_watchhi,3" },
199 { 19, 4, "c0_watchhi,4" },
200 { 19, 5, "c0_watchhi,5" },
201 { 19, 6, "c0_watchhi,6" },
202 { 19, 7, "c0_watchhi,7" },
203 { 25, 1, "c0_perfcnt,1" },
204 { 25, 2, "c0_perfcnt,2" },
205 { 25, 3, "c0_perfcnt,3" },
206 { 25, 4, "c0_perfcnt,4" },
207 { 25, 5, "c0_perfcnt,5" },
208 { 25, 6, "c0_perfcnt,6" },
209 { 25, 7, "c0_perfcnt,7" },
210 { 27, 1, "c0_cacheerr,1" },
211 { 27, 2, "c0_cacheerr,2" },
212 { 27, 3, "c0_cacheerr,3" },
213 { 28, 1, "c0_datalo" },
214 { 29, 1, "c0_datahi" }
217 static const char * const mips_cp0_names_mips3264r2
[32] =
219 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
220 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
221 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
222 "c0_status", "c0_cause", "c0_epc", "c0_prid",
223 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
224 "c0_xcontext", "$21", "$22", "c0_debug",
225 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
226 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
229 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] =
231 { 4, 1, "c0_contextconfig" },
232 { 0, 1, "c0_mvpcontrol" },
233 { 0, 2, "c0_mvpconf0" },
234 { 0, 3, "c0_mvpconf1" },
235 { 1, 1, "c0_vpecontrol" },
236 { 1, 2, "c0_vpeconf0" },
237 { 1, 3, "c0_vpeconf1" },
238 { 1, 4, "c0_yqmask" },
239 { 1, 5, "c0_vpeschedule" },
240 { 1, 6, "c0_vpeschefback" },
241 { 2, 1, "c0_tcstatus" },
242 { 2, 2, "c0_tcbind" },
243 { 2, 3, "c0_tcrestart" },
244 { 2, 4, "c0_tchalt" },
245 { 2, 5, "c0_tccontext" },
246 { 2, 6, "c0_tcschedule" },
247 { 2, 7, "c0_tcschefback" },
248 { 5, 1, "c0_pagegrain" },
249 { 6, 1, "c0_srsconf0" },
250 { 6, 2, "c0_srsconf1" },
251 { 6, 3, "c0_srsconf2" },
252 { 6, 4, "c0_srsconf3" },
253 { 6, 5, "c0_srsconf4" },
254 { 12, 1, "c0_intctl" },
255 { 12, 2, "c0_srsctl" },
256 { 12, 3, "c0_srsmap" },
257 { 15, 1, "c0_ebase" },
258 { 16, 1, "c0_config1" },
259 { 16, 2, "c0_config2" },
260 { 16, 3, "c0_config3" },
261 { 18, 1, "c0_watchlo,1" },
262 { 18, 2, "c0_watchlo,2" },
263 { 18, 3, "c0_watchlo,3" },
264 { 18, 4, "c0_watchlo,4" },
265 { 18, 5, "c0_watchlo,5" },
266 { 18, 6, "c0_watchlo,6" },
267 { 18, 7, "c0_watchlo,7" },
268 { 19, 1, "c0_watchhi,1" },
269 { 19, 2, "c0_watchhi,2" },
270 { 19, 3, "c0_watchhi,3" },
271 { 19, 4, "c0_watchhi,4" },
272 { 19, 5, "c0_watchhi,5" },
273 { 19, 6, "c0_watchhi,6" },
274 { 19, 7, "c0_watchhi,7" },
275 { 23, 1, "c0_tracecontrol" },
276 { 23, 2, "c0_tracecontrol2" },
277 { 23, 3, "c0_usertracedata" },
278 { 23, 4, "c0_tracebpc" },
279 { 25, 1, "c0_perfcnt,1" },
280 { 25, 2, "c0_perfcnt,2" },
281 { 25, 3, "c0_perfcnt,3" },
282 { 25, 4, "c0_perfcnt,4" },
283 { 25, 5, "c0_perfcnt,5" },
284 { 25, 6, "c0_perfcnt,6" },
285 { 25, 7, "c0_perfcnt,7" },
286 { 27, 1, "c0_cacheerr,1" },
287 { 27, 2, "c0_cacheerr,2" },
288 { 27, 3, "c0_cacheerr,3" },
289 { 28, 1, "c0_datalo" },
290 { 28, 2, "c0_taglo1" },
291 { 28, 3, "c0_datalo1" },
292 { 28, 4, "c0_taglo2" },
293 { 28, 5, "c0_datalo2" },
294 { 28, 6, "c0_taglo3" },
295 { 28, 7, "c0_datalo3" },
296 { 29, 1, "c0_datahi" },
297 { 29, 2, "c0_taghi1" },
298 { 29, 3, "c0_datahi1" },
299 { 29, 4, "c0_taghi2" },
300 { 29, 5, "c0_datahi2" },
301 { 29, 6, "c0_taghi3" },
302 { 29, 7, "c0_datahi3" },
305 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
306 static const char * const mips_cp0_names_sb1
[32] =
308 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
309 "c0_context", "c0_pagemask", "c0_wired", "$7",
310 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
311 "c0_status", "c0_cause", "c0_epc", "c0_prid",
312 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
313 "c0_xcontext", "$21", "$22", "c0_debug",
314 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
315 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
318 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] =
320 { 16, 1, "c0_config1" },
321 { 18, 1, "c0_watchlo,1" },
322 { 19, 1, "c0_watchhi,1" },
323 { 22, 0, "c0_perftrace" },
324 { 23, 3, "c0_edebug" },
325 { 25, 1, "c0_perfcnt,1" },
326 { 25, 2, "c0_perfcnt,2" },
327 { 25, 3, "c0_perfcnt,3" },
328 { 25, 4, "c0_perfcnt,4" },
329 { 25, 5, "c0_perfcnt,5" },
330 { 25, 6, "c0_perfcnt,6" },
331 { 25, 7, "c0_perfcnt,7" },
332 { 26, 1, "c0_buserr_pa" },
333 { 27, 1, "c0_cacheerr_d" },
334 { 27, 3, "c0_cacheerr_d_pa" },
335 { 28, 1, "c0_datalo_i" },
336 { 28, 2, "c0_taglo_d" },
337 { 28, 3, "c0_datalo_d" },
338 { 29, 1, "c0_datahi_i" },
339 { 29, 2, "c0_taghi_d" },
340 { 29, 3, "c0_datahi_d" },
343 /* Xlr cop0 register names. */
344 static const char * const mips_cp0_names_xlr
[32] = {
345 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
346 "c0_context", "c0_pagemask", "c0_wired", "$7",
347 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
348 "c0_status", "c0_cause", "c0_epc", "c0_prid",
349 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
350 "c0_xcontext", "$21", "$22", "c0_debug",
351 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
352 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
355 /* XLR's CP0 Select Registers. */
357 static const struct mips_cp0sel_name mips_cp0sel_names_xlr
[] = {
358 { 9, 6, "c0_extintreq" },
359 { 9, 7, "c0_extintmask" },
360 { 15, 1, "c0_ebase" },
361 { 16, 1, "c0_config1" },
362 { 16, 2, "c0_config2" },
363 { 16, 3, "c0_config3" },
364 { 16, 7, "c0_procid2" },
365 { 18, 1, "c0_watchlo,1" },
366 { 18, 2, "c0_watchlo,2" },
367 { 18, 3, "c0_watchlo,3" },
368 { 18, 4, "c0_watchlo,4" },
369 { 18, 5, "c0_watchlo,5" },
370 { 18, 6, "c0_watchlo,6" },
371 { 18, 7, "c0_watchlo,7" },
372 { 19, 1, "c0_watchhi,1" },
373 { 19, 2, "c0_watchhi,2" },
374 { 19, 3, "c0_watchhi,3" },
375 { 19, 4, "c0_watchhi,4" },
376 { 19, 5, "c0_watchhi,5" },
377 { 19, 6, "c0_watchhi,6" },
378 { 19, 7, "c0_watchhi,7" },
379 { 25, 1, "c0_perfcnt,1" },
380 { 25, 2, "c0_perfcnt,2" },
381 { 25, 3, "c0_perfcnt,3" },
382 { 25, 4, "c0_perfcnt,4" },
383 { 25, 5, "c0_perfcnt,5" },
384 { 25, 6, "c0_perfcnt,6" },
385 { 25, 7, "c0_perfcnt,7" },
386 { 27, 1, "c0_cacheerr,1" },
387 { 27, 2, "c0_cacheerr,2" },
388 { 27, 3, "c0_cacheerr,3" },
389 { 28, 1, "c0_datalo" },
390 { 29, 1, "c0_datahi" }
393 static const char * const mips_hwr_names_numeric
[32] =
395 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
396 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
397 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
398 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
401 static const char * const mips_hwr_names_mips3264r2
[32] =
403 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
404 "$4", "$5", "$6", "$7",
405 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
406 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
407 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
410 static const char * const msa_control_names
[32] =
412 "msa_ir", "msa_csr", "msa_access", "msa_save",
413 "msa_modify", "msa_request", "msa_map", "msa_unmap",
414 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
415 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
416 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
419 struct mips_abi_choice
422 const char * const *gpr_names
;
423 const char * const *fpr_names
;
426 struct mips_abi_choice mips_abi_choices
[] =
428 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
429 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
430 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
431 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
434 struct mips_arch_choice
438 unsigned long bfd_mach
;
442 const char * const *cp0_names
;
443 const struct mips_cp0sel_name
*cp0sel_names
;
444 unsigned int cp0sel_names_len
;
445 const char * const *cp1_names
;
446 const char * const *hwr_names
;
449 const struct mips_arch_choice mips_arch_choices
[] =
451 { "numeric", 0, 0, 0, 0, 0,
452 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
453 mips_hwr_names_numeric
},
455 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
, 0,
456 mips_cp0_names_r3000
, NULL
, 0, mips_cp1_names_numeric
,
457 mips_hwr_names_numeric
},
458 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
, 0,
459 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
460 mips_hwr_names_numeric
},
461 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
, 0,
462 mips_cp0_names_r4000
, NULL
, 0, mips_cp1_names_numeric
,
463 mips_hwr_names_numeric
},
464 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
, 0,
465 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
466 mips_hwr_names_numeric
},
467 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
, 0,
468 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
469 mips_hwr_names_numeric
},
470 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
, 0,
471 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
472 mips_hwr_names_numeric
},
473 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
, 0,
474 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
475 mips_hwr_names_numeric
},
476 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
, 0,
477 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
478 mips_hwr_names_numeric
},
479 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
, 0,
480 mips_cp0_names_r4000
, NULL
, 0, mips_cp1_names_numeric
,
481 mips_hwr_names_numeric
},
482 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
, 0,
483 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
484 mips_hwr_names_numeric
},
485 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
, 0,
486 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
487 mips_hwr_names_numeric
},
488 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
, 0,
489 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
490 mips_hwr_names_numeric
},
491 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
, 0,
492 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
493 mips_hwr_names_numeric
},
494 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
, 0,
495 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
496 mips_hwr_names_numeric
},
497 { "r5900", 1, bfd_mach_mips5900
, CPU_R5900
, ISA_MIPS3
, 0,
498 mips_cp0_names_r5900
, NULL
, 0, mips_cp1_names_numeric
,
499 mips_hwr_names_numeric
},
500 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
, 0,
501 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
502 mips_hwr_names_numeric
},
503 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
504 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
505 mips_hwr_names_numeric
},
506 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
507 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
508 mips_hwr_names_numeric
},
509 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
, 0,
510 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
511 mips_hwr_names_numeric
},
512 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
, 0,
513 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
514 mips_hwr_names_numeric
},
515 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
, 0,
516 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
517 mips_hwr_names_numeric
},
518 { "r14000", 1, bfd_mach_mips14000
, CPU_R14000
, ISA_MIPS4
, 0,
519 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
520 mips_hwr_names_numeric
},
521 { "r16000", 1, bfd_mach_mips16000
, CPU_R16000
, ISA_MIPS4
, 0,
522 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
523 mips_hwr_names_numeric
},
524 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
, 0,
525 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
526 mips_hwr_names_numeric
},
528 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
529 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
530 _MIPS32 Architecture For Programmers Volume I: Introduction to the
531 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
533 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
534 ISA_MIPS32
, ASE_SMARTMIPS
,
535 mips_cp0_names_mips3264
,
536 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
537 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
539 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
541 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
542 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
| ASE_XPA
),
543 mips_cp0_names_mips3264r2
,
544 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
545 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
547 { "mips32r3", 1, bfd_mach_mipsisa32r3
, CPU_MIPS32R3
,
549 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
550 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
| ASE_XPA
),
551 mips_cp0_names_mips3264r2
,
552 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
553 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
555 { "mips32r5", 1, bfd_mach_mipsisa32r5
, CPU_MIPS32R5
,
557 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
558 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
| ASE_XPA
),
559 mips_cp0_names_mips3264r2
,
560 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
561 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
563 { "mips32r6", 1, bfd_mach_mipsisa32r6
, CPU_MIPS32R6
,
565 (ASE_EVA
| ASE_MSA
| ASE_VIRT
| ASE_XPA
| ASE_MCU
| ASE_MT
| ASE_DSP
566 | ASE_DSPR2
| ASE_DSPR3
),
567 mips_cp0_names_mips3264r2
,
568 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
569 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
571 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
572 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
573 ISA_MIPS64
, ASE_MIPS3D
| ASE_MDMX
,
574 mips_cp0_names_mips3264
,
575 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
576 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
578 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
580 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
581 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
582 mips_cp0_names_mips3264r2
,
583 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
584 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
586 { "mips64r3", 1, bfd_mach_mipsisa64r3
, CPU_MIPS64R3
,
588 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
589 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
590 mips_cp0_names_mips3264r2
,
591 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
592 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
594 { "mips64r5", 1, bfd_mach_mipsisa64r5
, CPU_MIPS64R5
,
596 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
597 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
598 mips_cp0_names_mips3264r2
,
599 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
600 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
602 { "mips64r6", 1, bfd_mach_mipsisa64r6
, CPU_MIPS64R6
,
604 (ASE_EVA
| ASE_MSA
| ASE_MSA64
| ASE_XPA
| ASE_VIRT
| ASE_VIRT64
605 | ASE_MCU
| ASE_MT
| ASE_DSP
| ASE_DSPR2
| ASE_DSPR3
),
606 mips_cp0_names_mips3264r2
,
607 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
608 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
610 { "interaptiv-mr2", 1, bfd_mach_mips_interaptiv_mr2
, CPU_INTERAPTIV_MR2
,
612 ASE_MT
| ASE_EVA
| ASE_DSP
| ASE_DSPR2
| ASE_MIPS16E2
| ASE_MIPS16E2_MT
,
613 mips_cp0_names_mips3264r2
,
614 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
615 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
617 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
618 ISA_MIPS64
| INSN_SB1
, ASE_MIPS3D
,
620 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
621 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
623 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
624 ISA_MIPS3
| INSN_LOONGSON_2E
, 0, mips_cp0_names_numeric
,
625 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
627 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
628 ISA_MIPS3
| INSN_LOONGSON_2F
, 0, mips_cp0_names_numeric
,
629 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
631 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
632 ISA_MIPS64R2
| INSN_LOONGSON_3A
, 0, mips_cp0_names_numeric
,
633 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
635 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
636 ISA_MIPS64R2
| INSN_OCTEON
, 0, mips_cp0_names_numeric
, NULL
, 0,
637 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
639 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
640 ISA_MIPS64R2
| INSN_OCTEONP
, 0, mips_cp0_names_numeric
,
641 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
643 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
644 ISA_MIPS64R2
| INSN_OCTEON2
, 0, mips_cp0_names_numeric
,
645 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
647 { "octeon3", 1, bfd_mach_mips_octeon3
, CPU_OCTEON3
,
648 ISA_MIPS64R5
| INSN_OCTEON3
, ASE_VIRT
| ASE_VIRT64
,
649 mips_cp0_names_numeric
,
650 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
652 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
653 ISA_MIPS64
| INSN_XLR
, 0,
655 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
656 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
658 /* XLP is mostly like XLR, with the prominent exception it is being
660 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
661 ISA_MIPS64R2
| INSN_XLR
, 0,
663 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
664 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
666 /* This entry, mips16, is here only for ISA/processor selection; do
667 not print its name. */
668 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS64
,
669 ASE_MIPS16E2
| ASE_MIPS16E2_MT
,
670 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
671 mips_hwr_names_numeric
},
674 /* ISA and processor type to disassemble for, and register names to use.
675 set_default_mips_dis_options and parse_mips_dis_options fill in these
677 static int mips_processor
;
680 static int micromips_ase
;
681 static const char * const *mips_gpr_names
;
682 static const char * const *mips_fpr_names
;
683 static const char * const *mips_cp0_names
;
684 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
685 static int mips_cp0sel_names_len
;
686 static const char * const *mips_cp1_names
;
687 static const char * const *mips_hwr_names
;
690 static int no_aliases
; /* If set disassemble as most general inst. */
692 static const struct mips_abi_choice
*
693 choose_abi_by_name (const char *name
, unsigned int namelen
)
695 const struct mips_abi_choice
*c
;
698 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
699 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
700 && strlen (mips_abi_choices
[i
].name
) == namelen
)
701 c
= &mips_abi_choices
[i
];
706 static const struct mips_arch_choice
*
707 choose_arch_by_name (const char *name
, unsigned int namelen
)
709 const struct mips_arch_choice
*c
= NULL
;
712 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
713 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
714 && strlen (mips_arch_choices
[i
].name
) == namelen
)
715 c
= &mips_arch_choices
[i
];
720 static const struct mips_arch_choice
*
721 choose_arch_by_number (unsigned long mach
)
723 static unsigned long hint_bfd_mach
;
724 static const struct mips_arch_choice
*hint_arch_choice
;
725 const struct mips_arch_choice
*c
;
728 /* We optimize this because even if the user specifies no
729 flags, this will be done for every instruction! */
730 if (hint_bfd_mach
== mach
731 && hint_arch_choice
!= NULL
732 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
733 return hint_arch_choice
;
735 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
737 if (mips_arch_choices
[i
].bfd_mach_valid
738 && mips_arch_choices
[i
].bfd_mach
== mach
)
740 c
= &mips_arch_choices
[i
];
741 hint_bfd_mach
= mach
;
742 hint_arch_choice
= c
;
748 /* Check if the object uses NewABI conventions. */
751 is_newabi (Elf_Internal_Ehdr
*header
)
753 /* There are no old-style ABIs which use 64-bit ELF. */
754 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
757 /* If a 32-bit ELF file, n32 is a new-style ABI. */
758 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
764 /* Check if the object has microMIPS ASE code. */
767 is_micromips (Elf_Internal_Ehdr
*header
)
769 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
775 /* Convert ASE flags from .MIPS.abiflags to internal values. */
778 mips_convert_abiflags_ases (unsigned long afl_ases
)
780 unsigned long opcode_ases
= 0;
782 if (afl_ases
& AFL_ASE_DSP
)
783 opcode_ases
|= ASE_DSP
;
784 if (afl_ases
& AFL_ASE_DSPR2
)
785 opcode_ases
|= ASE_DSPR2
;
786 if (afl_ases
& AFL_ASE_EVA
)
787 opcode_ases
|= ASE_EVA
;
788 if (afl_ases
& AFL_ASE_MCU
)
789 opcode_ases
|= ASE_MCU
;
790 if (afl_ases
& AFL_ASE_MDMX
)
791 opcode_ases
|= ASE_MDMX
;
792 if (afl_ases
& AFL_ASE_MIPS3D
)
793 opcode_ases
|= ASE_MIPS3D
;
794 if (afl_ases
& AFL_ASE_MT
)
795 opcode_ases
|= ASE_MT
;
796 if (afl_ases
& AFL_ASE_SMARTMIPS
)
797 opcode_ases
|= ASE_SMARTMIPS
;
798 if (afl_ases
& AFL_ASE_VIRT
)
799 opcode_ases
|= ASE_VIRT
;
800 if (afl_ases
& AFL_ASE_MSA
)
801 opcode_ases
|= ASE_MSA
;
802 if (afl_ases
& AFL_ASE_XPA
)
803 opcode_ases
|= ASE_XPA
;
804 if (afl_ases
& AFL_ASE_DSPR3
)
805 opcode_ases
|= ASE_DSPR3
;
806 if (afl_ases
& AFL_ASE_MIPS16E2
)
807 opcode_ases
|= ASE_MIPS16E2
;
808 if ((afl_ases
& (AFL_ASE_MIPS16E2
| AFL_ASE_MT
))
809 == (AFL_ASE_MIPS16E2
| AFL_ASE_MT
))
810 opcode_ases
|= ASE_MIPS16E2_MT
;
815 set_default_mips_dis_options (struct disassemble_info
*info
)
817 const struct mips_arch_choice
*chosen_arch
;
819 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
820 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
821 CP0 register, and HWR names. */
822 mips_isa
= ISA_MIPS3
;
823 mips_processor
= CPU_R3000
;
826 mips_gpr_names
= mips_gpr_names_oldabi
;
827 mips_fpr_names
= mips_fpr_names_numeric
;
828 mips_cp0_names
= mips_cp0_names_numeric
;
829 mips_cp0sel_names
= NULL
;
830 mips_cp0sel_names_len
= 0;
831 mips_cp1_names
= mips_cp1_names_numeric
;
832 mips_hwr_names
= mips_hwr_names_numeric
;
835 /* Set ISA, architecture, and cp0 register names as best we can. */
836 #if ! SYMTAB_AVAILABLE
837 /* This is running out on a target machine, not in a host tool.
838 FIXME: Where does mips_target_info come from? */
839 target_processor
= mips_target_info
.processor
;
840 mips_isa
= mips_target_info
.isa
;
841 mips_ase
= mips_target_info
.ase
;
843 chosen_arch
= choose_arch_by_number (info
->mach
);
844 if (chosen_arch
!= NULL
)
846 mips_processor
= chosen_arch
->processor
;
847 mips_isa
= chosen_arch
->isa
;
848 mips_ase
= chosen_arch
->ase
;
849 mips_cp0_names
= chosen_arch
->cp0_names
;
850 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
851 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
852 mips_cp1_names
= chosen_arch
->cp1_names
;
853 mips_hwr_names
= chosen_arch
->hwr_names
;
856 /* Update settings according to the ELF file header flags. */
857 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
859 struct bfd
*abfd
= info
->section
->owner
;
860 Elf_Internal_Ehdr
*header
= elf_elfheader (abfd
);
861 Elf_Internal_ABIFlags_v0
*abiflags
= NULL
;
863 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
864 because we won't then have a MIPS/ELF BFD, however we need
865 to guard against a link error in a `--enable-targets=...'
866 configuration with a 32-bit host where the MIPS target is
867 a secondary, or with MIPS/ECOFF configurations. */
868 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
869 abiflags
= bfd_mips_elf_get_abiflags (abfd
);
871 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
872 if (is_newabi (header
))
873 mips_gpr_names
= mips_gpr_names_newabi
;
874 /* If a microMIPS binary, then don't use MIPS16 bindings. */
875 micromips_ase
= is_micromips (header
);
876 /* OR in any extra ASE flags set in ELF file structures. */
878 mips_ase
|= mips_convert_abiflags_ases (abiflags
->ases
);
879 else if (header
->e_flags
& EF_MIPS_ARCH_ASE_MDMX
)
880 mips_ase
|= ASE_MDMX
;
886 parse_mips_dis_option (const char *option
, unsigned int len
)
888 unsigned int i
, optionlen
, vallen
;
890 const struct mips_abi_choice
*chosen_abi
;
891 const struct mips_arch_choice
*chosen_arch
;
893 /* Try to match options that are simple flags */
894 if (CONST_STRNEQ (option
, "no-aliases"))
900 if (CONST_STRNEQ (option
, "msa"))
903 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
904 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R3
905 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R5
906 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
)
907 mips_ase
|= ASE_MSA64
;
911 if (CONST_STRNEQ (option
, "virt"))
913 mips_ase
|= ASE_VIRT
;
914 if (mips_isa
& ISA_MIPS64R2
915 || mips_isa
& ISA_MIPS64R3
916 || mips_isa
& ISA_MIPS64R5
917 || mips_isa
& ISA_MIPS64R6
)
918 mips_ase
|= ASE_VIRT64
;
922 if (CONST_STRNEQ (option
, "xpa"))
929 /* Look for the = that delimits the end of the option name. */
930 for (i
= 0; i
< len
; i
++)
931 if (option
[i
] == '=')
934 if (i
== 0) /* Invalid option: no name before '='. */
936 if (i
== len
) /* Invalid option: no '='. */
938 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
942 val
= option
+ (optionlen
+ 1);
943 vallen
= len
- (optionlen
+ 1);
945 if (strncmp ("gpr-names", option
, optionlen
) == 0
946 && strlen ("gpr-names") == optionlen
)
948 chosen_abi
= choose_abi_by_name (val
, vallen
);
949 if (chosen_abi
!= NULL
)
950 mips_gpr_names
= chosen_abi
->gpr_names
;
954 if (strncmp ("fpr-names", option
, optionlen
) == 0
955 && strlen ("fpr-names") == optionlen
)
957 chosen_abi
= choose_abi_by_name (val
, vallen
);
958 if (chosen_abi
!= NULL
)
959 mips_fpr_names
= chosen_abi
->fpr_names
;
963 if (strncmp ("cp0-names", option
, optionlen
) == 0
964 && strlen ("cp0-names") == optionlen
)
966 chosen_arch
= choose_arch_by_name (val
, vallen
);
967 if (chosen_arch
!= NULL
)
969 mips_cp0_names
= chosen_arch
->cp0_names
;
970 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
971 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
976 if (strncmp ("cp1-names", option
, optionlen
) == 0
977 && strlen ("cp1-names") == optionlen
)
979 chosen_arch
= choose_arch_by_name (val
, vallen
);
980 if (chosen_arch
!= NULL
)
981 mips_cp1_names
= chosen_arch
->cp1_names
;
985 if (strncmp ("hwr-names", option
, optionlen
) == 0
986 && strlen ("hwr-names") == optionlen
)
988 chosen_arch
= choose_arch_by_name (val
, vallen
);
989 if (chosen_arch
!= NULL
)
990 mips_hwr_names
= chosen_arch
->hwr_names
;
994 if (strncmp ("reg-names", option
, optionlen
) == 0
995 && strlen ("reg-names") == optionlen
)
997 /* We check both ABI and ARCH here unconditionally, so
998 that "numeric" will do the desirable thing: select
999 numeric register names for all registers. Other than
1000 that, a given name probably won't match both. */
1001 chosen_abi
= choose_abi_by_name (val
, vallen
);
1002 if (chosen_abi
!= NULL
)
1004 mips_gpr_names
= chosen_abi
->gpr_names
;
1005 mips_fpr_names
= chosen_abi
->fpr_names
;
1007 chosen_arch
= choose_arch_by_name (val
, vallen
);
1008 if (chosen_arch
!= NULL
)
1010 mips_cp0_names
= chosen_arch
->cp0_names
;
1011 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
1012 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
1013 mips_cp1_names
= chosen_arch
->cp1_names
;
1014 mips_hwr_names
= chosen_arch
->hwr_names
;
1019 /* Invalid option. */
1023 parse_mips_dis_options (const char *options
)
1025 const char *option_end
;
1027 if (options
== NULL
)
1030 while (*options
!= '\0')
1032 /* Skip empty options. */
1033 if (*options
== ',')
1039 /* We know that *options is neither NUL or a comma. */
1040 option_end
= options
+ 1;
1041 while (*option_end
!= ',' && *option_end
!= '\0')
1044 parse_mips_dis_option (options
, option_end
- options
);
1046 /* Go on to the next one. If option_end points to a comma, it
1047 will be skipped above. */
1048 options
= option_end
;
1052 static const struct mips_cp0sel_name
*
1053 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
1055 unsigned int cp0reg
,
1060 for (i
= 0; i
< len
; i
++)
1061 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
1066 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1069 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
1070 enum mips_reg_operand_type type
, int regno
)
1075 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
1079 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
1083 if (opcode
->pinfo
& (FP_D
| FP_S
))
1084 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
1086 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
1090 if (opcode
->membership
& INSN_5400
)
1091 info
->fprintf_func (info
->stream
, "$f%d", regno
);
1093 info
->fprintf_func (info
->stream
, "$v%d", regno
);
1097 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
1101 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1102 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
1103 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
1104 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
1106 info
->fprintf_func (info
->stream
, "$%d", regno
);
1110 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1114 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1118 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1121 case OP_REG_R5900_I
:
1122 info
->fprintf_func (info
->stream
, "$I");
1125 case OP_REG_R5900_Q
:
1126 info
->fprintf_func (info
->stream
, "$Q");
1129 case OP_REG_R5900_R
:
1130 info
->fprintf_func (info
->stream
, "$R");
1133 case OP_REG_R5900_ACC
:
1134 info
->fprintf_func (info
->stream
, "$ACC");
1138 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1141 case OP_REG_MSA_CTRL
:
1142 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1148 /* Used to track the state carried over from previous operands in
1150 struct mips_print_arg_state
{
1151 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1152 where the value is known to be unsigned and small. */
1153 unsigned int last_int
;
1155 /* The type and number of the last OP_REG seen. We only use this for
1156 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1157 enum mips_reg_operand_type last_reg_type
;
1158 unsigned int last_regno
;
1159 unsigned int dest_regno
;
1160 unsigned int seen_dest
;
1163 /* Initialize STATE for the start of an instruction. */
1166 init_print_arg_state (struct mips_print_arg_state
*state
)
1168 memset (state
, 0, sizeof (*state
));
1171 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1172 whose value is given by UVAL. */
1175 print_vu0_channel (struct disassemble_info
*info
,
1176 const struct mips_operand
*operand
, unsigned int uval
)
1178 if (operand
->size
== 4)
1179 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1180 uval
& 8 ? "x" : "",
1181 uval
& 4 ? "y" : "",
1182 uval
& 2 ? "z" : "",
1183 uval
& 1 ? "w" : "");
1184 else if (operand
->size
== 2)
1185 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1190 /* Record information about a register operand. */
1193 mips_seen_register (struct mips_print_arg_state
*state
,
1195 enum mips_reg_operand_type reg_type
)
1197 state
->last_reg_type
= reg_type
;
1198 state
->last_regno
= regno
;
1200 if (!state
->seen_dest
)
1202 state
->seen_dest
= 1;
1203 state
->dest_regno
= regno
;
1207 /* Print SAVE/RESTORE instruction operands according to the argument
1208 register mask AMASK, the number of static registers saved NSREG,
1209 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1210 and the frame size FRAME_SIZE. */
1213 mips_print_save_restore (struct disassemble_info
*info
, unsigned int amask
,
1214 unsigned int nsreg
, unsigned int ra
,
1215 unsigned int s0
, unsigned int s1
,
1216 unsigned int frame_size
)
1218 const fprintf_ftype infprintf
= info
->fprintf_func
;
1219 unsigned int nargs
, nstatics
, smask
, i
, j
;
1220 void *is
= info
->stream
;
1223 if (amask
== MIPS_SVRS_ALL_ARGS
)
1228 else if (amask
== MIPS_SVRS_ALL_STATICS
)
1236 nstatics
= amask
& 3;
1242 infprintf (is
, "%s", mips_gpr_names
[4]);
1244 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1248 infprintf (is
, "%s%d", sep
, frame_size
);
1251 infprintf (is
, ",%s", mips_gpr_names
[31]);
1258 if (nsreg
> 0) /* $s2-$s8 */
1259 smask
|= ((1 << nsreg
) - 1) << 2;
1261 for (i
= 0; i
< 9; i
++)
1262 if (smask
& (1 << i
))
1264 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1265 /* Skip over string of set bits. */
1266 for (j
= i
; smask
& (2 << j
); j
++)
1269 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1272 /* Statics $ax - $a3. */
1274 infprintf (is
, ",%s", mips_gpr_names
[7]);
1275 else if (nstatics
> 0)
1276 infprintf (is
, ",%s-%s",
1277 mips_gpr_names
[7 - nstatics
+ 1],
1282 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1283 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1284 the base address for OP_PCREL operands. */
1287 print_insn_arg (struct disassemble_info
*info
,
1288 struct mips_print_arg_state
*state
,
1289 const struct mips_opcode
*opcode
,
1290 const struct mips_operand
*operand
,
1294 const fprintf_ftype infprintf
= info
->fprintf_func
;
1295 void *is
= info
->stream
;
1297 switch (operand
->type
)
1301 const struct mips_int_operand
*int_op
;
1303 int_op
= (const struct mips_int_operand
*) operand
;
1304 uval
= mips_decode_int_operand (int_op
, uval
);
1305 state
->last_int
= uval
;
1306 if (int_op
->print_hex
)
1307 infprintf (is
, "0x%x", uval
);
1309 infprintf (is
, "%d", uval
);
1315 const struct mips_mapped_int_operand
*mint_op
;
1317 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1318 uval
= mint_op
->int_map
[uval
];
1319 state
->last_int
= uval
;
1320 if (mint_op
->print_hex
)
1321 infprintf (is
, "0x%x", uval
);
1323 infprintf (is
, "%d", uval
);
1329 const struct mips_msb_operand
*msb_op
;
1331 msb_op
= (const struct mips_msb_operand
*) operand
;
1332 uval
+= msb_op
->bias
;
1333 if (msb_op
->add_lsb
)
1334 uval
-= state
->last_int
;
1335 infprintf (is
, "0x%x", uval
);
1340 case OP_OPTIONAL_REG
:
1342 const struct mips_reg_operand
*reg_op
;
1344 reg_op
= (const struct mips_reg_operand
*) operand
;
1345 uval
= mips_decode_reg_operand (reg_op
, uval
);
1346 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1348 mips_seen_register (state
, uval
, reg_op
->reg_type
);
1354 const struct mips_reg_pair_operand
*pair_op
;
1356 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1357 print_reg (info
, opcode
, pair_op
->reg_type
,
1358 pair_op
->reg1_map
[uval
]);
1359 infprintf (is
, ",");
1360 print_reg (info
, opcode
, pair_op
->reg_type
,
1361 pair_op
->reg2_map
[uval
]);
1367 const struct mips_pcrel_operand
*pcrel_op
;
1369 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1370 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1372 /* For jumps and branches clear the ISA bit except for
1373 the GDB disassembler. */
1374 if (pcrel_op
->include_isa_bit
1375 && info
->flavour
!= bfd_target_unknown_flavour
)
1378 (*info
->print_address_func
) (info
->target
, info
);
1383 infprintf (is
, "%d", uval
);
1386 case OP_ADDIUSP_INT
:
1390 sval
= mips_signed_operand (operand
, uval
) * 4;
1391 if (sval
>= -8 && sval
< 8)
1393 infprintf (is
, "%d", sval
);
1397 case OP_CLO_CLZ_DEST
:
1399 unsigned int reg1
, reg2
;
1403 /* If one is zero use the other. */
1404 if (reg1
== reg2
|| reg2
== 0)
1405 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1407 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1409 /* Bogus, result depends on processor. */
1410 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1411 mips_gpr_names
[reg2
]);
1417 case OP_NON_ZERO_REG
:
1419 print_reg (info
, opcode
, OP_REG_GP
, uval
& 31);
1420 mips_seen_register (state
, uval
, OP_REG_GP
);
1424 case OP_LWM_SWM_LIST
:
1425 if (operand
->size
== 2)
1428 infprintf (is
, "%s,%s",
1430 mips_gpr_names
[31]);
1432 infprintf (is
, "%s-%s,%s",
1434 mips_gpr_names
[16 + uval
],
1435 mips_gpr_names
[31]);
1441 s_reg_encode
= uval
& 0xf;
1442 if (s_reg_encode
!= 0)
1444 if (s_reg_encode
== 1)
1445 infprintf (is
, "%s", mips_gpr_names
[16]);
1446 else if (s_reg_encode
< 9)
1447 infprintf (is
, "%s-%s",
1449 mips_gpr_names
[15 + s_reg_encode
]);
1450 else if (s_reg_encode
== 9)
1451 infprintf (is
, "%s-%s,%s",
1454 mips_gpr_names
[30]);
1456 infprintf (is
, "UNKNOWN");
1459 if (uval
& 0x10) /* For ra. */
1461 if (s_reg_encode
== 0)
1462 infprintf (is
, "%s", mips_gpr_names
[31]);
1464 infprintf (is
, ",%s", mips_gpr_names
[31]);
1469 case OP_ENTRY_EXIT_LIST
:
1472 unsigned int amask
, smask
;
1475 amask
= (uval
>> 3) & 7;
1476 if (amask
> 0 && amask
< 5)
1478 infprintf (is
, "%s", mips_gpr_names
[4]);
1480 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1484 smask
= (uval
>> 1) & 3;
1487 infprintf (is
, "%s??", sep
);
1492 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1494 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1500 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1504 if (amask
== 5 || amask
== 6)
1506 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1508 infprintf (is
, "-%s", mips_fpr_names
[1]);
1513 case OP_SAVE_RESTORE_LIST
:
1514 /* Should be handled by the caller due to complex behavior. */
1517 case OP_MDMX_IMM_REG
:
1523 if ((vsel
& 0x10) == 0)
1528 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1529 if ((vsel
& 1) == 0)
1531 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1532 infprintf (is
, "[%d]", vsel
>> 1);
1534 else if ((vsel
& 0x08) == 0)
1535 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1537 infprintf (is
, "0x%x", uval
);
1541 case OP_REPEAT_PREV_REG
:
1542 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1545 case OP_REPEAT_DEST_REG
:
1546 print_reg (info
, opcode
, state
->last_reg_type
, state
->dest_regno
);
1550 infprintf (is
, "$pc");
1554 print_reg (info
, opcode
, OP_REG_GP
, 28);
1558 case OP_VU0_MATCH_SUFFIX
:
1559 print_vu0_channel (info
, operand
, uval
);
1563 infprintf (is
, "[%d]", uval
);
1567 infprintf (is
, "[");
1568 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1569 infprintf (is
, "]");
1574 /* Validate the arguments for INSN, which is described by OPCODE.
1575 Use DECODE_OPERAND to get the encoding of each operand. */
1578 validate_insn_args (const struct mips_opcode
*opcode
,
1579 const struct mips_operand
*(*decode_operand
) (const char *),
1582 struct mips_print_arg_state state
;
1583 const struct mips_operand
*operand
;
1587 init_print_arg_state (&state
);
1588 for (s
= opcode
->args
; *s
; ++s
)
1602 operand
= decode_operand (s
);
1606 uval
= mips_extract_operand (operand
, insn
);
1607 switch (operand
->type
)
1610 case OP_OPTIONAL_REG
:
1612 const struct mips_reg_operand
*reg_op
;
1614 reg_op
= (const struct mips_reg_operand
*) operand
;
1615 uval
= mips_decode_reg_operand (reg_op
, uval
);
1616 mips_seen_register (&state
, uval
, reg_op
->reg_type
);
1622 unsigned int reg1
, reg2
;
1627 if (reg1
!= reg2
|| reg1
== 0)
1634 const struct mips_check_prev_operand
*prev_op
;
1636 prev_op
= (const struct mips_check_prev_operand
*) operand
;
1638 if (!prev_op
->zero_ok
&& uval
== 0)
1641 if (((prev_op
->less_than_ok
&& uval
< state
.last_regno
)
1642 || (prev_op
->greater_than_ok
&& uval
> state
.last_regno
)
1643 || (prev_op
->equal_ok
&& uval
== state
.last_regno
)))
1649 case OP_NON_ZERO_REG
:
1662 case OP_ADDIUSP_INT
:
1663 case OP_CLO_CLZ_DEST
:
1664 case OP_LWM_SWM_LIST
:
1665 case OP_ENTRY_EXIT_LIST
:
1666 case OP_MDMX_IMM_REG
:
1667 case OP_REPEAT_PREV_REG
:
1668 case OP_REPEAT_DEST_REG
:
1672 case OP_VU0_MATCH_SUFFIX
:
1675 case OP_SAVE_RESTORE_LIST
:
1679 if (*s
== 'm' || *s
== '+' || *s
== '-')
1686 /* Print the arguments for INSN, which is described by OPCODE.
1687 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1688 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1689 operand is for a branch or jump. */
1692 print_insn_args (struct disassemble_info
*info
,
1693 const struct mips_opcode
*opcode
,
1694 const struct mips_operand
*(*decode_operand
) (const char *),
1695 unsigned int insn
, bfd_vma insn_pc
, unsigned int length
)
1697 const fprintf_ftype infprintf
= info
->fprintf_func
;
1698 void *is
= info
->stream
;
1699 struct mips_print_arg_state state
;
1700 const struct mips_operand
*operand
;
1703 init_print_arg_state (&state
);
1704 for (s
= opcode
->args
; *s
; ++s
)
1711 infprintf (is
, "%c", *s
);
1716 infprintf (is
, "%c%c", *s
, *s
);
1720 operand
= decode_operand (s
);
1723 /* xgettext:c-format */
1725 _("# internal error, undefined operand in `%s %s'"),
1726 opcode
->name
, opcode
->args
);
1730 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1732 /* Handle this case here because of the complex behavior. */
1733 unsigned int amask
= (insn
>> 15) & 0xf;
1734 unsigned int nsreg
= (insn
>> 23) & 0x7;
1735 unsigned int ra
= insn
& 0x1000; /* $ra */
1736 unsigned int s0
= insn
& 0x800; /* $s0 */
1737 unsigned int s1
= insn
& 0x400; /* $s1 */
1738 unsigned int frame_size
= (((insn
>> 15) & 0xf0)
1739 | ((insn
>> 6) & 0x0f)) * 8;
1740 mips_print_save_restore (info
, amask
, nsreg
, ra
, s0
, s1
,
1743 else if (operand
->type
== OP_REG
1746 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1748 /* Coprocessor register 0 with sel field. */
1749 const struct mips_cp0sel_name
*n
;
1750 unsigned int reg
, sel
;
1752 reg
= mips_extract_operand (operand
, insn
);
1754 operand
= decode_operand (s
);
1755 sel
= mips_extract_operand (operand
, insn
);
1757 /* CP0 register including 'sel' code for mftc0, to be
1758 printed textually if known. If not known, print both
1759 CP0 register name and sel numerically since CP0 register
1760 with sel 0 may have a name unrelated to register being
1762 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1763 mips_cp0sel_names_len
,
1766 infprintf (is
, "%s", n
->name
);
1768 infprintf (is
, "$%d,%d", reg
, sel
);
1772 bfd_vma base_pc
= insn_pc
;
1774 /* Adjust the PC relative base so that branch/jump insns use
1775 the following PC as the base but genuinely PC relative
1776 operands use the current PC. */
1777 if (operand
->type
== OP_PCREL
)
1779 const struct mips_pcrel_operand
*pcrel_op
;
1781 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1782 /* The include_isa_bit flag is sufficient to distinguish
1783 branch/jump from other PC relative operands. */
1784 if (pcrel_op
->include_isa_bit
)
1788 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1789 mips_extract_operand (operand
, insn
));
1791 if (*s
== 'm' || *s
== '+' || *s
== '-')
1798 /* Print the mips instruction at address MEMADDR in debugged memory,
1799 on using INFO. Returns length of the instruction, in bytes, which is
1800 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1801 this is little-endian code. */
1804 print_insn_mips (bfd_vma memaddr
,
1806 struct disassemble_info
*info
)
1808 #define GET_OP(insn, field) \
1809 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1810 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1811 const fprintf_ftype infprintf
= info
->fprintf_func
;
1812 const struct mips_opcode
*op
;
1813 static bfd_boolean init
= 0;
1814 void *is
= info
->stream
;
1816 /* Build a hash table to shorten the search time. */
1821 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1823 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1825 if (op
->pinfo
== INSN_MACRO
1826 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1828 if (i
== GET_OP (op
->match
, OP
))
1839 info
->bytes_per_chunk
= INSNLEN
;
1840 info
->display_endian
= info
->endian
;
1841 info
->insn_info_valid
= 1;
1842 info
->branch_delay_insns
= 0;
1843 info
->data_size
= 0;
1844 info
->insn_type
= dis_nonbranch
;
1848 op
= mips_hash
[GET_OP (word
, OP
)];
1851 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1853 if (op
->pinfo
!= INSN_MACRO
1854 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1855 && (word
& op
->mask
) == op
->match
)
1857 /* We always disassemble the jalx instruction, except for MIPS r6. */
1858 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1859 && (strcmp (op
->name
, "jalx")
1860 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS32R6
1861 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
))
1864 /* Figure out instruction type and branch delay information. */
1865 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1867 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1868 info
->insn_type
= dis_jsr
;
1870 info
->insn_type
= dis_branch
;
1871 info
->branch_delay_insns
= 1;
1873 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1874 | INSN_COND_BRANCH_LIKELY
)) != 0)
1876 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1877 info
->insn_type
= dis_condjsr
;
1879 info
->insn_type
= dis_condbranch
;
1880 info
->branch_delay_insns
= 1;
1882 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1883 | INSN_LOAD_MEMORY
)) != 0)
1884 info
->insn_type
= dis_dref
;
1886 if (!validate_insn_args (op
, decode_mips_operand
, word
))
1889 infprintf (is
, "%s", op
->name
);
1890 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1894 infprintf (is
, ".");
1895 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1896 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1901 infprintf (is
, "\t");
1902 print_insn_args (info
, op
, decode_mips_operand
, word
,
1912 /* Handle undefined instructions. */
1913 info
->insn_type
= dis_noninsn
;
1914 infprintf (is
, "0x%x", word
);
1918 /* Disassemble an operand for a mips16 instruction. */
1921 print_mips16_insn_arg (struct disassemble_info
*info
,
1922 struct mips_print_arg_state
*state
,
1923 const struct mips_opcode
*opcode
,
1924 char type
, bfd_vma memaddr
,
1925 unsigned insn
, bfd_boolean use_extend
,
1926 unsigned extend
, bfd_boolean is_offset
)
1928 const fprintf_ftype infprintf
= info
->fprintf_func
;
1929 void *is
= info
->stream
;
1930 const struct mips_operand
*operand
, *ext_operand
;
1931 unsigned short ext_size
;
1943 infprintf (is
, "%c", type
);
1947 operand
= decode_mips16_operand (type
, FALSE
);
1950 /* xgettext:c-format */
1951 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
1952 opcode
->name
, opcode
->args
);
1956 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1958 /* Handle this case here because of the complex interaction
1959 with the EXTEND opcode. */
1960 unsigned int amask
= extend
& 0xf;
1961 unsigned int nsreg
= (extend
>> 8) & 0x7;
1962 unsigned int ra
= insn
& 0x40; /* $ra */
1963 unsigned int s0
= insn
& 0x20; /* $s0 */
1964 unsigned int s1
= insn
& 0x10; /* $s1 */
1965 unsigned int frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
1966 if (frame_size
== 0 && !use_extend
)
1968 mips_print_save_restore (info
, amask
, nsreg
, ra
, s0
, s1
, frame_size
);
1972 if (is_offset
&& operand
->type
== OP_INT
)
1974 const struct mips_int_operand
*int_op
;
1976 int_op
= (const struct mips_int_operand
*) operand
;
1977 info
->insn_type
= dis_dref
;
1978 info
->data_size
= 1 << int_op
->shift
;
1984 ext_operand
= decode_mips16_operand (type
, TRUE
);
1985 if (ext_operand
!= operand
1986 || (operand
->type
== OP_INT
&& operand
->lsb
== 0
1987 && mips_opcode_32bit_p (opcode
)))
1989 ext_size
= ext_operand
->size
;
1990 operand
= ext_operand
;
1993 if (operand
->size
== 26)
1994 uval
= ((extend
& 0x1f) << 21) | ((extend
& 0x3e0) << 11) | insn
;
1995 else if (ext_size
== 16 || ext_size
== 9)
1996 uval
= ((extend
& 0x1f) << 11) | (extend
& 0x7e0) | (insn
& 0x1f);
1997 else if (ext_size
== 15)
1998 uval
= ((extend
& 0xf) << 11) | (extend
& 0x7f0) | (insn
& 0xf);
1999 else if (ext_size
== 6)
2000 uval
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
2002 uval
= mips_extract_operand (operand
, (extend
<< 16) | insn
);
2004 uval
&= (1U << ext_size
) - 1;
2006 baseaddr
= memaddr
+ 2;
2007 if (operand
->type
== OP_PCREL
)
2009 const struct mips_pcrel_operand
*pcrel_op
;
2011 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
2012 if (!pcrel_op
->include_isa_bit
&& use_extend
)
2013 baseaddr
= memaddr
- 2;
2014 else if (!pcrel_op
->include_isa_bit
)
2018 /* If this instruction is in the delay slot of a JAL/JALX
2019 instruction, the base address is the address of the
2020 JAL/JALX instruction. If it is in the delay slot of
2021 a JR/JALR instruction, the base address is the address
2022 of the JR/JALR instruction. This test is unreliable:
2023 we have no way of knowing whether the previous word is
2024 instruction or data. */
2025 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
2026 && (((info
->endian
== BFD_ENDIAN_BIG
2027 ? bfd_getb16 (buffer
)
2028 : bfd_getl16 (buffer
))
2029 & 0xf800) == 0x1800))
2030 baseaddr
= memaddr
- 4;
2031 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
2033 && (((info
->endian
== BFD_ENDIAN_BIG
2034 ? bfd_getb16 (buffer
)
2035 : bfd_getl16 (buffer
))
2036 & 0xf89f) == 0xe800)
2037 && (((info
->endian
== BFD_ENDIAN_BIG
2038 ? bfd_getb16 (buffer
)
2039 : bfd_getl16 (buffer
))
2040 & 0x0060) != 0x0060))
2041 baseaddr
= memaddr
- 2;
2047 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
2053 /* Check if the given address is the last word of a MIPS16 PLT entry.
2054 This word is data and depending on the value it may interfere with
2055 disassembly of further PLT entries. We make use of the fact PLT
2056 symbols are marked BSF_SYNTHETIC. */
2058 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2062 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2063 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2069 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2078 /* Disassemble mips16 instructions. */
2081 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2083 const fprintf_ftype infprintf
= info
->fprintf_func
;
2086 const struct mips_opcode
*op
, *opend
;
2087 struct mips_print_arg_state state
;
2088 void *is
= info
->stream
;
2089 bfd_boolean have_second
;
2090 bfd_boolean extend_only
;
2091 unsigned int second
;
2095 info
->bytes_per_chunk
= 2;
2096 info
->display_endian
= info
->endian
;
2097 info
->insn_info_valid
= 1;
2098 info
->branch_delay_insns
= 0;
2099 info
->data_size
= 0;
2103 #define GET_OP(insn, field) \
2104 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2105 /* Decode PLT entry's GOT slot address word. */
2106 if (is_mips16_plt_tail (info
, memaddr
))
2108 info
->insn_type
= dis_noninsn
;
2109 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2112 unsigned int gotslot
;
2114 if (info
->endian
== BFD_ENDIAN_BIG
)
2115 gotslot
= bfd_getb32 (buffer
);
2117 gotslot
= bfd_getl32 (buffer
);
2118 infprintf (is
, ".word\t0x%x", gotslot
);
2125 info
->insn_type
= dis_nonbranch
;
2126 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2130 (*info
->memory_error_func
) (status
, memaddr
, info
);
2134 extend_only
= FALSE
;
2136 if (info
->endian
== BFD_ENDIAN_BIG
)
2137 first
= bfd_getb16 (buffer
);
2139 first
= bfd_getl16 (buffer
);
2141 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2145 if (info
->endian
== BFD_ENDIAN_BIG
)
2146 second
= bfd_getb16 (buffer
);
2148 second
= bfd_getl16 (buffer
);
2149 full
= (first
<< 16) | second
;
2153 have_second
= FALSE
;
2158 /* FIXME: Should probably use a hash table on the major opcode here. */
2160 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2161 for (op
= mips16_opcodes
; op
< opend
; op
++)
2163 enum match_kind match
;
2165 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
))
2168 if (op
->pinfo
== INSN_MACRO
2169 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
2171 else if (mips_opcode_32bit_p (op
))
2174 && (full
& op
->mask
) == op
->match
)
2179 else if ((first
& op
->mask
) == op
->match
)
2181 match
= MATCH_SHORT
;
2185 else if ((first
& 0xf800) == 0xf000
2188 && (second
& op
->mask
) == op
->match
)
2190 if (op
->pinfo2
& INSN2_SHORT_ONLY
)
2201 if (match
!= MATCH_NONE
)
2205 infprintf (is
, "%s", op
->name
);
2206 if (op
->args
[0] != '\0')
2207 infprintf (is
, "\t");
2209 init_print_arg_state (&state
);
2210 for (s
= op
->args
; *s
!= '\0'; s
++)
2214 && GET_OP (full
, RX
) == GET_OP (full
, RY
))
2216 /* Skip the register and the comma. */
2222 && GET_OP (full
, RZ
) == GET_OP (full
, RX
))
2224 /* Skip the register and the comma. */
2231 && op
->name
[strlen (op
->name
) - 1] == '0')
2233 /* Coprocessor register 0 with sel field. */
2234 const struct mips_cp0sel_name
*n
;
2235 const struct mips_operand
*operand
;
2236 unsigned int reg
, sel
;
2238 operand
= decode_mips16_operand (*s
, TRUE
);
2239 reg
= mips_extract_operand (operand
, (first
<< 16) | second
);
2241 operand
= decode_mips16_operand (*s
, TRUE
);
2242 sel
= mips_extract_operand (operand
, (first
<< 16) | second
);
2244 /* CP0 register including 'sel' code for mftc0, to be
2245 printed textually if known. If not known, print both
2246 CP0 register name and sel numerically since CP0 register
2247 with sel 0 may have a name unrelated to register being
2249 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2250 mips_cp0sel_names_len
,
2253 infprintf (is
, "%s", n
->name
);
2255 infprintf (is
, "$%d,%d", reg
, sel
);
2261 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
+ 2,
2262 second
, TRUE
, first
, s
[1] == '(');
2265 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
,
2266 first
, FALSE
, 0, s
[1] == '(');
2268 case MATCH_NONE
: /* Stop the compiler complaining. */
2273 /* Figure out branch instruction type and delay slot information. */
2274 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2275 info
->branch_delay_insns
= 1;
2276 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
2277 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
2279 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2280 info
->insn_type
= dis_jsr
;
2282 info
->insn_type
= dis_branch
;
2284 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
2285 info
->insn_type
= dis_condbranch
;
2287 return match
== MATCH_FULL
? 4 : 2;
2292 infprintf (is
, "0x%x", first
);
2293 info
->insn_type
= dis_noninsn
;
2298 /* Disassemble microMIPS instructions. */
2301 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2303 const fprintf_ftype infprintf
= info
->fprintf_func
;
2304 const struct mips_opcode
*op
, *opend
;
2305 void *is
= info
->stream
;
2307 unsigned int higher
;
2308 unsigned int length
;
2312 info
->bytes_per_chunk
= 2;
2313 info
->display_endian
= info
->endian
;
2314 info
->insn_info_valid
= 1;
2315 info
->branch_delay_insns
= 0;
2316 info
->data_size
= 0;
2317 info
->insn_type
= dis_nonbranch
;
2321 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2324 (*info
->memory_error_func
) (status
, memaddr
, info
);
2330 if (info
->endian
== BFD_ENDIAN_BIG
)
2331 insn
= bfd_getb16 (buffer
);
2333 insn
= bfd_getl16 (buffer
);
2335 if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2337 /* This is a 32-bit microMIPS instruction. */
2340 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2343 infprintf (is
, "micromips 0x%x", higher
);
2344 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2348 if (info
->endian
== BFD_ENDIAN_BIG
)
2349 insn
= bfd_getb16 (buffer
);
2351 insn
= bfd_getl16 (buffer
);
2353 insn
= insn
| (higher
<< 16);
2358 /* FIXME: Should probably use a hash table on the major opcode here. */
2360 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2361 for (op
= micromips_opcodes
; op
< opend
; op
++)
2363 if (op
->pinfo
!= INSN_MACRO
2364 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2365 && (insn
& op
->mask
) == op
->match
2366 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2367 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2369 if (!validate_insn_args (op
, decode_micromips_operand
, insn
))
2372 infprintf (is
, "%s", op
->name
);
2376 infprintf (is
, "\t");
2377 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2378 memaddr
+ 1, length
);
2381 /* Figure out instruction type and branch delay information. */
2383 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2384 info
->branch_delay_insns
= 1;
2385 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2386 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2388 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2389 info
->insn_type
= dis_jsr
;
2391 info
->insn_type
= dis_branch
;
2393 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2394 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2396 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2397 info
->insn_type
= dis_condjsr
;
2399 info
->insn_type
= dis_condbranch
;
2402 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2403 info
->insn_type
= dis_dref
;
2409 infprintf (is
, "0x%x", insn
);
2410 info
->insn_type
= dis_noninsn
;
2415 /* Return 1 if a symbol associated with the location being disassembled
2416 indicates a compressed mode, either MIPS16 or microMIPS, according to
2417 MICROMIPS_P. We iterate over all the symbols at the address being
2418 considered assuming if at least one of them indicates code compression,
2419 then such code has been genuinely produced here (other symbols could
2420 have been derived from function symbols defined elsewhere or could
2421 define data). Otherwise, return 0. */
2424 is_compressed_mode_p (struct disassemble_info
*info
, bfd_boolean micromips_p
)
2429 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2430 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2432 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2434 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2436 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2437 && info
->symtab
[i
]->section
== info
->section
)
2439 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2441 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2443 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2450 /* In an environment where we do not know the symbol type of the
2451 instruction we are forced to assume that the low order bit of the
2452 instructions' address may mark it as a mips16 instruction. If we
2453 are single stepping, or the pc is within the disassembled function,
2454 this works. Otherwise, we need a clue. Sometimes. */
2457 _print_insn_mips (bfd_vma memaddr
,
2458 struct disassemble_info
*info
,
2459 enum bfd_endian endianness
)
2461 bfd_byte buffer
[INSNLEN
];
2464 set_default_mips_dis_options (info
);
2465 parse_mips_dis_options (info
->disassembler_options
);
2467 if (info
->mach
== bfd_mach_mips16
)
2468 return print_insn_mips16 (memaddr
, info
);
2469 if (info
->mach
== bfd_mach_mips_micromips
)
2470 return print_insn_micromips (memaddr
, info
);
2473 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2474 /* Only a few tools will work this way. */
2478 return print_insn_micromips (memaddr
, info
);
2480 return print_insn_mips16 (memaddr
, info
);
2484 #if SYMTAB_AVAILABLE
2485 if (is_compressed_mode_p (info
, TRUE
))
2486 return print_insn_micromips (memaddr
, info
);
2487 if (is_compressed_mode_p (info
, FALSE
))
2488 return print_insn_mips16 (memaddr
, info
);
2491 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2496 if (endianness
== BFD_ENDIAN_BIG
)
2497 insn
= bfd_getb32 (buffer
);
2499 insn
= bfd_getl32 (buffer
);
2501 return print_insn_mips (memaddr
, insn
, info
);
2505 (*info
->memory_error_func
) (status
, memaddr
, info
);
2511 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2513 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2517 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2519 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2523 print_mips_disassembler_options (FILE *stream
)
2527 fprintf (stream
, _("\n\
2528 The following MIPS specific disassembler options are supported for use\n\
2529 with the -M switch (multiple options should be separated by commas):\n"));
2531 fprintf (stream
, _("\n\
2532 no-aliases Use canonical instruction forms.\n"));
2534 fprintf (stream
, _("\n\
2535 msa Recognize MSA instructions.\n"));
2537 fprintf (stream
, _("\n\
2538 virt Recognize the virtualization ASE instructions.\n"));
2540 fprintf (stream
, _("\n\
2541 xpa Recognize the eXtended Physical Address (XPA)\n\
2542 ASE instructions.\n"));
2544 fprintf (stream
, _("\n\
2545 gpr-names=ABI Print GPR names according to specified ABI.\n\
2546 Default: based on binary being disassembled.\n"));
2548 fprintf (stream
, _("\n\
2549 fpr-names=ABI Print FPR names according to specified ABI.\n\
2550 Default: numeric.\n"));
2552 fprintf (stream
, _("\n\
2553 cp0-names=ARCH Print CP0 register names according to\n\
2554 specified architecture.\n\
2555 Default: based on binary being disassembled.\n"));
2557 fprintf (stream
, _("\n\
2558 hwr-names=ARCH Print HWR names according to specified \n\
2560 Default: based on binary being disassembled.\n"));
2562 fprintf (stream
, _("\n\
2563 reg-names=ABI Print GPR and FPR names according to\n\
2564 specified ABI.\n"));
2566 fprintf (stream
, _("\n\
2567 reg-names=ARCH Print CP0 register and HWR names according to\n\
2568 specified architecture.\n"));
2570 fprintf (stream
, _("\n\
2571 For the options above, the following values are supported for \"ABI\":\n\
2573 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2574 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2575 fprintf (stream
, _("\n"));
2577 fprintf (stream
, _("\n\
2578 For the options above, The following values are supported for \"ARCH\":\n\
2580 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2581 if (*mips_arch_choices
[i
].name
!= '\0')
2582 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2583 fprintf (stream
, _("\n"));
2585 fprintf (stream
, _("\n"));