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
= NULL
;
851 /* We won't ever get here if !BFD64, because we won't then have
852 a MIPS/ELF BFD, however we need to guard against a link error
853 in a `--enable-targets=...' configuration with a 32-bit host,
854 where the MIPS target is a secondary. */
856 abiflags
= bfd_mips_elf_get_abiflags (abfd
);
858 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
859 if (is_newabi (header
))
860 mips_gpr_names
= mips_gpr_names_newabi
;
861 /* If a microMIPS binary, then don't use MIPS16 bindings. */
862 micromips_ase
= is_micromips (header
);
863 /* OR in any extra ASE flags set in ELF file structures. */
865 mips_ase
|= mips_convert_abiflags_ases (abiflags
->ases
);
866 else if (header
->e_flags
& EF_MIPS_ARCH_ASE_MDMX
)
867 mips_ase
|= ASE_MDMX
;
872 parse_mips_dis_option (const char *option
, unsigned int len
)
874 unsigned int i
, optionlen
, vallen
;
876 const struct mips_abi_choice
*chosen_abi
;
877 const struct mips_arch_choice
*chosen_arch
;
879 /* Try to match options that are simple flags */
880 if (CONST_STRNEQ (option
, "no-aliases"))
886 if (CONST_STRNEQ (option
, "msa"))
889 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
890 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R3
891 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R5
892 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
)
893 mips_ase
|= ASE_MSA64
;
897 if (CONST_STRNEQ (option
, "virt"))
899 mips_ase
|= ASE_VIRT
;
900 if (mips_isa
& ISA_MIPS64R2
901 || mips_isa
& ISA_MIPS64R3
902 || mips_isa
& ISA_MIPS64R5
903 || mips_isa
& ISA_MIPS64R6
)
904 mips_ase
|= ASE_VIRT64
;
908 if (CONST_STRNEQ (option
, "xpa"))
915 /* Look for the = that delimits the end of the option name. */
916 for (i
= 0; i
< len
; i
++)
917 if (option
[i
] == '=')
920 if (i
== 0) /* Invalid option: no name before '='. */
922 if (i
== len
) /* Invalid option: no '='. */
924 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
928 val
= option
+ (optionlen
+ 1);
929 vallen
= len
- (optionlen
+ 1);
931 if (strncmp ("gpr-names", option
, optionlen
) == 0
932 && strlen ("gpr-names") == optionlen
)
934 chosen_abi
= choose_abi_by_name (val
, vallen
);
935 if (chosen_abi
!= NULL
)
936 mips_gpr_names
= chosen_abi
->gpr_names
;
940 if (strncmp ("fpr-names", option
, optionlen
) == 0
941 && strlen ("fpr-names") == optionlen
)
943 chosen_abi
= choose_abi_by_name (val
, vallen
);
944 if (chosen_abi
!= NULL
)
945 mips_fpr_names
= chosen_abi
->fpr_names
;
949 if (strncmp ("cp0-names", option
, optionlen
) == 0
950 && strlen ("cp0-names") == optionlen
)
952 chosen_arch
= choose_arch_by_name (val
, vallen
);
953 if (chosen_arch
!= NULL
)
955 mips_cp0_names
= chosen_arch
->cp0_names
;
956 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
957 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
962 if (strncmp ("cp1-names", option
, optionlen
) == 0
963 && strlen ("cp1-names") == optionlen
)
965 chosen_arch
= choose_arch_by_name (val
, vallen
);
966 if (chosen_arch
!= NULL
)
967 mips_cp1_names
= chosen_arch
->cp1_names
;
971 if (strncmp ("hwr-names", option
, optionlen
) == 0
972 && strlen ("hwr-names") == optionlen
)
974 chosen_arch
= choose_arch_by_name (val
, vallen
);
975 if (chosen_arch
!= NULL
)
976 mips_hwr_names
= chosen_arch
->hwr_names
;
980 if (strncmp ("reg-names", option
, optionlen
) == 0
981 && strlen ("reg-names") == optionlen
)
983 /* We check both ABI and ARCH here unconditionally, so
984 that "numeric" will do the desirable thing: select
985 numeric register names for all registers. Other than
986 that, a given name probably won't match both. */
987 chosen_abi
= choose_abi_by_name (val
, vallen
);
988 if (chosen_abi
!= NULL
)
990 mips_gpr_names
= chosen_abi
->gpr_names
;
991 mips_fpr_names
= chosen_abi
->fpr_names
;
993 chosen_arch
= choose_arch_by_name (val
, vallen
);
994 if (chosen_arch
!= NULL
)
996 mips_cp0_names
= chosen_arch
->cp0_names
;
997 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
998 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
999 mips_cp1_names
= chosen_arch
->cp1_names
;
1000 mips_hwr_names
= chosen_arch
->hwr_names
;
1005 /* Invalid option. */
1009 parse_mips_dis_options (const char *options
)
1011 const char *option_end
;
1013 if (options
== NULL
)
1016 while (*options
!= '\0')
1018 /* Skip empty options. */
1019 if (*options
== ',')
1025 /* We know that *options is neither NUL or a comma. */
1026 option_end
= options
+ 1;
1027 while (*option_end
!= ',' && *option_end
!= '\0')
1030 parse_mips_dis_option (options
, option_end
- options
);
1032 /* Go on to the next one. If option_end points to a comma, it
1033 will be skipped above. */
1034 options
= option_end
;
1038 static const struct mips_cp0sel_name
*
1039 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
1041 unsigned int cp0reg
,
1046 for (i
= 0; i
< len
; i
++)
1047 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
1052 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1055 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
1056 enum mips_reg_operand_type type
, int regno
)
1061 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
1065 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
1069 if (opcode
->pinfo
& (FP_D
| FP_S
))
1070 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
1072 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
1076 if (opcode
->membership
& INSN_5400
)
1077 info
->fprintf_func (info
->stream
, "$f%d", regno
);
1079 info
->fprintf_func (info
->stream
, "$v%d", regno
);
1083 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
1087 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1088 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
1089 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
1090 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
1092 info
->fprintf_func (info
->stream
, "$%d", regno
);
1096 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1100 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1104 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1107 case OP_REG_R5900_I
:
1108 info
->fprintf_func (info
->stream
, "$I");
1111 case OP_REG_R5900_Q
:
1112 info
->fprintf_func (info
->stream
, "$Q");
1115 case OP_REG_R5900_R
:
1116 info
->fprintf_func (info
->stream
, "$R");
1119 case OP_REG_R5900_ACC
:
1120 info
->fprintf_func (info
->stream
, "$ACC");
1124 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1127 case OP_REG_MSA_CTRL
:
1128 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1134 /* Used to track the state carried over from previous operands in
1136 struct mips_print_arg_state
{
1137 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1138 where the value is known to be unsigned and small. */
1139 unsigned int last_int
;
1141 /* The type and number of the last OP_REG seen. We only use this for
1142 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1143 enum mips_reg_operand_type last_reg_type
;
1144 unsigned int last_regno
;
1145 unsigned int dest_regno
;
1146 unsigned int seen_dest
;
1149 /* Initialize STATE for the start of an instruction. */
1152 init_print_arg_state (struct mips_print_arg_state
*state
)
1154 memset (state
, 0, sizeof (*state
));
1157 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1158 whose value is given by UVAL. */
1161 print_vu0_channel (struct disassemble_info
*info
,
1162 const struct mips_operand
*operand
, unsigned int uval
)
1164 if (operand
->size
== 4)
1165 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1166 uval
& 8 ? "x" : "",
1167 uval
& 4 ? "y" : "",
1168 uval
& 2 ? "z" : "",
1169 uval
& 1 ? "w" : "");
1170 else if (operand
->size
== 2)
1171 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1176 /* Record information about a register operand. */
1179 mips_seen_register (struct mips_print_arg_state
*state
,
1181 enum mips_reg_operand_type reg_type
)
1183 state
->last_reg_type
= reg_type
;
1184 state
->last_regno
= regno
;
1186 if (!state
->seen_dest
)
1188 state
->seen_dest
= 1;
1189 state
->dest_regno
= regno
;
1193 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1194 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1195 the base address for OP_PCREL operands. */
1198 print_insn_arg (struct disassemble_info
*info
,
1199 struct mips_print_arg_state
*state
,
1200 const struct mips_opcode
*opcode
,
1201 const struct mips_operand
*operand
,
1205 const fprintf_ftype infprintf
= info
->fprintf_func
;
1206 void *is
= info
->stream
;
1208 switch (operand
->type
)
1212 const struct mips_int_operand
*int_op
;
1214 int_op
= (const struct mips_int_operand
*) operand
;
1215 uval
= mips_decode_int_operand (int_op
, uval
);
1216 state
->last_int
= uval
;
1217 if (int_op
->print_hex
)
1218 infprintf (is
, "0x%x", uval
);
1220 infprintf (is
, "%d", uval
);
1226 const struct mips_mapped_int_operand
*mint_op
;
1228 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1229 uval
= mint_op
->int_map
[uval
];
1230 state
->last_int
= uval
;
1231 if (mint_op
->print_hex
)
1232 infprintf (is
, "0x%x", uval
);
1234 infprintf (is
, "%d", uval
);
1240 const struct mips_msb_operand
*msb_op
;
1242 msb_op
= (const struct mips_msb_operand
*) operand
;
1243 uval
+= msb_op
->bias
;
1244 if (msb_op
->add_lsb
)
1245 uval
-= state
->last_int
;
1246 infprintf (is
, "0x%x", uval
);
1251 case OP_OPTIONAL_REG
:
1253 const struct mips_reg_operand
*reg_op
;
1255 reg_op
= (const struct mips_reg_operand
*) operand
;
1256 uval
= mips_decode_reg_operand (reg_op
, uval
);
1257 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1259 mips_seen_register (state
, uval
, reg_op
->reg_type
);
1265 const struct mips_reg_pair_operand
*pair_op
;
1267 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1268 print_reg (info
, opcode
, pair_op
->reg_type
,
1269 pair_op
->reg1_map
[uval
]);
1270 infprintf (is
, ",");
1271 print_reg (info
, opcode
, pair_op
->reg_type
,
1272 pair_op
->reg2_map
[uval
]);
1278 const struct mips_pcrel_operand
*pcrel_op
;
1280 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1281 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1283 /* Preserve the ISA bit for the GDB disassembler,
1284 otherwise clear it. */
1285 if (info
->flavour
!= bfd_target_unknown_flavour
)
1288 (*info
->print_address_func
) (info
->target
, info
);
1293 infprintf (is
, "%d", uval
);
1296 case OP_ADDIUSP_INT
:
1300 sval
= mips_signed_operand (operand
, uval
) * 4;
1301 if (sval
>= -8 && sval
< 8)
1303 infprintf (is
, "%d", sval
);
1307 case OP_CLO_CLZ_DEST
:
1309 unsigned int reg1
, reg2
;
1313 /* If one is zero use the other. */
1314 if (reg1
== reg2
|| reg2
== 0)
1315 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1317 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1319 /* Bogus, result depends on processor. */
1320 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1321 mips_gpr_names
[reg2
]);
1327 case OP_NON_ZERO_REG
:
1329 print_reg (info
, opcode
, OP_REG_GP
, uval
& 31);
1330 mips_seen_register (state
, uval
, OP_REG_GP
);
1334 case OP_LWM_SWM_LIST
:
1335 if (operand
->size
== 2)
1338 infprintf (is
, "%s,%s",
1340 mips_gpr_names
[31]);
1342 infprintf (is
, "%s-%s,%s",
1344 mips_gpr_names
[16 + uval
],
1345 mips_gpr_names
[31]);
1351 s_reg_encode
= uval
& 0xf;
1352 if (s_reg_encode
!= 0)
1354 if (s_reg_encode
== 1)
1355 infprintf (is
, "%s", mips_gpr_names
[16]);
1356 else if (s_reg_encode
< 9)
1357 infprintf (is
, "%s-%s",
1359 mips_gpr_names
[15 + s_reg_encode
]);
1360 else if (s_reg_encode
== 9)
1361 infprintf (is
, "%s-%s,%s",
1364 mips_gpr_names
[30]);
1366 infprintf (is
, "UNKNOWN");
1369 if (uval
& 0x10) /* For ra. */
1371 if (s_reg_encode
== 0)
1372 infprintf (is
, "%s", mips_gpr_names
[31]);
1374 infprintf (is
, ",%s", mips_gpr_names
[31]);
1379 case OP_ENTRY_EXIT_LIST
:
1382 unsigned int amask
, smask
;
1385 amask
= (uval
>> 3) & 7;
1386 if (amask
> 0 && amask
< 5)
1388 infprintf (is
, "%s", mips_gpr_names
[4]);
1390 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1394 smask
= (uval
>> 1) & 3;
1397 infprintf (is
, "%s??", sep
);
1402 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1404 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1410 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1414 if (amask
== 5 || amask
== 6)
1416 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1418 infprintf (is
, "-%s", mips_fpr_names
[1]);
1423 case OP_SAVE_RESTORE_LIST
:
1424 /* Should be handled by the caller due to extend behavior. */
1427 case OP_MDMX_IMM_REG
:
1433 if ((vsel
& 0x10) == 0)
1438 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1439 if ((vsel
& 1) == 0)
1441 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1442 infprintf (is
, "[%d]", vsel
>> 1);
1444 else if ((vsel
& 0x08) == 0)
1445 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1447 infprintf (is
, "0x%x", uval
);
1451 case OP_REPEAT_PREV_REG
:
1452 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1455 case OP_REPEAT_DEST_REG
:
1456 print_reg (info
, opcode
, state
->last_reg_type
, state
->dest_regno
);
1460 infprintf (is
, "$pc");
1464 case OP_VU0_MATCH_SUFFIX
:
1465 print_vu0_channel (info
, operand
, uval
);
1469 infprintf (is
, "[%d]", uval
);
1473 infprintf (is
, "[");
1474 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1475 infprintf (is
, "]");
1480 /* Validate the arguments for INSN, which is described by OPCODE.
1481 Use DECODE_OPERAND to get the encoding of each operand. */
1484 validate_insn_args (const struct mips_opcode
*opcode
,
1485 const struct mips_operand
*(*decode_operand
) (const char *),
1488 struct mips_print_arg_state state
;
1489 const struct mips_operand
*operand
;
1493 init_print_arg_state (&state
);
1494 for (s
= opcode
->args
; *s
; ++s
)
1508 operand
= decode_operand (s
);
1512 uval
= mips_extract_operand (operand
, insn
);
1513 switch (operand
->type
)
1516 case OP_OPTIONAL_REG
:
1518 const struct mips_reg_operand
*reg_op
;
1520 reg_op
= (const struct mips_reg_operand
*) operand
;
1521 uval
= mips_decode_reg_operand (reg_op
, uval
);
1522 mips_seen_register (&state
, uval
, reg_op
->reg_type
);
1528 unsigned int reg1
, reg2
;
1533 if (reg1
!= reg2
|| reg1
== 0)
1540 const struct mips_check_prev_operand
*prev_op
;
1542 prev_op
= (const struct mips_check_prev_operand
*) operand
;
1544 if (!prev_op
->zero_ok
&& uval
== 0)
1547 if (((prev_op
->less_than_ok
&& uval
< state
.last_regno
)
1548 || (prev_op
->greater_than_ok
&& uval
> state
.last_regno
)
1549 || (prev_op
->equal_ok
&& uval
== state
.last_regno
)))
1555 case OP_NON_ZERO_REG
:
1568 case OP_ADDIUSP_INT
:
1569 case OP_CLO_CLZ_DEST
:
1570 case OP_LWM_SWM_LIST
:
1571 case OP_ENTRY_EXIT_LIST
:
1572 case OP_MDMX_IMM_REG
:
1573 case OP_REPEAT_PREV_REG
:
1574 case OP_REPEAT_DEST_REG
:
1577 case OP_VU0_MATCH_SUFFIX
:
1582 case OP_SAVE_RESTORE_LIST
:
1583 /* Should be handled by the caller due to extend behavior. */
1587 if (*s
== 'm' || *s
== '+' || *s
== '-')
1594 /* Print the arguments for INSN, which is described by OPCODE.
1595 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1596 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1597 operand is for a branch or jump. */
1600 print_insn_args (struct disassemble_info
*info
,
1601 const struct mips_opcode
*opcode
,
1602 const struct mips_operand
*(*decode_operand
) (const char *),
1603 unsigned int insn
, bfd_vma insn_pc
, unsigned int length
)
1605 const fprintf_ftype infprintf
= info
->fprintf_func
;
1606 void *is
= info
->stream
;
1607 struct mips_print_arg_state state
;
1608 const struct mips_operand
*operand
;
1611 init_print_arg_state (&state
);
1612 for (s
= opcode
->args
; *s
; ++s
)
1619 infprintf (is
, "%c", *s
);
1624 infprintf (is
, "%c%c", *s
, *s
);
1628 operand
= decode_operand (s
);
1631 /* xgettext:c-format */
1633 _("# internal error, undefined operand in `%s %s'"),
1634 opcode
->name
, opcode
->args
);
1637 if (operand
->type
== OP_REG
1640 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1642 /* Coprocessor register 0 with sel field (MT ASE). */
1643 const struct mips_cp0sel_name
*n
;
1644 unsigned int reg
, sel
;
1646 reg
= mips_extract_operand (operand
, insn
);
1648 operand
= decode_operand (s
);
1649 sel
= mips_extract_operand (operand
, insn
);
1651 /* CP0 register including 'sel' code for mftc0, to be
1652 printed textually if known. If not known, print both
1653 CP0 register name and sel numerically since CP0 register
1654 with sel 0 may have a name unrelated to register being
1656 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1657 mips_cp0sel_names_len
,
1660 infprintf (is
, "%s", n
->name
);
1662 infprintf (is
, "$%d,%d", reg
, sel
);
1666 bfd_vma base_pc
= insn_pc
;
1668 /* Adjust the PC relative base so that branch/jump insns use
1669 the following PC as the base but genuinely PC relative
1670 operands use the current PC. */
1671 if (operand
->type
== OP_PCREL
)
1673 const struct mips_pcrel_operand
*pcrel_op
;
1675 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1676 /* The include_isa_bit flag is sufficient to distinguish
1677 branch/jump from other PC relative operands. */
1678 if (pcrel_op
->include_isa_bit
)
1682 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1683 mips_extract_operand (operand
, insn
));
1685 if (*s
== 'm' || *s
== '+' || *s
== '-')
1692 /* Print the mips instruction at address MEMADDR in debugged memory,
1693 on using INFO. Returns length of the instruction, in bytes, which is
1694 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1695 this is little-endian code. */
1698 print_insn_mips (bfd_vma memaddr
,
1700 struct disassemble_info
*info
)
1702 #define GET_OP(insn, field) \
1703 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1704 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1705 const fprintf_ftype infprintf
= info
->fprintf_func
;
1706 const struct mips_opcode
*op
;
1707 static bfd_boolean init
= 0;
1708 void *is
= info
->stream
;
1710 /* Build a hash table to shorten the search time. */
1715 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1717 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1719 if (op
->pinfo
== INSN_MACRO
1720 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1722 if (i
== GET_OP (op
->match
, OP
))
1733 info
->bytes_per_chunk
= INSNLEN
;
1734 info
->display_endian
= info
->endian
;
1735 info
->insn_info_valid
= 1;
1736 info
->branch_delay_insns
= 0;
1737 info
->data_size
= 0;
1738 info
->insn_type
= dis_nonbranch
;
1742 op
= mips_hash
[GET_OP (word
, OP
)];
1745 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1747 if (op
->pinfo
!= INSN_MACRO
1748 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1749 && (word
& op
->mask
) == op
->match
)
1751 /* We always disassemble the jalx instruction, except for MIPS r6. */
1752 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1753 && (strcmp (op
->name
, "jalx")
1754 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS32R6
1755 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
))
1758 /* Figure out instruction type and branch delay information. */
1759 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1761 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1762 info
->insn_type
= dis_jsr
;
1764 info
->insn_type
= dis_branch
;
1765 info
->branch_delay_insns
= 1;
1767 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1768 | INSN_COND_BRANCH_LIKELY
)) != 0)
1770 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1771 info
->insn_type
= dis_condjsr
;
1773 info
->insn_type
= dis_condbranch
;
1774 info
->branch_delay_insns
= 1;
1776 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1777 | INSN_LOAD_MEMORY
)) != 0)
1778 info
->insn_type
= dis_dref
;
1780 if (!validate_insn_args (op
, decode_mips_operand
, word
))
1783 infprintf (is
, "%s", op
->name
);
1784 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1788 infprintf (is
, ".");
1789 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1790 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1795 infprintf (is
, "\t");
1796 print_insn_args (info
, op
, decode_mips_operand
, word
,
1806 /* Handle undefined instructions. */
1807 info
->insn_type
= dis_noninsn
;
1808 infprintf (is
, "0x%x", word
);
1812 /* Disassemble an operand for a mips16 instruction. */
1815 print_mips16_insn_arg (struct disassemble_info
*info
,
1816 struct mips_print_arg_state
*state
,
1817 const struct mips_opcode
*opcode
,
1818 char type
, bfd_vma memaddr
,
1819 unsigned insn
, bfd_boolean use_extend
,
1820 unsigned extend
, bfd_boolean is_offset
)
1822 const fprintf_ftype infprintf
= info
->fprintf_func
;
1823 void *is
= info
->stream
;
1824 const struct mips_operand
*operand
, *ext_operand
;
1836 infprintf (is
, "%c", type
);
1840 operand
= decode_mips16_operand (type
, FALSE
);
1843 /* xgettext:c-format */
1844 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
1845 opcode
->name
, opcode
->args
);
1849 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1851 /* Handle this case here because of the complex interaction
1852 with the EXTEND opcode. */
1853 unsigned int amask
, nargs
, nstatics
, nsreg
, smask
, frame_size
, i
, j
;
1856 amask
= extend
& 0xf;
1857 if (amask
== MIPS16_ALL_ARGS
)
1862 else if (amask
== MIPS16_ALL_STATICS
)
1870 nstatics
= amask
& 3;
1876 infprintf (is
, "%s", mips_gpr_names
[4]);
1878 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1882 frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
1883 if (frame_size
== 0 && !use_extend
)
1885 infprintf (is
, "%s%d", sep
, frame_size
);
1887 if (insn
& 0x40) /* $ra */
1888 infprintf (is
, ",%s", mips_gpr_names
[31]);
1890 nsreg
= (extend
>> 8) & 0x7;
1892 if (insn
& 0x20) /* $s0 */
1894 if (insn
& 0x10) /* $s1 */
1896 if (nsreg
> 0) /* $s2-$s8 */
1897 smask
|= ((1 << nsreg
) - 1) << 2;
1899 for (i
= 0; i
< 9; i
++)
1900 if (smask
& (1 << i
))
1902 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1903 /* Skip over string of set bits. */
1904 for (j
= i
; smask
& (2 << j
); j
++)
1907 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1910 /* Statics $ax - $a3. */
1912 infprintf (is
, ",%s", mips_gpr_names
[7]);
1913 else if (nstatics
> 0)
1914 infprintf (is
, ",%s-%s",
1915 mips_gpr_names
[7 - nstatics
+ 1],
1920 if (is_offset
&& operand
->type
== OP_INT
)
1922 const struct mips_int_operand
*int_op
;
1924 int_op
= (const struct mips_int_operand
*) operand
;
1925 info
->insn_type
= dis_dref
;
1926 info
->data_size
= 1 << int_op
->shift
;
1929 if (operand
->size
== 26)
1930 /* In this case INSN is the first two bytes of the instruction
1931 and EXTEND is the second two bytes. */
1932 uval
= ((insn
& 0x1f) << 21) | ((insn
& 0x3e0) << 11) | extend
;
1935 /* Calculate the full field value. */
1936 uval
= mips_extract_operand (operand
, insn
);
1939 ext_operand
= decode_mips16_operand (type
, TRUE
);
1940 if (ext_operand
!= operand
)
1942 operand
= ext_operand
;
1943 if (operand
->size
== 16)
1944 uval
= (((extend
& 0x1f) << 11) | (extend
& 0x7e0)
1946 else if (operand
->size
== 15)
1947 uval
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1949 uval
= ((((extend
>> 6) & 0x1f) | (extend
& 0x20))
1950 & ((1U << operand
->size
) - 1));
1955 baseaddr
= memaddr
+ 2;
1956 if (operand
->type
== OP_PCREL
)
1958 const struct mips_pcrel_operand
*pcrel_op
;
1960 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1961 if (!pcrel_op
->include_isa_bit
&& use_extend
)
1962 baseaddr
= memaddr
- 2;
1963 else if (!pcrel_op
->include_isa_bit
)
1967 /* If this instruction is in the delay slot of a JAL/JALX
1968 instruction, the base address is the address of the
1969 JAL/JALX instruction. If it is in the delay slot of
1970 a JR/JALR instruction, the base address is the address
1971 of the JR/JALR instruction. This test is unreliable:
1972 we have no way of knowing whether the previous word is
1973 instruction or data. */
1974 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
1975 && (((info
->endian
== BFD_ENDIAN_BIG
1976 ? bfd_getb16 (buffer
)
1977 : bfd_getl16 (buffer
))
1978 & 0xf800) == 0x1800))
1979 baseaddr
= memaddr
- 4;
1980 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
1982 && (((info
->endian
== BFD_ENDIAN_BIG
1983 ? bfd_getb16 (buffer
)
1984 : bfd_getl16 (buffer
))
1985 & 0xf89f) == 0xe800)
1986 && (((info
->endian
== BFD_ENDIAN_BIG
1987 ? bfd_getb16 (buffer
)
1988 : bfd_getl16 (buffer
))
1989 & 0x0060) != 0x0060))
1990 baseaddr
= memaddr
- 2;
1996 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
2002 /* Check if the given address is the last word of a MIPS16 PLT entry.
2003 This word is data and depending on the value it may interfere with
2004 disassembly of further PLT entries. We make use of the fact PLT
2005 symbols are marked BSF_SYNTHETIC. */
2007 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
2011 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
2012 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
2018 /* Disassemble mips16 instructions. */
2021 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
2023 const fprintf_ftype infprintf
= info
->fprintf_func
;
2028 bfd_boolean use_extend
;
2030 const struct mips_opcode
*op
, *opend
;
2031 struct mips_print_arg_state state
;
2032 void *is
= info
->stream
;
2034 info
->bytes_per_chunk
= 2;
2035 info
->display_endian
= info
->endian
;
2036 info
->insn_info_valid
= 1;
2037 info
->branch_delay_insns
= 0;
2038 info
->data_size
= 0;
2042 #define GET_OP(insn, field) \
2043 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2044 /* Decode PLT entry's GOT slot address word. */
2045 if (is_mips16_plt_tail (info
, memaddr
))
2047 info
->insn_type
= dis_noninsn
;
2048 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2051 unsigned int gotslot
;
2053 if (info
->endian
== BFD_ENDIAN_BIG
)
2054 gotslot
= bfd_getb32 (buffer
);
2056 gotslot
= bfd_getl32 (buffer
);
2057 infprintf (is
, ".word\t0x%x", gotslot
);
2064 info
->insn_type
= dis_nonbranch
;
2065 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2069 (*info
->memory_error_func
) (status
, memaddr
, info
);
2075 if (info
->endian
== BFD_ENDIAN_BIG
)
2076 insn
= bfd_getb16 (buffer
);
2078 insn
= bfd_getl16 (buffer
);
2080 /* Handle the extend opcode specially. */
2082 if ((insn
& 0xf800) == 0xf000)
2085 extend
= insn
& 0x7ff;
2089 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2092 infprintf (is
, "extend\t0x%x", (unsigned int) extend
);
2093 (*info
->memory_error_func
) (status
, memaddr
, info
);
2097 if (info
->endian
== BFD_ENDIAN_BIG
)
2098 insn
= bfd_getb16 (buffer
);
2100 insn
= bfd_getl16 (buffer
);
2102 /* Check for an extend opcode followed by an extend opcode. */
2103 if ((insn
& 0xf800) == 0xf000)
2105 infprintf (is
, "extend\t0x%x", (unsigned int) extend
);
2106 info
->insn_type
= dis_noninsn
;
2113 /* FIXME: Should probably use a hash table on the major opcode here. */
2115 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2116 for (op
= mips16_opcodes
; op
< opend
; op
++)
2118 if (op
->pinfo
!= INSN_MACRO
2119 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2120 && (insn
& op
->mask
) == op
->match
)
2124 if (op
->args
[0] == 'a' || op
->args
[0] == 'i')
2128 infprintf (is
, "extend\t0x%x", (unsigned int) extend
);
2129 info
->insn_type
= dis_noninsn
;
2137 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2142 if (info
->endian
== BFD_ENDIAN_BIG
)
2143 extend
= bfd_getb16 (buffer
);
2145 extend
= bfd_getl16 (buffer
);
2150 infprintf (is
, "%s", op
->name
);
2151 if (op
->args
[0] != '\0')
2152 infprintf (is
, "\t");
2154 init_print_arg_state (&state
);
2155 for (s
= op
->args
; *s
!= '\0'; s
++)
2159 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
2161 /* Skip the register and the comma. */
2167 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
2169 /* Skip the register and the comma. */
2173 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
, insn
,
2174 use_extend
, extend
, s
[1] == '(');
2177 /* Figure out branch instruction type and delay slot information. */
2178 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2179 info
->branch_delay_insns
= 1;
2180 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
2181 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
2183 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2184 info
->insn_type
= dis_jsr
;
2186 info
->insn_type
= dis_branch
;
2188 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
2189 info
->insn_type
= dis_condbranch
;
2197 infprintf (is
, "0x%x ", extend
| 0xf000);
2198 infprintf (is
, "0x%x", insn
);
2199 info
->insn_type
= dis_noninsn
;
2204 /* Disassemble microMIPS instructions. */
2207 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2209 const fprintf_ftype infprintf
= info
->fprintf_func
;
2210 const struct mips_opcode
*op
, *opend
;
2211 void *is
= info
->stream
;
2213 unsigned int higher
;
2214 unsigned int length
;
2218 info
->bytes_per_chunk
= 2;
2219 info
->display_endian
= info
->endian
;
2220 info
->insn_info_valid
= 1;
2221 info
->branch_delay_insns
= 0;
2222 info
->data_size
= 0;
2223 info
->insn_type
= dis_nonbranch
;
2227 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2230 (*info
->memory_error_func
) (status
, memaddr
, info
);
2236 if (info
->endian
== BFD_ENDIAN_BIG
)
2237 insn
= bfd_getb16 (buffer
);
2239 insn
= bfd_getl16 (buffer
);
2241 if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2243 /* This is a 32-bit microMIPS instruction. */
2246 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2249 infprintf (is
, "micromips 0x%x", higher
);
2250 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2254 if (info
->endian
== BFD_ENDIAN_BIG
)
2255 insn
= bfd_getb16 (buffer
);
2257 insn
= bfd_getl16 (buffer
);
2259 insn
= insn
| (higher
<< 16);
2264 /* FIXME: Should probably use a hash table on the major opcode here. */
2266 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2267 for (op
= micromips_opcodes
; op
< opend
; op
++)
2269 if (op
->pinfo
!= INSN_MACRO
2270 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2271 && (insn
& op
->mask
) == op
->match
2272 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2273 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2275 if (!validate_insn_args (op
, decode_micromips_operand
, insn
))
2278 infprintf (is
, "%s", op
->name
);
2282 infprintf (is
, "\t");
2283 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2284 memaddr
+ 1, length
);
2287 /* Figure out instruction type and branch delay information. */
2289 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2290 info
->branch_delay_insns
= 1;
2291 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2292 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2294 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2295 info
->insn_type
= dis_jsr
;
2297 info
->insn_type
= dis_branch
;
2299 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2300 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2302 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2303 info
->insn_type
= dis_condjsr
;
2305 info
->insn_type
= dis_condbranch
;
2308 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2309 info
->insn_type
= dis_dref
;
2315 infprintf (is
, "0x%x", insn
);
2316 info
->insn_type
= dis_noninsn
;
2321 /* Return 1 if a symbol associated with the location being disassembled
2322 indicates a compressed mode, either MIPS16 or microMIPS, according to
2323 MICROMIPS_P. We iterate over all the symbols at the address being
2324 considered assuming if at least one of them indicates code compression,
2325 then such code has been genuinely produced here (other symbols could
2326 have been derived from function symbols defined elsewhere or could
2327 define data). Otherwise, return 0. */
2330 is_compressed_mode_p (struct disassemble_info
*info
, bfd_boolean micromips_p
)
2335 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2336 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2338 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2340 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2342 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2343 && info
->symtab
[i
]->section
== info
->section
)
2345 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2347 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2349 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2356 /* In an environment where we do not know the symbol type of the
2357 instruction we are forced to assume that the low order bit of the
2358 instructions' address may mark it as a mips16 instruction. If we
2359 are single stepping, or the pc is within the disassembled function,
2360 this works. Otherwise, we need a clue. Sometimes. */
2363 _print_insn_mips (bfd_vma memaddr
,
2364 struct disassemble_info
*info
,
2365 enum bfd_endian endianness
)
2367 bfd_byte buffer
[INSNLEN
];
2370 set_default_mips_dis_options (info
);
2371 parse_mips_dis_options (info
->disassembler_options
);
2373 if (info
->mach
== bfd_mach_mips16
)
2374 return print_insn_mips16 (memaddr
, info
);
2375 if (info
->mach
== bfd_mach_mips_micromips
)
2376 return print_insn_micromips (memaddr
, info
);
2379 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2380 /* Only a few tools will work this way. */
2384 return print_insn_micromips (memaddr
, info
);
2386 return print_insn_mips16 (memaddr
, info
);
2390 #if SYMTAB_AVAILABLE
2391 if (is_compressed_mode_p (info
, TRUE
))
2392 return print_insn_micromips (memaddr
, info
);
2393 if (is_compressed_mode_p (info
, FALSE
))
2394 return print_insn_mips16 (memaddr
, info
);
2397 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2402 if (endianness
== BFD_ENDIAN_BIG
)
2403 insn
= bfd_getb32 (buffer
);
2405 insn
= bfd_getl32 (buffer
);
2407 return print_insn_mips (memaddr
, insn
, info
);
2411 (*info
->memory_error_func
) (status
, memaddr
, info
);
2417 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2419 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2423 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2425 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2429 print_mips_disassembler_options (FILE *stream
)
2433 fprintf (stream
, _("\n\
2434 The following MIPS specific disassembler options are supported for use\n\
2435 with the -M switch (multiple options should be separated by commas):\n"));
2437 fprintf (stream
, _("\n\
2438 msa Recognize MSA instructions.\n"));
2440 fprintf (stream
, _("\n\
2441 virt Recognize the virtualization ASE instructions.\n"));
2443 fprintf (stream
, _("\n\
2444 xpa Recognize the eXtended Physical Address (XPA)\n\
2445 ASE instructions.\n"));
2447 fprintf (stream
, _("\n\
2448 gpr-names=ABI Print GPR names according to specified ABI.\n\
2449 Default: based on binary being disassembled.\n"));
2451 fprintf (stream
, _("\n\
2452 fpr-names=ABI Print FPR names according to specified ABI.\n\
2453 Default: numeric.\n"));
2455 fprintf (stream
, _("\n\
2456 cp0-names=ARCH Print CP0 register names according to\n\
2457 specified architecture.\n\
2458 Default: based on binary being disassembled.\n"));
2460 fprintf (stream
, _("\n\
2461 hwr-names=ARCH Print HWR names according to specified \n\
2463 Default: based on binary being disassembled.\n"));
2465 fprintf (stream
, _("\n\
2466 reg-names=ABI Print GPR and FPR names according to\n\
2467 specified ABI.\n"));
2469 fprintf (stream
, _("\n\
2470 reg-names=ARCH Print CP0 register and HWR names according to\n\
2471 specified architecture.\n"));
2473 fprintf (stream
, _("\n\
2474 For the options above, the following values are supported for \"ABI\":\n\
2476 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2477 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2478 fprintf (stream
, _("\n"));
2480 fprintf (stream
, _("\n\
2481 For the options above, The following values are supported for \"ARCH\":\n\
2483 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2484 if (*mips_arch_choices
[i
].name
!= '\0')
2485 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2486 fprintf (stream
, _("\n"));
2488 fprintf (stream
, _("\n"));