1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2014 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 struct mips_cp0sel_name mips_cp0sel_names_mipsr5900
[] =
163 { 24, 3, "c0_iabm" },
165 { 24, 5, "c0_dabm" },
167 { 24, 7, "c0_dvbm" },
168 { 25, 1, "c0_perfcnt,1" },
169 { 25, 2, "c0_perfcnt,2" }
172 static const char * const mips_cp0_names_mips3264
[32] =
174 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
175 "c0_context", "c0_pagemask", "c0_wired", "$7",
176 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
177 "c0_status", "c0_cause", "c0_epc", "c0_prid",
178 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
179 "c0_xcontext", "$21", "$22", "c0_debug",
180 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
181 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
184 static const char * const mips_cp1_names_mips3264
[32] =
186 "c1_fir", "c1_ufr", "$2", "$3",
187 "c1_unfr", "$5", "$6", "$7",
188 "$8", "$9", "$10", "$11",
189 "$12", "$13", "$14", "$15",
190 "$16", "$17", "$18", "$19",
191 "$20", "$21", "$22", "$23",
192 "$24", "c1_fccr", "c1_fexr", "$27",
193 "c1_fenr", "$29", "$30", "c1_fcsr"
196 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264
[] =
198 { 16, 1, "c0_config1" },
199 { 16, 2, "c0_config2" },
200 { 16, 3, "c0_config3" },
201 { 18, 1, "c0_watchlo,1" },
202 { 18, 2, "c0_watchlo,2" },
203 { 18, 3, "c0_watchlo,3" },
204 { 18, 4, "c0_watchlo,4" },
205 { 18, 5, "c0_watchlo,5" },
206 { 18, 6, "c0_watchlo,6" },
207 { 18, 7, "c0_watchlo,7" },
208 { 19, 1, "c0_watchhi,1" },
209 { 19, 2, "c0_watchhi,2" },
210 { 19, 3, "c0_watchhi,3" },
211 { 19, 4, "c0_watchhi,4" },
212 { 19, 5, "c0_watchhi,5" },
213 { 19, 6, "c0_watchhi,6" },
214 { 19, 7, "c0_watchhi,7" },
215 { 25, 1, "c0_perfcnt,1" },
216 { 25, 2, "c0_perfcnt,2" },
217 { 25, 3, "c0_perfcnt,3" },
218 { 25, 4, "c0_perfcnt,4" },
219 { 25, 5, "c0_perfcnt,5" },
220 { 25, 6, "c0_perfcnt,6" },
221 { 25, 7, "c0_perfcnt,7" },
222 { 27, 1, "c0_cacheerr,1" },
223 { 27, 2, "c0_cacheerr,2" },
224 { 27, 3, "c0_cacheerr,3" },
225 { 28, 1, "c0_datalo" },
226 { 29, 1, "c0_datahi" }
229 static const char * const mips_cp0_names_mips3264r2
[32] =
231 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
232 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
233 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
234 "c0_status", "c0_cause", "c0_epc", "c0_prid",
235 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
236 "c0_xcontext", "$21", "$22", "c0_debug",
237 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
238 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
241 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2
[] =
243 { 4, 1, "c0_contextconfig" },
244 { 0, 1, "c0_mvpcontrol" },
245 { 0, 2, "c0_mvpconf0" },
246 { 0, 3, "c0_mvpconf1" },
247 { 1, 1, "c0_vpecontrol" },
248 { 1, 2, "c0_vpeconf0" },
249 { 1, 3, "c0_vpeconf1" },
250 { 1, 4, "c0_yqmask" },
251 { 1, 5, "c0_vpeschedule" },
252 { 1, 6, "c0_vpeschefback" },
253 { 2, 1, "c0_tcstatus" },
254 { 2, 2, "c0_tcbind" },
255 { 2, 3, "c0_tcrestart" },
256 { 2, 4, "c0_tchalt" },
257 { 2, 5, "c0_tccontext" },
258 { 2, 6, "c0_tcschedule" },
259 { 2, 7, "c0_tcschefback" },
260 { 5, 1, "c0_pagegrain" },
261 { 6, 1, "c0_srsconf0" },
262 { 6, 2, "c0_srsconf1" },
263 { 6, 3, "c0_srsconf2" },
264 { 6, 4, "c0_srsconf3" },
265 { 6, 5, "c0_srsconf4" },
266 { 12, 1, "c0_intctl" },
267 { 12, 2, "c0_srsctl" },
268 { 12, 3, "c0_srsmap" },
269 { 15, 1, "c0_ebase" },
270 { 16, 1, "c0_config1" },
271 { 16, 2, "c0_config2" },
272 { 16, 3, "c0_config3" },
273 { 18, 1, "c0_watchlo,1" },
274 { 18, 2, "c0_watchlo,2" },
275 { 18, 3, "c0_watchlo,3" },
276 { 18, 4, "c0_watchlo,4" },
277 { 18, 5, "c0_watchlo,5" },
278 { 18, 6, "c0_watchlo,6" },
279 { 18, 7, "c0_watchlo,7" },
280 { 19, 1, "c0_watchhi,1" },
281 { 19, 2, "c0_watchhi,2" },
282 { 19, 3, "c0_watchhi,3" },
283 { 19, 4, "c0_watchhi,4" },
284 { 19, 5, "c0_watchhi,5" },
285 { 19, 6, "c0_watchhi,6" },
286 { 19, 7, "c0_watchhi,7" },
287 { 23, 1, "c0_tracecontrol" },
288 { 23, 2, "c0_tracecontrol2" },
289 { 23, 3, "c0_usertracedata" },
290 { 23, 4, "c0_tracebpc" },
291 { 25, 1, "c0_perfcnt,1" },
292 { 25, 2, "c0_perfcnt,2" },
293 { 25, 3, "c0_perfcnt,3" },
294 { 25, 4, "c0_perfcnt,4" },
295 { 25, 5, "c0_perfcnt,5" },
296 { 25, 6, "c0_perfcnt,6" },
297 { 25, 7, "c0_perfcnt,7" },
298 { 27, 1, "c0_cacheerr,1" },
299 { 27, 2, "c0_cacheerr,2" },
300 { 27, 3, "c0_cacheerr,3" },
301 { 28, 1, "c0_datalo" },
302 { 28, 2, "c0_taglo1" },
303 { 28, 3, "c0_datalo1" },
304 { 28, 4, "c0_taglo2" },
305 { 28, 5, "c0_datalo2" },
306 { 28, 6, "c0_taglo3" },
307 { 28, 7, "c0_datalo3" },
308 { 29, 1, "c0_datahi" },
309 { 29, 2, "c0_taghi1" },
310 { 29, 3, "c0_datahi1" },
311 { 29, 4, "c0_taghi2" },
312 { 29, 5, "c0_datahi2" },
313 { 29, 6, "c0_taghi3" },
314 { 29, 7, "c0_datahi3" },
317 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
318 static const char * const mips_cp0_names_sb1
[32] =
320 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
321 "c0_context", "c0_pagemask", "c0_wired", "$7",
322 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
323 "c0_status", "c0_cause", "c0_epc", "c0_prid",
324 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
325 "c0_xcontext", "$21", "$22", "c0_debug",
326 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
327 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
330 static const struct mips_cp0sel_name mips_cp0sel_names_sb1
[] =
332 { 16, 1, "c0_config1" },
333 { 18, 1, "c0_watchlo,1" },
334 { 19, 1, "c0_watchhi,1" },
335 { 22, 0, "c0_perftrace" },
336 { 23, 3, "c0_edebug" },
337 { 25, 1, "c0_perfcnt,1" },
338 { 25, 2, "c0_perfcnt,2" },
339 { 25, 3, "c0_perfcnt,3" },
340 { 25, 4, "c0_perfcnt,4" },
341 { 25, 5, "c0_perfcnt,5" },
342 { 25, 6, "c0_perfcnt,6" },
343 { 25, 7, "c0_perfcnt,7" },
344 { 26, 1, "c0_buserr_pa" },
345 { 27, 1, "c0_cacheerr_d" },
346 { 27, 3, "c0_cacheerr_d_pa" },
347 { 28, 1, "c0_datalo_i" },
348 { 28, 2, "c0_taglo_d" },
349 { 28, 3, "c0_datalo_d" },
350 { 29, 1, "c0_datahi_i" },
351 { 29, 2, "c0_taghi_d" },
352 { 29, 3, "c0_datahi_d" },
355 /* Xlr cop0 register names. */
356 static const char * const mips_cp0_names_xlr
[32] = {
357 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
358 "c0_context", "c0_pagemask", "c0_wired", "$7",
359 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
360 "c0_status", "c0_cause", "c0_epc", "c0_prid",
361 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
362 "c0_xcontext", "$21", "$22", "c0_debug",
363 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
364 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
367 /* XLR's CP0 Select Registers. */
369 static const struct mips_cp0sel_name mips_cp0sel_names_xlr
[] = {
370 { 9, 6, "c0_extintreq" },
371 { 9, 7, "c0_extintmask" },
372 { 15, 1, "c0_ebase" },
373 { 16, 1, "c0_config1" },
374 { 16, 2, "c0_config2" },
375 { 16, 3, "c0_config3" },
376 { 16, 7, "c0_procid2" },
377 { 18, 1, "c0_watchlo,1" },
378 { 18, 2, "c0_watchlo,2" },
379 { 18, 3, "c0_watchlo,3" },
380 { 18, 4, "c0_watchlo,4" },
381 { 18, 5, "c0_watchlo,5" },
382 { 18, 6, "c0_watchlo,6" },
383 { 18, 7, "c0_watchlo,7" },
384 { 19, 1, "c0_watchhi,1" },
385 { 19, 2, "c0_watchhi,2" },
386 { 19, 3, "c0_watchhi,3" },
387 { 19, 4, "c0_watchhi,4" },
388 { 19, 5, "c0_watchhi,5" },
389 { 19, 6, "c0_watchhi,6" },
390 { 19, 7, "c0_watchhi,7" },
391 { 25, 1, "c0_perfcnt,1" },
392 { 25, 2, "c0_perfcnt,2" },
393 { 25, 3, "c0_perfcnt,3" },
394 { 25, 4, "c0_perfcnt,4" },
395 { 25, 5, "c0_perfcnt,5" },
396 { 25, 6, "c0_perfcnt,6" },
397 { 25, 7, "c0_perfcnt,7" },
398 { 27, 1, "c0_cacheerr,1" },
399 { 27, 2, "c0_cacheerr,2" },
400 { 27, 3, "c0_cacheerr,3" },
401 { 28, 1, "c0_datalo" },
402 { 29, 1, "c0_datahi" }
405 static const char * const mips_hwr_names_numeric
[32] =
407 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
408 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
409 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
410 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
413 static const char * const mips_hwr_names_mips3264r2
[32] =
415 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
416 "$4", "$5", "$6", "$7",
417 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
418 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
419 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
422 static const char * const msa_control_names
[32] =
424 "msa_ir", "msa_csr", "msa_access", "msa_save",
425 "msa_modify", "msa_request", "msa_map", "msa_unmap",
426 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
427 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
428 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
431 struct mips_abi_choice
434 const char * const *gpr_names
;
435 const char * const *fpr_names
;
438 struct mips_abi_choice mips_abi_choices
[] =
440 { "numeric", mips_gpr_names_numeric
, mips_fpr_names_numeric
},
441 { "32", mips_gpr_names_oldabi
, mips_fpr_names_32
},
442 { "n32", mips_gpr_names_newabi
, mips_fpr_names_n32
},
443 { "64", mips_gpr_names_newabi
, mips_fpr_names_64
},
446 struct mips_arch_choice
450 unsigned long bfd_mach
;
454 const char * const *cp0_names
;
455 const struct mips_cp0sel_name
*cp0sel_names
;
456 unsigned int cp0sel_names_len
;
457 const char * const *cp1_names
;
458 const char * const *hwr_names
;
461 const struct mips_arch_choice mips_arch_choices
[] =
463 { "numeric", 0, 0, 0, 0, 0,
464 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
465 mips_hwr_names_numeric
},
467 { "r3000", 1, bfd_mach_mips3000
, CPU_R3000
, ISA_MIPS1
, 0,
468 mips_cp0_names_r3000
, NULL
, 0, mips_cp1_names_numeric
,
469 mips_hwr_names_numeric
},
470 { "r3900", 1, bfd_mach_mips3900
, CPU_R3900
, ISA_MIPS1
, 0,
471 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
472 mips_hwr_names_numeric
},
473 { "r4000", 1, bfd_mach_mips4000
, CPU_R4000
, ISA_MIPS3
, 0,
474 mips_cp0_names_r4000
, NULL
, 0, mips_cp1_names_numeric
,
475 mips_hwr_names_numeric
},
476 { "r4010", 1, bfd_mach_mips4010
, CPU_R4010
, ISA_MIPS2
, 0,
477 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
478 mips_hwr_names_numeric
},
479 { "vr4100", 1, bfd_mach_mips4100
, CPU_VR4100
, ISA_MIPS3
, 0,
480 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
481 mips_hwr_names_numeric
},
482 { "vr4111", 1, bfd_mach_mips4111
, CPU_R4111
, ISA_MIPS3
, 0,
483 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
484 mips_hwr_names_numeric
},
485 { "vr4120", 1, bfd_mach_mips4120
, CPU_VR4120
, ISA_MIPS3
, 0,
486 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
487 mips_hwr_names_numeric
},
488 { "r4300", 1, bfd_mach_mips4300
, CPU_R4300
, ISA_MIPS3
, 0,
489 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
490 mips_hwr_names_numeric
},
491 { "r4400", 1, bfd_mach_mips4400
, CPU_R4400
, ISA_MIPS3
, 0,
492 mips_cp0_names_r4000
, NULL
, 0, mips_cp1_names_numeric
,
493 mips_hwr_names_numeric
},
494 { "r4600", 1, bfd_mach_mips4600
, CPU_R4600
, ISA_MIPS3
, 0,
495 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
496 mips_hwr_names_numeric
},
497 { "r4650", 1, bfd_mach_mips4650
, CPU_R4650
, ISA_MIPS3
, 0,
498 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
499 mips_hwr_names_numeric
},
500 { "r5000", 1, bfd_mach_mips5000
, CPU_R5000
, ISA_MIPS4
, 0,
501 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
502 mips_hwr_names_numeric
},
503 { "vr5400", 1, bfd_mach_mips5400
, CPU_VR5400
, ISA_MIPS4
, 0,
504 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
505 mips_hwr_names_numeric
},
506 { "vr5500", 1, bfd_mach_mips5500
, CPU_VR5500
, ISA_MIPS4
, 0,
507 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
508 mips_hwr_names_numeric
},
509 { "r5900", 1, bfd_mach_mips5900
, CPU_R5900
, ISA_MIPS3
, 0,
510 mips_cp0_names_r5900
, NULL
, 0, mips_cp1_names_numeric
,
511 mips_hwr_names_numeric
},
512 { "r6000", 1, bfd_mach_mips6000
, CPU_R6000
, ISA_MIPS2
, 0,
513 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
514 mips_hwr_names_numeric
},
515 { "rm7000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
516 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
517 mips_hwr_names_numeric
},
518 { "rm9000", 1, bfd_mach_mips7000
, CPU_RM7000
, ISA_MIPS4
, 0,
519 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
520 mips_hwr_names_numeric
},
521 { "r8000", 1, bfd_mach_mips8000
, CPU_R8000
, ISA_MIPS4
, 0,
522 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
523 mips_hwr_names_numeric
},
524 { "r10000", 1, bfd_mach_mips10000
, CPU_R10000
, ISA_MIPS4
, 0,
525 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
526 mips_hwr_names_numeric
},
527 { "r12000", 1, bfd_mach_mips12000
, CPU_R12000
, ISA_MIPS4
, 0,
528 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
529 mips_hwr_names_numeric
},
530 { "r14000", 1, bfd_mach_mips14000
, CPU_R14000
, ISA_MIPS4
, 0,
531 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
532 mips_hwr_names_numeric
},
533 { "r16000", 1, bfd_mach_mips16000
, CPU_R16000
, ISA_MIPS4
, 0,
534 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
535 mips_hwr_names_numeric
},
536 { "mips5", 1, bfd_mach_mips5
, CPU_MIPS5
, ISA_MIPS5
, 0,
537 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
538 mips_hwr_names_numeric
},
540 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
541 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
542 _MIPS32 Architecture For Programmers Volume I: Introduction to the
543 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
545 { "mips32", 1, bfd_mach_mipsisa32
, CPU_MIPS32
,
546 ISA_MIPS32
, ASE_SMARTMIPS
,
547 mips_cp0_names_mips3264
,
548 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
549 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
551 { "mips32r2", 1, bfd_mach_mipsisa32r2
, CPU_MIPS32R2
,
553 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
554 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
| ASE_XPA
),
555 mips_cp0_names_mips3264r2
,
556 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
557 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
559 { "mips32r3", 1, bfd_mach_mipsisa32r3
, CPU_MIPS32R3
,
561 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
562 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
| ASE_XPA
),
563 mips_cp0_names_mips3264r2
,
564 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
565 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
567 { "mips32r5", 1, bfd_mach_mipsisa32r5
, CPU_MIPS32R5
,
569 (ASE_SMARTMIPS
| ASE_DSP
| ASE_DSPR2
| ASE_EVA
| ASE_MIPS3D
570 | ASE_MT
| ASE_MCU
| ASE_VIRT
| ASE_MSA
| ASE_XPA
),
571 mips_cp0_names_mips3264r2
,
572 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
573 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
575 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
576 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
577 ISA_MIPS64
, ASE_MIPS3D
| ASE_MDMX
,
578 mips_cp0_names_mips3264
,
579 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
580 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
582 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
584 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
585 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
586 mips_cp0_names_mips3264r2
,
587 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
588 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
590 { "mips64r3", 1, bfd_mach_mipsisa64r3
, CPU_MIPS64R3
,
592 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
593 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
594 mips_cp0_names_mips3264r2
,
595 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
596 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
598 { "mips64r5", 1, bfd_mach_mipsisa64r5
, CPU_MIPS64R5
,
600 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
601 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
602 mips_cp0_names_mips3264r2
,
603 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
604 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
606 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
607 ISA_MIPS64
| INSN_SB1
, ASE_MIPS3D
,
609 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
610 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
612 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
613 ISA_MIPS3
| INSN_LOONGSON_2E
, 0, mips_cp0_names_numeric
,
614 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
616 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
617 ISA_MIPS3
| INSN_LOONGSON_2F
, 0, mips_cp0_names_numeric
,
618 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
620 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
621 ISA_MIPS64R2
| INSN_LOONGSON_3A
, 0, mips_cp0_names_numeric
,
622 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
624 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
625 ISA_MIPS64R2
| INSN_OCTEON
, 0, mips_cp0_names_numeric
, NULL
, 0,
626 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
628 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
629 ISA_MIPS64R2
| INSN_OCTEONP
, 0, mips_cp0_names_numeric
,
630 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
632 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
633 ISA_MIPS64R2
| INSN_OCTEON2
, 0, mips_cp0_names_numeric
,
634 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
636 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
637 ISA_MIPS64
| INSN_XLR
, 0,
639 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
640 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
642 /* XLP is mostly like XLR, with the prominent exception it is being
644 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
645 ISA_MIPS64R2
| INSN_XLR
, 0,
647 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
648 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
650 /* This entry, mips16, is here only for ISA/processor selection; do
651 not print its name. */
652 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
, 0,
653 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
654 mips_hwr_names_numeric
},
657 /* ISA and processor type to disassemble for, and register names to use.
658 set_default_mips_dis_options and parse_mips_dis_options fill in these
660 static int mips_processor
;
663 static int micromips_ase
;
664 static const char * const *mips_gpr_names
;
665 static const char * const *mips_fpr_names
;
666 static const char * const *mips_cp0_names
;
667 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
668 static int mips_cp0sel_names_len
;
669 static const char * const *mips_cp1_names
;
670 static const char * const *mips_hwr_names
;
673 static int no_aliases
; /* If set disassemble as most general inst. */
675 static const struct mips_abi_choice
*
676 choose_abi_by_name (const char *name
, unsigned int namelen
)
678 const struct mips_abi_choice
*c
;
681 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
682 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
683 && strlen (mips_abi_choices
[i
].name
) == namelen
)
684 c
= &mips_abi_choices
[i
];
689 static const struct mips_arch_choice
*
690 choose_arch_by_name (const char *name
, unsigned int namelen
)
692 const struct mips_arch_choice
*c
= NULL
;
695 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
696 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
697 && strlen (mips_arch_choices
[i
].name
) == namelen
)
698 c
= &mips_arch_choices
[i
];
703 static const struct mips_arch_choice
*
704 choose_arch_by_number (unsigned long mach
)
706 static unsigned long hint_bfd_mach
;
707 static const struct mips_arch_choice
*hint_arch_choice
;
708 const struct mips_arch_choice
*c
;
711 /* We optimize this because even if the user specifies no
712 flags, this will be done for every instruction! */
713 if (hint_bfd_mach
== mach
714 && hint_arch_choice
!= NULL
715 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
716 return hint_arch_choice
;
718 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
720 if (mips_arch_choices
[i
].bfd_mach_valid
721 && mips_arch_choices
[i
].bfd_mach
== mach
)
723 c
= &mips_arch_choices
[i
];
724 hint_bfd_mach
= mach
;
725 hint_arch_choice
= c
;
731 /* Check if the object uses NewABI conventions. */
734 is_newabi (Elf_Internal_Ehdr
*header
)
736 /* There are no old-style ABIs which use 64-bit ELF. */
737 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
740 /* If a 32-bit ELF file, n32 is a new-style ABI. */
741 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
747 /* Check if the object has microMIPS ASE code. */
750 is_micromips (Elf_Internal_Ehdr
*header
)
752 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
759 set_default_mips_dis_options (struct disassemble_info
*info
)
761 const struct mips_arch_choice
*chosen_arch
;
763 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
764 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
765 CP0 register, and HWR names. */
766 mips_isa
= ISA_MIPS3
;
767 mips_processor
= CPU_R3000
;
770 mips_gpr_names
= mips_gpr_names_oldabi
;
771 mips_fpr_names
= mips_fpr_names_numeric
;
772 mips_cp0_names
= mips_cp0_names_numeric
;
773 mips_cp0sel_names
= NULL
;
774 mips_cp0sel_names_len
= 0;
775 mips_cp1_names
= mips_cp1_names_numeric
;
776 mips_hwr_names
= mips_hwr_names_numeric
;
779 /* Update settings according to the ELF file header flags. */
780 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
782 Elf_Internal_Ehdr
*header
;
784 header
= elf_elfheader (info
->section
->owner
);
785 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
786 if (is_newabi (header
))
787 mips_gpr_names
= mips_gpr_names_newabi
;
788 /* If a microMIPS binary, then don't use MIPS16 bindings. */
789 micromips_ase
= is_micromips (header
);
792 /* Set ISA, architecture, and cp0 register names as best we can. */
793 #if ! SYMTAB_AVAILABLE
794 /* This is running out on a target machine, not in a host tool.
795 FIXME: Where does mips_target_info come from? */
796 target_processor
= mips_target_info
.processor
;
797 mips_isa
= mips_target_info
.isa
;
798 mips_ase
= mips_target_info
.ase
;
800 chosen_arch
= choose_arch_by_number (info
->mach
);
801 if (chosen_arch
!= NULL
)
803 mips_processor
= chosen_arch
->processor
;
804 mips_isa
= chosen_arch
->isa
;
805 mips_ase
= chosen_arch
->ase
;
806 mips_cp0_names
= chosen_arch
->cp0_names
;
807 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
808 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
809 mips_cp1_names
= chosen_arch
->cp1_names
;
810 mips_hwr_names
= chosen_arch
->hwr_names
;
816 parse_mips_dis_option (const char *option
, unsigned int len
)
818 unsigned int i
, optionlen
, vallen
;
820 const struct mips_abi_choice
*chosen_abi
;
821 const struct mips_arch_choice
*chosen_arch
;
823 /* Try to match options that are simple flags */
824 if (CONST_STRNEQ (option
, "no-aliases"))
830 if (CONST_STRNEQ (option
, "msa"))
833 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
834 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R3
835 || (mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R5
)
836 mips_ase
|= ASE_MSA64
;
840 if (CONST_STRNEQ (option
, "virt"))
842 mips_ase
|= ASE_VIRT
;
843 if (mips_isa
& ISA_MIPS64R2
844 || mips_isa
& ISA_MIPS64R3
845 || mips_isa
& ISA_MIPS64R5
)
846 mips_ase
|= ASE_VIRT64
;
850 if (CONST_STRNEQ (option
, "xpa"))
857 /* Look for the = that delimits the end of the option name. */
858 for (i
= 0; i
< len
; i
++)
859 if (option
[i
] == '=')
862 if (i
== 0) /* Invalid option: no name before '='. */
864 if (i
== len
) /* Invalid option: no '='. */
866 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
870 val
= option
+ (optionlen
+ 1);
871 vallen
= len
- (optionlen
+ 1);
873 if (strncmp ("gpr-names", option
, optionlen
) == 0
874 && strlen ("gpr-names") == optionlen
)
876 chosen_abi
= choose_abi_by_name (val
, vallen
);
877 if (chosen_abi
!= NULL
)
878 mips_gpr_names
= chosen_abi
->gpr_names
;
882 if (strncmp ("fpr-names", option
, optionlen
) == 0
883 && strlen ("fpr-names") == optionlen
)
885 chosen_abi
= choose_abi_by_name (val
, vallen
);
886 if (chosen_abi
!= NULL
)
887 mips_fpr_names
= chosen_abi
->fpr_names
;
891 if (strncmp ("cp0-names", option
, optionlen
) == 0
892 && strlen ("cp0-names") == optionlen
)
894 chosen_arch
= choose_arch_by_name (val
, vallen
);
895 if (chosen_arch
!= NULL
)
897 mips_cp0_names
= chosen_arch
->cp0_names
;
898 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
899 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
904 if (strncmp ("cp1-names", option
, optionlen
) == 0
905 && strlen ("cp1-names") == optionlen
)
907 chosen_arch
= choose_arch_by_name (val
, vallen
);
908 if (chosen_arch
!= NULL
)
909 mips_cp1_names
= chosen_arch
->cp1_names
;
913 if (strncmp ("hwr-names", option
, optionlen
) == 0
914 && strlen ("hwr-names") == optionlen
)
916 chosen_arch
= choose_arch_by_name (val
, vallen
);
917 if (chosen_arch
!= NULL
)
918 mips_hwr_names
= chosen_arch
->hwr_names
;
922 if (strncmp ("reg-names", option
, optionlen
) == 0
923 && strlen ("reg-names") == optionlen
)
925 /* We check both ABI and ARCH here unconditionally, so
926 that "numeric" will do the desirable thing: select
927 numeric register names for all registers. Other than
928 that, a given name probably won't match both. */
929 chosen_abi
= choose_abi_by_name (val
, vallen
);
930 if (chosen_abi
!= NULL
)
932 mips_gpr_names
= chosen_abi
->gpr_names
;
933 mips_fpr_names
= chosen_abi
->fpr_names
;
935 chosen_arch
= choose_arch_by_name (val
, vallen
);
936 if (chosen_arch
!= NULL
)
938 mips_cp0_names
= chosen_arch
->cp0_names
;
939 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
940 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
941 mips_cp1_names
= chosen_arch
->cp1_names
;
942 mips_hwr_names
= chosen_arch
->hwr_names
;
947 /* Invalid option. */
951 parse_mips_dis_options (const char *options
)
953 const char *option_end
;
958 while (*options
!= '\0')
960 /* Skip empty options. */
967 /* We know that *options is neither NUL or a comma. */
968 option_end
= options
+ 1;
969 while (*option_end
!= ',' && *option_end
!= '\0')
972 parse_mips_dis_option (options
, option_end
- options
);
974 /* Go on to the next one. If option_end points to a comma, it
975 will be skipped above. */
976 options
= option_end
;
980 static const struct mips_cp0sel_name
*
981 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
988 for (i
= 0; i
< len
; i
++)
989 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
994 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
997 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
998 enum mips_reg_operand_type type
, int regno
)
1003 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
1007 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
1011 if (opcode
->pinfo
& (FP_D
| FP_S
))
1012 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
1014 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
1018 if (opcode
->membership
& INSN_5400
)
1019 info
->fprintf_func (info
->stream
, "$f%d", regno
);
1021 info
->fprintf_func (info
->stream
, "$v%d", regno
);
1025 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
1029 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1030 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
1031 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
1032 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
1034 info
->fprintf_func (info
->stream
, "$%d", regno
);
1038 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1042 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1046 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1049 case OP_REG_R5900_I
:
1050 info
->fprintf_func (info
->stream
, "$I");
1053 case OP_REG_R5900_Q
:
1054 info
->fprintf_func (info
->stream
, "$Q");
1057 case OP_REG_R5900_R
:
1058 info
->fprintf_func (info
->stream
, "$R");
1061 case OP_REG_R5900_ACC
:
1062 info
->fprintf_func (info
->stream
, "$ACC");
1066 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1069 case OP_REG_MSA_CTRL
:
1070 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1076 /* Used to track the state carried over from previous operands in
1078 struct mips_print_arg_state
{
1079 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1080 where the value is known to be unsigned and small. */
1081 unsigned int last_int
;
1083 /* The type and number of the last OP_REG seen. We only use this for
1084 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1085 enum mips_reg_operand_type last_reg_type
;
1086 unsigned int last_regno
;
1089 /* Initialize STATE for the start of an instruction. */
1092 init_print_arg_state (struct mips_print_arg_state
*state
)
1094 memset (state
, 0, sizeof (*state
));
1097 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1098 whose value is given by UVAL. */
1101 print_vu0_channel (struct disassemble_info
*info
,
1102 const struct mips_operand
*operand
, unsigned int uval
)
1104 if (operand
->size
== 4)
1105 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1106 uval
& 8 ? "x" : "",
1107 uval
& 4 ? "y" : "",
1108 uval
& 2 ? "z" : "",
1109 uval
& 1 ? "w" : "");
1110 else if (operand
->size
== 2)
1111 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1116 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1117 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1118 the base address for OP_PCREL operands. */
1121 print_insn_arg (struct disassemble_info
*info
,
1122 struct mips_print_arg_state
*state
,
1123 const struct mips_opcode
*opcode
,
1124 const struct mips_operand
*operand
,
1128 const fprintf_ftype infprintf
= info
->fprintf_func
;
1129 void *is
= info
->stream
;
1131 switch (operand
->type
)
1135 const struct mips_int_operand
*int_op
;
1137 int_op
= (const struct mips_int_operand
*) operand
;
1138 uval
= mips_decode_int_operand (int_op
, uval
);
1139 state
->last_int
= uval
;
1140 if (int_op
->print_hex
)
1141 infprintf (is
, "0x%x", uval
);
1143 infprintf (is
, "%d", uval
);
1149 const struct mips_mapped_int_operand
*mint_op
;
1151 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1152 uval
= mint_op
->int_map
[uval
];
1153 state
->last_int
= uval
;
1154 if (mint_op
->print_hex
)
1155 infprintf (is
, "0x%x", uval
);
1157 infprintf (is
, "%d", uval
);
1163 const struct mips_msb_operand
*msb_op
;
1165 msb_op
= (const struct mips_msb_operand
*) operand
;
1166 uval
+= msb_op
->bias
;
1167 if (msb_op
->add_lsb
)
1168 uval
-= state
->last_int
;
1169 infprintf (is
, "0x%x", uval
);
1174 case OP_OPTIONAL_REG
:
1176 const struct mips_reg_operand
*reg_op
;
1178 reg_op
= (const struct mips_reg_operand
*) operand
;
1179 uval
= mips_decode_reg_operand (reg_op
, uval
);
1180 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1182 state
->last_reg_type
= reg_op
->reg_type
;
1183 state
->last_regno
= uval
;
1189 const struct mips_reg_pair_operand
*pair_op
;
1191 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1192 print_reg (info
, opcode
, pair_op
->reg_type
,
1193 pair_op
->reg1_map
[uval
]);
1194 infprintf (is
, ",");
1195 print_reg (info
, opcode
, pair_op
->reg_type
,
1196 pair_op
->reg2_map
[uval
]);
1202 const struct mips_pcrel_operand
*pcrel_op
;
1204 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1205 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1207 /* Preserve the ISA bit for the GDB disassembler,
1208 otherwise clear it. */
1209 if (info
->flavour
!= bfd_target_unknown_flavour
)
1212 (*info
->print_address_func
) (info
->target
, info
);
1217 infprintf (is
, "%d", uval
);
1220 case OP_ADDIUSP_INT
:
1224 sval
= mips_signed_operand (operand
, uval
) * 4;
1225 if (sval
>= -8 && sval
< 8)
1227 infprintf (is
, "%d", sval
);
1231 case OP_CLO_CLZ_DEST
:
1233 unsigned int reg1
, reg2
;
1237 /* If one is zero use the other. */
1238 if (reg1
== reg2
|| reg2
== 0)
1239 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1241 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1243 /* Bogus, result depends on processor. */
1244 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1245 mips_gpr_names
[reg2
]);
1249 case OP_LWM_SWM_LIST
:
1250 if (operand
->size
== 2)
1253 infprintf (is
, "%s,%s",
1255 mips_gpr_names
[31]);
1257 infprintf (is
, "%s-%s,%s",
1259 mips_gpr_names
[16 + uval
],
1260 mips_gpr_names
[31]);
1266 s_reg_encode
= uval
& 0xf;
1267 if (s_reg_encode
!= 0)
1269 if (s_reg_encode
== 1)
1270 infprintf (is
, "%s", mips_gpr_names
[16]);
1271 else if (s_reg_encode
< 9)
1272 infprintf (is
, "%s-%s",
1274 mips_gpr_names
[15 + s_reg_encode
]);
1275 else if (s_reg_encode
== 9)
1276 infprintf (is
, "%s-%s,%s",
1279 mips_gpr_names
[30]);
1281 infprintf (is
, "UNKNOWN");
1284 if (uval
& 0x10) /* For ra. */
1286 if (s_reg_encode
== 0)
1287 infprintf (is
, "%s", mips_gpr_names
[31]);
1289 infprintf (is
, ",%s", mips_gpr_names
[31]);
1294 case OP_ENTRY_EXIT_LIST
:
1297 unsigned int amask
, smask
;
1300 amask
= (uval
>> 3) & 7;
1301 if (amask
> 0 && amask
< 5)
1303 infprintf (is
, "%s", mips_gpr_names
[4]);
1305 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1309 smask
= (uval
>> 1) & 3;
1312 infprintf (is
, "%s??", sep
);
1317 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1319 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1325 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1329 if (amask
== 5 || amask
== 6)
1331 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1333 infprintf (is
, "-%s", mips_fpr_names
[1]);
1338 case OP_SAVE_RESTORE_LIST
:
1339 /* Should be handled by the caller due to extend behavior. */
1342 case OP_MDMX_IMM_REG
:
1348 if ((vsel
& 0x10) == 0)
1353 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1354 if ((vsel
& 1) == 0)
1356 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1357 infprintf (is
, "[%d]", vsel
>> 1);
1359 else if ((vsel
& 0x08) == 0)
1360 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1362 infprintf (is
, "0x%x", uval
);
1366 case OP_REPEAT_PREV_REG
:
1367 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1370 case OP_REPEAT_DEST_REG
:
1371 /* Should always match OP_REPEAT_PREV_REG first. */
1375 infprintf (is
, "$pc");
1379 case OP_VU0_MATCH_SUFFIX
:
1380 print_vu0_channel (info
, operand
, uval
);
1384 infprintf (is
, "[%d]", uval
);
1388 infprintf (is
, "[");
1389 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1390 infprintf (is
, "]");
1395 /* Print the arguments for INSN, which is described by OPCODE.
1396 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1397 as the base of OP_PCREL operands. */
1400 print_insn_args (struct disassemble_info
*info
,
1401 const struct mips_opcode
*opcode
,
1402 const struct mips_operand
*(*decode_operand
) (const char *),
1403 unsigned int insn
, bfd_vma base_pc
)
1405 const fprintf_ftype infprintf
= info
->fprintf_func
;
1406 void *is
= info
->stream
;
1407 struct mips_print_arg_state state
;
1408 const struct mips_operand
*operand
;
1411 init_print_arg_state (&state
);
1412 for (s
= opcode
->args
; *s
; ++s
)
1419 infprintf (is
, "%c", *s
);
1424 infprintf (is
, "%c%c", *s
, *s
);
1428 operand
= decode_operand (s
);
1431 /* xgettext:c-format */
1433 _("# internal error, undefined operand in `%s %s'"),
1434 opcode
->name
, opcode
->args
);
1437 if (operand
->type
== OP_REG
1440 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1442 /* Coprocessor register 0 with sel field (MT ASE). */
1443 const struct mips_cp0sel_name
*n
;
1444 unsigned int reg
, sel
;
1446 reg
= mips_extract_operand (operand
, insn
);
1448 operand
= decode_operand (s
);
1449 sel
= mips_extract_operand (operand
, insn
);
1451 /* CP0 register including 'sel' code for mftc0, to be
1452 printed textually if known. If not known, print both
1453 CP0 register name and sel numerically since CP0 register
1454 with sel 0 may have a name unrelated to register being
1456 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1457 mips_cp0sel_names_len
,
1460 infprintf (is
, "%s", n
->name
);
1462 infprintf (is
, "$%d,%d", reg
, sel
);
1465 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1466 mips_extract_operand (operand
, insn
));
1467 if (*s
== 'm' || *s
== '+')
1474 /* Print the mips instruction at address MEMADDR in debugged memory,
1475 on using INFO. Returns length of the instruction, in bytes, which is
1476 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1477 this is little-endian code. */
1480 print_insn_mips (bfd_vma memaddr
,
1482 struct disassemble_info
*info
)
1484 #define GET_OP(insn, field) \
1485 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1486 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1487 const fprintf_ftype infprintf
= info
->fprintf_func
;
1488 const struct mips_opcode
*op
;
1489 static bfd_boolean init
= 0;
1490 void *is
= info
->stream
;
1492 /* Build a hash table to shorten the search time. */
1497 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1499 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1501 if (op
->pinfo
== INSN_MACRO
1502 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1504 if (i
== GET_OP (op
->match
, OP
))
1515 info
->bytes_per_chunk
= INSNLEN
;
1516 info
->display_endian
= info
->endian
;
1517 info
->insn_info_valid
= 1;
1518 info
->branch_delay_insns
= 0;
1519 info
->data_size
= 0;
1520 info
->insn_type
= dis_nonbranch
;
1524 op
= mips_hash
[GET_OP (word
, OP
)];
1527 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1529 if (op
->pinfo
!= INSN_MACRO
1530 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1531 && (word
& op
->mask
) == op
->match
)
1533 /* We always allow to disassemble the jalx instruction. */
1534 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1535 && strcmp (op
->name
, "jalx"))
1538 /* Figure out instruction type and branch delay information. */
1539 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1541 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1542 info
->insn_type
= dis_jsr
;
1544 info
->insn_type
= dis_branch
;
1545 info
->branch_delay_insns
= 1;
1547 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1548 | INSN_COND_BRANCH_LIKELY
)) != 0)
1550 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1551 info
->insn_type
= dis_condjsr
;
1553 info
->insn_type
= dis_condbranch
;
1554 info
->branch_delay_insns
= 1;
1556 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1557 | INSN_LOAD_MEMORY
)) != 0)
1558 info
->insn_type
= dis_dref
;
1560 infprintf (is
, "%s", op
->name
);
1561 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1565 infprintf (is
, ".");
1566 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1567 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1572 infprintf (is
, "\t");
1573 print_insn_args (info
, op
, decode_mips_operand
, word
,
1583 /* Handle undefined instructions. */
1584 info
->insn_type
= dis_noninsn
;
1585 infprintf (is
, "0x%x", word
);
1589 /* Disassemble an operand for a mips16 instruction. */
1592 print_mips16_insn_arg (struct disassemble_info
*info
,
1593 struct mips_print_arg_state
*state
,
1594 const struct mips_opcode
*opcode
,
1595 char type
, bfd_vma memaddr
,
1596 unsigned insn
, bfd_boolean use_extend
,
1597 unsigned extend
, bfd_boolean is_offset
)
1599 const fprintf_ftype infprintf
= info
->fprintf_func
;
1600 void *is
= info
->stream
;
1601 const struct mips_operand
*operand
, *ext_operand
;
1613 infprintf (is
, "%c", type
);
1617 operand
= decode_mips16_operand (type
, FALSE
);
1620 /* xgettext:c-format */
1621 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
1622 opcode
->name
, opcode
->args
);
1626 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1628 /* Handle this case here because of the complex interation
1629 with the EXTEND opcode. */
1630 unsigned int amask
, nargs
, nstatics
, nsreg
, smask
, frame_size
, i
, j
;
1633 amask
= extend
& 0xf;
1634 if (amask
== MIPS16_ALL_ARGS
)
1639 else if (amask
== MIPS16_ALL_STATICS
)
1647 nstatics
= amask
& 3;
1653 infprintf (is
, "%s", mips_gpr_names
[4]);
1655 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1659 frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
1660 if (frame_size
== 0 && !use_extend
)
1662 infprintf (is
, "%s%d", sep
, frame_size
);
1664 if (insn
& 0x40) /* $ra */
1665 infprintf (is
, ",%s", mips_gpr_names
[31]);
1667 nsreg
= (extend
>> 8) & 0x7;
1669 if (insn
& 0x20) /* $s0 */
1671 if (insn
& 0x10) /* $s1 */
1673 if (nsreg
> 0) /* $s2-$s8 */
1674 smask
|= ((1 << nsreg
) - 1) << 2;
1676 for (i
= 0; i
< 9; i
++)
1677 if (smask
& (1 << i
))
1679 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1680 /* Skip over string of set bits. */
1681 for (j
= i
; smask
& (2 << j
); j
++)
1684 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1687 /* Statics $ax - $a3. */
1689 infprintf (is
, ",%s", mips_gpr_names
[7]);
1690 else if (nstatics
> 0)
1691 infprintf (is
, ",%s-%s",
1692 mips_gpr_names
[7 - nstatics
+ 1],
1697 if (is_offset
&& operand
->type
== OP_INT
)
1699 const struct mips_int_operand
*int_op
;
1701 int_op
= (const struct mips_int_operand
*) operand
;
1702 info
->insn_type
= dis_dref
;
1703 info
->data_size
= 1 << int_op
->shift
;
1706 if (operand
->size
== 26)
1707 /* In this case INSN is the first two bytes of the instruction
1708 and EXTEND is the second two bytes. */
1709 uval
= ((insn
& 0x1f) << 21) | ((insn
& 0x3e0) << 11) | extend
;
1712 /* Calculate the full field value. */
1713 uval
= mips_extract_operand (operand
, insn
);
1716 ext_operand
= decode_mips16_operand (type
, TRUE
);
1717 if (ext_operand
!= operand
)
1719 operand
= ext_operand
;
1720 if (operand
->size
== 16)
1721 uval
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1722 else if (operand
->size
== 15)
1723 uval
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1725 uval
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1730 baseaddr
= memaddr
+ 2;
1731 if (operand
->type
== OP_PCREL
)
1733 const struct mips_pcrel_operand
*pcrel_op
;
1735 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1736 if (!pcrel_op
->include_isa_bit
&& use_extend
)
1737 baseaddr
= memaddr
- 2;
1738 else if (!pcrel_op
->include_isa_bit
)
1742 /* If this instruction is in the delay slot of a JR
1743 instruction, the base address is the address of the
1744 JR instruction. If it is in the delay slot of a JALR
1745 instruction, the base address is the address of the
1746 JALR instruction. This test is unreliable: we have
1747 no way of knowing whether the previous word is
1748 instruction or data. */
1749 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
1750 && (((info
->endian
== BFD_ENDIAN_BIG
1751 ? bfd_getb16 (buffer
)
1752 : bfd_getl16 (buffer
))
1753 & 0xf800) == 0x1800))
1754 baseaddr
= memaddr
- 4;
1755 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
1757 && (((info
->endian
== BFD_ENDIAN_BIG
1758 ? bfd_getb16 (buffer
)
1759 : bfd_getl16 (buffer
))
1760 & 0xf81f) == 0xe800))
1761 baseaddr
= memaddr
- 2;
1767 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
1773 /* Check if the given address is the last word of a MIPS16 PLT entry.
1774 This word is data and depending on the value it may interfere with
1775 disassembly of further PLT entries. We make use of the fact PLT
1776 symbols are marked BSF_SYNTHETIC. */
1778 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
1782 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
1783 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
1789 /* Disassemble mips16 instructions. */
1792 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
1794 const fprintf_ftype infprintf
= info
->fprintf_func
;
1799 bfd_boolean use_extend
;
1801 const struct mips_opcode
*op
, *opend
;
1802 struct mips_print_arg_state state
;
1803 void *is
= info
->stream
;
1805 info
->bytes_per_chunk
= 2;
1806 info
->display_endian
= info
->endian
;
1807 info
->insn_info_valid
= 1;
1808 info
->branch_delay_insns
= 0;
1809 info
->data_size
= 0;
1813 #define GET_OP(insn, field) \
1814 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1815 /* Decode PLT entry's GOT slot address word. */
1816 if (is_mips16_plt_tail (info
, memaddr
))
1818 info
->insn_type
= dis_noninsn
;
1819 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
1822 unsigned int gotslot
;
1824 if (info
->endian
== BFD_ENDIAN_BIG
)
1825 gotslot
= bfd_getb32 (buffer
);
1827 gotslot
= bfd_getl32 (buffer
);
1828 infprintf (is
, ".word\t0x%x", gotslot
);
1835 info
->insn_type
= dis_nonbranch
;
1836 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1840 (*info
->memory_error_func
) (status
, memaddr
, info
);
1846 if (info
->endian
== BFD_ENDIAN_BIG
)
1847 insn
= bfd_getb16 (buffer
);
1849 insn
= bfd_getl16 (buffer
);
1851 /* Handle the extend opcode specially. */
1853 if ((insn
& 0xf800) == 0xf000)
1856 extend
= insn
& 0x7ff;
1860 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1863 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1864 (*info
->memory_error_func
) (status
, memaddr
, info
);
1868 if (info
->endian
== BFD_ENDIAN_BIG
)
1869 insn
= bfd_getb16 (buffer
);
1871 insn
= bfd_getl16 (buffer
);
1873 /* Check for an extend opcode followed by an extend opcode. */
1874 if ((insn
& 0xf800) == 0xf000)
1876 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1877 info
->insn_type
= dis_noninsn
;
1884 /* FIXME: Should probably use a hash table on the major opcode here. */
1886 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
1887 for (op
= mips16_opcodes
; op
< opend
; op
++)
1889 if (op
->pinfo
!= INSN_MACRO
1890 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1891 && (insn
& op
->mask
) == op
->match
)
1895 if (op
->args
[0] == 'a' || op
->args
[0] == 'i')
1899 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1900 info
->insn_type
= dis_noninsn
;
1908 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
1913 if (info
->endian
== BFD_ENDIAN_BIG
)
1914 extend
= bfd_getb16 (buffer
);
1916 extend
= bfd_getl16 (buffer
);
1921 infprintf (is
, "%s", op
->name
);
1922 if (op
->args
[0] != '\0')
1923 infprintf (is
, "\t");
1925 init_print_arg_state (&state
);
1926 for (s
= op
->args
; *s
!= '\0'; s
++)
1930 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
1932 /* Skip the register and the comma. */
1938 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
1940 /* Skip the register and the comma. */
1944 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
, insn
,
1945 use_extend
, extend
, s
[1] == '(');
1948 /* Figure out branch instruction type and delay slot information. */
1949 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1950 info
->branch_delay_insns
= 1;
1951 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
1952 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
1954 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1955 info
->insn_type
= dis_jsr
;
1957 info
->insn_type
= dis_branch
;
1959 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
1960 info
->insn_type
= dis_condbranch
;
1968 infprintf (is
, "0x%x", extend
| 0xf000);
1969 infprintf (is
, "0x%x", insn
);
1970 info
->insn_type
= dis_noninsn
;
1975 /* Disassemble microMIPS instructions. */
1978 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
1980 const fprintf_ftype infprintf
= info
->fprintf_func
;
1981 const struct mips_opcode
*op
, *opend
;
1982 void *is
= info
->stream
;
1984 unsigned int higher
;
1985 unsigned int length
;
1989 info
->bytes_per_chunk
= 2;
1990 info
->display_endian
= info
->endian
;
1991 info
->insn_info_valid
= 1;
1992 info
->branch_delay_insns
= 0;
1993 info
->data_size
= 0;
1994 info
->insn_type
= dis_nonbranch
;
1998 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
2001 (*info
->memory_error_func
) (status
, memaddr
, info
);
2007 if (info
->endian
== BFD_ENDIAN_BIG
)
2008 insn
= bfd_getb16 (buffer
);
2010 insn
= bfd_getl16 (buffer
);
2012 if ((insn
& 0xfc00) == 0x7c00)
2014 /* This is a 48-bit microMIPS instruction. */
2017 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2020 infprintf (is
, "micromips 0x%x", higher
);
2021 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2024 if (info
->endian
== BFD_ENDIAN_BIG
)
2025 insn
= bfd_getb16 (buffer
);
2027 insn
= bfd_getl16 (buffer
);
2028 higher
= (higher
<< 16) | insn
;
2030 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
2033 infprintf (is
, "micromips 0x%x", higher
);
2034 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2037 if (info
->endian
== BFD_ENDIAN_BIG
)
2038 insn
= bfd_getb16 (buffer
);
2040 insn
= bfd_getl16 (buffer
);
2041 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2043 info
->insn_type
= dis_noninsn
;
2046 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2048 /* This is a 32-bit microMIPS instruction. */
2051 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2054 infprintf (is
, "micromips 0x%x", higher
);
2055 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2059 if (info
->endian
== BFD_ENDIAN_BIG
)
2060 insn
= bfd_getb16 (buffer
);
2062 insn
= bfd_getl16 (buffer
);
2064 insn
= insn
| (higher
<< 16);
2069 /* FIXME: Should probably use a hash table on the major opcode here. */
2071 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2072 for (op
= micromips_opcodes
; op
< opend
; op
++)
2074 if (op
->pinfo
!= INSN_MACRO
2075 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2076 && (insn
& op
->mask
) == op
->match
2077 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2078 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2080 infprintf (is
, "%s", op
->name
);
2084 infprintf (is
, "\t");
2085 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2086 memaddr
+ length
+ 1);
2089 /* Figure out instruction type and branch delay information. */
2091 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2092 info
->branch_delay_insns
= 1;
2093 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2094 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2096 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2097 info
->insn_type
= dis_jsr
;
2099 info
->insn_type
= dis_branch
;
2101 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2102 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2104 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2105 info
->insn_type
= dis_condjsr
;
2107 info
->insn_type
= dis_condbranch
;
2110 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2111 info
->insn_type
= dis_dref
;
2117 infprintf (is
, "0x%x", insn
);
2118 info
->insn_type
= dis_noninsn
;
2123 /* Return 1 if a symbol associated with the location being disassembled
2124 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2125 all the symbols at the address being considered assuming if at least
2126 one of them indicates code compression, then such code has been
2127 genuinely produced here (other symbols could have been derived from
2128 function symbols defined elsewhere or could define data). Otherwise,
2132 is_compressed_mode_p (struct disassemble_info
*info
)
2137 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2138 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2140 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2142 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2144 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2145 && info
->symtab
[i
]->section
== info
->section
)
2147 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2149 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2151 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2158 /* In an environment where we do not know the symbol type of the
2159 instruction we are forced to assume that the low order bit of the
2160 instructions' address may mark it as a mips16 instruction. If we
2161 are single stepping, or the pc is within the disassembled function,
2162 this works. Otherwise, we need a clue. Sometimes. */
2165 _print_insn_mips (bfd_vma memaddr
,
2166 struct disassemble_info
*info
,
2167 enum bfd_endian endianness
)
2169 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
2170 bfd_byte buffer
[INSNLEN
];
2173 set_default_mips_dis_options (info
);
2174 parse_mips_dis_options (info
->disassembler_options
);
2176 if (info
->mach
== bfd_mach_mips16
)
2177 return print_insn_mips16 (memaddr
, info
);
2178 if (info
->mach
== bfd_mach_mips_micromips
)
2179 return print_insn_micromips (memaddr
, info
);
2181 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
2184 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2185 /* Only a few tools will work this way. */
2187 return print_insn_compr (memaddr
, info
);
2190 #if SYMTAB_AVAILABLE
2191 if (is_compressed_mode_p (info
))
2192 return print_insn_compr (memaddr
, info
);
2195 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2200 if (endianness
== BFD_ENDIAN_BIG
)
2201 insn
= bfd_getb32 (buffer
);
2203 insn
= bfd_getl32 (buffer
);
2205 return print_insn_mips (memaddr
, insn
, info
);
2209 (*info
->memory_error_func
) (status
, memaddr
, info
);
2215 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2217 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2221 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2223 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2227 print_mips_disassembler_options (FILE *stream
)
2231 fprintf (stream
, _("\n\
2232 The following MIPS specific disassembler options are supported for use\n\
2233 with the -M switch (multiple options should be separated by commas):\n"));
2235 fprintf (stream
, _("\n\
2236 msa Recognize MSA instructions.\n"));
2238 fprintf (stream
, _("\n\
2239 virt Recognize the virtualization ASE instructions.\n"));
2241 fprintf (stream
, _("\n\
2242 xpa Recognize the eXtended Physical Address (XPA) ASE instructions.\n"));
2244 fprintf (stream
, _("\n\
2245 gpr-names=ABI Print GPR names according to specified ABI.\n\
2246 Default: based on binary being disassembled.\n"));
2248 fprintf (stream
, _("\n\
2249 fpr-names=ABI Print FPR names according to specified ABI.\n\
2250 Default: numeric.\n"));
2252 fprintf (stream
, _("\n\
2253 cp0-names=ARCH Print CP0 register names according to\n\
2254 specified architecture.\n\
2255 Default: based on binary being disassembled.\n"));
2257 fprintf (stream
, _("\n\
2258 hwr-names=ARCH Print HWR names according to specified \n\
2260 Default: based on binary being disassembled.\n"));
2262 fprintf (stream
, _("\n\
2263 reg-names=ABI Print GPR and FPR names according to\n\
2264 specified ABI.\n"));
2266 fprintf (stream
, _("\n\
2267 reg-names=ARCH Print CP0 register and HWR names according to\n\
2268 specified architecture.\n"));
2270 fprintf (stream
, _("\n\
2271 For the options above, the following values are supported for \"ABI\":\n\
2273 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2274 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2275 fprintf (stream
, _("\n"));
2277 fprintf (stream
, _("\n\
2278 For the options above, The following values are supported for \"ARCH\":\n\
2280 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2281 if (*mips_arch_choices
[i
].name
!= '\0')
2282 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2283 fprintf (stream
, _("\n"));
2285 fprintf (stream
, _("\n"));