1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2016 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. */
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 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
611 ISA_MIPS64
| INSN_SB1
, ASE_MIPS3D
,
613 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
614 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
616 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
617 ISA_MIPS3
| INSN_LOONGSON_2E
, 0, mips_cp0_names_numeric
,
618 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
620 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
621 ISA_MIPS3
| INSN_LOONGSON_2F
, 0, mips_cp0_names_numeric
,
622 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
624 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
625 ISA_MIPS64R2
| INSN_LOONGSON_3A
, 0, mips_cp0_names_numeric
,
626 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
628 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
629 ISA_MIPS64R2
| INSN_OCTEON
, 0, mips_cp0_names_numeric
, NULL
, 0,
630 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
632 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
633 ISA_MIPS64R2
| INSN_OCTEONP
, 0, mips_cp0_names_numeric
,
634 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
636 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
637 ISA_MIPS64R2
| INSN_OCTEON2
, 0, mips_cp0_names_numeric
,
638 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
640 { "octeon3", 1, bfd_mach_mips_octeon3
, CPU_OCTEON3
,
641 ISA_MIPS64R5
| INSN_OCTEON3
, ASE_VIRT
| ASE_VIRT64
,
642 mips_cp0_names_numeric
,
643 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
645 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
646 ISA_MIPS64
| INSN_XLR
, 0,
648 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
649 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
651 /* XLP is mostly like XLR, with the prominent exception it is being
653 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
654 ISA_MIPS64R2
| INSN_XLR
, 0,
656 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
657 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
659 /* This entry, mips16, is here only for ISA/processor selection; do
660 not print its name. */
661 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
, 0,
662 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
663 mips_hwr_names_numeric
},
666 /* ISA and processor type to disassemble for, and register names to use.
667 set_default_mips_dis_options and parse_mips_dis_options fill in these
669 static int mips_processor
;
672 static int micromips_ase
;
673 static const char * const *mips_gpr_names
;
674 static const char * const *mips_fpr_names
;
675 static const char * const *mips_cp0_names
;
676 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
677 static int mips_cp0sel_names_len
;
678 static const char * const *mips_cp1_names
;
679 static const char * const *mips_hwr_names
;
682 static int no_aliases
; /* If set disassemble as most general inst. */
684 static const struct mips_abi_choice
*
685 choose_abi_by_name (const char *name
, unsigned int namelen
)
687 const struct mips_abi_choice
*c
;
690 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
691 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
692 && strlen (mips_abi_choices
[i
].name
) == namelen
)
693 c
= &mips_abi_choices
[i
];
698 static const struct mips_arch_choice
*
699 choose_arch_by_name (const char *name
, unsigned int namelen
)
701 const struct mips_arch_choice
*c
= NULL
;
704 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
705 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
706 && strlen (mips_arch_choices
[i
].name
) == namelen
)
707 c
= &mips_arch_choices
[i
];
712 static const struct mips_arch_choice
*
713 choose_arch_by_number (unsigned long mach
)
715 static unsigned long hint_bfd_mach
;
716 static const struct mips_arch_choice
*hint_arch_choice
;
717 const struct mips_arch_choice
*c
;
720 /* We optimize this because even if the user specifies no
721 flags, this will be done for every instruction! */
722 if (hint_bfd_mach
== mach
723 && hint_arch_choice
!= NULL
724 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
725 return hint_arch_choice
;
727 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
729 if (mips_arch_choices
[i
].bfd_mach_valid
730 && mips_arch_choices
[i
].bfd_mach
== mach
)
732 c
= &mips_arch_choices
[i
];
733 hint_bfd_mach
= mach
;
734 hint_arch_choice
= c
;
740 /* Check if the object uses NewABI conventions. */
743 is_newabi (Elf_Internal_Ehdr
*header
)
745 /* There are no old-style ABIs which use 64-bit ELF. */
746 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
749 /* If a 32-bit ELF file, n32 is a new-style ABI. */
750 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
756 /* Check if the object has microMIPS ASE code. */
759 is_micromips (Elf_Internal_Ehdr
*header
)
761 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
767 /* Convert ASE flags from .MIPS.abiflags to internal values. */
770 mips_convert_abiflags_ases (unsigned long afl_ases
)
772 unsigned long opcode_ases
= 0;
774 if (afl_ases
& AFL_ASE_DSP
)
775 opcode_ases
|= ASE_DSP
;
776 if (afl_ases
& AFL_ASE_DSPR2
)
777 opcode_ases
|= ASE_DSPR2
;
778 if (afl_ases
& AFL_ASE_EVA
)
779 opcode_ases
|= ASE_EVA
;
780 if (afl_ases
& AFL_ASE_MCU
)
781 opcode_ases
|= ASE_MCU
;
782 if (afl_ases
& AFL_ASE_MDMX
)
783 opcode_ases
|= ASE_MDMX
;
784 if (afl_ases
& AFL_ASE_MIPS3D
)
785 opcode_ases
|= ASE_MIPS3D
;
786 if (afl_ases
& AFL_ASE_MT
)
787 opcode_ases
|= ASE_MT
;
788 if (afl_ases
& AFL_ASE_SMARTMIPS
)
789 opcode_ases
|= ASE_SMARTMIPS
;
790 if (afl_ases
& AFL_ASE_VIRT
)
791 opcode_ases
|= ASE_VIRT
;
792 if (afl_ases
& AFL_ASE_MSA
)
793 opcode_ases
|= ASE_MSA
;
794 if (afl_ases
& AFL_ASE_XPA
)
795 opcode_ases
|= ASE_XPA
;
796 if (afl_ases
& AFL_ASE_DSPR3
)
797 opcode_ases
|= ASE_DSPR3
;
802 set_default_mips_dis_options (struct disassemble_info
*info
)
804 const struct mips_arch_choice
*chosen_arch
;
806 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
807 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
808 CP0 register, and HWR names. */
809 mips_isa
= ISA_MIPS3
;
810 mips_processor
= CPU_R3000
;
813 mips_gpr_names
= mips_gpr_names_oldabi
;
814 mips_fpr_names
= mips_fpr_names_numeric
;
815 mips_cp0_names
= mips_cp0_names_numeric
;
816 mips_cp0sel_names
= NULL
;
817 mips_cp0sel_names_len
= 0;
818 mips_cp1_names
= mips_cp1_names_numeric
;
819 mips_hwr_names
= mips_hwr_names_numeric
;
822 /* Set ISA, architecture, and cp0 register names as best we can. */
823 #if ! SYMTAB_AVAILABLE
824 /* This is running out on a target machine, not in a host tool.
825 FIXME: Where does mips_target_info come from? */
826 target_processor
= mips_target_info
.processor
;
827 mips_isa
= mips_target_info
.isa
;
828 mips_ase
= mips_target_info
.ase
;
830 chosen_arch
= choose_arch_by_number (info
->mach
);
831 if (chosen_arch
!= NULL
)
833 mips_processor
= chosen_arch
->processor
;
834 mips_isa
= chosen_arch
->isa
;
835 mips_ase
= chosen_arch
->ase
;
836 mips_cp0_names
= chosen_arch
->cp0_names
;
837 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
838 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
839 mips_cp1_names
= chosen_arch
->cp1_names
;
840 mips_hwr_names
= chosen_arch
->hwr_names
;
844 /* Update settings according to the ELF file header flags. */
845 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
847 struct bfd
*abfd
= info
->section
->owner
;
848 Elf_Internal_Ehdr
*header
= elf_elfheader (abfd
);
849 Elf_Internal_ABIFlags_v0
*abiflags
= bfd_mips_elf_get_abiflags (abfd
);
851 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
852 if (is_newabi (header
))
853 mips_gpr_names
= mips_gpr_names_newabi
;
854 /* If a microMIPS binary, then don't use MIPS16 bindings. */
855 micromips_ase
= is_micromips (header
);
856 /* OR in any extra ASE flags set in ELF file structures. */
858 mips_ase
|= mips_convert_abiflags_ases (abiflags
->ases
);
859 else if (header
->e_flags
& EF_MIPS_ARCH_ASE_MDMX
)
860 mips_ase
|= ASE_MDMX
;
865 parse_mips_dis_option (const char *option
, unsigned int len
)
867 unsigned int i
, optionlen
, vallen
;
869 const struct mips_abi_choice
*chosen_abi
;
870 const struct mips_arch_choice
*chosen_arch
;
872 /* Try to match options that are simple flags */
873 if (CONST_STRNEQ (option
, "no-aliases"))
879 if (CONST_STRNEQ (option
, "msa"))
882 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
883 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R3
884 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R5
885 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
)
886 mips_ase
|= ASE_MSA64
;
890 if (CONST_STRNEQ (option
, "virt"))
892 mips_ase
|= ASE_VIRT
;
893 if (mips_isa
& ISA_MIPS64R2
894 || mips_isa
& ISA_MIPS64R3
895 || mips_isa
& ISA_MIPS64R5
896 || mips_isa
& ISA_MIPS64R6
)
897 mips_ase
|= ASE_VIRT64
;
901 if (CONST_STRNEQ (option
, "xpa"))
908 /* Look for the = that delimits the end of the option name. */
909 for (i
= 0; i
< len
; i
++)
910 if (option
[i
] == '=')
913 if (i
== 0) /* Invalid option: no name before '='. */
915 if (i
== len
) /* Invalid option: no '='. */
917 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
921 val
= option
+ (optionlen
+ 1);
922 vallen
= len
- (optionlen
+ 1);
924 if (strncmp ("gpr-names", option
, optionlen
) == 0
925 && strlen ("gpr-names") == optionlen
)
927 chosen_abi
= choose_abi_by_name (val
, vallen
);
928 if (chosen_abi
!= NULL
)
929 mips_gpr_names
= chosen_abi
->gpr_names
;
933 if (strncmp ("fpr-names", option
, optionlen
) == 0
934 && strlen ("fpr-names") == optionlen
)
936 chosen_abi
= choose_abi_by_name (val
, vallen
);
937 if (chosen_abi
!= NULL
)
938 mips_fpr_names
= chosen_abi
->fpr_names
;
942 if (strncmp ("cp0-names", option
, optionlen
) == 0
943 && strlen ("cp0-names") == optionlen
)
945 chosen_arch
= choose_arch_by_name (val
, vallen
);
946 if (chosen_arch
!= NULL
)
948 mips_cp0_names
= chosen_arch
->cp0_names
;
949 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
950 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
955 if (strncmp ("cp1-names", option
, optionlen
) == 0
956 && strlen ("cp1-names") == optionlen
)
958 chosen_arch
= choose_arch_by_name (val
, vallen
);
959 if (chosen_arch
!= NULL
)
960 mips_cp1_names
= chosen_arch
->cp1_names
;
964 if (strncmp ("hwr-names", option
, optionlen
) == 0
965 && strlen ("hwr-names") == optionlen
)
967 chosen_arch
= choose_arch_by_name (val
, vallen
);
968 if (chosen_arch
!= NULL
)
969 mips_hwr_names
= chosen_arch
->hwr_names
;
973 if (strncmp ("reg-names", option
, optionlen
) == 0
974 && strlen ("reg-names") == optionlen
)
976 /* We check both ABI and ARCH here unconditionally, so
977 that "numeric" will do the desirable thing: select
978 numeric register names for all registers. Other than
979 that, a given name probably won't match both. */
980 chosen_abi
= choose_abi_by_name (val
, vallen
);
981 if (chosen_abi
!= NULL
)
983 mips_gpr_names
= chosen_abi
->gpr_names
;
984 mips_fpr_names
= chosen_abi
->fpr_names
;
986 chosen_arch
= choose_arch_by_name (val
, vallen
);
987 if (chosen_arch
!= NULL
)
989 mips_cp0_names
= chosen_arch
->cp0_names
;
990 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
991 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
992 mips_cp1_names
= chosen_arch
->cp1_names
;
993 mips_hwr_names
= chosen_arch
->hwr_names
;
998 /* Invalid option. */
1002 parse_mips_dis_options (const char *options
)
1004 const char *option_end
;
1006 if (options
== NULL
)
1009 while (*options
!= '\0')
1011 /* Skip empty options. */
1012 if (*options
== ',')
1018 /* We know that *options is neither NUL or a comma. */
1019 option_end
= options
+ 1;
1020 while (*option_end
!= ',' && *option_end
!= '\0')
1023 parse_mips_dis_option (options
, option_end
- options
);
1025 /* Go on to the next one. If option_end points to a comma, it
1026 will be skipped above. */
1027 options
= option_end
;
1031 static const struct mips_cp0sel_name
*
1032 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
1034 unsigned int cp0reg
,
1039 for (i
= 0; i
< len
; i
++)
1040 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
1045 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1048 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
1049 enum mips_reg_operand_type type
, int regno
)
1054 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
1058 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
1062 if (opcode
->pinfo
& (FP_D
| FP_S
))
1063 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
1065 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
1069 if (opcode
->membership
& INSN_5400
)
1070 info
->fprintf_func (info
->stream
, "$f%d", regno
);
1072 info
->fprintf_func (info
->stream
, "$v%d", regno
);
1076 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
1080 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1081 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
1082 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
1083 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
1085 info
->fprintf_func (info
->stream
, "$%d", regno
);
1089 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1093 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1097 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1100 case OP_REG_R5900_I
:
1101 info
->fprintf_func (info
->stream
, "$I");
1104 case OP_REG_R5900_Q
:
1105 info
->fprintf_func (info
->stream
, "$Q");
1108 case OP_REG_R5900_R
:
1109 info
->fprintf_func (info
->stream
, "$R");
1112 case OP_REG_R5900_ACC
:
1113 info
->fprintf_func (info
->stream
, "$ACC");
1117 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1120 case OP_REG_MSA_CTRL
:
1121 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1127 /* Used to track the state carried over from previous operands in
1129 struct mips_print_arg_state
{
1130 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1131 where the value is known to be unsigned and small. */
1132 unsigned int last_int
;
1134 /* The type and number of the last OP_REG seen. We only use this for
1135 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1136 enum mips_reg_operand_type last_reg_type
;
1137 unsigned int last_regno
;
1138 unsigned int dest_regno
;
1139 unsigned int seen_dest
;
1142 /* Initialize STATE for the start of an instruction. */
1145 init_print_arg_state (struct mips_print_arg_state
*state
)
1147 memset (state
, 0, sizeof (*state
));
1150 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1151 whose value is given by UVAL. */
1154 print_vu0_channel (struct disassemble_info
*info
,
1155 const struct mips_operand
*operand
, unsigned int uval
)
1157 if (operand
->size
== 4)
1158 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1159 uval
& 8 ? "x" : "",
1160 uval
& 4 ? "y" : "",
1161 uval
& 2 ? "z" : "",
1162 uval
& 1 ? "w" : "");
1163 else if (operand
->size
== 2)
1164 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1169 /* Record information about a register operand. */
1172 mips_seen_register (struct mips_print_arg_state
*state
,
1174 enum mips_reg_operand_type reg_type
)
1176 state
->last_reg_type
= reg_type
;
1177 state
->last_regno
= regno
;
1179 if (!state
->seen_dest
)
1181 state
->seen_dest
= 1;
1182 state
->dest_regno
= regno
;
1186 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1187 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1188 the base address for OP_PCREL operands. */
1191 print_insn_arg (struct disassemble_info
*info
,
1192 struct mips_print_arg_state
*state
,
1193 const struct mips_opcode
*opcode
,
1194 const struct mips_operand
*operand
,
1198 const fprintf_ftype infprintf
= info
->fprintf_func
;
1199 void *is
= info
->stream
;
1201 switch (operand
->type
)
1205 const struct mips_int_operand
*int_op
;
1207 int_op
= (const struct mips_int_operand
*) operand
;
1208 uval
= mips_decode_int_operand (int_op
, uval
);
1209 state
->last_int
= uval
;
1210 if (int_op
->print_hex
)
1211 infprintf (is
, "0x%x", uval
);
1213 infprintf (is
, "%d", uval
);
1219 const struct mips_mapped_int_operand
*mint_op
;
1221 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1222 uval
= mint_op
->int_map
[uval
];
1223 state
->last_int
= uval
;
1224 if (mint_op
->print_hex
)
1225 infprintf (is
, "0x%x", uval
);
1227 infprintf (is
, "%d", uval
);
1233 const struct mips_msb_operand
*msb_op
;
1235 msb_op
= (const struct mips_msb_operand
*) operand
;
1236 uval
+= msb_op
->bias
;
1237 if (msb_op
->add_lsb
)
1238 uval
-= state
->last_int
;
1239 infprintf (is
, "0x%x", uval
);
1244 case OP_OPTIONAL_REG
:
1246 const struct mips_reg_operand
*reg_op
;
1248 reg_op
= (const struct mips_reg_operand
*) operand
;
1249 uval
= mips_decode_reg_operand (reg_op
, uval
);
1250 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1252 mips_seen_register (state
, uval
, reg_op
->reg_type
);
1258 const struct mips_reg_pair_operand
*pair_op
;
1260 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1261 print_reg (info
, opcode
, pair_op
->reg_type
,
1262 pair_op
->reg1_map
[uval
]);
1263 infprintf (is
, ",");
1264 print_reg (info
, opcode
, pair_op
->reg_type
,
1265 pair_op
->reg2_map
[uval
]);
1271 const struct mips_pcrel_operand
*pcrel_op
;
1273 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1274 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1276 /* Preserve the ISA bit for the GDB disassembler,
1277 otherwise clear it. */
1278 if (info
->flavour
!= bfd_target_unknown_flavour
)
1281 (*info
->print_address_func
) (info
->target
, info
);
1286 infprintf (is
, "%d", uval
);
1289 case OP_ADDIUSP_INT
:
1293 sval
= mips_signed_operand (operand
, uval
) * 4;
1294 if (sval
>= -8 && sval
< 8)
1296 infprintf (is
, "%d", sval
);
1300 case OP_CLO_CLZ_DEST
:
1302 unsigned int reg1
, reg2
;
1306 /* If one is zero use the other. */
1307 if (reg1
== reg2
|| reg2
== 0)
1308 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1310 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1312 /* Bogus, result depends on processor. */
1313 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1314 mips_gpr_names
[reg2
]);
1320 case OP_NON_ZERO_REG
:
1322 print_reg (info
, opcode
, OP_REG_GP
, uval
& 31);
1323 mips_seen_register (state
, uval
, OP_REG_GP
);
1327 case OP_LWM_SWM_LIST
:
1328 if (operand
->size
== 2)
1331 infprintf (is
, "%s,%s",
1333 mips_gpr_names
[31]);
1335 infprintf (is
, "%s-%s,%s",
1337 mips_gpr_names
[16 + uval
],
1338 mips_gpr_names
[31]);
1344 s_reg_encode
= uval
& 0xf;
1345 if (s_reg_encode
!= 0)
1347 if (s_reg_encode
== 1)
1348 infprintf (is
, "%s", mips_gpr_names
[16]);
1349 else if (s_reg_encode
< 9)
1350 infprintf (is
, "%s-%s",
1352 mips_gpr_names
[15 + s_reg_encode
]);
1353 else if (s_reg_encode
== 9)
1354 infprintf (is
, "%s-%s,%s",
1357 mips_gpr_names
[30]);
1359 infprintf (is
, "UNKNOWN");
1362 if (uval
& 0x10) /* For ra. */
1364 if (s_reg_encode
== 0)
1365 infprintf (is
, "%s", mips_gpr_names
[31]);
1367 infprintf (is
, ",%s", mips_gpr_names
[31]);
1372 case OP_ENTRY_EXIT_LIST
:
1375 unsigned int amask
, smask
;
1378 amask
= (uval
>> 3) & 7;
1379 if (amask
> 0 && amask
< 5)
1381 infprintf (is
, "%s", mips_gpr_names
[4]);
1383 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1387 smask
= (uval
>> 1) & 3;
1390 infprintf (is
, "%s??", sep
);
1395 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1397 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1403 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1407 if (amask
== 5 || amask
== 6)
1409 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1411 infprintf (is
, "-%s", mips_fpr_names
[1]);
1416 case OP_SAVE_RESTORE_LIST
:
1417 /* Should be handled by the caller due to extend behavior. */
1420 case OP_MDMX_IMM_REG
:
1426 if ((vsel
& 0x10) == 0)
1431 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1432 if ((vsel
& 1) == 0)
1434 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1435 infprintf (is
, "[%d]", vsel
>> 1);
1437 else if ((vsel
& 0x08) == 0)
1438 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1440 infprintf (is
, "0x%x", uval
);
1444 case OP_REPEAT_PREV_REG
:
1445 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1448 case OP_REPEAT_DEST_REG
:
1449 print_reg (info
, opcode
, state
->last_reg_type
, state
->dest_regno
);
1453 infprintf (is
, "$pc");
1457 case OP_VU0_MATCH_SUFFIX
:
1458 print_vu0_channel (info
, operand
, uval
);
1462 infprintf (is
, "[%d]", uval
);
1466 infprintf (is
, "[");
1467 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1468 infprintf (is
, "]");
1473 /* Validate the arguments for INSN, which is described by OPCODE.
1474 Use DECODE_OPERAND to get the encoding of each operand. */
1477 validate_insn_args (const struct mips_opcode
*opcode
,
1478 const struct mips_operand
*(*decode_operand
) (const char *),
1481 struct mips_print_arg_state state
;
1482 const struct mips_operand
*operand
;
1486 init_print_arg_state (&state
);
1487 for (s
= opcode
->args
; *s
; ++s
)
1501 operand
= decode_operand (s
);
1505 uval
= mips_extract_operand (operand
, insn
);
1506 switch (operand
->type
)
1509 case OP_OPTIONAL_REG
:
1511 const struct mips_reg_operand
*reg_op
;
1513 reg_op
= (const struct mips_reg_operand
*) operand
;
1514 uval
= mips_decode_reg_operand (reg_op
, uval
);
1515 mips_seen_register (&state
, uval
, reg_op
->reg_type
);
1521 unsigned int reg1
, reg2
;
1526 if (reg1
!= reg2
|| reg1
== 0)
1533 const struct mips_check_prev_operand
*prev_op
;
1535 prev_op
= (const struct mips_check_prev_operand
*) operand
;
1537 if (!prev_op
->zero_ok
&& uval
== 0)
1540 if (((prev_op
->less_than_ok
&& uval
< state
.last_regno
)
1541 || (prev_op
->greater_than_ok
&& uval
> state
.last_regno
)
1542 || (prev_op
->equal_ok
&& uval
== state
.last_regno
)))
1548 case OP_NON_ZERO_REG
:
1561 case OP_ADDIUSP_INT
:
1562 case OP_CLO_CLZ_DEST
:
1563 case OP_LWM_SWM_LIST
:
1564 case OP_ENTRY_EXIT_LIST
:
1565 case OP_MDMX_IMM_REG
:
1566 case OP_REPEAT_PREV_REG
:
1567 case OP_REPEAT_DEST_REG
:
1570 case OP_VU0_MATCH_SUFFIX
:
1575 case OP_SAVE_RESTORE_LIST
:
1576 /* Should be handled by the caller due to extend behavior. */
1580 if (*s
== 'm' || *s
== '+' || *s
== '-')
1587 /* Print the arguments for INSN, which is described by OPCODE.
1588 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1589 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1590 operand is for a branch or jump. */
1593 print_insn_args (struct disassemble_info
*info
,
1594 const struct mips_opcode
*opcode
,
1595 const struct mips_operand
*(*decode_operand
) (const char *),
1596 unsigned int insn
, bfd_vma insn_pc
, unsigned int length
)
1598 const fprintf_ftype infprintf
= info
->fprintf_func
;
1599 void *is
= info
->stream
;
1600 struct mips_print_arg_state state
;
1601 const struct mips_operand
*operand
;
1604 init_print_arg_state (&state
);
1605 for (s
= opcode
->args
; *s
; ++s
)
1612 infprintf (is
, "%c", *s
);
1617 infprintf (is
, "%c%c", *s
, *s
);
1621 operand
= decode_operand (s
);
1624 /* xgettext:c-format */
1626 _("# internal error, undefined operand in `%s %s'"),
1627 opcode
->name
, opcode
->args
);
1630 if (operand
->type
== OP_REG
1633 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1635 /* Coprocessor register 0 with sel field (MT ASE). */
1636 const struct mips_cp0sel_name
*n
;
1637 unsigned int reg
, sel
;
1639 reg
= mips_extract_operand (operand
, insn
);
1641 operand
= decode_operand (s
);
1642 sel
= mips_extract_operand (operand
, insn
);
1644 /* CP0 register including 'sel' code for mftc0, to be
1645 printed textually if known. If not known, print both
1646 CP0 register name and sel numerically since CP0 register
1647 with sel 0 may have a name unrelated to register being
1649 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1650 mips_cp0sel_names_len
,
1653 infprintf (is
, "%s", n
->name
);
1655 infprintf (is
, "$%d,%d", reg
, sel
);
1659 bfd_vma base_pc
= insn_pc
;
1661 /* Adjust the PC relative base so that branch/jump insns use
1662 the following PC as the base but genuinely PC relative
1663 operands use the current PC. */
1664 if (operand
->type
== OP_PCREL
)
1666 const struct mips_pcrel_operand
*pcrel_op
;
1668 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1669 /* The include_isa_bit flag is sufficient to distinguish
1670 branch/jump from other PC relative operands. */
1671 if (pcrel_op
->include_isa_bit
)
1675 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1676 mips_extract_operand (operand
, insn
));
1678 if (*s
== 'm' || *s
== '+' || *s
== '-')
1685 /* Print the mips instruction at address MEMADDR in debugged memory,
1686 on using INFO. Returns length of the instruction, in bytes, which is
1687 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1688 this is little-endian code. */
1691 print_insn_mips (bfd_vma memaddr
,
1693 struct disassemble_info
*info
)
1695 #define GET_OP(insn, field) \
1696 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1697 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1698 const fprintf_ftype infprintf
= info
->fprintf_func
;
1699 const struct mips_opcode
*op
;
1700 static bfd_boolean init
= 0;
1701 void *is
= info
->stream
;
1703 /* Build a hash table to shorten the search time. */
1708 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1710 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1712 if (op
->pinfo
== INSN_MACRO
1713 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1715 if (i
== GET_OP (op
->match
, OP
))
1726 info
->bytes_per_chunk
= INSNLEN
;
1727 info
->display_endian
= info
->endian
;
1728 info
->insn_info_valid
= 1;
1729 info
->branch_delay_insns
= 0;
1730 info
->data_size
= 0;
1731 info
->insn_type
= dis_nonbranch
;
1735 op
= mips_hash
[GET_OP (word
, OP
)];
1738 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1740 if (op
->pinfo
!= INSN_MACRO
1741 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1742 && (word
& op
->mask
) == op
->match
)
1744 /* We always disassemble the jalx instruction, except for MIPS r6. */
1745 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1746 && (strcmp (op
->name
, "jalx")
1747 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS32R6
1748 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
))
1751 /* Figure out instruction type and branch delay information. */
1752 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1754 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1755 info
->insn_type
= dis_jsr
;
1757 info
->insn_type
= dis_branch
;
1758 info
->branch_delay_insns
= 1;
1760 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1761 | INSN_COND_BRANCH_LIKELY
)) != 0)
1763 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1764 info
->insn_type
= dis_condjsr
;
1766 info
->insn_type
= dis_condbranch
;
1767 info
->branch_delay_insns
= 1;
1769 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1770 | INSN_LOAD_MEMORY
)) != 0)
1771 info
->insn_type
= dis_dref
;
1773 if (!validate_insn_args (op
, decode_mips_operand
, word
))
1776 infprintf (is
, "%s", op
->name
);
1777 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1781 infprintf (is
, ".");
1782 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1783 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1788 infprintf (is
, "\t");
1789 print_insn_args (info
, op
, decode_mips_operand
, word
,
1799 /* Handle undefined instructions. */
1800 info
->insn_type
= dis_noninsn
;
1801 infprintf (is
, "0x%x", word
);
1805 /* Disassemble an operand for a mips16 instruction. */
1808 print_mips16_insn_arg (struct disassemble_info
*info
,
1809 struct mips_print_arg_state
*state
,
1810 const struct mips_opcode
*opcode
,
1811 char type
, bfd_vma memaddr
,
1812 unsigned insn
, bfd_boolean use_extend
,
1813 unsigned extend
, bfd_boolean is_offset
)
1815 const fprintf_ftype infprintf
= info
->fprintf_func
;
1816 void *is
= info
->stream
;
1817 const struct mips_operand
*operand
, *ext_operand
;
1829 infprintf (is
, "%c", type
);
1833 operand
= decode_mips16_operand (type
, FALSE
);
1836 /* xgettext:c-format */
1837 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
1838 opcode
->name
, opcode
->args
);
1842 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1844 /* Handle this case here because of the complex interaction
1845 with the EXTEND opcode. */
1846 unsigned int amask
, nargs
, nstatics
, nsreg
, smask
, frame_size
, i
, j
;
1849 amask
= extend
& 0xf;
1850 if (amask
== MIPS16_ALL_ARGS
)
1855 else if (amask
== MIPS16_ALL_STATICS
)
1863 nstatics
= amask
& 3;
1869 infprintf (is
, "%s", mips_gpr_names
[4]);
1871 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1875 frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
1876 if (frame_size
== 0 && !use_extend
)
1878 infprintf (is
, "%s%d", sep
, frame_size
);
1880 if (insn
& 0x40) /* $ra */
1881 infprintf (is
, ",%s", mips_gpr_names
[31]);
1883 nsreg
= (extend
>> 8) & 0x7;
1885 if (insn
& 0x20) /* $s0 */
1887 if (insn
& 0x10) /* $s1 */
1889 if (nsreg
> 0) /* $s2-$s8 */
1890 smask
|= ((1 << nsreg
) - 1) << 2;
1892 for (i
= 0; i
< 9; i
++)
1893 if (smask
& (1 << i
))
1895 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1896 /* Skip over string of set bits. */
1897 for (j
= i
; smask
& (2 << j
); j
++)
1900 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1903 /* Statics $ax - $a3. */
1905 infprintf (is
, ",%s", mips_gpr_names
[7]);
1906 else if (nstatics
> 0)
1907 infprintf (is
, ",%s-%s",
1908 mips_gpr_names
[7 - nstatics
+ 1],
1913 if (is_offset
&& operand
->type
== OP_INT
)
1915 const struct mips_int_operand
*int_op
;
1917 int_op
= (const struct mips_int_operand
*) operand
;
1918 info
->insn_type
= dis_dref
;
1919 info
->data_size
= 1 << int_op
->shift
;
1922 if (operand
->size
== 26)
1923 /* In this case INSN is the first two bytes of the instruction
1924 and EXTEND is the second two bytes. */
1925 uval
= ((insn
& 0x1f) << 21) | ((insn
& 0x3e0) << 11) | extend
;
1928 /* Calculate the full field value. */
1929 uval
= mips_extract_operand (operand
, insn
);
1932 ext_operand
= decode_mips16_operand (type
, TRUE
);
1933 if (ext_operand
!= operand
)
1935 operand
= ext_operand
;
1936 if (operand
->size
== 16)
1937 uval
= (((extend
& 0x1f) << 11) | (extend
& 0x7e0)
1939 else if (operand
->size
== 15)
1940 uval
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1942 uval
= ((((extend
>> 6) & 0x1f) | (extend
& 0x20))
1943 & ((1U << operand
->size
) - 1));
1948 baseaddr
= memaddr
+ 2;
1949 if (operand
->type
== OP_PCREL
)
1951 const struct mips_pcrel_operand
*pcrel_op
;
1953 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1954 if (!pcrel_op
->include_isa_bit
&& use_extend
)
1955 baseaddr
= memaddr
- 2;
1956 else if (!pcrel_op
->include_isa_bit
)
1960 /* If this instruction is in the delay slot of a JAL/JALX
1961 instruction, the base address is the address of the
1962 JAL/JALX instruction. If it is in the delay slot of
1963 a JR/JALR instruction, the base address is the address
1964 of the JR/JALR instruction. This test is unreliable:
1965 we have no way of knowing whether the previous word is
1966 instruction or data. */
1967 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
1968 && (((info
->endian
== BFD_ENDIAN_BIG
1969 ? bfd_getb16 (buffer
)
1970 : bfd_getl16 (buffer
))
1971 & 0xf800) == 0x1800))
1972 baseaddr
= memaddr
- 4;
1973 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
1975 && (((info
->endian
== BFD_ENDIAN_BIG
1976 ? bfd_getb16 (buffer
)
1977 : bfd_getl16 (buffer
))
1978 & 0xf89f) == 0xe800)
1979 && (((info
->endian
== BFD_ENDIAN_BIG
1980 ? bfd_getb16 (buffer
)
1981 : bfd_getl16 (buffer
))
1982 & 0x0060) != 0x0060))
1983 baseaddr
= memaddr
- 2;
1989 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
1995 /* Check if the given address is the last word of a MIPS16 PLT entry.
1996 This word is data and depending on the value it may interfere with
1997 disassembly of further PLT entries. We make use of the fact PLT
1998 symbols are marked BSF_SYNTHETIC. */
2000 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2004 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2005 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2011 /* Disassemble mips16 instructions. */
2014 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2016 const fprintf_ftype infprintf
= info
->fprintf_func
;
2021 bfd_boolean use_extend
;
2023 const struct mips_opcode
*op
, *opend
;
2024 struct mips_print_arg_state state
;
2025 void *is
= info
->stream
;
2027 info
->bytes_per_chunk
= 2;
2028 info
->display_endian
= info
->endian
;
2029 info
->insn_info_valid
= 1;
2030 info
->branch_delay_insns
= 0;
2031 info
->data_size
= 0;
2035 #define GET_OP(insn, field) \
2036 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2037 /* Decode PLT entry's GOT slot address word. */
2038 if (is_mips16_plt_tail (info
, memaddr
))
2040 info
->insn_type
= dis_noninsn
;
2041 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2044 unsigned int gotslot
;
2046 if (info
->endian
== BFD_ENDIAN_BIG
)
2047 gotslot
= bfd_getb32 (buffer
);
2049 gotslot
= bfd_getl32 (buffer
);
2050 infprintf (is
, ".word\t0x%x", gotslot
);
2057 info
->insn_type
= dis_nonbranch
;
2058 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2062 (*info
->memory_error_func
) (status
, memaddr
, info
);
2068 if (info
->endian
== BFD_ENDIAN_BIG
)
2069 insn
= bfd_getb16 (buffer
);
2071 insn
= bfd_getl16 (buffer
);
2073 /* Handle the extend opcode specially. */
2075 if ((insn
& 0xf800) == 0xf000)
2078 extend
= insn
& 0x7ff;
2082 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2085 infprintf (is
, "extend\t0x%x", (unsigned int) extend
);
2086 (*info
->memory_error_func
) (status
, memaddr
, info
);
2090 if (info
->endian
== BFD_ENDIAN_BIG
)
2091 insn
= bfd_getb16 (buffer
);
2093 insn
= bfd_getl16 (buffer
);
2095 /* Check for an extend opcode followed by an extend opcode. */
2096 if ((insn
& 0xf800) == 0xf000)
2098 infprintf (is
, "extend\t0x%x", (unsigned int) extend
);
2099 info
->insn_type
= dis_noninsn
;
2106 /* FIXME: Should probably use a hash table on the major opcode here. */
2108 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2109 for (op
= mips16_opcodes
; op
< opend
; op
++)
2111 if (op
->pinfo
!= INSN_MACRO
2112 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2113 && (insn
& op
->mask
) == op
->match
)
2117 if (op
->args
[0] == 'a' || op
->args
[0] == 'i')
2121 infprintf (is
, "extend\t0x%x", (unsigned int) extend
);
2122 info
->insn_type
= dis_noninsn
;
2130 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2135 if (info
->endian
== BFD_ENDIAN_BIG
)
2136 extend
= bfd_getb16 (buffer
);
2138 extend
= bfd_getl16 (buffer
);
2143 infprintf (is
, "%s", op
->name
);
2144 if (op
->args
[0] != '\0')
2145 infprintf (is
, "\t");
2147 init_print_arg_state (&state
);
2148 for (s
= op
->args
; *s
!= '\0'; s
++)
2152 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
2154 /* Skip the register and the comma. */
2160 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
2162 /* Skip the register and the comma. */
2166 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
, insn
,
2167 use_extend
, extend
, s
[1] == '(');
2170 /* Figure out branch instruction type and delay slot information. */
2171 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2172 info
->branch_delay_insns
= 1;
2173 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
2174 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
2176 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2177 info
->insn_type
= dis_jsr
;
2179 info
->insn_type
= dis_branch
;
2181 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
2182 info
->insn_type
= dis_condbranch
;
2190 infprintf (is
, "0x%x ", extend
| 0xf000);
2191 infprintf (is
, "0x%x", insn
);
2192 info
->insn_type
= dis_noninsn
;
2197 /* Disassemble microMIPS instructions. */
2200 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2202 const fprintf_ftype infprintf
= info
->fprintf_func
;
2203 const struct mips_opcode
*op
, *opend
;
2204 void *is
= info
->stream
;
2206 unsigned int higher
;
2207 unsigned int length
;
2211 info
->bytes_per_chunk
= 2;
2212 info
->display_endian
= info
->endian
;
2213 info
->insn_info_valid
= 1;
2214 info
->branch_delay_insns
= 0;
2215 info
->data_size
= 0;
2216 info
->insn_type
= dis_nonbranch
;
2220 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2223 (*info
->memory_error_func
) (status
, memaddr
, info
);
2229 if (info
->endian
== BFD_ENDIAN_BIG
)
2230 insn
= bfd_getb16 (buffer
);
2232 insn
= bfd_getl16 (buffer
);
2234 if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2236 /* This is a 32-bit microMIPS instruction. */
2239 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2242 infprintf (is
, "micromips 0x%x", higher
);
2243 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2247 if (info
->endian
== BFD_ENDIAN_BIG
)
2248 insn
= bfd_getb16 (buffer
);
2250 insn
= bfd_getl16 (buffer
);
2252 insn
= insn
| (higher
<< 16);
2257 /* FIXME: Should probably use a hash table on the major opcode here. */
2259 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2260 for (op
= micromips_opcodes
; op
< opend
; op
++)
2262 if (op
->pinfo
!= INSN_MACRO
2263 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2264 && (insn
& op
->mask
) == op
->match
2265 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2266 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2268 if (!validate_insn_args (op
, decode_micromips_operand
, insn
))
2271 infprintf (is
, "%s", op
->name
);
2275 infprintf (is
, "\t");
2276 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2277 memaddr
+ 1, length
);
2280 /* Figure out instruction type and branch delay information. */
2282 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2283 info
->branch_delay_insns
= 1;
2284 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2285 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2287 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2288 info
->insn_type
= dis_jsr
;
2290 info
->insn_type
= dis_branch
;
2292 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2293 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2295 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2296 info
->insn_type
= dis_condjsr
;
2298 info
->insn_type
= dis_condbranch
;
2301 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2302 info
->insn_type
= dis_dref
;
2308 infprintf (is
, "0x%x", insn
);
2309 info
->insn_type
= dis_noninsn
;
2314 /* Return 1 if a symbol associated with the location being disassembled
2315 indicates a compressed mode, either MIPS16 or microMIPS, according to
2316 MICROMIPS_P. We iterate over all the symbols at the address being
2317 considered assuming if at least one of them indicates code compression,
2318 then such code has been genuinely produced here (other symbols could
2319 have been derived from function symbols defined elsewhere or could
2320 define data). Otherwise, return 0. */
2323 is_compressed_mode_p (struct disassemble_info
*info
, bfd_boolean micromips_p
)
2328 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2329 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2331 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2333 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2335 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2336 && info
->symtab
[i
]->section
== info
->section
)
2338 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2340 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2342 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2349 /* In an environment where we do not know the symbol type of the
2350 instruction we are forced to assume that the low order bit of the
2351 instructions' address may mark it as a mips16 instruction. If we
2352 are single stepping, or the pc is within the disassembled function,
2353 this works. Otherwise, we need a clue. Sometimes. */
2356 _print_insn_mips (bfd_vma memaddr
,
2357 struct disassemble_info
*info
,
2358 enum bfd_endian endianness
)
2360 bfd_byte buffer
[INSNLEN
];
2363 set_default_mips_dis_options (info
);
2364 parse_mips_dis_options (info
->disassembler_options
);
2366 if (info
->mach
== bfd_mach_mips16
)
2367 return print_insn_mips16 (memaddr
, info
);
2368 if (info
->mach
== bfd_mach_mips_micromips
)
2369 return print_insn_micromips (memaddr
, info
);
2372 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2373 /* Only a few tools will work this way. */
2377 return print_insn_micromips (memaddr
, info
);
2379 return print_insn_mips16 (memaddr
, info
);
2383 #if SYMTAB_AVAILABLE
2384 if (is_compressed_mode_p (info
, TRUE
))
2385 return print_insn_micromips (memaddr
, info
);
2386 if (is_compressed_mode_p (info
, FALSE
))
2387 return print_insn_mips16 (memaddr
, info
);
2390 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2395 if (endianness
== BFD_ENDIAN_BIG
)
2396 insn
= bfd_getb32 (buffer
);
2398 insn
= bfd_getl32 (buffer
);
2400 return print_insn_mips (memaddr
, insn
, info
);
2404 (*info
->memory_error_func
) (status
, memaddr
, info
);
2410 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2412 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2416 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2418 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2422 print_mips_disassembler_options (FILE *stream
)
2426 fprintf (stream
, _("\n\
2427 The following MIPS specific disassembler options are supported for use\n\
2428 with the -M switch (multiple options should be separated by commas):\n"));
2430 fprintf (stream
, _("\n\
2431 msa Recognize MSA instructions.\n"));
2433 fprintf (stream
, _("\n\
2434 virt Recognize the virtualization ASE instructions.\n"));
2436 fprintf (stream
, _("\n\
2437 xpa Recognize the eXtended Physical Address (XPA)\n\
2438 ASE instructions.\n"));
2440 fprintf (stream
, _("\n\
2441 gpr-names=ABI Print GPR names according to specified ABI.\n\
2442 Default: based on binary being disassembled.\n"));
2444 fprintf (stream
, _("\n\
2445 fpr-names=ABI Print FPR names according to specified ABI.\n\
2446 Default: numeric.\n"));
2448 fprintf (stream
, _("\n\
2449 cp0-names=ARCH Print CP0 register names according to\n\
2450 specified architecture.\n\
2451 Default: based on binary being disassembled.\n"));
2453 fprintf (stream
, _("\n\
2454 hwr-names=ARCH Print HWR names according to specified \n\
2456 Default: based on binary being disassembled.\n"));
2458 fprintf (stream
, _("\n\
2459 reg-names=ABI Print GPR and FPR names according to\n\
2460 specified ABI.\n"));
2462 fprintf (stream
, _("\n\
2463 reg-names=ARCH Print CP0 register and HWR names according to\n\
2464 specified architecture.\n"));
2466 fprintf (stream
, _("\n\
2467 For the options above, the following values are supported for \"ABI\":\n\
2469 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2470 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2471 fprintf (stream
, _("\n"));
2473 fprintf (stream
, _("\n\
2474 For the options above, The following values are supported for \"ARCH\":\n\
2476 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2477 if (*mips_arch_choices
[i
].name
!= '\0')
2478 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2479 fprintf (stream
, _("\n"));
2481 fprintf (stream
, _("\n"));