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)
768 set_default_mips_dis_options (struct disassemble_info
*info
)
770 const struct mips_arch_choice
*chosen_arch
;
772 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
773 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
774 CP0 register, and HWR names. */
775 mips_isa
= ISA_MIPS3
;
776 mips_processor
= CPU_R3000
;
779 mips_gpr_names
= mips_gpr_names_oldabi
;
780 mips_fpr_names
= mips_fpr_names_numeric
;
781 mips_cp0_names
= mips_cp0_names_numeric
;
782 mips_cp0sel_names
= NULL
;
783 mips_cp0sel_names_len
= 0;
784 mips_cp1_names
= mips_cp1_names_numeric
;
785 mips_hwr_names
= mips_hwr_names_numeric
;
788 /* Update settings according to the ELF file header flags. */
789 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
791 Elf_Internal_Ehdr
*header
;
793 header
= elf_elfheader (info
->section
->owner
);
794 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
795 if (is_newabi (header
))
796 mips_gpr_names
= mips_gpr_names_newabi
;
797 /* If a microMIPS binary, then don't use MIPS16 bindings. */
798 micromips_ase
= is_micromips (header
);
801 /* Set ISA, architecture, and cp0 register names as best we can. */
802 #if ! SYMTAB_AVAILABLE
803 /* This is running out on a target machine, not in a host tool.
804 FIXME: Where does mips_target_info come from? */
805 target_processor
= mips_target_info
.processor
;
806 mips_isa
= mips_target_info
.isa
;
807 mips_ase
= mips_target_info
.ase
;
809 chosen_arch
= choose_arch_by_number (info
->mach
);
810 if (chosen_arch
!= NULL
)
812 mips_processor
= chosen_arch
->processor
;
813 mips_isa
= chosen_arch
->isa
;
814 mips_ase
= chosen_arch
->ase
;
815 mips_cp0_names
= chosen_arch
->cp0_names
;
816 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
817 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
818 mips_cp1_names
= chosen_arch
->cp1_names
;
819 mips_hwr_names
= chosen_arch
->hwr_names
;
825 parse_mips_dis_option (const char *option
, unsigned int len
)
827 unsigned int i
, optionlen
, vallen
;
829 const struct mips_abi_choice
*chosen_abi
;
830 const struct mips_arch_choice
*chosen_arch
;
832 /* Try to match options that are simple flags */
833 if (CONST_STRNEQ (option
, "no-aliases"))
839 if (CONST_STRNEQ (option
, "msa"))
842 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
843 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R3
844 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R5
845 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
)
846 mips_ase
|= ASE_MSA64
;
850 if (CONST_STRNEQ (option
, "virt"))
852 mips_ase
|= ASE_VIRT
;
853 if (mips_isa
& ISA_MIPS64R2
854 || mips_isa
& ISA_MIPS64R3
855 || mips_isa
& ISA_MIPS64R5
856 || mips_isa
& ISA_MIPS64R6
)
857 mips_ase
|= ASE_VIRT64
;
861 if (CONST_STRNEQ (option
, "xpa"))
868 /* Look for the = that delimits the end of the option name. */
869 for (i
= 0; i
< len
; i
++)
870 if (option
[i
] == '=')
873 if (i
== 0) /* Invalid option: no name before '='. */
875 if (i
== len
) /* Invalid option: no '='. */
877 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
881 val
= option
+ (optionlen
+ 1);
882 vallen
= len
- (optionlen
+ 1);
884 if (strncmp ("gpr-names", option
, optionlen
) == 0
885 && strlen ("gpr-names") == optionlen
)
887 chosen_abi
= choose_abi_by_name (val
, vallen
);
888 if (chosen_abi
!= NULL
)
889 mips_gpr_names
= chosen_abi
->gpr_names
;
893 if (strncmp ("fpr-names", option
, optionlen
) == 0
894 && strlen ("fpr-names") == optionlen
)
896 chosen_abi
= choose_abi_by_name (val
, vallen
);
897 if (chosen_abi
!= NULL
)
898 mips_fpr_names
= chosen_abi
->fpr_names
;
902 if (strncmp ("cp0-names", option
, optionlen
) == 0
903 && strlen ("cp0-names") == optionlen
)
905 chosen_arch
= choose_arch_by_name (val
, vallen
);
906 if (chosen_arch
!= NULL
)
908 mips_cp0_names
= chosen_arch
->cp0_names
;
909 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
910 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
915 if (strncmp ("cp1-names", option
, optionlen
) == 0
916 && strlen ("cp1-names") == optionlen
)
918 chosen_arch
= choose_arch_by_name (val
, vallen
);
919 if (chosen_arch
!= NULL
)
920 mips_cp1_names
= chosen_arch
->cp1_names
;
924 if (strncmp ("hwr-names", option
, optionlen
) == 0
925 && strlen ("hwr-names") == optionlen
)
927 chosen_arch
= choose_arch_by_name (val
, vallen
);
928 if (chosen_arch
!= NULL
)
929 mips_hwr_names
= chosen_arch
->hwr_names
;
933 if (strncmp ("reg-names", option
, optionlen
) == 0
934 && strlen ("reg-names") == optionlen
)
936 /* We check both ABI and ARCH here unconditionally, so
937 that "numeric" will do the desirable thing: select
938 numeric register names for all registers. Other than
939 that, a given name probably won't match both. */
940 chosen_abi
= choose_abi_by_name (val
, vallen
);
941 if (chosen_abi
!= NULL
)
943 mips_gpr_names
= chosen_abi
->gpr_names
;
944 mips_fpr_names
= chosen_abi
->fpr_names
;
946 chosen_arch
= choose_arch_by_name (val
, vallen
);
947 if (chosen_arch
!= NULL
)
949 mips_cp0_names
= chosen_arch
->cp0_names
;
950 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
951 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
952 mips_cp1_names
= chosen_arch
->cp1_names
;
953 mips_hwr_names
= chosen_arch
->hwr_names
;
958 /* Invalid option. */
962 parse_mips_dis_options (const char *options
)
964 const char *option_end
;
969 while (*options
!= '\0')
971 /* Skip empty options. */
978 /* We know that *options is neither NUL or a comma. */
979 option_end
= options
+ 1;
980 while (*option_end
!= ',' && *option_end
!= '\0')
983 parse_mips_dis_option (options
, option_end
- options
);
985 /* Go on to the next one. If option_end points to a comma, it
986 will be skipped above. */
987 options
= option_end
;
991 static const struct mips_cp0sel_name
*
992 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
999 for (i
= 0; i
< len
; i
++)
1000 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
1005 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1008 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
1009 enum mips_reg_operand_type type
, int regno
)
1014 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
1018 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
1022 if (opcode
->pinfo
& (FP_D
| FP_S
))
1023 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
1025 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
1029 if (opcode
->membership
& INSN_5400
)
1030 info
->fprintf_func (info
->stream
, "$f%d", regno
);
1032 info
->fprintf_func (info
->stream
, "$v%d", regno
);
1036 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
1040 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1041 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
1042 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
1043 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
1045 info
->fprintf_func (info
->stream
, "$%d", regno
);
1049 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1053 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1057 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1060 case OP_REG_R5900_I
:
1061 info
->fprintf_func (info
->stream
, "$I");
1064 case OP_REG_R5900_Q
:
1065 info
->fprintf_func (info
->stream
, "$Q");
1068 case OP_REG_R5900_R
:
1069 info
->fprintf_func (info
->stream
, "$R");
1072 case OP_REG_R5900_ACC
:
1073 info
->fprintf_func (info
->stream
, "$ACC");
1077 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1080 case OP_REG_MSA_CTRL
:
1081 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1087 /* Used to track the state carried over from previous operands in
1089 struct mips_print_arg_state
{
1090 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1091 where the value is known to be unsigned and small. */
1092 unsigned int last_int
;
1094 /* The type and number of the last OP_REG seen. We only use this for
1095 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1096 enum mips_reg_operand_type last_reg_type
;
1097 unsigned int last_regno
;
1098 unsigned int dest_regno
;
1099 unsigned int seen_dest
;
1102 /* Initialize STATE for the start of an instruction. */
1105 init_print_arg_state (struct mips_print_arg_state
*state
)
1107 memset (state
, 0, sizeof (*state
));
1110 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1111 whose value is given by UVAL. */
1114 print_vu0_channel (struct disassemble_info
*info
,
1115 const struct mips_operand
*operand
, unsigned int uval
)
1117 if (operand
->size
== 4)
1118 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1119 uval
& 8 ? "x" : "",
1120 uval
& 4 ? "y" : "",
1121 uval
& 2 ? "z" : "",
1122 uval
& 1 ? "w" : "");
1123 else if (operand
->size
== 2)
1124 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1129 /* Record information about a register operand. */
1132 mips_seen_register (struct mips_print_arg_state
*state
,
1134 enum mips_reg_operand_type reg_type
)
1136 state
->last_reg_type
= reg_type
;
1137 state
->last_regno
= regno
;
1139 if (!state
->seen_dest
)
1141 state
->seen_dest
= 1;
1142 state
->dest_regno
= regno
;
1146 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1147 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1148 the base address for OP_PCREL operands. */
1151 print_insn_arg (struct disassemble_info
*info
,
1152 struct mips_print_arg_state
*state
,
1153 const struct mips_opcode
*opcode
,
1154 const struct mips_operand
*operand
,
1158 const fprintf_ftype infprintf
= info
->fprintf_func
;
1159 void *is
= info
->stream
;
1161 switch (operand
->type
)
1165 const struct mips_int_operand
*int_op
;
1167 int_op
= (const struct mips_int_operand
*) operand
;
1168 uval
= mips_decode_int_operand (int_op
, uval
);
1169 state
->last_int
= uval
;
1170 if (int_op
->print_hex
)
1171 infprintf (is
, "0x%x", uval
);
1173 infprintf (is
, "%d", uval
);
1179 const struct mips_mapped_int_operand
*mint_op
;
1181 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1182 uval
= mint_op
->int_map
[uval
];
1183 state
->last_int
= uval
;
1184 if (mint_op
->print_hex
)
1185 infprintf (is
, "0x%x", uval
);
1187 infprintf (is
, "%d", uval
);
1193 const struct mips_msb_operand
*msb_op
;
1195 msb_op
= (const struct mips_msb_operand
*) operand
;
1196 uval
+= msb_op
->bias
;
1197 if (msb_op
->add_lsb
)
1198 uval
-= state
->last_int
;
1199 infprintf (is
, "0x%x", uval
);
1204 case OP_OPTIONAL_REG
:
1206 const struct mips_reg_operand
*reg_op
;
1208 reg_op
= (const struct mips_reg_operand
*) operand
;
1209 uval
= mips_decode_reg_operand (reg_op
, uval
);
1210 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1212 mips_seen_register (state
, uval
, reg_op
->reg_type
);
1218 const struct mips_reg_pair_operand
*pair_op
;
1220 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1221 print_reg (info
, opcode
, pair_op
->reg_type
,
1222 pair_op
->reg1_map
[uval
]);
1223 infprintf (is
, ",");
1224 print_reg (info
, opcode
, pair_op
->reg_type
,
1225 pair_op
->reg2_map
[uval
]);
1231 const struct mips_pcrel_operand
*pcrel_op
;
1233 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1234 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1236 /* Preserve the ISA bit for the GDB disassembler,
1237 otherwise clear it. */
1238 if (info
->flavour
!= bfd_target_unknown_flavour
)
1241 (*info
->print_address_func
) (info
->target
, info
);
1246 infprintf (is
, "%d", uval
);
1249 case OP_ADDIUSP_INT
:
1253 sval
= mips_signed_operand (operand
, uval
) * 4;
1254 if (sval
>= -8 && sval
< 8)
1256 infprintf (is
, "%d", sval
);
1260 case OP_CLO_CLZ_DEST
:
1262 unsigned int reg1
, reg2
;
1266 /* If one is zero use the other. */
1267 if (reg1
== reg2
|| reg2
== 0)
1268 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1270 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1272 /* Bogus, result depends on processor. */
1273 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1274 mips_gpr_names
[reg2
]);
1280 case OP_NON_ZERO_REG
:
1282 print_reg (info
, opcode
, OP_REG_GP
, uval
& 31);
1283 mips_seen_register (state
, uval
, OP_REG_GP
);
1287 case OP_LWM_SWM_LIST
:
1288 if (operand
->size
== 2)
1291 infprintf (is
, "%s,%s",
1293 mips_gpr_names
[31]);
1295 infprintf (is
, "%s-%s,%s",
1297 mips_gpr_names
[16 + uval
],
1298 mips_gpr_names
[31]);
1304 s_reg_encode
= uval
& 0xf;
1305 if (s_reg_encode
!= 0)
1307 if (s_reg_encode
== 1)
1308 infprintf (is
, "%s", mips_gpr_names
[16]);
1309 else if (s_reg_encode
< 9)
1310 infprintf (is
, "%s-%s",
1312 mips_gpr_names
[15 + s_reg_encode
]);
1313 else if (s_reg_encode
== 9)
1314 infprintf (is
, "%s-%s,%s",
1317 mips_gpr_names
[30]);
1319 infprintf (is
, "UNKNOWN");
1322 if (uval
& 0x10) /* For ra. */
1324 if (s_reg_encode
== 0)
1325 infprintf (is
, "%s", mips_gpr_names
[31]);
1327 infprintf (is
, ",%s", mips_gpr_names
[31]);
1332 case OP_ENTRY_EXIT_LIST
:
1335 unsigned int amask
, smask
;
1338 amask
= (uval
>> 3) & 7;
1339 if (amask
> 0 && amask
< 5)
1341 infprintf (is
, "%s", mips_gpr_names
[4]);
1343 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1347 smask
= (uval
>> 1) & 3;
1350 infprintf (is
, "%s??", sep
);
1355 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1357 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1363 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1367 if (amask
== 5 || amask
== 6)
1369 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1371 infprintf (is
, "-%s", mips_fpr_names
[1]);
1376 case OP_SAVE_RESTORE_LIST
:
1377 /* Should be handled by the caller due to extend behavior. */
1380 case OP_MDMX_IMM_REG
:
1386 if ((vsel
& 0x10) == 0)
1391 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1392 if ((vsel
& 1) == 0)
1394 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1395 infprintf (is
, "[%d]", vsel
>> 1);
1397 else if ((vsel
& 0x08) == 0)
1398 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1400 infprintf (is
, "0x%x", uval
);
1404 case OP_REPEAT_PREV_REG
:
1405 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1408 case OP_REPEAT_DEST_REG
:
1409 print_reg (info
, opcode
, state
->last_reg_type
, state
->dest_regno
);
1413 infprintf (is
, "$pc");
1417 case OP_VU0_MATCH_SUFFIX
:
1418 print_vu0_channel (info
, operand
, uval
);
1422 infprintf (is
, "[%d]", uval
);
1426 infprintf (is
, "[");
1427 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1428 infprintf (is
, "]");
1433 /* Validate the arguments for INSN, which is described by OPCODE.
1434 Use DECODE_OPERAND to get the encoding of each operand. */
1437 validate_insn_args (const struct mips_opcode
*opcode
,
1438 const struct mips_operand
*(*decode_operand
) (const char *),
1441 struct mips_print_arg_state state
;
1442 const struct mips_operand
*operand
;
1446 init_print_arg_state (&state
);
1447 for (s
= opcode
->args
; *s
; ++s
)
1461 operand
= decode_operand (s
);
1465 uval
= mips_extract_operand (operand
, insn
);
1466 switch (operand
->type
)
1469 case OP_OPTIONAL_REG
:
1471 const struct mips_reg_operand
*reg_op
;
1473 reg_op
= (const struct mips_reg_operand
*) operand
;
1474 uval
= mips_decode_reg_operand (reg_op
, uval
);
1475 mips_seen_register (&state
, uval
, reg_op
->reg_type
);
1481 unsigned int reg1
, reg2
;
1486 if (reg1
!= reg2
|| reg1
== 0)
1493 const struct mips_check_prev_operand
*prev_op
;
1495 prev_op
= (const struct mips_check_prev_operand
*) operand
;
1497 if (!prev_op
->zero_ok
&& uval
== 0)
1500 if (((prev_op
->less_than_ok
&& uval
< state
.last_regno
)
1501 || (prev_op
->greater_than_ok
&& uval
> state
.last_regno
)
1502 || (prev_op
->equal_ok
&& uval
== state
.last_regno
)))
1508 case OP_NON_ZERO_REG
:
1521 case OP_ADDIUSP_INT
:
1522 case OP_CLO_CLZ_DEST
:
1523 case OP_LWM_SWM_LIST
:
1524 case OP_ENTRY_EXIT_LIST
:
1525 case OP_MDMX_IMM_REG
:
1526 case OP_REPEAT_PREV_REG
:
1527 case OP_REPEAT_DEST_REG
:
1530 case OP_VU0_MATCH_SUFFIX
:
1535 case OP_SAVE_RESTORE_LIST
:
1536 /* Should be handled by the caller due to extend behavior. */
1540 if (*s
== 'm' || *s
== '+' || *s
== '-')
1547 /* Print the arguments for INSN, which is described by OPCODE.
1548 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1549 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1550 operand is for a branch or jump. */
1553 print_insn_args (struct disassemble_info
*info
,
1554 const struct mips_opcode
*opcode
,
1555 const struct mips_operand
*(*decode_operand
) (const char *),
1556 unsigned int insn
, bfd_vma insn_pc
, unsigned int length
)
1558 const fprintf_ftype infprintf
= info
->fprintf_func
;
1559 void *is
= info
->stream
;
1560 struct mips_print_arg_state state
;
1561 const struct mips_operand
*operand
;
1564 init_print_arg_state (&state
);
1565 for (s
= opcode
->args
; *s
; ++s
)
1572 infprintf (is
, "%c", *s
);
1577 infprintf (is
, "%c%c", *s
, *s
);
1581 operand
= decode_operand (s
);
1584 /* xgettext:c-format */
1586 _("# internal error, undefined operand in `%s %s'"),
1587 opcode
->name
, opcode
->args
);
1590 if (operand
->type
== OP_REG
1593 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1595 /* Coprocessor register 0 with sel field (MT ASE). */
1596 const struct mips_cp0sel_name
*n
;
1597 unsigned int reg
, sel
;
1599 reg
= mips_extract_operand (operand
, insn
);
1601 operand
= decode_operand (s
);
1602 sel
= mips_extract_operand (operand
, insn
);
1604 /* CP0 register including 'sel' code for mftc0, to be
1605 printed textually if known. If not known, print both
1606 CP0 register name and sel numerically since CP0 register
1607 with sel 0 may have a name unrelated to register being
1609 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1610 mips_cp0sel_names_len
,
1613 infprintf (is
, "%s", n
->name
);
1615 infprintf (is
, "$%d,%d", reg
, sel
);
1619 bfd_vma base_pc
= insn_pc
;
1621 /* Adjust the PC relative base so that branch/jump insns use
1622 the following PC as the base but genuinely PC relative
1623 operands use the current PC. */
1624 if (operand
->type
== OP_PCREL
)
1626 const struct mips_pcrel_operand
*pcrel_op
;
1628 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1629 /* The include_isa_bit flag is sufficient to distinguish
1630 branch/jump from other PC relative operands. */
1631 if (pcrel_op
->include_isa_bit
)
1635 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1636 mips_extract_operand (operand
, insn
));
1638 if (*s
== 'm' || *s
== '+' || *s
== '-')
1645 /* Print the mips instruction at address MEMADDR in debugged memory,
1646 on using INFO. Returns length of the instruction, in bytes, which is
1647 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1648 this is little-endian code. */
1651 print_insn_mips (bfd_vma memaddr
,
1653 struct disassemble_info
*info
)
1655 #define GET_OP(insn, field) \
1656 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1657 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1658 const fprintf_ftype infprintf
= info
->fprintf_func
;
1659 const struct mips_opcode
*op
;
1660 static bfd_boolean init
= 0;
1661 void *is
= info
->stream
;
1663 /* Build a hash table to shorten the search time. */
1668 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1670 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1672 if (op
->pinfo
== INSN_MACRO
1673 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1675 if (i
== GET_OP (op
->match
, OP
))
1686 info
->bytes_per_chunk
= INSNLEN
;
1687 info
->display_endian
= info
->endian
;
1688 info
->insn_info_valid
= 1;
1689 info
->branch_delay_insns
= 0;
1690 info
->data_size
= 0;
1691 info
->insn_type
= dis_nonbranch
;
1695 op
= mips_hash
[GET_OP (word
, OP
)];
1698 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1700 if (op
->pinfo
!= INSN_MACRO
1701 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1702 && (word
& op
->mask
) == op
->match
)
1704 /* We always disassemble the jalx instruction, except for MIPS r6. */
1705 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1706 && (strcmp (op
->name
, "jalx")
1707 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS32R6
1708 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R6
))
1711 /* Figure out instruction type and branch delay information. */
1712 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1714 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1715 info
->insn_type
= dis_jsr
;
1717 info
->insn_type
= dis_branch
;
1718 info
->branch_delay_insns
= 1;
1720 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1721 | INSN_COND_BRANCH_LIKELY
)) != 0)
1723 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1724 info
->insn_type
= dis_condjsr
;
1726 info
->insn_type
= dis_condbranch
;
1727 info
->branch_delay_insns
= 1;
1729 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1730 | INSN_LOAD_MEMORY
)) != 0)
1731 info
->insn_type
= dis_dref
;
1733 if (!validate_insn_args (op
, decode_mips_operand
, word
))
1736 infprintf (is
, "%s", op
->name
);
1737 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1741 infprintf (is
, ".");
1742 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1743 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1748 infprintf (is
, "\t");
1749 print_insn_args (info
, op
, decode_mips_operand
, word
,
1759 /* Handle undefined instructions. */
1760 info
->insn_type
= dis_noninsn
;
1761 infprintf (is
, "0x%x", word
);
1765 /* Disassemble an operand for a mips16 instruction. */
1768 print_mips16_insn_arg (struct disassemble_info
*info
,
1769 struct mips_print_arg_state
*state
,
1770 const struct mips_opcode
*opcode
,
1771 char type
, bfd_vma memaddr
,
1772 unsigned insn
, bfd_boolean use_extend
,
1773 unsigned extend
, bfd_boolean is_offset
)
1775 const fprintf_ftype infprintf
= info
->fprintf_func
;
1776 void *is
= info
->stream
;
1777 const struct mips_operand
*operand
, *ext_operand
;
1789 infprintf (is
, "%c", type
);
1793 operand
= decode_mips16_operand (type
, FALSE
);
1796 /* xgettext:c-format */
1797 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
1798 opcode
->name
, opcode
->args
);
1802 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1804 /* Handle this case here because of the complex interation
1805 with the EXTEND opcode. */
1806 unsigned int amask
, nargs
, nstatics
, nsreg
, smask
, frame_size
, i
, j
;
1809 amask
= extend
& 0xf;
1810 if (amask
== MIPS16_ALL_ARGS
)
1815 else if (amask
== MIPS16_ALL_STATICS
)
1823 nstatics
= amask
& 3;
1829 infprintf (is
, "%s", mips_gpr_names
[4]);
1831 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1835 frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
1836 if (frame_size
== 0 && !use_extend
)
1838 infprintf (is
, "%s%d", sep
, frame_size
);
1840 if (insn
& 0x40) /* $ra */
1841 infprintf (is
, ",%s", mips_gpr_names
[31]);
1843 nsreg
= (extend
>> 8) & 0x7;
1845 if (insn
& 0x20) /* $s0 */
1847 if (insn
& 0x10) /* $s1 */
1849 if (nsreg
> 0) /* $s2-$s8 */
1850 smask
|= ((1 << nsreg
) - 1) << 2;
1852 for (i
= 0; i
< 9; i
++)
1853 if (smask
& (1 << i
))
1855 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1856 /* Skip over string of set bits. */
1857 for (j
= i
; smask
& (2 << j
); j
++)
1860 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1863 /* Statics $ax - $a3. */
1865 infprintf (is
, ",%s", mips_gpr_names
[7]);
1866 else if (nstatics
> 0)
1867 infprintf (is
, ",%s-%s",
1868 mips_gpr_names
[7 - nstatics
+ 1],
1873 if (is_offset
&& operand
->type
== OP_INT
)
1875 const struct mips_int_operand
*int_op
;
1877 int_op
= (const struct mips_int_operand
*) operand
;
1878 info
->insn_type
= dis_dref
;
1879 info
->data_size
= 1 << int_op
->shift
;
1882 if (operand
->size
== 26)
1883 /* In this case INSN is the first two bytes of the instruction
1884 and EXTEND is the second two bytes. */
1885 uval
= ((insn
& 0x1f) << 21) | ((insn
& 0x3e0) << 11) | extend
;
1888 /* Calculate the full field value. */
1889 uval
= mips_extract_operand (operand
, insn
);
1892 ext_operand
= decode_mips16_operand (type
, TRUE
);
1893 if (ext_operand
!= operand
)
1895 operand
= ext_operand
;
1896 if (operand
->size
== 16)
1897 uval
= (((extend
& 0x1f) << 11) | (extend
& 0x7e0)
1899 else if (operand
->size
== 15)
1900 uval
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1902 uval
= ((((extend
>> 6) & 0x1f) | (extend
& 0x20))
1903 & ((1U << operand
->size
) - 1));
1908 baseaddr
= memaddr
+ 2;
1909 if (operand
->type
== OP_PCREL
)
1911 const struct mips_pcrel_operand
*pcrel_op
;
1913 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1914 if (!pcrel_op
->include_isa_bit
&& use_extend
)
1915 baseaddr
= memaddr
- 2;
1916 else if (!pcrel_op
->include_isa_bit
)
1920 /* If this instruction is in the delay slot of a JR
1921 instruction, the base address is the address of the
1922 JR instruction. If it is in the delay slot of a JALR
1923 instruction, the base address is the address of the
1924 JALR instruction. This test is unreliable: we have
1925 no way of knowing whether the previous word is
1926 instruction or data. */
1927 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
1928 && (((info
->endian
== BFD_ENDIAN_BIG
1929 ? bfd_getb16 (buffer
)
1930 : bfd_getl16 (buffer
))
1931 & 0xf800) == 0x1800))
1932 baseaddr
= memaddr
- 4;
1933 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
1935 && (((info
->endian
== BFD_ENDIAN_BIG
1936 ? bfd_getb16 (buffer
)
1937 : bfd_getl16 (buffer
))
1938 & 0xf81f) == 0xe800))
1939 baseaddr
= memaddr
- 2;
1945 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
1951 /* Check if the given address is the last word of a MIPS16 PLT entry.
1952 This word is data and depending on the value it may interfere with
1953 disassembly of further PLT entries. We make use of the fact PLT
1954 symbols are marked BSF_SYNTHETIC. */
1956 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
1960 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
1961 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
1967 /* Disassemble mips16 instructions. */
1970 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
1972 const fprintf_ftype infprintf
= info
->fprintf_func
;
1977 bfd_boolean use_extend
;
1979 const struct mips_opcode
*op
, *opend
;
1980 struct mips_print_arg_state state
;
1981 void *is
= info
->stream
;
1983 info
->bytes_per_chunk
= 2;
1984 info
->display_endian
= info
->endian
;
1985 info
->insn_info_valid
= 1;
1986 info
->branch_delay_insns
= 0;
1987 info
->data_size
= 0;
1991 #define GET_OP(insn, field) \
1992 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1993 /* Decode PLT entry's GOT slot address word. */
1994 if (is_mips16_plt_tail (info
, memaddr
))
1996 info
->insn_type
= dis_noninsn
;
1997 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
2000 unsigned int gotslot
;
2002 if (info
->endian
== BFD_ENDIAN_BIG
)
2003 gotslot
= bfd_getb32 (buffer
);
2005 gotslot
= bfd_getl32 (buffer
);
2006 infprintf (is
, ".word\t0x%x", gotslot
);
2013 info
->insn_type
= dis_nonbranch
;
2014 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2018 (*info
->memory_error_func
) (status
, memaddr
, info
);
2024 if (info
->endian
== BFD_ENDIAN_BIG
)
2025 insn
= bfd_getb16 (buffer
);
2027 insn
= bfd_getl16 (buffer
);
2029 /* Handle the extend opcode specially. */
2031 if ((insn
& 0xf800) == 0xf000)
2034 extend
= insn
& 0x7ff;
2038 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2041 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2042 (*info
->memory_error_func
) (status
, memaddr
, info
);
2046 if (info
->endian
== BFD_ENDIAN_BIG
)
2047 insn
= bfd_getb16 (buffer
);
2049 insn
= bfd_getl16 (buffer
);
2051 /* Check for an extend opcode followed by an extend opcode. */
2052 if ((insn
& 0xf800) == 0xf000)
2054 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2055 info
->insn_type
= dis_noninsn
;
2062 /* FIXME: Should probably use a hash table on the major opcode here. */
2064 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
2065 for (op
= mips16_opcodes
; op
< opend
; op
++)
2067 if (op
->pinfo
!= INSN_MACRO
2068 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2069 && (insn
& op
->mask
) == op
->match
)
2073 if (op
->args
[0] == 'a' || op
->args
[0] == 'i')
2077 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
2078 info
->insn_type
= dis_noninsn
;
2086 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
2091 if (info
->endian
== BFD_ENDIAN_BIG
)
2092 extend
= bfd_getb16 (buffer
);
2094 extend
= bfd_getl16 (buffer
);
2099 infprintf (is
, "%s", op
->name
);
2100 if (op
->args
[0] != '\0')
2101 infprintf (is
, "\t");
2103 init_print_arg_state (&state
);
2104 for (s
= op
->args
; *s
!= '\0'; s
++)
2108 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
2110 /* Skip the register and the comma. */
2116 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
2118 /* Skip the register and the comma. */
2122 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
, insn
,
2123 use_extend
, extend
, s
[1] == '(');
2126 /* Figure out branch instruction type and delay slot information. */
2127 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
2128 info
->branch_delay_insns
= 1;
2129 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
2130 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
2132 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2133 info
->insn_type
= dis_jsr
;
2135 info
->insn_type
= dis_branch
;
2137 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
2138 info
->insn_type
= dis_condbranch
;
2146 infprintf (is
, "0x%x", extend
| 0xf000);
2147 infprintf (is
, "0x%x", insn
);
2148 info
->insn_type
= dis_noninsn
;
2153 /* Disassemble microMIPS instructions. */
2156 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
2158 const fprintf_ftype infprintf
= info
->fprintf_func
;
2159 const struct mips_opcode
*op
, *opend
;
2160 void *is
= info
->stream
;
2162 unsigned int higher
;
2163 unsigned int length
;
2167 info
->bytes_per_chunk
= 2;
2168 info
->display_endian
= info
->endian
;
2169 info
->insn_info_valid
= 1;
2170 info
->branch_delay_insns
= 0;
2171 info
->data_size
= 0;
2172 info
->insn_type
= dis_nonbranch
;
2176 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2179 (*info
->memory_error_func
) (status
, memaddr
, info
);
2185 if (info
->endian
== BFD_ENDIAN_BIG
)
2186 insn
= bfd_getb16 (buffer
);
2188 insn
= bfd_getl16 (buffer
);
2190 if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2192 /* This is a 32-bit microMIPS instruction. */
2195 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2198 infprintf (is
, "micromips 0x%x", higher
);
2199 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2203 if (info
->endian
== BFD_ENDIAN_BIG
)
2204 insn
= bfd_getb16 (buffer
);
2206 insn
= bfd_getl16 (buffer
);
2208 insn
= insn
| (higher
<< 16);
2213 /* FIXME: Should probably use a hash table on the major opcode here. */
2215 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2216 for (op
= micromips_opcodes
; op
< opend
; op
++)
2218 if (op
->pinfo
!= INSN_MACRO
2219 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2220 && (insn
& op
->mask
) == op
->match
2221 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2222 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2224 if (!validate_insn_args (op
, decode_micromips_operand
, insn
))
2227 infprintf (is
, "%s", op
->name
);
2231 infprintf (is
, "\t");
2232 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2233 memaddr
+ 1, length
);
2236 /* Figure out instruction type and branch delay information. */
2238 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2239 info
->branch_delay_insns
= 1;
2240 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2241 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2243 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2244 info
->insn_type
= dis_jsr
;
2246 info
->insn_type
= dis_branch
;
2248 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2249 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2251 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2252 info
->insn_type
= dis_condjsr
;
2254 info
->insn_type
= dis_condbranch
;
2257 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2258 info
->insn_type
= dis_dref
;
2264 infprintf (is
, "0x%x", insn
);
2265 info
->insn_type
= dis_noninsn
;
2270 /* Return 1 if a symbol associated with the location being disassembled
2271 indicates a compressed mode, either MIPS16 or microMIPS, according to
2272 MICROMIPS_P. We iterate over all the symbols at the address being
2273 considered assuming if at least one of them indicates code compression,
2274 then such code has been genuinely produced here (other symbols could
2275 have been derived from function symbols defined elsewhere or could
2276 define data). Otherwise, return 0. */
2279 is_compressed_mode_p (struct disassemble_info
*info
, bfd_boolean micromips_p
)
2284 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2285 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2287 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2289 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2291 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2292 && info
->symtab
[i
]->section
== info
->section
)
2294 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2296 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2298 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2305 /* In an environment where we do not know the symbol type of the
2306 instruction we are forced to assume that the low order bit of the
2307 instructions' address may mark it as a mips16 instruction. If we
2308 are single stepping, or the pc is within the disassembled function,
2309 this works. Otherwise, we need a clue. Sometimes. */
2312 _print_insn_mips (bfd_vma memaddr
,
2313 struct disassemble_info
*info
,
2314 enum bfd_endian endianness
)
2316 bfd_byte buffer
[INSNLEN
];
2319 set_default_mips_dis_options (info
);
2320 parse_mips_dis_options (info
->disassembler_options
);
2322 if (info
->mach
== bfd_mach_mips16
)
2323 return print_insn_mips16 (memaddr
, info
);
2324 if (info
->mach
== bfd_mach_mips_micromips
)
2325 return print_insn_micromips (memaddr
, info
);
2328 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2329 /* Only a few tools will work this way. */
2333 return print_insn_micromips (memaddr
, info
);
2335 return print_insn_mips16 (memaddr
, info
);
2339 #if SYMTAB_AVAILABLE
2340 if (is_compressed_mode_p (info
, TRUE
))
2341 return print_insn_micromips (memaddr
, info
);
2342 if (is_compressed_mode_p (info
, FALSE
))
2343 return print_insn_mips16 (memaddr
, info
);
2346 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2351 if (endianness
== BFD_ENDIAN_BIG
)
2352 insn
= bfd_getb32 (buffer
);
2354 insn
= bfd_getl32 (buffer
);
2356 return print_insn_mips (memaddr
, insn
, info
);
2360 (*info
->memory_error_func
) (status
, memaddr
, info
);
2366 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2368 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2372 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2374 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2378 print_mips_disassembler_options (FILE *stream
)
2382 fprintf (stream
, _("\n\
2383 The following MIPS specific disassembler options are supported for use\n\
2384 with the -M switch (multiple options should be separated by commas):\n"));
2386 fprintf (stream
, _("\n\
2387 msa Recognize MSA instructions.\n"));
2389 fprintf (stream
, _("\n\
2390 virt Recognize the virtualization ASE instructions.\n"));
2392 fprintf (stream
, _("\n\
2393 xpa Recognize the eXtended Physical Address (XPA)\n\
2394 ASE instructions.\n"));
2396 fprintf (stream
, _("\n\
2397 gpr-names=ABI Print GPR names according to specified ABI.\n\
2398 Default: based on binary being disassembled.\n"));
2400 fprintf (stream
, _("\n\
2401 fpr-names=ABI Print FPR names according to specified ABI.\n\
2402 Default: numeric.\n"));
2404 fprintf (stream
, _("\n\
2405 cp0-names=ARCH Print CP0 register names according to\n\
2406 specified architecture.\n\
2407 Default: based on binary being disassembled.\n"));
2409 fprintf (stream
, _("\n\
2410 hwr-names=ARCH Print HWR names according to specified \n\
2412 Default: based on binary being disassembled.\n"));
2414 fprintf (stream
, _("\n\
2415 reg-names=ABI Print GPR and FPR names according to\n\
2416 specified ABI.\n"));
2418 fprintf (stream
, _("\n\
2419 reg-names=ARCH Print CP0 register and HWR names according to\n\
2420 specified architecture.\n"));
2422 fprintf (stream
, _("\n\
2423 For the options above, the following values are supported for \"ABI\":\n\
2425 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2426 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2427 fprintf (stream
, _("\n"));
2429 fprintf (stream
, _("\n\
2430 For the options above, The following values are supported for \"ARCH\":\n\
2432 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2433 if (*mips_arch_choices
[i
].name
!= '\0')
2434 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2435 fprintf (stream
, _("\n"));
2437 fprintf (stream
, _("\n"));