1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2018 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
| ASE_CRC
),
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
| ASE_CRC
607 mips_cp0_names_mips3264r2
,
608 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
609 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
611 { "interaptiv-mr2", 1, bfd_mach_mips_interaptiv_mr2
, CPU_INTERAPTIV_MR2
,
613 ASE_MT
| ASE_EVA
| ASE_DSP
| ASE_DSPR2
| ASE_MIPS16E2
| ASE_MIPS16E2_MT
,
614 mips_cp0_names_mips3264r2
,
615 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
616 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
618 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
619 ISA_MIPS64
| INSN_SB1
, ASE_MIPS3D
,
621 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
622 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
624 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
625 ISA_MIPS3
| INSN_LOONGSON_2E
, 0, mips_cp0_names_numeric
,
626 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
628 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
629 ISA_MIPS3
| INSN_LOONGSON_2F
, 0, mips_cp0_names_numeric
,
630 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
632 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
633 ISA_MIPS64R2
| INSN_LOONGSON_3A
, 0, mips_cp0_names_numeric
,
634 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
636 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
637 ISA_MIPS64R2
| INSN_OCTEON
, 0, mips_cp0_names_numeric
, NULL
, 0,
638 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
640 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
641 ISA_MIPS64R2
| INSN_OCTEONP
, 0, mips_cp0_names_numeric
,
642 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
644 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
645 ISA_MIPS64R2
| INSN_OCTEON2
, 0, mips_cp0_names_numeric
,
646 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
648 { "octeon3", 1, bfd_mach_mips_octeon3
, CPU_OCTEON3
,
649 ISA_MIPS64R5
| INSN_OCTEON3
, ASE_VIRT
| ASE_VIRT64
,
650 mips_cp0_names_numeric
,
651 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
653 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
654 ISA_MIPS64
| INSN_XLR
, 0,
656 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
657 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
659 /* XLP is mostly like XLR, with the prominent exception it is being
661 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
662 ISA_MIPS64R2
| INSN_XLR
, 0,
664 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
665 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
667 /* This entry, mips16, is here only for ISA/processor selection; do
668 not print its name. */
669 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS64
,
670 ASE_MIPS16E2
| ASE_MIPS16E2_MT
,
671 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
672 mips_hwr_names_numeric
},
675 /* ISA and processor type to disassemble for, and register names to use.
676 set_default_mips_dis_options and parse_mips_dis_options fill in these
678 static int mips_processor
;
681 static int micromips_ase
;
682 static const char * const *mips_gpr_names
;
683 static const char * const *mips_fpr_names
;
684 static const char * const *mips_cp0_names
;
685 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
686 static int mips_cp0sel_names_len
;
687 static const char * const *mips_cp1_names
;
688 static const char * const *mips_hwr_names
;
691 static int no_aliases
; /* If set disassemble as most general inst. */
693 static const struct mips_abi_choice
*
694 choose_abi_by_name (const char *name
, unsigned int namelen
)
696 const struct mips_abi_choice
*c
;
699 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
700 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
701 && strlen (mips_abi_choices
[i
].name
) == namelen
)
702 c
= &mips_abi_choices
[i
];
707 static const struct mips_arch_choice
*
708 choose_arch_by_name (const char *name
, unsigned int namelen
)
710 const struct mips_arch_choice
*c
= NULL
;
713 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
714 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
715 && strlen (mips_arch_choices
[i
].name
) == namelen
)
716 c
= &mips_arch_choices
[i
];
721 static const struct mips_arch_choice
*
722 choose_arch_by_number (unsigned long mach
)
724 static unsigned long hint_bfd_mach
;
725 static const struct mips_arch_choice
*hint_arch_choice
;
726 const struct mips_arch_choice
*c
;
729 /* We optimize this because even if the user specifies no
730 flags, this will be done for every instruction! */
731 if (hint_bfd_mach
== mach
732 && hint_arch_choice
!= NULL
733 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
734 return hint_arch_choice
;
736 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
738 if (mips_arch_choices
[i
].bfd_mach_valid
739 && mips_arch_choices
[i
].bfd_mach
== mach
)
741 c
= &mips_arch_choices
[i
];
742 hint_bfd_mach
= mach
;
743 hint_arch_choice
= c
;
749 /* Check if the object uses NewABI conventions. */
752 is_newabi (Elf_Internal_Ehdr
*header
)
754 /* There are no old-style ABIs which use 64-bit ELF. */
755 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
758 /* If a 32-bit ELF file, n32 is a new-style ABI. */
759 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
765 /* Check if the object has microMIPS ASE code. */
768 is_micromips (Elf_Internal_Ehdr
*header
)
770 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
776 /* Convert ASE flags from .MIPS.abiflags to internal values. */
779 mips_convert_abiflags_ases (unsigned long afl_ases
)
781 unsigned long opcode_ases
= 0;
783 if (afl_ases
& AFL_ASE_DSP
)
784 opcode_ases
|= ASE_DSP
;
785 if (afl_ases
& AFL_ASE_DSPR2
)
786 opcode_ases
|= ASE_DSPR2
;
787 if (afl_ases
& AFL_ASE_EVA
)
788 opcode_ases
|= ASE_EVA
;
789 if (afl_ases
& AFL_ASE_MCU
)
790 opcode_ases
|= ASE_MCU
;
791 if (afl_ases
& AFL_ASE_MDMX
)
792 opcode_ases
|= ASE_MDMX
;
793 if (afl_ases
& AFL_ASE_MIPS3D
)
794 opcode_ases
|= ASE_MIPS3D
;
795 if (afl_ases
& AFL_ASE_MT
)
796 opcode_ases
|= ASE_MT
;
797 if (afl_ases
& AFL_ASE_SMARTMIPS
)
798 opcode_ases
|= ASE_SMARTMIPS
;
799 if (afl_ases
& AFL_ASE_VIRT
)
800 opcode_ases
|= ASE_VIRT
;
801 if (afl_ases
& AFL_ASE_MSA
)
802 opcode_ases
|= ASE_MSA
;
803 if (afl_ases
& AFL_ASE_XPA
)
804 opcode_ases
|= ASE_XPA
;
805 if (afl_ases
& AFL_ASE_DSPR3
)
806 opcode_ases
|= ASE_DSPR3
;
807 if (afl_ases
& AFL_ASE_MIPS16E2
)
808 opcode_ases
|= ASE_MIPS16E2
;
812 /* Calculate combination ASE flags from regular ASE flags. */
815 mips_calculate_combination_ases (unsigned long opcode_ases
)
817 unsigned long combination_ases
= 0;
819 if ((opcode_ases
& (ASE_XPA
| ASE_VIRT
)) == (ASE_XPA
| ASE_VIRT
))
820 combination_ases
|= ASE_XPA_VIRT
;
821 if ((opcode_ases
& (ASE_MIPS16E2
| ASE_MT
)) == (ASE_MIPS16E2
| ASE_MT
))
822 combination_ases
|= ASE_MIPS16E2_MT
;
823 return combination_ases
;
827 set_default_mips_dis_options (struct disassemble_info
*info
)
829 const struct mips_arch_choice
*chosen_arch
;
831 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
832 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
833 CP0 register, and HWR names. */
834 mips_isa
= ISA_MIPS3
;
835 mips_processor
= CPU_R3000
;
838 mips_gpr_names
= mips_gpr_names_oldabi
;
839 mips_fpr_names
= mips_fpr_names_numeric
;
840 mips_cp0_names
= mips_cp0_names_numeric
;
841 mips_cp0sel_names
= NULL
;
842 mips_cp0sel_names_len
= 0;
843 mips_cp1_names
= mips_cp1_names_numeric
;
844 mips_hwr_names
= mips_hwr_names_numeric
;
847 /* Set ISA, architecture, and cp0 register names as best we can. */
848 #if ! SYMTAB_AVAILABLE
849 /* This is running out on a target machine, not in a host tool.
850 FIXME: Where does mips_target_info come from? */
851 target_processor
= mips_target_info
.processor
;
852 mips_isa
= mips_target_info
.isa
;
853 mips_ase
= mips_target_info
.ase
;
855 chosen_arch
= choose_arch_by_number (info
->mach
);
856 if (chosen_arch
!= NULL
)
858 mips_processor
= chosen_arch
->processor
;
859 mips_isa
= chosen_arch
->isa
;
860 mips_ase
= chosen_arch
->ase
;
861 mips_cp0_names
= chosen_arch
->cp0_names
;
862 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
863 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
864 mips_cp1_names
= chosen_arch
->cp1_names
;
865 mips_hwr_names
= chosen_arch
->hwr_names
;
868 /* Update settings according to the ELF file header flags. */
869 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
871 struct bfd
*abfd
= info
->section
->owner
;
872 Elf_Internal_Ehdr
*header
= elf_elfheader (abfd
);
873 Elf_Internal_ABIFlags_v0
*abiflags
= NULL
;
875 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
876 because we won't then have a MIPS/ELF BFD, however we need
877 to guard against a link error in a `--enable-targets=...'
878 configuration with a 32-bit host where the MIPS target is
879 a secondary, or with MIPS/ECOFF configurations. */
880 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
881 abiflags
= bfd_mips_elf_get_abiflags (abfd
);
883 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
884 if (is_newabi (header
))
885 mips_gpr_names
= mips_gpr_names_newabi
;
886 /* If a microMIPS binary, then don't use MIPS16 bindings. */
887 micromips_ase
= is_micromips (header
);
888 /* OR in any extra ASE flags set in ELF file structures. */
890 mips_ase
|= mips_convert_abiflags_ases (abiflags
->ases
);
891 else if (header
->e_flags
& EF_MIPS_ARCH_ASE_MDMX
)
892 mips_ase
|= ASE_MDMX
;
895 mips_ase
|= mips_calculate_combination_ases (mips_ase
);
898 /* Parse an ASE disassembler option and set the corresponding global
899 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
902 parse_mips_ase_option (const char *option
)
904 if (CONST_STRNEQ (option
, "msa"))
907 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
908 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R3
909 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R5
910 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
)
911 mips_ase
|= ASE_MSA64
;
915 if (CONST_STRNEQ (option
, "virt"))
917 mips_ase
|= ASE_VIRT
;
918 if (mips_isa
& ISA_MIPS64R2
919 || mips_isa
& ISA_MIPS64R3
920 || mips_isa
& ISA_MIPS64R5
921 || mips_isa
& ISA_MIPS64R6
)
922 mips_ase
|= ASE_VIRT64
;
926 if (CONST_STRNEQ (option
, "xpa"))
936 parse_mips_dis_option (const char *option
, unsigned int len
)
938 unsigned int i
, optionlen
, vallen
;
940 const struct mips_abi_choice
*chosen_abi
;
941 const struct mips_arch_choice
*chosen_arch
;
943 /* Try to match options that are simple flags */
944 if (CONST_STRNEQ (option
, "no-aliases"))
950 if (parse_mips_ase_option (option
))
952 mips_ase
|= mips_calculate_combination_ases (mips_ase
);
956 /* Look for the = that delimits the end of the option name. */
957 for (i
= 0; i
< len
; i
++)
958 if (option
[i
] == '=')
961 if (i
== 0) /* Invalid option: no name before '='. */
963 if (i
== len
) /* Invalid option: no '='. */
965 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
969 val
= option
+ (optionlen
+ 1);
970 vallen
= len
- (optionlen
+ 1);
972 if (strncmp ("gpr-names", option
, optionlen
) == 0
973 && strlen ("gpr-names") == optionlen
)
975 chosen_abi
= choose_abi_by_name (val
, vallen
);
976 if (chosen_abi
!= NULL
)
977 mips_gpr_names
= chosen_abi
->gpr_names
;
981 if (strncmp ("fpr-names", option
, optionlen
) == 0
982 && strlen ("fpr-names") == optionlen
)
984 chosen_abi
= choose_abi_by_name (val
, vallen
);
985 if (chosen_abi
!= NULL
)
986 mips_fpr_names
= chosen_abi
->fpr_names
;
990 if (strncmp ("cp0-names", option
, optionlen
) == 0
991 && strlen ("cp0-names") == optionlen
)
993 chosen_arch
= choose_arch_by_name (val
, vallen
);
994 if (chosen_arch
!= NULL
)
996 mips_cp0_names
= chosen_arch
->cp0_names
;
997 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
998 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
1003 if (strncmp ("cp1-names", option
, optionlen
) == 0
1004 && strlen ("cp1-names") == optionlen
)
1006 chosen_arch
= choose_arch_by_name (val
, vallen
);
1007 if (chosen_arch
!= NULL
)
1008 mips_cp1_names
= chosen_arch
->cp1_names
;
1012 if (strncmp ("hwr-names", option
, optionlen
) == 0
1013 && strlen ("hwr-names") == optionlen
)
1015 chosen_arch
= choose_arch_by_name (val
, vallen
);
1016 if (chosen_arch
!= NULL
)
1017 mips_hwr_names
= chosen_arch
->hwr_names
;
1021 if (strncmp ("reg-names", option
, optionlen
) == 0
1022 && strlen ("reg-names") == optionlen
)
1024 /* We check both ABI and ARCH here unconditionally, so
1025 that "numeric" will do the desirable thing: select
1026 numeric register names for all registers. Other than
1027 that, a given name probably won't match both. */
1028 chosen_abi
= choose_abi_by_name (val
, vallen
);
1029 if (chosen_abi
!= NULL
)
1031 mips_gpr_names
= chosen_abi
->gpr_names
;
1032 mips_fpr_names
= chosen_abi
->fpr_names
;
1034 chosen_arch
= choose_arch_by_name (val
, vallen
);
1035 if (chosen_arch
!= NULL
)
1037 mips_cp0_names
= chosen_arch
->cp0_names
;
1038 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
1039 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
1040 mips_cp1_names
= chosen_arch
->cp1_names
;
1041 mips_hwr_names
= chosen_arch
->hwr_names
;
1046 /* Invalid option. */
1050 parse_mips_dis_options (const char *options
)
1052 const char *option_end
;
1054 if (options
== NULL
)
1057 while (*options
!= '\0')
1059 /* Skip empty options. */
1060 if (*options
== ',')
1066 /* We know that *options is neither NUL or a comma. */
1067 option_end
= options
+ 1;
1068 while (*option_end
!= ',' && *option_end
!= '\0')
1071 parse_mips_dis_option (options
, option_end
- options
);
1073 /* Go on to the next one. If option_end points to a comma, it
1074 will be skipped above. */
1075 options
= option_end
;
1079 static const struct mips_cp0sel_name
*
1080 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
1082 unsigned int cp0reg
,
1087 for (i
= 0; i
< len
; i
++)
1088 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
1093 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1096 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
1097 enum mips_reg_operand_type type
, int regno
)
1102 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
1106 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
1110 if (opcode
->pinfo
& (FP_D
| FP_S
))
1111 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
1113 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
1117 if (opcode
->membership
& INSN_5400
)
1118 info
->fprintf_func (info
->stream
, "$f%d", regno
);
1120 info
->fprintf_func (info
->stream
, "$v%d", regno
);
1124 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
1128 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1129 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
1130 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
1131 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
1133 info
->fprintf_func (info
->stream
, "$%d", regno
);
1137 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1141 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1145 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1148 case OP_REG_R5900_I
:
1149 info
->fprintf_func (info
->stream
, "$I");
1152 case OP_REG_R5900_Q
:
1153 info
->fprintf_func (info
->stream
, "$Q");
1156 case OP_REG_R5900_R
:
1157 info
->fprintf_func (info
->stream
, "$R");
1160 case OP_REG_R5900_ACC
:
1161 info
->fprintf_func (info
->stream
, "$ACC");
1165 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1168 case OP_REG_MSA_CTRL
:
1169 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1175 /* Used to track the state carried over from previous operands in
1177 struct mips_print_arg_state
{
1178 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1179 where the value is known to be unsigned and small. */
1180 unsigned int last_int
;
1182 /* The type and number of the last OP_REG seen. We only use this for
1183 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1184 enum mips_reg_operand_type last_reg_type
;
1185 unsigned int last_regno
;
1186 unsigned int dest_regno
;
1187 unsigned int seen_dest
;
1190 /* Initialize STATE for the start of an instruction. */
1193 init_print_arg_state (struct mips_print_arg_state
*state
)
1195 memset (state
, 0, sizeof (*state
));
1198 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1199 whose value is given by UVAL. */
1202 print_vu0_channel (struct disassemble_info
*info
,
1203 const struct mips_operand
*operand
, unsigned int uval
)
1205 if (operand
->size
== 4)
1206 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1207 uval
& 8 ? "x" : "",
1208 uval
& 4 ? "y" : "",
1209 uval
& 2 ? "z" : "",
1210 uval
& 1 ? "w" : "");
1211 else if (operand
->size
== 2)
1212 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1217 /* Record information about a register operand. */
1220 mips_seen_register (struct mips_print_arg_state
*state
,
1222 enum mips_reg_operand_type reg_type
)
1224 state
->last_reg_type
= reg_type
;
1225 state
->last_regno
= regno
;
1227 if (!state
->seen_dest
)
1229 state
->seen_dest
= 1;
1230 state
->dest_regno
= regno
;
1234 /* Print SAVE/RESTORE instruction operands according to the argument
1235 register mask AMASK, the number of static registers saved NSREG,
1236 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1237 and the frame size FRAME_SIZE. */
1240 mips_print_save_restore (struct disassemble_info
*info
, unsigned int amask
,
1241 unsigned int nsreg
, unsigned int ra
,
1242 unsigned int s0
, unsigned int s1
,
1243 unsigned int frame_size
)
1245 const fprintf_ftype infprintf
= info
->fprintf_func
;
1246 unsigned int nargs
, nstatics
, smask
, i
, j
;
1247 void *is
= info
->stream
;
1250 if (amask
== MIPS_SVRS_ALL_ARGS
)
1255 else if (amask
== MIPS_SVRS_ALL_STATICS
)
1263 nstatics
= amask
& 3;
1269 infprintf (is
, "%s", mips_gpr_names
[4]);
1271 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1275 infprintf (is
, "%s%d", sep
, frame_size
);
1278 infprintf (is
, ",%s", mips_gpr_names
[31]);
1285 if (nsreg
> 0) /* $s2-$s8 */
1286 smask
|= ((1 << nsreg
) - 1) << 2;
1288 for (i
= 0; i
< 9; i
++)
1289 if (smask
& (1 << i
))
1291 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1292 /* Skip over string of set bits. */
1293 for (j
= i
; smask
& (2 << j
); j
++)
1296 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1299 /* Statics $ax - $a3. */
1301 infprintf (is
, ",%s", mips_gpr_names
[7]);
1302 else if (nstatics
> 0)
1303 infprintf (is
, ",%s-%s",
1304 mips_gpr_names
[7 - nstatics
+ 1],
1309 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1310 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1311 the base address for OP_PCREL operands. */
1314 print_insn_arg (struct disassemble_info
*info
,
1315 struct mips_print_arg_state
*state
,
1316 const struct mips_opcode
*opcode
,
1317 const struct mips_operand
*operand
,
1321 const fprintf_ftype infprintf
= info
->fprintf_func
;
1322 void *is
= info
->stream
;
1324 switch (operand
->type
)
1328 const struct mips_int_operand
*int_op
;
1330 int_op
= (const struct mips_int_operand
*) operand
;
1331 uval
= mips_decode_int_operand (int_op
, uval
);
1332 state
->last_int
= uval
;
1333 if (int_op
->print_hex
)
1334 infprintf (is
, "0x%x", uval
);
1336 infprintf (is
, "%d", uval
);
1342 const struct mips_mapped_int_operand
*mint_op
;
1344 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1345 uval
= mint_op
->int_map
[uval
];
1346 state
->last_int
= uval
;
1347 if (mint_op
->print_hex
)
1348 infprintf (is
, "0x%x", uval
);
1350 infprintf (is
, "%d", uval
);
1356 const struct mips_msb_operand
*msb_op
;
1358 msb_op
= (const struct mips_msb_operand
*) operand
;
1359 uval
+= msb_op
->bias
;
1360 if (msb_op
->add_lsb
)
1361 uval
-= state
->last_int
;
1362 infprintf (is
, "0x%x", uval
);
1367 case OP_OPTIONAL_REG
:
1369 const struct mips_reg_operand
*reg_op
;
1371 reg_op
= (const struct mips_reg_operand
*) operand
;
1372 uval
= mips_decode_reg_operand (reg_op
, uval
);
1373 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1375 mips_seen_register (state
, uval
, reg_op
->reg_type
);
1381 const struct mips_reg_pair_operand
*pair_op
;
1383 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1384 print_reg (info
, opcode
, pair_op
->reg_type
,
1385 pair_op
->reg1_map
[uval
]);
1386 infprintf (is
, ",");
1387 print_reg (info
, opcode
, pair_op
->reg_type
,
1388 pair_op
->reg2_map
[uval
]);
1394 const struct mips_pcrel_operand
*pcrel_op
;
1396 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1397 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1399 /* For jumps and branches clear the ISA bit except for
1400 the GDB disassembler. */
1401 if (pcrel_op
->include_isa_bit
1402 && info
->flavour
!= bfd_target_unknown_flavour
)
1405 (*info
->print_address_func
) (info
->target
, info
);
1410 infprintf (is
, "%d", uval
);
1413 case OP_ADDIUSP_INT
:
1417 sval
= mips_signed_operand (operand
, uval
) * 4;
1418 if (sval
>= -8 && sval
< 8)
1420 infprintf (is
, "%d", sval
);
1424 case OP_CLO_CLZ_DEST
:
1426 unsigned int reg1
, reg2
;
1430 /* If one is zero use the other. */
1431 if (reg1
== reg2
|| reg2
== 0)
1432 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1434 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1436 /* Bogus, result depends on processor. */
1437 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1438 mips_gpr_names
[reg2
]);
1444 case OP_NON_ZERO_REG
:
1446 print_reg (info
, opcode
, OP_REG_GP
, uval
& 31);
1447 mips_seen_register (state
, uval
, OP_REG_GP
);
1451 case OP_LWM_SWM_LIST
:
1452 if (operand
->size
== 2)
1455 infprintf (is
, "%s,%s",
1457 mips_gpr_names
[31]);
1459 infprintf (is
, "%s-%s,%s",
1461 mips_gpr_names
[16 + uval
],
1462 mips_gpr_names
[31]);
1468 s_reg_encode
= uval
& 0xf;
1469 if (s_reg_encode
!= 0)
1471 if (s_reg_encode
== 1)
1472 infprintf (is
, "%s", mips_gpr_names
[16]);
1473 else if (s_reg_encode
< 9)
1474 infprintf (is
, "%s-%s",
1476 mips_gpr_names
[15 + s_reg_encode
]);
1477 else if (s_reg_encode
== 9)
1478 infprintf (is
, "%s-%s,%s",
1481 mips_gpr_names
[30]);
1483 infprintf (is
, "UNKNOWN");
1486 if (uval
& 0x10) /* For ra. */
1488 if (s_reg_encode
== 0)
1489 infprintf (is
, "%s", mips_gpr_names
[31]);
1491 infprintf (is
, ",%s", mips_gpr_names
[31]);
1496 case OP_ENTRY_EXIT_LIST
:
1499 unsigned int amask
, smask
;
1502 amask
= (uval
>> 3) & 7;
1503 if (amask
> 0 && amask
< 5)
1505 infprintf (is
, "%s", mips_gpr_names
[4]);
1507 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1511 smask
= (uval
>> 1) & 3;
1514 infprintf (is
, "%s??", sep
);
1519 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1521 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1527 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1531 if (amask
== 5 || amask
== 6)
1533 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1535 infprintf (is
, "-%s", mips_fpr_names
[1]);
1540 case OP_SAVE_RESTORE_LIST
:
1541 /* Should be handled by the caller due to complex behavior. */
1544 case OP_MDMX_IMM_REG
:
1550 if ((vsel
& 0x10) == 0)
1555 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1556 if ((vsel
& 1) == 0)
1558 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1559 infprintf (is
, "[%d]", vsel
>> 1);
1561 else if ((vsel
& 0x08) == 0)
1562 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1564 infprintf (is
, "0x%x", uval
);
1568 case OP_REPEAT_PREV_REG
:
1569 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1572 case OP_REPEAT_DEST_REG
:
1573 print_reg (info
, opcode
, state
->last_reg_type
, state
->dest_regno
);
1577 infprintf (is
, "$pc");
1581 print_reg (info
, opcode
, OP_REG_GP
, 28);
1585 case OP_VU0_MATCH_SUFFIX
:
1586 print_vu0_channel (info
, operand
, uval
);
1590 infprintf (is
, "[%d]", uval
);
1594 infprintf (is
, "[");
1595 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1596 infprintf (is
, "]");
1601 /* Validate the arguments for INSN, which is described by OPCODE.
1602 Use DECODE_OPERAND to get the encoding of each operand. */
1605 validate_insn_args (const struct mips_opcode
*opcode
,
1606 const struct mips_operand
*(*decode_operand
) (const char *),
1609 struct mips_print_arg_state state
;
1610 const struct mips_operand
*operand
;
1614 init_print_arg_state (&state
);
1615 for (s
= opcode
->args
; *s
; ++s
)
1629 operand
= decode_operand (s
);
1633 uval
= mips_extract_operand (operand
, insn
);
1634 switch (operand
->type
)
1637 case OP_OPTIONAL_REG
:
1639 const struct mips_reg_operand
*reg_op
;
1641 reg_op
= (const struct mips_reg_operand
*) operand
;
1642 uval
= mips_decode_reg_operand (reg_op
, uval
);
1643 mips_seen_register (&state
, uval
, reg_op
->reg_type
);
1649 unsigned int reg1
, reg2
;
1654 if (reg1
!= reg2
|| reg1
== 0)
1661 const struct mips_check_prev_operand
*prev_op
;
1663 prev_op
= (const struct mips_check_prev_operand
*) operand
;
1665 if (!prev_op
->zero_ok
&& uval
== 0)
1668 if (((prev_op
->less_than_ok
&& uval
< state
.last_regno
)
1669 || (prev_op
->greater_than_ok
&& uval
> state
.last_regno
)
1670 || (prev_op
->equal_ok
&& uval
== state
.last_regno
)))
1676 case OP_NON_ZERO_REG
:
1689 case OP_ADDIUSP_INT
:
1690 case OP_CLO_CLZ_DEST
:
1691 case OP_LWM_SWM_LIST
:
1692 case OP_ENTRY_EXIT_LIST
:
1693 case OP_MDMX_IMM_REG
:
1694 case OP_REPEAT_PREV_REG
:
1695 case OP_REPEAT_DEST_REG
:
1699 case OP_VU0_MATCH_SUFFIX
:
1702 case OP_SAVE_RESTORE_LIST
:
1706 if (*s
== 'm' || *s
== '+' || *s
== '-')
1713 /* Print the arguments for INSN, which is described by OPCODE.
1714 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1715 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1716 operand is for a branch or jump. */
1719 print_insn_args (struct disassemble_info
*info
,
1720 const struct mips_opcode
*opcode
,
1721 const struct mips_operand
*(*decode_operand
) (const char *),
1722 unsigned int insn
, bfd_vma insn_pc
, unsigned int length
)
1724 const fprintf_ftype infprintf
= info
->fprintf_func
;
1725 void *is
= info
->stream
;
1726 struct mips_print_arg_state state
;
1727 const struct mips_operand
*operand
;
1730 init_print_arg_state (&state
);
1731 for (s
= opcode
->args
; *s
; ++s
)
1738 infprintf (is
, "%c", *s
);
1743 infprintf (is
, "%c%c", *s
, *s
);
1747 operand
= decode_operand (s
);
1750 /* xgettext:c-format */
1752 _("# internal error, undefined operand in `%s %s'"),
1753 opcode
->name
, opcode
->args
);
1757 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1759 /* Handle this case here because of the complex behavior. */
1760 unsigned int amask
= (insn
>> 15) & 0xf;
1761 unsigned int nsreg
= (insn
>> 23) & 0x7;
1762 unsigned int ra
= insn
& 0x1000; /* $ra */
1763 unsigned int s0
= insn
& 0x800; /* $s0 */
1764 unsigned int s1
= insn
& 0x400; /* $s1 */
1765 unsigned int frame_size
= (((insn
>> 15) & 0xf0)
1766 | ((insn
>> 6) & 0x0f)) * 8;
1767 mips_print_save_restore (info
, amask
, nsreg
, ra
, s0
, s1
,
1770 else if (operand
->type
== OP_REG
1773 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1775 /* Coprocessor register 0 with sel field. */
1776 const struct mips_cp0sel_name
*n
;
1777 unsigned int reg
, sel
;
1779 reg
= mips_extract_operand (operand
, insn
);
1781 operand
= decode_operand (s
);
1782 sel
= mips_extract_operand (operand
, insn
);
1784 /* CP0 register including 'sel' code for mftc0, to be
1785 printed textually if known. If not known, print both
1786 CP0 register name and sel numerically since CP0 register
1787 with sel 0 may have a name unrelated to register being
1789 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1790 mips_cp0sel_names_len
,
1793 infprintf (is
, "%s", n
->name
);
1795 infprintf (is
, "$%d,%d", reg
, sel
);
1799 bfd_vma base_pc
= insn_pc
;
1801 /* Adjust the PC relative base so that branch/jump insns use
1802 the following PC as the base but genuinely PC relative
1803 operands use the current PC. */
1804 if (operand
->type
== OP_PCREL
)
1806 const struct mips_pcrel_operand
*pcrel_op
;
1808 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1809 /* The include_isa_bit flag is sufficient to distinguish
1810 branch/jump from other PC relative operands. */
1811 if (pcrel_op
->include_isa_bit
)
1815 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1816 mips_extract_operand (operand
, insn
));
1818 if (*s
== 'm' || *s
== '+' || *s
== '-')
1825 /* Print the mips instruction at address MEMADDR in debugged memory,
1826 on using INFO. Returns length of the instruction, in bytes, which is
1827 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1828 this is little-endian code. */
1831 print_insn_mips (bfd_vma memaddr
,
1833 struct disassemble_info
*info
)
1835 #define GET_OP(insn, field) \
1836 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1837 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1838 const fprintf_ftype infprintf
= info
->fprintf_func
;
1839 const struct mips_opcode
*op
;
1840 static bfd_boolean init
= 0;
1841 void *is
= info
->stream
;
1843 /* Build a hash table to shorten the search time. */
1848 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1850 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1852 if (op
->pinfo
== INSN_MACRO
1853 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1855 if (i
== GET_OP (op
->match
, OP
))
1866 info
->bytes_per_chunk
= INSNLEN
;
1867 info
->display_endian
= info
->endian
;
1868 info
->insn_info_valid
= 1;
1869 info
->branch_delay_insns
= 0;
1870 info
->data_size
= 0;
1871 info
->insn_type
= dis_nonbranch
;
1875 op
= mips_hash
[GET_OP (word
, OP
)];
1878 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1880 if (op
->pinfo
!= INSN_MACRO
1881 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1882 && (word
& op
->mask
) == op
->match
)
1884 /* We always disassemble the jalx instruction, except for MIPS r6. */
1885 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1886 && (strcmp (op
->name
, "jalx")
1887 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS32R6
1888 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
))
1891 /* Figure out instruction type and branch delay information. */
1892 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1894 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1895 info
->insn_type
= dis_jsr
;
1897 info
->insn_type
= dis_branch
;
1898 info
->branch_delay_insns
= 1;
1900 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1901 | INSN_COND_BRANCH_LIKELY
)) != 0)
1903 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1904 info
->insn_type
= dis_condjsr
;
1906 info
->insn_type
= dis_condbranch
;
1907 info
->branch_delay_insns
= 1;
1909 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1910 | INSN_LOAD_MEMORY
)) != 0)
1911 info
->insn_type
= dis_dref
;
1913 if (!validate_insn_args (op
, decode_mips_operand
, word
))
1916 infprintf (is
, "%s", op
->name
);
1917 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1921 infprintf (is
, ".");
1922 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1923 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1928 infprintf (is
, "\t");
1929 print_insn_args (info
, op
, decode_mips_operand
, word
,
1939 /* Handle undefined instructions. */
1940 info
->insn_type
= dis_noninsn
;
1941 infprintf (is
, "0x%x", word
);
1945 /* Disassemble an operand for a mips16 instruction. */
1948 print_mips16_insn_arg (struct disassemble_info
*info
,
1949 struct mips_print_arg_state
*state
,
1950 const struct mips_opcode
*opcode
,
1951 char type
, bfd_vma memaddr
,
1952 unsigned insn
, bfd_boolean use_extend
,
1953 unsigned extend
, bfd_boolean is_offset
)
1955 const fprintf_ftype infprintf
= info
->fprintf_func
;
1956 void *is
= info
->stream
;
1957 const struct mips_operand
*operand
, *ext_operand
;
1958 unsigned short ext_size
;
1970 infprintf (is
, "%c", type
);
1974 operand
= decode_mips16_operand (type
, FALSE
);
1977 /* xgettext:c-format */
1978 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
1979 opcode
->name
, opcode
->args
);
1983 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1985 /* Handle this case here because of the complex interaction
1986 with the EXTEND opcode. */
1987 unsigned int amask
= extend
& 0xf;
1988 unsigned int nsreg
= (extend
>> 8) & 0x7;
1989 unsigned int ra
= insn
& 0x40; /* $ra */
1990 unsigned int s0
= insn
& 0x20; /* $s0 */
1991 unsigned int s1
= insn
& 0x10; /* $s1 */
1992 unsigned int frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
1993 if (frame_size
== 0 && !use_extend
)
1995 mips_print_save_restore (info
, amask
, nsreg
, ra
, s0
, s1
, frame_size
);
1999 if (is_offset
&& operand
->type
== OP_INT
)
2001 const struct mips_int_operand
*int_op
;
2003 int_op
= (const struct mips_int_operand
*) operand
;
2004 info
->insn_type
= dis_dref
;
2005 info
->data_size
= 1 << int_op
->shift
;
2011 ext_operand
= decode_mips16_operand (type
, TRUE
);
2012 if (ext_operand
!= operand
2013 || (operand
->type
== OP_INT
&& operand
->lsb
== 0
2014 && mips_opcode_32bit_p (opcode
)))
2016 ext_size
= ext_operand
->size
;
2017 operand
= ext_operand
;
2020 if (operand
->size
== 26)
2021 uval
= ((extend
& 0x1f) << 21) | ((extend
& 0x3e0) << 11) | insn
;
2022 else if (ext_size
== 16 || ext_size
== 9)
2023 uval
= ((extend
& 0x1f) << 11) | (extend
& 0x7e0) | (insn
& 0x1f);
2024 else if (ext_size
== 15)
2025 uval
= ((extend
& 0xf) << 11) | (extend
& 0x7f0) | (insn
& 0xf);
2026 else if (ext_size
== 6)
2027 uval
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
2029 uval
= mips_extract_operand (operand
, (extend
<< 16) | insn
);
2031 uval
&= (1U << ext_size
) - 1;
2033 baseaddr
= memaddr
+ 2;
2034 if (operand
->type
== OP_PCREL
)
2036 const struct mips_pcrel_operand
*pcrel_op
;
2038 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
2039 if (!pcrel_op
->include_isa_bit
&& use_extend
)
2040 baseaddr
= memaddr
- 2;
2041 else if (!pcrel_op
->include_isa_bit
)
2045 /* If this instruction is in the delay slot of a JAL/JALX
2046 instruction, the base address is the address of the
2047 JAL/JALX instruction. If it is in the delay slot of
2048 a JR/JALR instruction, the base address is the address
2049 of the JR/JALR instruction. This test is unreliable:
2050 we have no way of knowing whether the previous word is
2051 instruction or data. */
2052 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
2053 && (((info
->endian
== BFD_ENDIAN_BIG
2054 ? bfd_getb16 (buffer
)
2055 : bfd_getl16 (buffer
))
2056 & 0xf800) == 0x1800))
2057 baseaddr
= memaddr
- 4;
2058 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
2060 && (((info
->endian
== BFD_ENDIAN_BIG
2061 ? bfd_getb16 (buffer
)
2062 : bfd_getl16 (buffer
))
2063 & 0xf89f) == 0xe800)
2064 && (((info
->endian
== BFD_ENDIAN_BIG
2065 ? bfd_getb16 (buffer
)
2066 : bfd_getl16 (buffer
))
2067 & 0x0060) != 0x0060))
2068 baseaddr
= memaddr
- 2;
2074 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
2080 /* Check if the given address is the last word of a MIPS16 PLT entry.
2081 This word is data and depending on the value it may interfere with
2082 disassembly of further PLT entries. We make use of the fact PLT
2083 symbols are marked BSF_SYNTHETIC. */
2085 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2089 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2090 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2096 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2105 /* Disassemble mips16 instructions. */
2108 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2110 const fprintf_ftype infprintf
= info
->fprintf_func
;
2113 const struct mips_opcode
*op
, *opend
;
2114 struct mips_print_arg_state state
;
2115 void *is
= info
->stream
;
2116 bfd_boolean have_second
;
2117 bfd_boolean extend_only
;
2118 unsigned int second
;
2122 info
->bytes_per_chunk
= 2;
2123 info
->display_endian
= info
->endian
;
2124 info
->insn_info_valid
= 1;
2125 info
->branch_delay_insns
= 0;
2126 info
->data_size
= 0;
2130 #define GET_OP(insn, field) \
2131 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2132 /* Decode PLT entry's GOT slot address word. */
2133 if (is_mips16_plt_tail (info
, memaddr
))
2135 info
->insn_type
= dis_noninsn
;
2136 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2139 unsigned int gotslot
;
2141 if (info
->endian
== BFD_ENDIAN_BIG
)
2142 gotslot
= bfd_getb32 (buffer
);
2144 gotslot
= bfd_getl32 (buffer
);
2145 infprintf (is
, ".word\t0x%x", gotslot
);
2152 info
->insn_type
= dis_nonbranch
;
2153 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2157 (*info
->memory_error_func
) (status
, memaddr
, info
);
2161 extend_only
= FALSE
;
2163 if (info
->endian
== BFD_ENDIAN_BIG
)
2164 first
= bfd_getb16 (buffer
);
2166 first
= bfd_getl16 (buffer
);
2168 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2172 if (info
->endian
== BFD_ENDIAN_BIG
)
2173 second
= bfd_getb16 (buffer
);
2175 second
= bfd_getl16 (buffer
);
2176 full
= (first
<< 16) | second
;
2180 have_second
= FALSE
;
2185 /* FIXME: Should probably use a hash table on the major opcode here. */
2187 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2188 for (op
= mips16_opcodes
; op
< opend
; op
++)
2190 enum match_kind match
;
2192 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
))
2195 if (op
->pinfo
== INSN_MACRO
2196 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
2198 else if (mips_opcode_32bit_p (op
))
2201 && (full
& op
->mask
) == op
->match
)
2206 else if ((first
& op
->mask
) == op
->match
)
2208 match
= MATCH_SHORT
;
2212 else if ((first
& 0xf800) == 0xf000
2215 && (second
& op
->mask
) == op
->match
)
2217 if (op
->pinfo2
& INSN2_SHORT_ONLY
)
2228 if (match
!= MATCH_NONE
)
2232 infprintf (is
, "%s", op
->name
);
2233 if (op
->args
[0] != '\0')
2234 infprintf (is
, "\t");
2236 init_print_arg_state (&state
);
2237 for (s
= op
->args
; *s
!= '\0'; s
++)
2241 && GET_OP (full
, RX
) == GET_OP (full
, RY
))
2243 /* Skip the register and the comma. */
2249 && GET_OP (full
, RZ
) == GET_OP (full
, RX
))
2251 /* Skip the register and the comma. */
2258 && op
->name
[strlen (op
->name
) - 1] == '0')
2260 /* Coprocessor register 0 with sel field. */
2261 const struct mips_cp0sel_name
*n
;
2262 const struct mips_operand
*operand
;
2263 unsigned int reg
, sel
;
2265 operand
= decode_mips16_operand (*s
, TRUE
);
2266 reg
= mips_extract_operand (operand
, (first
<< 16) | second
);
2268 operand
= decode_mips16_operand (*s
, TRUE
);
2269 sel
= mips_extract_operand (operand
, (first
<< 16) | second
);
2271 /* CP0 register including 'sel' code for mftc0, to be
2272 printed textually if known. If not known, print both
2273 CP0 register name and sel numerically since CP0 register
2274 with sel 0 may have a name unrelated to register being
2276 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2277 mips_cp0sel_names_len
,
2280 infprintf (is
, "%s", n
->name
);
2282 infprintf (is
, "$%d,%d", reg
, sel
);
2288 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
+ 2,
2289 second
, TRUE
, first
, s
[1] == '(');
2292 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
,
2293 first
, FALSE
, 0, s
[1] == '(');
2295 case MATCH_NONE
: /* Stop the compiler complaining. */
2300 /* Figure out branch instruction type and delay slot information. */
2301 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2302 info
->branch_delay_insns
= 1;
2303 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
2304 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
2306 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2307 info
->insn_type
= dis_jsr
;
2309 info
->insn_type
= dis_branch
;
2311 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
2312 info
->insn_type
= dis_condbranch
;
2314 return match
== MATCH_FULL
? 4 : 2;
2319 infprintf (is
, "0x%x", first
);
2320 info
->insn_type
= dis_noninsn
;
2325 /* Disassemble microMIPS instructions. */
2328 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2330 const fprintf_ftype infprintf
= info
->fprintf_func
;
2331 const struct mips_opcode
*op
, *opend
;
2332 void *is
= info
->stream
;
2334 unsigned int higher
;
2335 unsigned int length
;
2339 info
->bytes_per_chunk
= 2;
2340 info
->display_endian
= info
->endian
;
2341 info
->insn_info_valid
= 1;
2342 info
->branch_delay_insns
= 0;
2343 info
->data_size
= 0;
2344 info
->insn_type
= dis_nonbranch
;
2348 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2351 (*info
->memory_error_func
) (status
, memaddr
, info
);
2357 if (info
->endian
== BFD_ENDIAN_BIG
)
2358 insn
= bfd_getb16 (buffer
);
2360 insn
= bfd_getl16 (buffer
);
2362 if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2364 /* This is a 32-bit microMIPS instruction. */
2367 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2370 infprintf (is
, "micromips 0x%x", higher
);
2371 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2375 if (info
->endian
== BFD_ENDIAN_BIG
)
2376 insn
= bfd_getb16 (buffer
);
2378 insn
= bfd_getl16 (buffer
);
2380 insn
= insn
| (higher
<< 16);
2385 /* FIXME: Should probably use a hash table on the major opcode here. */
2387 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2388 for (op
= micromips_opcodes
; op
< opend
; op
++)
2390 if (op
->pinfo
!= INSN_MACRO
2391 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2392 && (insn
& op
->mask
) == op
->match
2393 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2394 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2396 if (!validate_insn_args (op
, decode_micromips_operand
, insn
))
2399 infprintf (is
, "%s", op
->name
);
2403 infprintf (is
, "\t");
2404 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2405 memaddr
+ 1, length
);
2408 /* Figure out instruction type and branch delay information. */
2410 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2411 info
->branch_delay_insns
= 1;
2412 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2413 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2415 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2416 info
->insn_type
= dis_jsr
;
2418 info
->insn_type
= dis_branch
;
2420 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2421 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2423 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2424 info
->insn_type
= dis_condjsr
;
2426 info
->insn_type
= dis_condbranch
;
2429 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2430 info
->insn_type
= dis_dref
;
2436 infprintf (is
, "0x%x", insn
);
2437 info
->insn_type
= dis_noninsn
;
2442 /* Return 1 if a symbol associated with the location being disassembled
2443 indicates a compressed mode, either MIPS16 or microMIPS, according to
2444 MICROMIPS_P. We iterate over all the symbols at the address being
2445 considered assuming if at least one of them indicates code compression,
2446 then such code has been genuinely produced here (other symbols could
2447 have been derived from function symbols defined elsewhere or could
2448 define data). Otherwise, return 0. */
2451 is_compressed_mode_p (struct disassemble_info
*info
, bfd_boolean micromips_p
)
2456 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2457 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2459 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2461 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2463 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2464 && info
->symtab
[i
]->section
== info
->section
)
2466 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2468 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2470 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2477 /* In an environment where we do not know the symbol type of the
2478 instruction we are forced to assume that the low order bit of the
2479 instructions' address may mark it as a mips16 instruction. If we
2480 are single stepping, or the pc is within the disassembled function,
2481 this works. Otherwise, we need a clue. Sometimes. */
2484 _print_insn_mips (bfd_vma memaddr
,
2485 struct disassemble_info
*info
,
2486 enum bfd_endian endianness
)
2488 bfd_byte buffer
[INSNLEN
];
2491 set_default_mips_dis_options (info
);
2492 parse_mips_dis_options (info
->disassembler_options
);
2494 if (info
->mach
== bfd_mach_mips16
)
2495 return print_insn_mips16 (memaddr
, info
);
2496 if (info
->mach
== bfd_mach_mips_micromips
)
2497 return print_insn_micromips (memaddr
, info
);
2500 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2501 /* Only a few tools will work this way. */
2505 return print_insn_micromips (memaddr
, info
);
2507 return print_insn_mips16 (memaddr
, info
);
2511 #if SYMTAB_AVAILABLE
2512 if (is_compressed_mode_p (info
, TRUE
))
2513 return print_insn_micromips (memaddr
, info
);
2514 if (is_compressed_mode_p (info
, FALSE
))
2515 return print_insn_mips16 (memaddr
, info
);
2518 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2523 if (endianness
== BFD_ENDIAN_BIG
)
2524 insn
= bfd_getb32 (buffer
);
2526 insn
= bfd_getl32 (buffer
);
2528 return print_insn_mips (memaddr
, insn
, info
);
2532 (*info
->memory_error_func
) (status
, memaddr
, info
);
2538 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2540 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2544 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2546 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2550 print_mips_disassembler_options (FILE *stream
)
2554 fprintf (stream
, _("\n\
2555 The following MIPS specific disassembler options are supported for use\n\
2556 with the -M switch (multiple options should be separated by commas):\n"));
2558 fprintf (stream
, _("\n\
2559 no-aliases Use canonical instruction forms.\n"));
2561 fprintf (stream
, _("\n\
2562 msa Recognize MSA instructions.\n"));
2564 fprintf (stream
, _("\n\
2565 virt Recognize the virtualization ASE instructions.\n"));
2567 fprintf (stream
, _("\n\
2568 xpa Recognize the eXtended Physical Address (XPA)\n\
2569 ASE instructions.\n"));
2571 fprintf (stream
, _("\n\
2572 gpr-names=ABI Print GPR names according to specified ABI.\n\
2573 Default: based on binary being disassembled.\n"));
2575 fprintf (stream
, _("\n\
2576 fpr-names=ABI Print FPR names according to specified ABI.\n\
2577 Default: numeric.\n"));
2579 fprintf (stream
, _("\n\
2580 cp0-names=ARCH Print CP0 register names according to\n\
2581 specified architecture.\n\
2582 Default: based on binary being disassembled.\n"));
2584 fprintf (stream
, _("\n\
2585 hwr-names=ARCH Print HWR names according to specified \n\
2587 Default: based on binary being disassembled.\n"));
2589 fprintf (stream
, _("\n\
2590 reg-names=ABI Print GPR and FPR names according to\n\
2591 specified ABI.\n"));
2593 fprintf (stream
, _("\n\
2594 reg-names=ARCH Print CP0 register and HWR names according to\n\
2595 specified architecture.\n"));
2597 fprintf (stream
, _("\n\
2598 For the options above, the following values are supported for \"ABI\":\n\
2600 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2601 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2602 fprintf (stream
, _("\n"));
2604 fprintf (stream
, _("\n\
2605 For the options above, The following values are supported for \"ARCH\":\n\
2607 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2608 if (*mips_arch_choices
[i
].name
!= '\0')
2609 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2610 fprintf (stream
, _("\n"));
2612 fprintf (stream
, _("\n"));