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
;
811 /* Calculate combination ASE flags from regular ASE flags. */
814 mips_calculate_combination_ases (unsigned long opcode_ases
)
816 unsigned long combination_ases
= 0;
818 if ((opcode_ases
& (ASE_MIPS16E2
| ASE_MT
)) == (ASE_MIPS16E2
| ASE_MT
))
819 combination_ases
|= ASE_MIPS16E2_MT
;
820 return combination_ases
;
824 set_default_mips_dis_options (struct disassemble_info
*info
)
826 const struct mips_arch_choice
*chosen_arch
;
828 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
829 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
830 CP0 register, and HWR names. */
831 mips_isa
= ISA_MIPS3
;
832 mips_processor
= CPU_R3000
;
835 mips_gpr_names
= mips_gpr_names_oldabi
;
836 mips_fpr_names
= mips_fpr_names_numeric
;
837 mips_cp0_names
= mips_cp0_names_numeric
;
838 mips_cp0sel_names
= NULL
;
839 mips_cp0sel_names_len
= 0;
840 mips_cp1_names
= mips_cp1_names_numeric
;
841 mips_hwr_names
= mips_hwr_names_numeric
;
844 /* Set ISA, architecture, and cp0 register names as best we can. */
845 #if ! SYMTAB_AVAILABLE
846 /* This is running out on a target machine, not in a host tool.
847 FIXME: Where does mips_target_info come from? */
848 target_processor
= mips_target_info
.processor
;
849 mips_isa
= mips_target_info
.isa
;
850 mips_ase
= mips_target_info
.ase
;
852 chosen_arch
= choose_arch_by_number (info
->mach
);
853 if (chosen_arch
!= NULL
)
855 mips_processor
= chosen_arch
->processor
;
856 mips_isa
= chosen_arch
->isa
;
857 mips_ase
= chosen_arch
->ase
;
858 mips_cp0_names
= chosen_arch
->cp0_names
;
859 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
860 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
861 mips_cp1_names
= chosen_arch
->cp1_names
;
862 mips_hwr_names
= chosen_arch
->hwr_names
;
865 /* Update settings according to the ELF file header flags. */
866 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
868 struct bfd
*abfd
= info
->section
->owner
;
869 Elf_Internal_Ehdr
*header
= elf_elfheader (abfd
);
870 Elf_Internal_ABIFlags_v0
*abiflags
= NULL
;
872 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
873 because we won't then have a MIPS/ELF BFD, however we need
874 to guard against a link error in a `--enable-targets=...'
875 configuration with a 32-bit host where the MIPS target is
876 a secondary, or with MIPS/ECOFF configurations. */
877 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
878 abiflags
= bfd_mips_elf_get_abiflags (abfd
);
880 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
881 if (is_newabi (header
))
882 mips_gpr_names
= mips_gpr_names_newabi
;
883 /* If a microMIPS binary, then don't use MIPS16 bindings. */
884 micromips_ase
= is_micromips (header
);
885 /* OR in any extra ASE flags set in ELF file structures. */
887 mips_ase
|= mips_convert_abiflags_ases (abiflags
->ases
);
888 else if (header
->e_flags
& EF_MIPS_ARCH_ASE_MDMX
)
889 mips_ase
|= ASE_MDMX
;
892 mips_ase
|= mips_calculate_combination_ases (mips_ase
);
896 parse_mips_dis_option (const char *option
, unsigned int len
)
898 unsigned int i
, optionlen
, vallen
;
900 const struct mips_abi_choice
*chosen_abi
;
901 const struct mips_arch_choice
*chosen_arch
;
903 /* Try to match options that are simple flags */
904 if (CONST_STRNEQ (option
, "no-aliases"))
910 if (CONST_STRNEQ (option
, "msa"))
913 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
914 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R3
915 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R5
916 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
)
917 mips_ase
|= ASE_MSA64
;
921 if (CONST_STRNEQ (option
, "virt"))
923 mips_ase
|= ASE_VIRT
;
924 if (mips_isa
& ISA_MIPS64R2
925 || mips_isa
& ISA_MIPS64R3
926 || mips_isa
& ISA_MIPS64R5
927 || mips_isa
& ISA_MIPS64R6
)
928 mips_ase
|= ASE_VIRT64
;
932 if (CONST_STRNEQ (option
, "xpa"))
939 /* Look for the = that delimits the end of the option name. */
940 for (i
= 0; i
< len
; i
++)
941 if (option
[i
] == '=')
944 if (i
== 0) /* Invalid option: no name before '='. */
946 if (i
== len
) /* Invalid option: no '='. */
948 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
952 val
= option
+ (optionlen
+ 1);
953 vallen
= len
- (optionlen
+ 1);
955 if (strncmp ("gpr-names", option
, optionlen
) == 0
956 && strlen ("gpr-names") == optionlen
)
958 chosen_abi
= choose_abi_by_name (val
, vallen
);
959 if (chosen_abi
!= NULL
)
960 mips_gpr_names
= chosen_abi
->gpr_names
;
964 if (strncmp ("fpr-names", option
, optionlen
) == 0
965 && strlen ("fpr-names") == optionlen
)
967 chosen_abi
= choose_abi_by_name (val
, vallen
);
968 if (chosen_abi
!= NULL
)
969 mips_fpr_names
= chosen_abi
->fpr_names
;
973 if (strncmp ("cp0-names", option
, optionlen
) == 0
974 && strlen ("cp0-names") == optionlen
)
976 chosen_arch
= choose_arch_by_name (val
, vallen
);
977 if (chosen_arch
!= NULL
)
979 mips_cp0_names
= chosen_arch
->cp0_names
;
980 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
981 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
986 if (strncmp ("cp1-names", option
, optionlen
) == 0
987 && strlen ("cp1-names") == optionlen
)
989 chosen_arch
= choose_arch_by_name (val
, vallen
);
990 if (chosen_arch
!= NULL
)
991 mips_cp1_names
= chosen_arch
->cp1_names
;
995 if (strncmp ("hwr-names", option
, optionlen
) == 0
996 && strlen ("hwr-names") == optionlen
)
998 chosen_arch
= choose_arch_by_name (val
, vallen
);
999 if (chosen_arch
!= NULL
)
1000 mips_hwr_names
= chosen_arch
->hwr_names
;
1004 if (strncmp ("reg-names", option
, optionlen
) == 0
1005 && strlen ("reg-names") == optionlen
)
1007 /* We check both ABI and ARCH here unconditionally, so
1008 that "numeric" will do the desirable thing: select
1009 numeric register names for all registers. Other than
1010 that, a given name probably won't match both. */
1011 chosen_abi
= choose_abi_by_name (val
, vallen
);
1012 if (chosen_abi
!= NULL
)
1014 mips_gpr_names
= chosen_abi
->gpr_names
;
1015 mips_fpr_names
= chosen_abi
->fpr_names
;
1017 chosen_arch
= choose_arch_by_name (val
, vallen
);
1018 if (chosen_arch
!= NULL
)
1020 mips_cp0_names
= chosen_arch
->cp0_names
;
1021 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
1022 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
1023 mips_cp1_names
= chosen_arch
->cp1_names
;
1024 mips_hwr_names
= chosen_arch
->hwr_names
;
1029 /* Invalid option. */
1033 parse_mips_dis_options (const char *options
)
1035 const char *option_end
;
1037 if (options
== NULL
)
1040 while (*options
!= '\0')
1042 /* Skip empty options. */
1043 if (*options
== ',')
1049 /* We know that *options is neither NUL or a comma. */
1050 option_end
= options
+ 1;
1051 while (*option_end
!= ',' && *option_end
!= '\0')
1054 parse_mips_dis_option (options
, option_end
- options
);
1056 /* Go on to the next one. If option_end points to a comma, it
1057 will be skipped above. */
1058 options
= option_end
;
1062 static const struct mips_cp0sel_name
*
1063 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
1065 unsigned int cp0reg
,
1070 for (i
= 0; i
< len
; i
++)
1071 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
1076 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1079 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
1080 enum mips_reg_operand_type type
, int regno
)
1085 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
1089 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
1093 if (opcode
->pinfo
& (FP_D
| FP_S
))
1094 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
1096 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
1100 if (opcode
->membership
& INSN_5400
)
1101 info
->fprintf_func (info
->stream
, "$f%d", regno
);
1103 info
->fprintf_func (info
->stream
, "$v%d", regno
);
1107 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
1111 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1112 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
1113 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
1114 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
1116 info
->fprintf_func (info
->stream
, "$%d", regno
);
1120 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1124 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1128 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1131 case OP_REG_R5900_I
:
1132 info
->fprintf_func (info
->stream
, "$I");
1135 case OP_REG_R5900_Q
:
1136 info
->fprintf_func (info
->stream
, "$Q");
1139 case OP_REG_R5900_R
:
1140 info
->fprintf_func (info
->stream
, "$R");
1143 case OP_REG_R5900_ACC
:
1144 info
->fprintf_func (info
->stream
, "$ACC");
1148 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1151 case OP_REG_MSA_CTRL
:
1152 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1158 /* Used to track the state carried over from previous operands in
1160 struct mips_print_arg_state
{
1161 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1162 where the value is known to be unsigned and small. */
1163 unsigned int last_int
;
1165 /* The type and number of the last OP_REG seen. We only use this for
1166 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1167 enum mips_reg_operand_type last_reg_type
;
1168 unsigned int last_regno
;
1169 unsigned int dest_regno
;
1170 unsigned int seen_dest
;
1173 /* Initialize STATE for the start of an instruction. */
1176 init_print_arg_state (struct mips_print_arg_state
*state
)
1178 memset (state
, 0, sizeof (*state
));
1181 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1182 whose value is given by UVAL. */
1185 print_vu0_channel (struct disassemble_info
*info
,
1186 const struct mips_operand
*operand
, unsigned int uval
)
1188 if (operand
->size
== 4)
1189 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1190 uval
& 8 ? "x" : "",
1191 uval
& 4 ? "y" : "",
1192 uval
& 2 ? "z" : "",
1193 uval
& 1 ? "w" : "");
1194 else if (operand
->size
== 2)
1195 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1200 /* Record information about a register operand. */
1203 mips_seen_register (struct mips_print_arg_state
*state
,
1205 enum mips_reg_operand_type reg_type
)
1207 state
->last_reg_type
= reg_type
;
1208 state
->last_regno
= regno
;
1210 if (!state
->seen_dest
)
1212 state
->seen_dest
= 1;
1213 state
->dest_regno
= regno
;
1217 /* Print SAVE/RESTORE instruction operands according to the argument
1218 register mask AMASK, the number of static registers saved NSREG,
1219 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1220 and the frame size FRAME_SIZE. */
1223 mips_print_save_restore (struct disassemble_info
*info
, unsigned int amask
,
1224 unsigned int nsreg
, unsigned int ra
,
1225 unsigned int s0
, unsigned int s1
,
1226 unsigned int frame_size
)
1228 const fprintf_ftype infprintf
= info
->fprintf_func
;
1229 unsigned int nargs
, nstatics
, smask
, i
, j
;
1230 void *is
= info
->stream
;
1233 if (amask
== MIPS_SVRS_ALL_ARGS
)
1238 else if (amask
== MIPS_SVRS_ALL_STATICS
)
1246 nstatics
= amask
& 3;
1252 infprintf (is
, "%s", mips_gpr_names
[4]);
1254 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1258 infprintf (is
, "%s%d", sep
, frame_size
);
1261 infprintf (is
, ",%s", mips_gpr_names
[31]);
1268 if (nsreg
> 0) /* $s2-$s8 */
1269 smask
|= ((1 << nsreg
) - 1) << 2;
1271 for (i
= 0; i
< 9; i
++)
1272 if (smask
& (1 << i
))
1274 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1275 /* Skip over string of set bits. */
1276 for (j
= i
; smask
& (2 << j
); j
++)
1279 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1282 /* Statics $ax - $a3. */
1284 infprintf (is
, ",%s", mips_gpr_names
[7]);
1285 else if (nstatics
> 0)
1286 infprintf (is
, ",%s-%s",
1287 mips_gpr_names
[7 - nstatics
+ 1],
1292 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1293 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1294 the base address for OP_PCREL operands. */
1297 print_insn_arg (struct disassemble_info
*info
,
1298 struct mips_print_arg_state
*state
,
1299 const struct mips_opcode
*opcode
,
1300 const struct mips_operand
*operand
,
1304 const fprintf_ftype infprintf
= info
->fprintf_func
;
1305 void *is
= info
->stream
;
1307 switch (operand
->type
)
1311 const struct mips_int_operand
*int_op
;
1313 int_op
= (const struct mips_int_operand
*) operand
;
1314 uval
= mips_decode_int_operand (int_op
, uval
);
1315 state
->last_int
= uval
;
1316 if (int_op
->print_hex
)
1317 infprintf (is
, "0x%x", uval
);
1319 infprintf (is
, "%d", uval
);
1325 const struct mips_mapped_int_operand
*mint_op
;
1327 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1328 uval
= mint_op
->int_map
[uval
];
1329 state
->last_int
= uval
;
1330 if (mint_op
->print_hex
)
1331 infprintf (is
, "0x%x", uval
);
1333 infprintf (is
, "%d", uval
);
1339 const struct mips_msb_operand
*msb_op
;
1341 msb_op
= (const struct mips_msb_operand
*) operand
;
1342 uval
+= msb_op
->bias
;
1343 if (msb_op
->add_lsb
)
1344 uval
-= state
->last_int
;
1345 infprintf (is
, "0x%x", uval
);
1350 case OP_OPTIONAL_REG
:
1352 const struct mips_reg_operand
*reg_op
;
1354 reg_op
= (const struct mips_reg_operand
*) operand
;
1355 uval
= mips_decode_reg_operand (reg_op
, uval
);
1356 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1358 mips_seen_register (state
, uval
, reg_op
->reg_type
);
1364 const struct mips_reg_pair_operand
*pair_op
;
1366 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1367 print_reg (info
, opcode
, pair_op
->reg_type
,
1368 pair_op
->reg1_map
[uval
]);
1369 infprintf (is
, ",");
1370 print_reg (info
, opcode
, pair_op
->reg_type
,
1371 pair_op
->reg2_map
[uval
]);
1377 const struct mips_pcrel_operand
*pcrel_op
;
1379 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1380 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1382 /* For jumps and branches clear the ISA bit except for
1383 the GDB disassembler. */
1384 if (pcrel_op
->include_isa_bit
1385 && info
->flavour
!= bfd_target_unknown_flavour
)
1388 (*info
->print_address_func
) (info
->target
, info
);
1393 infprintf (is
, "%d", uval
);
1396 case OP_ADDIUSP_INT
:
1400 sval
= mips_signed_operand (operand
, uval
) * 4;
1401 if (sval
>= -8 && sval
< 8)
1403 infprintf (is
, "%d", sval
);
1407 case OP_CLO_CLZ_DEST
:
1409 unsigned int reg1
, reg2
;
1413 /* If one is zero use the other. */
1414 if (reg1
== reg2
|| reg2
== 0)
1415 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1417 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1419 /* Bogus, result depends on processor. */
1420 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1421 mips_gpr_names
[reg2
]);
1427 case OP_NON_ZERO_REG
:
1429 print_reg (info
, opcode
, OP_REG_GP
, uval
& 31);
1430 mips_seen_register (state
, uval
, OP_REG_GP
);
1434 case OP_LWM_SWM_LIST
:
1435 if (operand
->size
== 2)
1438 infprintf (is
, "%s,%s",
1440 mips_gpr_names
[31]);
1442 infprintf (is
, "%s-%s,%s",
1444 mips_gpr_names
[16 + uval
],
1445 mips_gpr_names
[31]);
1451 s_reg_encode
= uval
& 0xf;
1452 if (s_reg_encode
!= 0)
1454 if (s_reg_encode
== 1)
1455 infprintf (is
, "%s", mips_gpr_names
[16]);
1456 else if (s_reg_encode
< 9)
1457 infprintf (is
, "%s-%s",
1459 mips_gpr_names
[15 + s_reg_encode
]);
1460 else if (s_reg_encode
== 9)
1461 infprintf (is
, "%s-%s,%s",
1464 mips_gpr_names
[30]);
1466 infprintf (is
, "UNKNOWN");
1469 if (uval
& 0x10) /* For ra. */
1471 if (s_reg_encode
== 0)
1472 infprintf (is
, "%s", mips_gpr_names
[31]);
1474 infprintf (is
, ",%s", mips_gpr_names
[31]);
1479 case OP_ENTRY_EXIT_LIST
:
1482 unsigned int amask
, smask
;
1485 amask
= (uval
>> 3) & 7;
1486 if (amask
> 0 && amask
< 5)
1488 infprintf (is
, "%s", mips_gpr_names
[4]);
1490 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1494 smask
= (uval
>> 1) & 3;
1497 infprintf (is
, "%s??", sep
);
1502 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1504 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1510 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1514 if (amask
== 5 || amask
== 6)
1516 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1518 infprintf (is
, "-%s", mips_fpr_names
[1]);
1523 case OP_SAVE_RESTORE_LIST
:
1524 /* Should be handled by the caller due to complex behavior. */
1527 case OP_MDMX_IMM_REG
:
1533 if ((vsel
& 0x10) == 0)
1538 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1539 if ((vsel
& 1) == 0)
1541 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1542 infprintf (is
, "[%d]", vsel
>> 1);
1544 else if ((vsel
& 0x08) == 0)
1545 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1547 infprintf (is
, "0x%x", uval
);
1551 case OP_REPEAT_PREV_REG
:
1552 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1555 case OP_REPEAT_DEST_REG
:
1556 print_reg (info
, opcode
, state
->last_reg_type
, state
->dest_regno
);
1560 infprintf (is
, "$pc");
1564 print_reg (info
, opcode
, OP_REG_GP
, 28);
1568 case OP_VU0_MATCH_SUFFIX
:
1569 print_vu0_channel (info
, operand
, uval
);
1573 infprintf (is
, "[%d]", uval
);
1577 infprintf (is
, "[");
1578 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1579 infprintf (is
, "]");
1584 /* Validate the arguments for INSN, which is described by OPCODE.
1585 Use DECODE_OPERAND to get the encoding of each operand. */
1588 validate_insn_args (const struct mips_opcode
*opcode
,
1589 const struct mips_operand
*(*decode_operand
) (const char *),
1592 struct mips_print_arg_state state
;
1593 const struct mips_operand
*operand
;
1597 init_print_arg_state (&state
);
1598 for (s
= opcode
->args
; *s
; ++s
)
1612 operand
= decode_operand (s
);
1616 uval
= mips_extract_operand (operand
, insn
);
1617 switch (operand
->type
)
1620 case OP_OPTIONAL_REG
:
1622 const struct mips_reg_operand
*reg_op
;
1624 reg_op
= (const struct mips_reg_operand
*) operand
;
1625 uval
= mips_decode_reg_operand (reg_op
, uval
);
1626 mips_seen_register (&state
, uval
, reg_op
->reg_type
);
1632 unsigned int reg1
, reg2
;
1637 if (reg1
!= reg2
|| reg1
== 0)
1644 const struct mips_check_prev_operand
*prev_op
;
1646 prev_op
= (const struct mips_check_prev_operand
*) operand
;
1648 if (!prev_op
->zero_ok
&& uval
== 0)
1651 if (((prev_op
->less_than_ok
&& uval
< state
.last_regno
)
1652 || (prev_op
->greater_than_ok
&& uval
> state
.last_regno
)
1653 || (prev_op
->equal_ok
&& uval
== state
.last_regno
)))
1659 case OP_NON_ZERO_REG
:
1672 case OP_ADDIUSP_INT
:
1673 case OP_CLO_CLZ_DEST
:
1674 case OP_LWM_SWM_LIST
:
1675 case OP_ENTRY_EXIT_LIST
:
1676 case OP_MDMX_IMM_REG
:
1677 case OP_REPEAT_PREV_REG
:
1678 case OP_REPEAT_DEST_REG
:
1682 case OP_VU0_MATCH_SUFFIX
:
1685 case OP_SAVE_RESTORE_LIST
:
1689 if (*s
== 'm' || *s
== '+' || *s
== '-')
1696 /* Print the arguments for INSN, which is described by OPCODE.
1697 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1698 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1699 operand is for a branch or jump. */
1702 print_insn_args (struct disassemble_info
*info
,
1703 const struct mips_opcode
*opcode
,
1704 const struct mips_operand
*(*decode_operand
) (const char *),
1705 unsigned int insn
, bfd_vma insn_pc
, unsigned int length
)
1707 const fprintf_ftype infprintf
= info
->fprintf_func
;
1708 void *is
= info
->stream
;
1709 struct mips_print_arg_state state
;
1710 const struct mips_operand
*operand
;
1713 init_print_arg_state (&state
);
1714 for (s
= opcode
->args
; *s
; ++s
)
1721 infprintf (is
, "%c", *s
);
1726 infprintf (is
, "%c%c", *s
, *s
);
1730 operand
= decode_operand (s
);
1733 /* xgettext:c-format */
1735 _("# internal error, undefined operand in `%s %s'"),
1736 opcode
->name
, opcode
->args
);
1740 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1742 /* Handle this case here because of the complex behavior. */
1743 unsigned int amask
= (insn
>> 15) & 0xf;
1744 unsigned int nsreg
= (insn
>> 23) & 0x7;
1745 unsigned int ra
= insn
& 0x1000; /* $ra */
1746 unsigned int s0
= insn
& 0x800; /* $s0 */
1747 unsigned int s1
= insn
& 0x400; /* $s1 */
1748 unsigned int frame_size
= (((insn
>> 15) & 0xf0)
1749 | ((insn
>> 6) & 0x0f)) * 8;
1750 mips_print_save_restore (info
, amask
, nsreg
, ra
, s0
, s1
,
1753 else if (operand
->type
== OP_REG
1756 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1758 /* Coprocessor register 0 with sel field. */
1759 const struct mips_cp0sel_name
*n
;
1760 unsigned int reg
, sel
;
1762 reg
= mips_extract_operand (operand
, insn
);
1764 operand
= decode_operand (s
);
1765 sel
= mips_extract_operand (operand
, insn
);
1767 /* CP0 register including 'sel' code for mftc0, to be
1768 printed textually if known. If not known, print both
1769 CP0 register name and sel numerically since CP0 register
1770 with sel 0 may have a name unrelated to register being
1772 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1773 mips_cp0sel_names_len
,
1776 infprintf (is
, "%s", n
->name
);
1778 infprintf (is
, "$%d,%d", reg
, sel
);
1782 bfd_vma base_pc
= insn_pc
;
1784 /* Adjust the PC relative base so that branch/jump insns use
1785 the following PC as the base but genuinely PC relative
1786 operands use the current PC. */
1787 if (operand
->type
== OP_PCREL
)
1789 const struct mips_pcrel_operand
*pcrel_op
;
1791 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1792 /* The include_isa_bit flag is sufficient to distinguish
1793 branch/jump from other PC relative operands. */
1794 if (pcrel_op
->include_isa_bit
)
1798 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1799 mips_extract_operand (operand
, insn
));
1801 if (*s
== 'm' || *s
== '+' || *s
== '-')
1808 /* Print the mips instruction at address MEMADDR in debugged memory,
1809 on using INFO. Returns length of the instruction, in bytes, which is
1810 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1811 this is little-endian code. */
1814 print_insn_mips (bfd_vma memaddr
,
1816 struct disassemble_info
*info
)
1818 #define GET_OP(insn, field) \
1819 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1820 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1821 const fprintf_ftype infprintf
= info
->fprintf_func
;
1822 const struct mips_opcode
*op
;
1823 static bfd_boolean init
= 0;
1824 void *is
= info
->stream
;
1826 /* Build a hash table to shorten the search time. */
1831 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1833 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1835 if (op
->pinfo
== INSN_MACRO
1836 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1838 if (i
== GET_OP (op
->match
, OP
))
1849 info
->bytes_per_chunk
= INSNLEN
;
1850 info
->display_endian
= info
->endian
;
1851 info
->insn_info_valid
= 1;
1852 info
->branch_delay_insns
= 0;
1853 info
->data_size
= 0;
1854 info
->insn_type
= dis_nonbranch
;
1858 op
= mips_hash
[GET_OP (word
, OP
)];
1861 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1863 if (op
->pinfo
!= INSN_MACRO
1864 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1865 && (word
& op
->mask
) == op
->match
)
1867 /* We always disassemble the jalx instruction, except for MIPS r6. */
1868 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1869 && (strcmp (op
->name
, "jalx")
1870 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS32R6
1871 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
))
1874 /* Figure out instruction type and branch delay information. */
1875 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1877 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1878 info
->insn_type
= dis_jsr
;
1880 info
->insn_type
= dis_branch
;
1881 info
->branch_delay_insns
= 1;
1883 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1884 | INSN_COND_BRANCH_LIKELY
)) != 0)
1886 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1887 info
->insn_type
= dis_condjsr
;
1889 info
->insn_type
= dis_condbranch
;
1890 info
->branch_delay_insns
= 1;
1892 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1893 | INSN_LOAD_MEMORY
)) != 0)
1894 info
->insn_type
= dis_dref
;
1896 if (!validate_insn_args (op
, decode_mips_operand
, word
))
1899 infprintf (is
, "%s", op
->name
);
1900 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1904 infprintf (is
, ".");
1905 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1906 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1911 infprintf (is
, "\t");
1912 print_insn_args (info
, op
, decode_mips_operand
, word
,
1922 /* Handle undefined instructions. */
1923 info
->insn_type
= dis_noninsn
;
1924 infprintf (is
, "0x%x", word
);
1928 /* Disassemble an operand for a mips16 instruction. */
1931 print_mips16_insn_arg (struct disassemble_info
*info
,
1932 struct mips_print_arg_state
*state
,
1933 const struct mips_opcode
*opcode
,
1934 char type
, bfd_vma memaddr
,
1935 unsigned insn
, bfd_boolean use_extend
,
1936 unsigned extend
, bfd_boolean is_offset
)
1938 const fprintf_ftype infprintf
= info
->fprintf_func
;
1939 void *is
= info
->stream
;
1940 const struct mips_operand
*operand
, *ext_operand
;
1941 unsigned short ext_size
;
1953 infprintf (is
, "%c", type
);
1957 operand
= decode_mips16_operand (type
, FALSE
);
1960 /* xgettext:c-format */
1961 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
1962 opcode
->name
, opcode
->args
);
1966 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1968 /* Handle this case here because of the complex interaction
1969 with the EXTEND opcode. */
1970 unsigned int amask
= extend
& 0xf;
1971 unsigned int nsreg
= (extend
>> 8) & 0x7;
1972 unsigned int ra
= insn
& 0x40; /* $ra */
1973 unsigned int s0
= insn
& 0x20; /* $s0 */
1974 unsigned int s1
= insn
& 0x10; /* $s1 */
1975 unsigned int frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
1976 if (frame_size
== 0 && !use_extend
)
1978 mips_print_save_restore (info
, amask
, nsreg
, ra
, s0
, s1
, frame_size
);
1982 if (is_offset
&& operand
->type
== OP_INT
)
1984 const struct mips_int_operand
*int_op
;
1986 int_op
= (const struct mips_int_operand
*) operand
;
1987 info
->insn_type
= dis_dref
;
1988 info
->data_size
= 1 << int_op
->shift
;
1994 ext_operand
= decode_mips16_operand (type
, TRUE
);
1995 if (ext_operand
!= operand
1996 || (operand
->type
== OP_INT
&& operand
->lsb
== 0
1997 && mips_opcode_32bit_p (opcode
)))
1999 ext_size
= ext_operand
->size
;
2000 operand
= ext_operand
;
2003 if (operand
->size
== 26)
2004 uval
= ((extend
& 0x1f) << 21) | ((extend
& 0x3e0) << 11) | insn
;
2005 else if (ext_size
== 16 || ext_size
== 9)
2006 uval
= ((extend
& 0x1f) << 11) | (extend
& 0x7e0) | (insn
& 0x1f);
2007 else if (ext_size
== 15)
2008 uval
= ((extend
& 0xf) << 11) | (extend
& 0x7f0) | (insn
& 0xf);
2009 else if (ext_size
== 6)
2010 uval
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
2012 uval
= mips_extract_operand (operand
, (extend
<< 16) | insn
);
2014 uval
&= (1U << ext_size
) - 1;
2016 baseaddr
= memaddr
+ 2;
2017 if (operand
->type
== OP_PCREL
)
2019 const struct mips_pcrel_operand
*pcrel_op
;
2021 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
2022 if (!pcrel_op
->include_isa_bit
&& use_extend
)
2023 baseaddr
= memaddr
- 2;
2024 else if (!pcrel_op
->include_isa_bit
)
2028 /* If this instruction is in the delay slot of a JAL/JALX
2029 instruction, the base address is the address of the
2030 JAL/JALX instruction. If it is in the delay slot of
2031 a JR/JALR instruction, the base address is the address
2032 of the JR/JALR instruction. This test is unreliable:
2033 we have no way of knowing whether the previous word is
2034 instruction or data. */
2035 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
2036 && (((info
->endian
== BFD_ENDIAN_BIG
2037 ? bfd_getb16 (buffer
)
2038 : bfd_getl16 (buffer
))
2039 & 0xf800) == 0x1800))
2040 baseaddr
= memaddr
- 4;
2041 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
2043 && (((info
->endian
== BFD_ENDIAN_BIG
2044 ? bfd_getb16 (buffer
)
2045 : bfd_getl16 (buffer
))
2046 & 0xf89f) == 0xe800)
2047 && (((info
->endian
== BFD_ENDIAN_BIG
2048 ? bfd_getb16 (buffer
)
2049 : bfd_getl16 (buffer
))
2050 & 0x0060) != 0x0060))
2051 baseaddr
= memaddr
- 2;
2057 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
2063 /* Check if the given address is the last word of a MIPS16 PLT entry.
2064 This word is data and depending on the value it may interfere with
2065 disassembly of further PLT entries. We make use of the fact PLT
2066 symbols are marked BSF_SYNTHETIC. */
2068 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2072 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2073 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2079 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2088 /* Disassemble mips16 instructions. */
2091 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2093 const fprintf_ftype infprintf
= info
->fprintf_func
;
2096 const struct mips_opcode
*op
, *opend
;
2097 struct mips_print_arg_state state
;
2098 void *is
= info
->stream
;
2099 bfd_boolean have_second
;
2100 bfd_boolean extend_only
;
2101 unsigned int second
;
2105 info
->bytes_per_chunk
= 2;
2106 info
->display_endian
= info
->endian
;
2107 info
->insn_info_valid
= 1;
2108 info
->branch_delay_insns
= 0;
2109 info
->data_size
= 0;
2113 #define GET_OP(insn, field) \
2114 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2115 /* Decode PLT entry's GOT slot address word. */
2116 if (is_mips16_plt_tail (info
, memaddr
))
2118 info
->insn_type
= dis_noninsn
;
2119 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2122 unsigned int gotslot
;
2124 if (info
->endian
== BFD_ENDIAN_BIG
)
2125 gotslot
= bfd_getb32 (buffer
);
2127 gotslot
= bfd_getl32 (buffer
);
2128 infprintf (is
, ".word\t0x%x", gotslot
);
2135 info
->insn_type
= dis_nonbranch
;
2136 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2140 (*info
->memory_error_func
) (status
, memaddr
, info
);
2144 extend_only
= FALSE
;
2146 if (info
->endian
== BFD_ENDIAN_BIG
)
2147 first
= bfd_getb16 (buffer
);
2149 first
= bfd_getl16 (buffer
);
2151 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2155 if (info
->endian
== BFD_ENDIAN_BIG
)
2156 second
= bfd_getb16 (buffer
);
2158 second
= bfd_getl16 (buffer
);
2159 full
= (first
<< 16) | second
;
2163 have_second
= FALSE
;
2168 /* FIXME: Should probably use a hash table on the major opcode here. */
2170 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2171 for (op
= mips16_opcodes
; op
< opend
; op
++)
2173 enum match_kind match
;
2175 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
))
2178 if (op
->pinfo
== INSN_MACRO
2179 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
2181 else if (mips_opcode_32bit_p (op
))
2184 && (full
& op
->mask
) == op
->match
)
2189 else if ((first
& op
->mask
) == op
->match
)
2191 match
= MATCH_SHORT
;
2195 else if ((first
& 0xf800) == 0xf000
2198 && (second
& op
->mask
) == op
->match
)
2200 if (op
->pinfo2
& INSN2_SHORT_ONLY
)
2211 if (match
!= MATCH_NONE
)
2215 infprintf (is
, "%s", op
->name
);
2216 if (op
->args
[0] != '\0')
2217 infprintf (is
, "\t");
2219 init_print_arg_state (&state
);
2220 for (s
= op
->args
; *s
!= '\0'; s
++)
2224 && GET_OP (full
, RX
) == GET_OP (full
, RY
))
2226 /* Skip the register and the comma. */
2232 && GET_OP (full
, RZ
) == GET_OP (full
, RX
))
2234 /* Skip the register and the comma. */
2241 && op
->name
[strlen (op
->name
) - 1] == '0')
2243 /* Coprocessor register 0 with sel field. */
2244 const struct mips_cp0sel_name
*n
;
2245 const struct mips_operand
*operand
;
2246 unsigned int reg
, sel
;
2248 operand
= decode_mips16_operand (*s
, TRUE
);
2249 reg
= mips_extract_operand (operand
, (first
<< 16) | second
);
2251 operand
= decode_mips16_operand (*s
, TRUE
);
2252 sel
= mips_extract_operand (operand
, (first
<< 16) | second
);
2254 /* CP0 register including 'sel' code for mftc0, to be
2255 printed textually if known. If not known, print both
2256 CP0 register name and sel numerically since CP0 register
2257 with sel 0 may have a name unrelated to register being
2259 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
2260 mips_cp0sel_names_len
,
2263 infprintf (is
, "%s", n
->name
);
2265 infprintf (is
, "$%d,%d", reg
, sel
);
2271 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
+ 2,
2272 second
, TRUE
, first
, s
[1] == '(');
2275 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
,
2276 first
, FALSE
, 0, s
[1] == '(');
2278 case MATCH_NONE
: /* Stop the compiler complaining. */
2283 /* Figure out branch instruction type and delay slot information. */
2284 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2285 info
->branch_delay_insns
= 1;
2286 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
2287 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
2289 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2290 info
->insn_type
= dis_jsr
;
2292 info
->insn_type
= dis_branch
;
2294 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
2295 info
->insn_type
= dis_condbranch
;
2297 return match
== MATCH_FULL
? 4 : 2;
2302 infprintf (is
, "0x%x", first
);
2303 info
->insn_type
= dis_noninsn
;
2308 /* Disassemble microMIPS instructions. */
2311 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2313 const fprintf_ftype infprintf
= info
->fprintf_func
;
2314 const struct mips_opcode
*op
, *opend
;
2315 void *is
= info
->stream
;
2317 unsigned int higher
;
2318 unsigned int length
;
2322 info
->bytes_per_chunk
= 2;
2323 info
->display_endian
= info
->endian
;
2324 info
->insn_info_valid
= 1;
2325 info
->branch_delay_insns
= 0;
2326 info
->data_size
= 0;
2327 info
->insn_type
= dis_nonbranch
;
2331 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2334 (*info
->memory_error_func
) (status
, memaddr
, info
);
2340 if (info
->endian
== BFD_ENDIAN_BIG
)
2341 insn
= bfd_getb16 (buffer
);
2343 insn
= bfd_getl16 (buffer
);
2345 if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2347 /* This is a 32-bit microMIPS instruction. */
2350 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2353 infprintf (is
, "micromips 0x%x", higher
);
2354 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2358 if (info
->endian
== BFD_ENDIAN_BIG
)
2359 insn
= bfd_getb16 (buffer
);
2361 insn
= bfd_getl16 (buffer
);
2363 insn
= insn
| (higher
<< 16);
2368 /* FIXME: Should probably use a hash table on the major opcode here. */
2370 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2371 for (op
= micromips_opcodes
; op
< opend
; op
++)
2373 if (op
->pinfo
!= INSN_MACRO
2374 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2375 && (insn
& op
->mask
) == op
->match
2376 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2377 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2379 if (!validate_insn_args (op
, decode_micromips_operand
, insn
))
2382 infprintf (is
, "%s", op
->name
);
2386 infprintf (is
, "\t");
2387 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2388 memaddr
+ 1, length
);
2391 /* Figure out instruction type and branch delay information. */
2393 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2394 info
->branch_delay_insns
= 1;
2395 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2396 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2398 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2399 info
->insn_type
= dis_jsr
;
2401 info
->insn_type
= dis_branch
;
2403 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2404 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2406 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2407 info
->insn_type
= dis_condjsr
;
2409 info
->insn_type
= dis_condbranch
;
2412 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2413 info
->insn_type
= dis_dref
;
2419 infprintf (is
, "0x%x", insn
);
2420 info
->insn_type
= dis_noninsn
;
2425 /* Return 1 if a symbol associated with the location being disassembled
2426 indicates a compressed mode, either MIPS16 or microMIPS, according to
2427 MICROMIPS_P. We iterate over all the symbols at the address being
2428 considered assuming if at least one of them indicates code compression,
2429 then such code has been genuinely produced here (other symbols could
2430 have been derived from function symbols defined elsewhere or could
2431 define data). Otherwise, return 0. */
2434 is_compressed_mode_p (struct disassemble_info
*info
, bfd_boolean micromips_p
)
2439 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2440 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2442 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2444 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2446 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2447 && info
->symtab
[i
]->section
== info
->section
)
2449 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2451 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2453 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2460 /* In an environment where we do not know the symbol type of the
2461 instruction we are forced to assume that the low order bit of the
2462 instructions' address may mark it as a mips16 instruction. If we
2463 are single stepping, or the pc is within the disassembled function,
2464 this works. Otherwise, we need a clue. Sometimes. */
2467 _print_insn_mips (bfd_vma memaddr
,
2468 struct disassemble_info
*info
,
2469 enum bfd_endian endianness
)
2471 bfd_byte buffer
[INSNLEN
];
2474 set_default_mips_dis_options (info
);
2475 parse_mips_dis_options (info
->disassembler_options
);
2477 if (info
->mach
== bfd_mach_mips16
)
2478 return print_insn_mips16 (memaddr
, info
);
2479 if (info
->mach
== bfd_mach_mips_micromips
)
2480 return print_insn_micromips (memaddr
, info
);
2483 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2484 /* Only a few tools will work this way. */
2488 return print_insn_micromips (memaddr
, info
);
2490 return print_insn_mips16 (memaddr
, info
);
2494 #if SYMTAB_AVAILABLE
2495 if (is_compressed_mode_p (info
, TRUE
))
2496 return print_insn_micromips (memaddr
, info
);
2497 if (is_compressed_mode_p (info
, FALSE
))
2498 return print_insn_mips16 (memaddr
, info
);
2501 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2506 if (endianness
== BFD_ENDIAN_BIG
)
2507 insn
= bfd_getb32 (buffer
);
2509 insn
= bfd_getl32 (buffer
);
2511 return print_insn_mips (memaddr
, insn
, info
);
2515 (*info
->memory_error_func
) (status
, memaddr
, info
);
2521 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2523 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2527 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2529 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2533 print_mips_disassembler_options (FILE *stream
)
2537 fprintf (stream
, _("\n\
2538 The following MIPS specific disassembler options are supported for use\n\
2539 with the -M switch (multiple options should be separated by commas):\n"));
2541 fprintf (stream
, _("\n\
2542 no-aliases Use canonical instruction forms.\n"));
2544 fprintf (stream
, _("\n\
2545 msa Recognize MSA instructions.\n"));
2547 fprintf (stream
, _("\n\
2548 virt Recognize the virtualization ASE instructions.\n"));
2550 fprintf (stream
, _("\n\
2551 xpa Recognize the eXtended Physical Address (XPA)\n\
2552 ASE instructions.\n"));
2554 fprintf (stream
, _("\n\
2555 gpr-names=ABI Print GPR names according to specified ABI.\n\
2556 Default: based on binary being disassembled.\n"));
2558 fprintf (stream
, _("\n\
2559 fpr-names=ABI Print FPR names according to specified ABI.\n\
2560 Default: numeric.\n"));
2562 fprintf (stream
, _("\n\
2563 cp0-names=ARCH Print CP0 register names according to\n\
2564 specified architecture.\n\
2565 Default: based on binary being disassembled.\n"));
2567 fprintf (stream
, _("\n\
2568 hwr-names=ARCH Print HWR names according to specified \n\
2570 Default: based on binary being disassembled.\n"));
2572 fprintf (stream
, _("\n\
2573 reg-names=ABI Print GPR and FPR names according to\n\
2574 specified ABI.\n"));
2576 fprintf (stream
, _("\n\
2577 reg-names=ARCH Print CP0 register and HWR names according to\n\
2578 specified architecture.\n"));
2580 fprintf (stream
, _("\n\
2581 For the options above, the following values are supported for \"ABI\":\n\
2583 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2584 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2585 fprintf (stream
, _("\n"));
2587 fprintf (stream
, _("\n\
2588 For the options above, The following values are supported for \"ARCH\":\n\
2590 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2591 if (*mips_arch_choices
[i
].name
!= '\0')
2592 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2593 fprintf (stream
, _("\n"));
2595 fprintf (stream
, _("\n"));