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 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
560 { "mips64", 1, bfd_mach_mipsisa64
, CPU_MIPS64
,
561 ISA_MIPS64
, ASE_MIPS3D
| ASE_MDMX
,
562 mips_cp0_names_mips3264
,
563 mips_cp0sel_names_mips3264
, ARRAY_SIZE (mips_cp0sel_names_mips3264
),
564 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
566 { "mips64r2", 1, bfd_mach_mipsisa64r2
, CPU_MIPS64R2
,
568 (ASE_MIPS3D
| ASE_DSP
| ASE_DSPR2
| ASE_DSP64
| ASE_EVA
| ASE_MT
569 | ASE_MCU
| ASE_VIRT
| ASE_VIRT64
| ASE_MSA
| ASE_MSA64
| ASE_XPA
),
570 mips_cp0_names_mips3264r2
,
571 mips_cp0sel_names_mips3264r2
, ARRAY_SIZE (mips_cp0sel_names_mips3264r2
),
572 mips_cp1_names_mips3264
, mips_hwr_names_mips3264r2
},
574 { "sb1", 1, bfd_mach_mips_sb1
, CPU_SB1
,
575 ISA_MIPS64
| INSN_SB1
, ASE_MIPS3D
,
577 mips_cp0sel_names_sb1
, ARRAY_SIZE (mips_cp0sel_names_sb1
),
578 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
580 { "loongson2e", 1, bfd_mach_mips_loongson_2e
, CPU_LOONGSON_2E
,
581 ISA_MIPS3
| INSN_LOONGSON_2E
, 0, mips_cp0_names_numeric
,
582 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
584 { "loongson2f", 1, bfd_mach_mips_loongson_2f
, CPU_LOONGSON_2F
,
585 ISA_MIPS3
| INSN_LOONGSON_2F
, 0, mips_cp0_names_numeric
,
586 NULL
, 0, mips_cp1_names_numeric
, mips_hwr_names_numeric
},
588 { "loongson3a", 1, bfd_mach_mips_loongson_3a
, CPU_LOONGSON_3A
,
589 ISA_MIPS64R2
| INSN_LOONGSON_3A
, 0, mips_cp0_names_numeric
,
590 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
592 { "octeon", 1, bfd_mach_mips_octeon
, CPU_OCTEON
,
593 ISA_MIPS64R2
| INSN_OCTEON
, 0, mips_cp0_names_numeric
, NULL
, 0,
594 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
596 { "octeon+", 1, bfd_mach_mips_octeonp
, CPU_OCTEONP
,
597 ISA_MIPS64R2
| INSN_OCTEONP
, 0, mips_cp0_names_numeric
,
598 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
600 { "octeon2", 1, bfd_mach_mips_octeon2
, CPU_OCTEON2
,
601 ISA_MIPS64R2
| INSN_OCTEON2
, 0, mips_cp0_names_numeric
,
602 NULL
, 0, mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
604 { "xlr", 1, bfd_mach_mips_xlr
, CPU_XLR
,
605 ISA_MIPS64
| INSN_XLR
, 0,
607 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
608 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
610 /* XLP is mostly like XLR, with the prominent exception it is being
612 { "xlp", 1, bfd_mach_mips_xlr
, CPU_XLR
,
613 ISA_MIPS64R2
| INSN_XLR
, 0,
615 mips_cp0sel_names_xlr
, ARRAY_SIZE (mips_cp0sel_names_xlr
),
616 mips_cp1_names_mips3264
, mips_hwr_names_numeric
},
618 /* This entry, mips16, is here only for ISA/processor selection; do
619 not print its name. */
620 { "", 1, bfd_mach_mips16
, CPU_MIPS16
, ISA_MIPS3
, 0,
621 mips_cp0_names_numeric
, NULL
, 0, mips_cp1_names_numeric
,
622 mips_hwr_names_numeric
},
625 /* ISA and processor type to disassemble for, and register names to use.
626 set_default_mips_dis_options and parse_mips_dis_options fill in these
628 static int mips_processor
;
631 static int micromips_ase
;
632 static const char * const *mips_gpr_names
;
633 static const char * const *mips_fpr_names
;
634 static const char * const *mips_cp0_names
;
635 static const struct mips_cp0sel_name
*mips_cp0sel_names
;
636 static int mips_cp0sel_names_len
;
637 static const char * const *mips_cp1_names
;
638 static const char * const *mips_hwr_names
;
641 static int no_aliases
; /* If set disassemble as most general inst. */
643 static const struct mips_abi_choice
*
644 choose_abi_by_name (const char *name
, unsigned int namelen
)
646 const struct mips_abi_choice
*c
;
649 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_abi_choices
) && c
== NULL
; i
++)
650 if (strncmp (mips_abi_choices
[i
].name
, name
, namelen
) == 0
651 && strlen (mips_abi_choices
[i
].name
) == namelen
)
652 c
= &mips_abi_choices
[i
];
657 static const struct mips_arch_choice
*
658 choose_arch_by_name (const char *name
, unsigned int namelen
)
660 const struct mips_arch_choice
*c
= NULL
;
663 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
664 if (strncmp (mips_arch_choices
[i
].name
, name
, namelen
) == 0
665 && strlen (mips_arch_choices
[i
].name
) == namelen
)
666 c
= &mips_arch_choices
[i
];
671 static const struct mips_arch_choice
*
672 choose_arch_by_number (unsigned long mach
)
674 static unsigned long hint_bfd_mach
;
675 static const struct mips_arch_choice
*hint_arch_choice
;
676 const struct mips_arch_choice
*c
;
679 /* We optimize this because even if the user specifies no
680 flags, this will be done for every instruction! */
681 if (hint_bfd_mach
== mach
682 && hint_arch_choice
!= NULL
683 && hint_arch_choice
->bfd_mach
== hint_bfd_mach
)
684 return hint_arch_choice
;
686 for (i
= 0, c
= NULL
; i
< ARRAY_SIZE (mips_arch_choices
) && c
== NULL
; i
++)
688 if (mips_arch_choices
[i
].bfd_mach_valid
689 && mips_arch_choices
[i
].bfd_mach
== mach
)
691 c
= &mips_arch_choices
[i
];
692 hint_bfd_mach
= mach
;
693 hint_arch_choice
= c
;
699 /* Check if the object uses NewABI conventions. */
702 is_newabi (Elf_Internal_Ehdr
*header
)
704 /* There are no old-style ABIs which use 64-bit ELF. */
705 if (header
->e_ident
[EI_CLASS
] == ELFCLASS64
)
708 /* If a 32-bit ELF file, n32 is a new-style ABI. */
709 if ((header
->e_flags
& EF_MIPS_ABI2
) != 0)
715 /* Check if the object has microMIPS ASE code. */
718 is_micromips (Elf_Internal_Ehdr
*header
)
720 if ((header
->e_flags
& EF_MIPS_ARCH_ASE_MICROMIPS
) != 0)
727 set_default_mips_dis_options (struct disassemble_info
*info
)
729 const struct mips_arch_choice
*chosen_arch
;
731 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
732 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
733 CP0 register, and HWR names. */
734 mips_isa
= ISA_MIPS3
;
735 mips_processor
= CPU_R3000
;
738 mips_gpr_names
= mips_gpr_names_oldabi
;
739 mips_fpr_names
= mips_fpr_names_numeric
;
740 mips_cp0_names
= mips_cp0_names_numeric
;
741 mips_cp0sel_names
= NULL
;
742 mips_cp0sel_names_len
= 0;
743 mips_cp1_names
= mips_cp1_names_numeric
;
744 mips_hwr_names
= mips_hwr_names_numeric
;
747 /* Update settings according to the ELF file header flags. */
748 if (info
->flavour
== bfd_target_elf_flavour
&& info
->section
!= NULL
)
750 Elf_Internal_Ehdr
*header
;
752 header
= elf_elfheader (info
->section
->owner
);
753 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
754 if (is_newabi (header
))
755 mips_gpr_names
= mips_gpr_names_newabi
;
756 /* If a microMIPS binary, then don't use MIPS16 bindings. */
757 micromips_ase
= is_micromips (header
);
760 /* Set ISA, architecture, and cp0 register names as best we can. */
761 #if ! SYMTAB_AVAILABLE
762 /* This is running out on a target machine, not in a host tool.
763 FIXME: Where does mips_target_info come from? */
764 target_processor
= mips_target_info
.processor
;
765 mips_isa
= mips_target_info
.isa
;
766 mips_ase
= mips_target_info
.ase
;
768 chosen_arch
= choose_arch_by_number (info
->mach
);
769 if (chosen_arch
!= NULL
)
771 mips_processor
= chosen_arch
->processor
;
772 mips_isa
= chosen_arch
->isa
;
773 mips_ase
= chosen_arch
->ase
;
774 mips_cp0_names
= chosen_arch
->cp0_names
;
775 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
776 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
777 mips_cp1_names
= chosen_arch
->cp1_names
;
778 mips_hwr_names
= chosen_arch
->hwr_names
;
784 parse_mips_dis_option (const char *option
, unsigned int len
)
786 unsigned int i
, optionlen
, vallen
;
788 const struct mips_abi_choice
*chosen_abi
;
789 const struct mips_arch_choice
*chosen_arch
;
791 /* Try to match options that are simple flags */
792 if (CONST_STRNEQ (option
, "no-aliases"))
798 if (CONST_STRNEQ (option
, "msa"))
801 if ((mips_isa
& INSN_ISA_MASK
) == ISA_MIPS64R2
)
802 mips_ase
|= ASE_MSA64
;
806 if (CONST_STRNEQ (option
, "virt"))
808 mips_ase
|= ASE_VIRT
;
809 if (mips_isa
& ISA_MIPS64R2
)
810 mips_ase
|= ASE_VIRT64
;
814 if (CONST_STRNEQ (option
, "xpa"))
821 /* Look for the = that delimits the end of the option name. */
822 for (i
= 0; i
< len
; i
++)
823 if (option
[i
] == '=')
826 if (i
== 0) /* Invalid option: no name before '='. */
828 if (i
== len
) /* Invalid option: no '='. */
830 if (i
== (len
- 1)) /* Invalid option: no value after '='. */
834 val
= option
+ (optionlen
+ 1);
835 vallen
= len
- (optionlen
+ 1);
837 if (strncmp ("gpr-names", option
, optionlen
) == 0
838 && strlen ("gpr-names") == optionlen
)
840 chosen_abi
= choose_abi_by_name (val
, vallen
);
841 if (chosen_abi
!= NULL
)
842 mips_gpr_names
= chosen_abi
->gpr_names
;
846 if (strncmp ("fpr-names", option
, optionlen
) == 0
847 && strlen ("fpr-names") == optionlen
)
849 chosen_abi
= choose_abi_by_name (val
, vallen
);
850 if (chosen_abi
!= NULL
)
851 mips_fpr_names
= chosen_abi
->fpr_names
;
855 if (strncmp ("cp0-names", option
, optionlen
) == 0
856 && strlen ("cp0-names") == optionlen
)
858 chosen_arch
= choose_arch_by_name (val
, vallen
);
859 if (chosen_arch
!= NULL
)
861 mips_cp0_names
= chosen_arch
->cp0_names
;
862 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
863 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
868 if (strncmp ("cp1-names", option
, optionlen
) == 0
869 && strlen ("cp1-names") == optionlen
)
871 chosen_arch
= choose_arch_by_name (val
, vallen
);
872 if (chosen_arch
!= NULL
)
873 mips_cp1_names
= chosen_arch
->cp1_names
;
877 if (strncmp ("hwr-names", option
, optionlen
) == 0
878 && strlen ("hwr-names") == optionlen
)
880 chosen_arch
= choose_arch_by_name (val
, vallen
);
881 if (chosen_arch
!= NULL
)
882 mips_hwr_names
= chosen_arch
->hwr_names
;
886 if (strncmp ("reg-names", option
, optionlen
) == 0
887 && strlen ("reg-names") == optionlen
)
889 /* We check both ABI and ARCH here unconditionally, so
890 that "numeric" will do the desirable thing: select
891 numeric register names for all registers. Other than
892 that, a given name probably won't match both. */
893 chosen_abi
= choose_abi_by_name (val
, vallen
);
894 if (chosen_abi
!= NULL
)
896 mips_gpr_names
= chosen_abi
->gpr_names
;
897 mips_fpr_names
= chosen_abi
->fpr_names
;
899 chosen_arch
= choose_arch_by_name (val
, vallen
);
900 if (chosen_arch
!= NULL
)
902 mips_cp0_names
= chosen_arch
->cp0_names
;
903 mips_cp0sel_names
= chosen_arch
->cp0sel_names
;
904 mips_cp0sel_names_len
= chosen_arch
->cp0sel_names_len
;
905 mips_cp1_names
= chosen_arch
->cp1_names
;
906 mips_hwr_names
= chosen_arch
->hwr_names
;
911 /* Invalid option. */
915 parse_mips_dis_options (const char *options
)
917 const char *option_end
;
922 while (*options
!= '\0')
924 /* Skip empty options. */
931 /* We know that *options is neither NUL or a comma. */
932 option_end
= options
+ 1;
933 while (*option_end
!= ',' && *option_end
!= '\0')
936 parse_mips_dis_option (options
, option_end
- options
);
938 /* Go on to the next one. If option_end points to a comma, it
939 will be skipped above. */
940 options
= option_end
;
944 static const struct mips_cp0sel_name
*
945 lookup_mips_cp0sel_name (const struct mips_cp0sel_name
*names
,
952 for (i
= 0; i
< len
; i
++)
953 if (names
[i
].cp0reg
== cp0reg
&& names
[i
].sel
== sel
)
958 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
961 print_reg (struct disassemble_info
*info
, const struct mips_opcode
*opcode
,
962 enum mips_reg_operand_type type
, int regno
)
967 info
->fprintf_func (info
->stream
, "%s", mips_gpr_names
[regno
]);
971 info
->fprintf_func (info
->stream
, "%s", mips_fpr_names
[regno
]);
975 if (opcode
->pinfo
& (FP_D
| FP_S
))
976 info
->fprintf_func (info
->stream
, "$fcc%d", regno
);
978 info
->fprintf_func (info
->stream
, "$cc%d", regno
);
982 if (opcode
->membership
& INSN_5400
)
983 info
->fprintf_func (info
->stream
, "$f%d", regno
);
985 info
->fprintf_func (info
->stream
, "$v%d", regno
);
989 info
->fprintf_func (info
->stream
, "$ac%d", regno
);
993 if (opcode
->name
[strlen (opcode
->name
) - 1] == '0')
994 info
->fprintf_func (info
->stream
, "%s", mips_cp0_names
[regno
]);
995 else if (opcode
->name
[strlen (opcode
->name
) - 1] == '1')
996 info
->fprintf_func (info
->stream
, "%s", mips_cp1_names
[regno
]);
998 info
->fprintf_func (info
->stream
, "$%d", regno
);
1002 info
->fprintf_func (info
->stream
, "%s", mips_hwr_names
[regno
]);
1006 info
->fprintf_func (info
->stream
, "$vf%d", regno
);
1010 info
->fprintf_func (info
->stream
, "$vi%d", regno
);
1013 case OP_REG_R5900_I
:
1014 info
->fprintf_func (info
->stream
, "$I");
1017 case OP_REG_R5900_Q
:
1018 info
->fprintf_func (info
->stream
, "$Q");
1021 case OP_REG_R5900_R
:
1022 info
->fprintf_func (info
->stream
, "$R");
1025 case OP_REG_R5900_ACC
:
1026 info
->fprintf_func (info
->stream
, "$ACC");
1030 info
->fprintf_func (info
->stream
, "$w%d", regno
);
1033 case OP_REG_MSA_CTRL
:
1034 info
->fprintf_func (info
->stream
, "%s", msa_control_names
[regno
]);
1040 /* Used to track the state carried over from previous operands in
1042 struct mips_print_arg_state
{
1043 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1044 where the value is known to be unsigned and small. */
1045 unsigned int last_int
;
1047 /* The type and number of the last OP_REG seen. We only use this for
1048 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1049 enum mips_reg_operand_type last_reg_type
;
1050 unsigned int last_regno
;
1053 /* Initialize STATE for the start of an instruction. */
1056 init_print_arg_state (struct mips_print_arg_state
*state
)
1058 memset (state
, 0, sizeof (*state
));
1061 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1062 whose value is given by UVAL. */
1065 print_vu0_channel (struct disassemble_info
*info
,
1066 const struct mips_operand
*operand
, unsigned int uval
)
1068 if (operand
->size
== 4)
1069 info
->fprintf_func (info
->stream
, "%s%s%s%s",
1070 uval
& 8 ? "x" : "",
1071 uval
& 4 ? "y" : "",
1072 uval
& 2 ? "z" : "",
1073 uval
& 1 ? "w" : "");
1074 else if (operand
->size
== 2)
1075 info
->fprintf_func (info
->stream
, "%c", "xyzw"[uval
]);
1080 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1081 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1082 the base address for OP_PCREL operands. */
1085 print_insn_arg (struct disassemble_info
*info
,
1086 struct mips_print_arg_state
*state
,
1087 const struct mips_opcode
*opcode
,
1088 const struct mips_operand
*operand
,
1092 const fprintf_ftype infprintf
= info
->fprintf_func
;
1093 void *is
= info
->stream
;
1095 switch (operand
->type
)
1099 const struct mips_int_operand
*int_op
;
1101 int_op
= (const struct mips_int_operand
*) operand
;
1102 uval
= mips_decode_int_operand (int_op
, uval
);
1103 state
->last_int
= uval
;
1104 if (int_op
->print_hex
)
1105 infprintf (is
, "0x%x", uval
);
1107 infprintf (is
, "%d", uval
);
1113 const struct mips_mapped_int_operand
*mint_op
;
1115 mint_op
= (const struct mips_mapped_int_operand
*) operand
;
1116 uval
= mint_op
->int_map
[uval
];
1117 state
->last_int
= uval
;
1118 if (mint_op
->print_hex
)
1119 infprintf (is
, "0x%x", uval
);
1121 infprintf (is
, "%d", uval
);
1127 const struct mips_msb_operand
*msb_op
;
1129 msb_op
= (const struct mips_msb_operand
*) operand
;
1130 uval
+= msb_op
->bias
;
1131 if (msb_op
->add_lsb
)
1132 uval
-= state
->last_int
;
1133 infprintf (is
, "0x%x", uval
);
1138 case OP_OPTIONAL_REG
:
1140 const struct mips_reg_operand
*reg_op
;
1142 reg_op
= (const struct mips_reg_operand
*) operand
;
1143 uval
= mips_decode_reg_operand (reg_op
, uval
);
1144 print_reg (info
, opcode
, reg_op
->reg_type
, uval
);
1146 state
->last_reg_type
= reg_op
->reg_type
;
1147 state
->last_regno
= uval
;
1153 const struct mips_reg_pair_operand
*pair_op
;
1155 pair_op
= (const struct mips_reg_pair_operand
*) operand
;
1156 print_reg (info
, opcode
, pair_op
->reg_type
,
1157 pair_op
->reg1_map
[uval
]);
1158 infprintf (is
, ",");
1159 print_reg (info
, opcode
, pair_op
->reg_type
,
1160 pair_op
->reg2_map
[uval
]);
1166 const struct mips_pcrel_operand
*pcrel_op
;
1168 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1169 info
->target
= mips_decode_pcrel_operand (pcrel_op
, base_pc
, uval
);
1171 /* Preserve the ISA bit for the GDB disassembler,
1172 otherwise clear it. */
1173 if (info
->flavour
!= bfd_target_unknown_flavour
)
1176 (*info
->print_address_func
) (info
->target
, info
);
1181 infprintf (is
, "%d", uval
);
1184 case OP_ADDIUSP_INT
:
1188 sval
= mips_signed_operand (operand
, uval
) * 4;
1189 if (sval
>= -8 && sval
< 8)
1191 infprintf (is
, "%d", sval
);
1195 case OP_CLO_CLZ_DEST
:
1197 unsigned int reg1
, reg2
;
1201 /* If one is zero use the other. */
1202 if (reg1
== reg2
|| reg2
== 0)
1203 infprintf (is
, "%s", mips_gpr_names
[reg1
]);
1205 infprintf (is
, "%s", mips_gpr_names
[reg2
]);
1207 /* Bogus, result depends on processor. */
1208 infprintf (is
, "%s or %s", mips_gpr_names
[reg1
],
1209 mips_gpr_names
[reg2
]);
1213 case OP_LWM_SWM_LIST
:
1214 if (operand
->size
== 2)
1217 infprintf (is
, "%s,%s",
1219 mips_gpr_names
[31]);
1221 infprintf (is
, "%s-%s,%s",
1223 mips_gpr_names
[16 + uval
],
1224 mips_gpr_names
[31]);
1230 s_reg_encode
= uval
& 0xf;
1231 if (s_reg_encode
!= 0)
1233 if (s_reg_encode
== 1)
1234 infprintf (is
, "%s", mips_gpr_names
[16]);
1235 else if (s_reg_encode
< 9)
1236 infprintf (is
, "%s-%s",
1238 mips_gpr_names
[15 + s_reg_encode
]);
1239 else if (s_reg_encode
== 9)
1240 infprintf (is
, "%s-%s,%s",
1243 mips_gpr_names
[30]);
1245 infprintf (is
, "UNKNOWN");
1248 if (uval
& 0x10) /* For ra. */
1250 if (s_reg_encode
== 0)
1251 infprintf (is
, "%s", mips_gpr_names
[31]);
1253 infprintf (is
, ",%s", mips_gpr_names
[31]);
1258 case OP_ENTRY_EXIT_LIST
:
1261 unsigned int amask
, smask
;
1264 amask
= (uval
>> 3) & 7;
1265 if (amask
> 0 && amask
< 5)
1267 infprintf (is
, "%s", mips_gpr_names
[4]);
1269 infprintf (is
, "-%s", mips_gpr_names
[amask
+ 3]);
1273 smask
= (uval
>> 1) & 3;
1276 infprintf (is
, "%s??", sep
);
1281 infprintf (is
, "%s%s", sep
, mips_gpr_names
[16]);
1283 infprintf (is
, "-%s", mips_gpr_names
[smask
+ 15]);
1289 infprintf (is
, "%s%s", sep
, mips_gpr_names
[31]);
1293 if (amask
== 5 || amask
== 6)
1295 infprintf (is
, "%s%s", sep
, mips_fpr_names
[0]);
1297 infprintf (is
, "-%s", mips_fpr_names
[1]);
1302 case OP_SAVE_RESTORE_LIST
:
1303 /* Should be handled by the caller due to extend behavior. */
1306 case OP_MDMX_IMM_REG
:
1312 if ((vsel
& 0x10) == 0)
1317 for (fmt
= 0; fmt
< 3; fmt
++, vsel
>>= 1)
1318 if ((vsel
& 1) == 0)
1320 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1321 infprintf (is
, "[%d]", vsel
>> 1);
1323 else if ((vsel
& 0x08) == 0)
1324 print_reg (info
, opcode
, OP_REG_VEC
, uval
);
1326 infprintf (is
, "0x%x", uval
);
1330 case OP_REPEAT_PREV_REG
:
1331 print_reg (info
, opcode
, state
->last_reg_type
, state
->last_regno
);
1334 case OP_REPEAT_DEST_REG
:
1335 /* Should always match OP_REPEAT_PREV_REG first. */
1339 infprintf (is
, "$pc");
1343 case OP_VU0_MATCH_SUFFIX
:
1344 print_vu0_channel (info
, operand
, uval
);
1348 infprintf (is
, "[%d]", uval
);
1352 infprintf (is
, "[");
1353 print_reg (info
, opcode
, OP_REG_GP
, uval
);
1354 infprintf (is
, "]");
1359 /* Print the arguments for INSN, which is described by OPCODE.
1360 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1361 as the base of OP_PCREL operands. */
1364 print_insn_args (struct disassemble_info
*info
,
1365 const struct mips_opcode
*opcode
,
1366 const struct mips_operand
*(*decode_operand
) (const char *),
1367 unsigned int insn
, bfd_vma base_pc
)
1369 const fprintf_ftype infprintf
= info
->fprintf_func
;
1370 void *is
= info
->stream
;
1371 struct mips_print_arg_state state
;
1372 const struct mips_operand
*operand
;
1375 init_print_arg_state (&state
);
1376 for (s
= opcode
->args
; *s
; ++s
)
1383 infprintf (is
, "%c", *s
);
1388 infprintf (is
, "%c%c", *s
, *s
);
1392 operand
= decode_operand (s
);
1395 /* xgettext:c-format */
1397 _("# internal error, undefined operand in `%s %s'"),
1398 opcode
->name
, opcode
->args
);
1401 if (operand
->type
== OP_REG
1404 && opcode
->name
[strlen (opcode
->name
) - 1] == '0')
1406 /* Coprocessor register 0 with sel field (MT ASE). */
1407 const struct mips_cp0sel_name
*n
;
1408 unsigned int reg
, sel
;
1410 reg
= mips_extract_operand (operand
, insn
);
1412 operand
= decode_operand (s
);
1413 sel
= mips_extract_operand (operand
, insn
);
1415 /* CP0 register including 'sel' code for mftc0, to be
1416 printed textually if known. If not known, print both
1417 CP0 register name and sel numerically since CP0 register
1418 with sel 0 may have a name unrelated to register being
1420 n
= lookup_mips_cp0sel_name (mips_cp0sel_names
,
1421 mips_cp0sel_names_len
,
1424 infprintf (is
, "%s", n
->name
);
1426 infprintf (is
, "$%d,%d", reg
, sel
);
1429 print_insn_arg (info
, &state
, opcode
, operand
, base_pc
,
1430 mips_extract_operand (operand
, insn
));
1431 if (*s
== 'm' || *s
== '+')
1438 /* Print the mips instruction at address MEMADDR in debugged memory,
1439 on using INFO. Returns length of the instruction, in bytes, which is
1440 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1441 this is little-endian code. */
1444 print_insn_mips (bfd_vma memaddr
,
1446 struct disassemble_info
*info
)
1448 #define GET_OP(insn, field) \
1449 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1450 static const struct mips_opcode
*mips_hash
[OP_MASK_OP
+ 1];
1451 const fprintf_ftype infprintf
= info
->fprintf_func
;
1452 const struct mips_opcode
*op
;
1453 static bfd_boolean init
= 0;
1454 void *is
= info
->stream
;
1456 /* Build a hash table to shorten the search time. */
1461 for (i
= 0; i
<= OP_MASK_OP
; i
++)
1463 for (op
= mips_opcodes
; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1465 if (op
->pinfo
== INSN_MACRO
1466 || (no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
)))
1468 if (i
== GET_OP (op
->match
, OP
))
1479 info
->bytes_per_chunk
= INSNLEN
;
1480 info
->display_endian
= info
->endian
;
1481 info
->insn_info_valid
= 1;
1482 info
->branch_delay_insns
= 0;
1483 info
->data_size
= 0;
1484 info
->insn_type
= dis_nonbranch
;
1488 op
= mips_hash
[GET_OP (word
, OP
)];
1491 for (; op
< &mips_opcodes
[NUMOPCODES
]; op
++)
1493 if (op
->pinfo
!= INSN_MACRO
1494 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1495 && (word
& op
->mask
) == op
->match
)
1497 /* We always allow to disassemble the jalx instruction. */
1498 if (!opcode_is_member (op
, mips_isa
, mips_ase
, mips_processor
)
1499 && strcmp (op
->name
, "jalx"))
1502 /* Figure out instruction type and branch delay information. */
1503 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1505 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
1506 info
->insn_type
= dis_jsr
;
1508 info
->insn_type
= dis_branch
;
1509 info
->branch_delay_insns
= 1;
1511 else if ((op
->pinfo
& (INSN_COND_BRANCH_DELAY
1512 | INSN_COND_BRANCH_LIKELY
)) != 0)
1514 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1515 info
->insn_type
= dis_condjsr
;
1517 info
->insn_type
= dis_condbranch
;
1518 info
->branch_delay_insns
= 1;
1520 else if ((op
->pinfo
& (INSN_STORE_MEMORY
1521 | INSN_LOAD_MEMORY
)) != 0)
1522 info
->insn_type
= dis_dref
;
1524 infprintf (is
, "%s", op
->name
);
1525 if (op
->pinfo2
& INSN2_VU0_CHANNEL_SUFFIX
)
1529 infprintf (is
, ".");
1530 uval
= mips_extract_operand (&mips_vu0_channel_mask
, word
);
1531 print_vu0_channel (info
, &mips_vu0_channel_mask
, uval
);
1536 infprintf (is
, "\t");
1537 print_insn_args (info
, op
, decode_mips_operand
, word
,
1547 /* Handle undefined instructions. */
1548 info
->insn_type
= dis_noninsn
;
1549 infprintf (is
, "0x%x", word
);
1553 /* Disassemble an operand for a mips16 instruction. */
1556 print_mips16_insn_arg (struct disassemble_info
*info
,
1557 struct mips_print_arg_state
*state
,
1558 const struct mips_opcode
*opcode
,
1559 char type
, bfd_vma memaddr
,
1560 unsigned insn
, bfd_boolean use_extend
,
1561 unsigned extend
, bfd_boolean is_offset
)
1563 const fprintf_ftype infprintf
= info
->fprintf_func
;
1564 void *is
= info
->stream
;
1565 const struct mips_operand
*operand
, *ext_operand
;
1577 infprintf (is
, "%c", type
);
1581 operand
= decode_mips16_operand (type
, FALSE
);
1584 /* xgettext:c-format */
1585 infprintf (is
, _("# internal error, undefined operand in `%s %s'"),
1586 opcode
->name
, opcode
->args
);
1590 if (operand
->type
== OP_SAVE_RESTORE_LIST
)
1592 /* Handle this case here because of the complex interation
1593 with the EXTEND opcode. */
1594 unsigned int amask
, nargs
, nstatics
, nsreg
, smask
, frame_size
, i
, j
;
1597 amask
= extend
& 0xf;
1598 if (amask
== MIPS16_ALL_ARGS
)
1603 else if (amask
== MIPS16_ALL_STATICS
)
1611 nstatics
= amask
& 3;
1617 infprintf (is
, "%s", mips_gpr_names
[4]);
1619 infprintf (is
, "-%s", mips_gpr_names
[4 + nargs
- 1]);
1623 frame_size
= ((extend
& 0xf0) | (insn
& 0x0f)) * 8;
1624 if (frame_size
== 0 && !use_extend
)
1626 infprintf (is
, "%s%d", sep
, frame_size
);
1628 if (insn
& 0x40) /* $ra */
1629 infprintf (is
, ",%s", mips_gpr_names
[31]);
1631 nsreg
= (extend
>> 8) & 0x7;
1633 if (insn
& 0x20) /* $s0 */
1635 if (insn
& 0x10) /* $s1 */
1637 if (nsreg
> 0) /* $s2-$s8 */
1638 smask
|= ((1 << nsreg
) - 1) << 2;
1640 for (i
= 0; i
< 9; i
++)
1641 if (smask
& (1 << i
))
1643 infprintf (is
, ",%s", mips_gpr_names
[i
== 8 ? 30 : (16 + i
)]);
1644 /* Skip over string of set bits. */
1645 for (j
= i
; smask
& (2 << j
); j
++)
1648 infprintf (is
, "-%s", mips_gpr_names
[j
== 8 ? 30 : (16 + j
)]);
1651 /* Statics $ax - $a3. */
1653 infprintf (is
, ",%s", mips_gpr_names
[7]);
1654 else if (nstatics
> 0)
1655 infprintf (is
, ",%s-%s",
1656 mips_gpr_names
[7 - nstatics
+ 1],
1661 if (is_offset
&& operand
->type
== OP_INT
)
1663 const struct mips_int_operand
*int_op
;
1665 int_op
= (const struct mips_int_operand
*) operand
;
1666 info
->insn_type
= dis_dref
;
1667 info
->data_size
= 1 << int_op
->shift
;
1670 if (operand
->size
== 26)
1671 /* In this case INSN is the first two bytes of the instruction
1672 and EXTEND is the second two bytes. */
1673 uval
= ((insn
& 0x1f) << 21) | ((insn
& 0x3e0) << 11) | extend
;
1676 /* Calculate the full field value. */
1677 uval
= mips_extract_operand (operand
, insn
);
1680 ext_operand
= decode_mips16_operand (type
, TRUE
);
1681 if (ext_operand
!= operand
)
1683 operand
= ext_operand
;
1684 if (operand
->size
== 16)
1685 uval
|= ((extend
& 0x1f) << 11) | (extend
& 0x7e0);
1686 else if (operand
->size
== 15)
1687 uval
|= ((extend
& 0xf) << 11) | (extend
& 0x7f0);
1689 uval
= ((extend
>> 6) & 0x1f) | (extend
& 0x20);
1694 baseaddr
= memaddr
+ 2;
1695 if (operand
->type
== OP_PCREL
)
1697 const struct mips_pcrel_operand
*pcrel_op
;
1699 pcrel_op
= (const struct mips_pcrel_operand
*) operand
;
1700 if (!pcrel_op
->include_isa_bit
&& use_extend
)
1701 baseaddr
= memaddr
- 2;
1702 else if (!pcrel_op
->include_isa_bit
)
1706 /* If this instruction is in the delay slot of a JR
1707 instruction, the base address is the address of the
1708 JR instruction. If it is in the delay slot of a JALR
1709 instruction, the base address is the address of the
1710 JALR instruction. This test is unreliable: we have
1711 no way of knowing whether the previous word is
1712 instruction or data. */
1713 if (info
->read_memory_func (memaddr
- 4, buffer
, 2, info
) == 0
1714 && (((info
->endian
== BFD_ENDIAN_BIG
1715 ? bfd_getb16 (buffer
)
1716 : bfd_getl16 (buffer
))
1717 & 0xf800) == 0x1800))
1718 baseaddr
= memaddr
- 4;
1719 else if (info
->read_memory_func (memaddr
- 2, buffer
, 2,
1721 && (((info
->endian
== BFD_ENDIAN_BIG
1722 ? bfd_getb16 (buffer
)
1723 : bfd_getl16 (buffer
))
1724 & 0xf81f) == 0xe800))
1725 baseaddr
= memaddr
- 2;
1731 print_insn_arg (info
, state
, opcode
, operand
, baseaddr
+ 1, uval
);
1737 /* Check if the given address is the last word of a MIPS16 PLT entry.
1738 This word is data and depending on the value it may interfere with
1739 disassembly of further PLT entries. We make use of the fact PLT
1740 symbols are marked BSF_SYNTHETIC. */
1742 is_mips16_plt_tail (struct disassemble_info
*info
, bfd_vma addr
)
1746 && (info
->symbols
[0]->flags
& BSF_SYNTHETIC
)
1747 && addr
== bfd_asymbol_value (info
->symbols
[0]) + 12)
1753 /* Disassemble mips16 instructions. */
1756 print_insn_mips16 (bfd_vma memaddr
, struct disassemble_info
*info
)
1758 const fprintf_ftype infprintf
= info
->fprintf_func
;
1763 bfd_boolean use_extend
;
1765 const struct mips_opcode
*op
, *opend
;
1766 struct mips_print_arg_state state
;
1767 void *is
= info
->stream
;
1769 info
->bytes_per_chunk
= 2;
1770 info
->display_endian
= info
->endian
;
1771 info
->insn_info_valid
= 1;
1772 info
->branch_delay_insns
= 0;
1773 info
->data_size
= 0;
1777 #define GET_OP(insn, field) \
1778 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1779 /* Decode PLT entry's GOT slot address word. */
1780 if (is_mips16_plt_tail (info
, memaddr
))
1782 info
->insn_type
= dis_noninsn
;
1783 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
1786 unsigned int gotslot
;
1788 if (info
->endian
== BFD_ENDIAN_BIG
)
1789 gotslot
= bfd_getb32 (buffer
);
1791 gotslot
= bfd_getl32 (buffer
);
1792 infprintf (is
, ".word\t0x%x", gotslot
);
1799 info
->insn_type
= dis_nonbranch
;
1800 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1804 (*info
->memory_error_func
) (status
, memaddr
, info
);
1810 if (info
->endian
== BFD_ENDIAN_BIG
)
1811 insn
= bfd_getb16 (buffer
);
1813 insn
= bfd_getl16 (buffer
);
1815 /* Handle the extend opcode specially. */
1817 if ((insn
& 0xf800) == 0xf000)
1820 extend
= insn
& 0x7ff;
1824 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1827 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1828 (*info
->memory_error_func
) (status
, memaddr
, info
);
1832 if (info
->endian
== BFD_ENDIAN_BIG
)
1833 insn
= bfd_getb16 (buffer
);
1835 insn
= bfd_getl16 (buffer
);
1837 /* Check for an extend opcode followed by an extend opcode. */
1838 if ((insn
& 0xf800) == 0xf000)
1840 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1841 info
->insn_type
= dis_noninsn
;
1848 /* FIXME: Should probably use a hash table on the major opcode here. */
1850 opend
= mips16_opcodes
+ bfd_mips16_num_opcodes
;
1851 for (op
= mips16_opcodes
; op
< opend
; op
++)
1853 if (op
->pinfo
!= INSN_MACRO
1854 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
1855 && (insn
& op
->mask
) == op
->match
)
1859 if (op
->args
[0] == 'a' || op
->args
[0] == 'i')
1863 infprintf (is
, "extend 0x%x", (unsigned int) extend
);
1864 info
->insn_type
= dis_noninsn
;
1872 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2,
1877 if (info
->endian
== BFD_ENDIAN_BIG
)
1878 extend
= bfd_getb16 (buffer
);
1880 extend
= bfd_getl16 (buffer
);
1885 infprintf (is
, "%s", op
->name
);
1886 if (op
->args
[0] != '\0')
1887 infprintf (is
, "\t");
1889 init_print_arg_state (&state
);
1890 for (s
= op
->args
; *s
!= '\0'; s
++)
1894 && GET_OP (insn
, RX
) == GET_OP (insn
, RY
))
1896 /* Skip the register and the comma. */
1902 && GET_OP (insn
, RZ
) == GET_OP (insn
, RX
))
1904 /* Skip the register and the comma. */
1908 print_mips16_insn_arg (info
, &state
, op
, *s
, memaddr
, insn
,
1909 use_extend
, extend
, s
[1] == '(');
1912 /* Figure out branch instruction type and delay slot information. */
1913 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0)
1914 info
->branch_delay_insns
= 1;
1915 if ((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
) != 0
1916 || (op
->pinfo2
& INSN2_UNCOND_BRANCH
) != 0)
1918 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
1919 info
->insn_type
= dis_jsr
;
1921 info
->insn_type
= dis_branch
;
1923 else if ((op
->pinfo2
& INSN2_COND_BRANCH
) != 0)
1924 info
->insn_type
= dis_condbranch
;
1932 infprintf (is
, "0x%x", extend
| 0xf000);
1933 infprintf (is
, "0x%x", insn
);
1934 info
->insn_type
= dis_noninsn
;
1939 /* Disassemble microMIPS instructions. */
1942 print_insn_micromips (bfd_vma memaddr
, struct disassemble_info
*info
)
1944 const fprintf_ftype infprintf
= info
->fprintf_func
;
1945 const struct mips_opcode
*op
, *opend
;
1946 void *is
= info
->stream
;
1948 unsigned int higher
;
1949 unsigned int length
;
1953 info
->bytes_per_chunk
= 2;
1954 info
->display_endian
= info
->endian
;
1955 info
->insn_info_valid
= 1;
1956 info
->branch_delay_insns
= 0;
1957 info
->data_size
= 0;
1958 info
->insn_type
= dis_nonbranch
;
1962 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
1965 (*info
->memory_error_func
) (status
, memaddr
, info
);
1971 if (info
->endian
== BFD_ENDIAN_BIG
)
1972 insn
= bfd_getb16 (buffer
);
1974 insn
= bfd_getl16 (buffer
);
1976 if ((insn
& 0xfc00) == 0x7c00)
1978 /* This is a 48-bit microMIPS instruction. */
1981 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
1984 infprintf (is
, "micromips 0x%x", higher
);
1985 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
1988 if (info
->endian
== BFD_ENDIAN_BIG
)
1989 insn
= bfd_getb16 (buffer
);
1991 insn
= bfd_getl16 (buffer
);
1992 higher
= (higher
<< 16) | insn
;
1994 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
1997 infprintf (is
, "micromips 0x%x", higher
);
1998 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
2001 if (info
->endian
== BFD_ENDIAN_BIG
)
2002 insn
= bfd_getb16 (buffer
);
2004 insn
= bfd_getl16 (buffer
);
2005 infprintf (is
, "0x%x%04x (48-bit insn)", higher
, insn
);
2007 info
->insn_type
= dis_noninsn
;
2010 else if ((insn
& 0x1c00) == 0x0000 || (insn
& 0x1000) == 0x1000)
2012 /* This is a 32-bit microMIPS instruction. */
2015 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
2018 infprintf (is
, "micromips 0x%x", higher
);
2019 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
2023 if (info
->endian
== BFD_ENDIAN_BIG
)
2024 insn
= bfd_getb16 (buffer
);
2026 insn
= bfd_getl16 (buffer
);
2028 insn
= insn
| (higher
<< 16);
2033 /* FIXME: Should probably use a hash table on the major opcode here. */
2035 opend
= micromips_opcodes
+ bfd_micromips_num_opcodes
;
2036 for (op
= micromips_opcodes
; op
< opend
; op
++)
2038 if (op
->pinfo
!= INSN_MACRO
2039 && !(no_aliases
&& (op
->pinfo2
& INSN2_ALIAS
))
2040 && (insn
& op
->mask
) == op
->match
2041 && ((length
== 2 && (op
->mask
& 0xffff0000) == 0)
2042 || (length
== 4 && (op
->mask
& 0xffff0000) != 0)))
2044 infprintf (is
, "%s", op
->name
);
2048 infprintf (is
, "\t");
2049 print_insn_args (info
, op
, decode_micromips_operand
, insn
,
2050 memaddr
+ length
+ 1);
2053 /* Figure out instruction type and branch delay information. */
2055 & (INSN_UNCOND_BRANCH_DELAY
| INSN_COND_BRANCH_DELAY
)) != 0)
2056 info
->branch_delay_insns
= 1;
2057 if (((op
->pinfo
& INSN_UNCOND_BRANCH_DELAY
)
2058 | (op
->pinfo2
& INSN2_UNCOND_BRANCH
)) != 0)
2060 if ((op
->pinfo
& (INSN_WRITE_GPR_31
| INSN_WRITE_1
)) != 0)
2061 info
->insn_type
= dis_jsr
;
2063 info
->insn_type
= dis_branch
;
2065 else if (((op
->pinfo
& INSN_COND_BRANCH_DELAY
)
2066 | (op
->pinfo2
& INSN2_COND_BRANCH
)) != 0)
2068 if ((op
->pinfo
& INSN_WRITE_GPR_31
) != 0)
2069 info
->insn_type
= dis_condjsr
;
2071 info
->insn_type
= dis_condbranch
;
2074 & (INSN_STORE_MEMORY
| INSN_LOAD_MEMORY
)) != 0)
2075 info
->insn_type
= dis_dref
;
2081 infprintf (is
, "0x%x", insn
);
2082 info
->insn_type
= dis_noninsn
;
2087 /* Return 1 if a symbol associated with the location being disassembled
2088 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2089 all the symbols at the address being considered assuming if at least
2090 one of them indicates code compression, then such code has been
2091 genuinely produced here (other symbols could have been derived from
2092 function symbols defined elsewhere or could define data). Otherwise,
2096 is_compressed_mode_p (struct disassemble_info
*info
)
2101 for (i
= info
->symtab_pos
, l
= i
+ info
->num_symbols
; i
< l
; i
++)
2102 if (((info
->symtab
[i
])->flags
& BSF_SYNTHETIC
) != 0
2104 && ELF_ST_IS_MIPS16 ((*info
->symbols
)->udata
.i
))
2106 && ELF_ST_IS_MICROMIPS ((*info
->symbols
)->udata
.i
))))
2108 else if (bfd_asymbol_flavour (info
->symtab
[i
]) == bfd_target_elf_flavour
2109 && info
->symtab
[i
]->section
== info
->section
)
2111 elf_symbol_type
*symbol
= (elf_symbol_type
*) info
->symtab
[i
];
2113 && ELF_ST_IS_MIPS16 (symbol
->internal_elf_sym
.st_other
))
2115 && ELF_ST_IS_MICROMIPS (symbol
->internal_elf_sym
.st_other
)))
2122 /* In an environment where we do not know the symbol type of the
2123 instruction we are forced to assume that the low order bit of the
2124 instructions' address may mark it as a mips16 instruction. If we
2125 are single stepping, or the pc is within the disassembled function,
2126 this works. Otherwise, we need a clue. Sometimes. */
2129 _print_insn_mips (bfd_vma memaddr
,
2130 struct disassemble_info
*info
,
2131 enum bfd_endian endianness
)
2133 int (*print_insn_compr
) (bfd_vma
, struct disassemble_info
*);
2134 bfd_byte buffer
[INSNLEN
];
2137 set_default_mips_dis_options (info
);
2138 parse_mips_dis_options (info
->disassembler_options
);
2140 if (info
->mach
== bfd_mach_mips16
)
2141 return print_insn_mips16 (memaddr
, info
);
2142 if (info
->mach
== bfd_mach_mips_micromips
)
2143 return print_insn_micromips (memaddr
, info
);
2145 print_insn_compr
= !micromips_ase
? print_insn_mips16
: print_insn_micromips
;
2148 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2149 /* Only a few tools will work this way. */
2151 return print_insn_compr (memaddr
, info
);
2154 #if SYMTAB_AVAILABLE
2155 if (is_compressed_mode_p (info
))
2156 return print_insn_compr (memaddr
, info
);
2159 status
= (*info
->read_memory_func
) (memaddr
, buffer
, INSNLEN
, info
);
2164 if (endianness
== BFD_ENDIAN_BIG
)
2165 insn
= bfd_getb32 (buffer
);
2167 insn
= bfd_getl32 (buffer
);
2169 return print_insn_mips (memaddr
, insn
, info
);
2173 (*info
->memory_error_func
) (status
, memaddr
, info
);
2179 print_insn_big_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2181 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_BIG
);
2185 print_insn_little_mips (bfd_vma memaddr
, struct disassemble_info
*info
)
2187 return _print_insn_mips (memaddr
, info
, BFD_ENDIAN_LITTLE
);
2191 print_mips_disassembler_options (FILE *stream
)
2195 fprintf (stream
, _("\n\
2196 The following MIPS specific disassembler options are supported for use\n\
2197 with the -M switch (multiple options should be separated by commas):\n"));
2199 fprintf (stream
, _("\n\
2200 msa Recognize MSA instructions.\n"));
2202 fprintf (stream
, _("\n\
2203 virt Recognize the virtualization ASE instructions.\n"));
2205 fprintf (stream
, _("\n\
2206 xpa Recognize the eXtended Physical Address (XPA) ASE instructions.\n"));
2208 fprintf (stream
, _("\n\
2209 gpr-names=ABI Print GPR names according to specified ABI.\n\
2210 Default: based on binary being disassembled.\n"));
2212 fprintf (stream
, _("\n\
2213 fpr-names=ABI Print FPR names according to specified ABI.\n\
2214 Default: numeric.\n"));
2216 fprintf (stream
, _("\n\
2217 cp0-names=ARCH Print CP0 register names according to\n\
2218 specified architecture.\n\
2219 Default: based on binary being disassembled.\n"));
2221 fprintf (stream
, _("\n\
2222 hwr-names=ARCH Print HWR names according to specified \n\
2224 Default: based on binary being disassembled.\n"));
2226 fprintf (stream
, _("\n\
2227 reg-names=ABI Print GPR and FPR names according to\n\
2228 specified ABI.\n"));
2230 fprintf (stream
, _("\n\
2231 reg-names=ARCH Print CP0 register and HWR names according to\n\
2232 specified architecture.\n"));
2234 fprintf (stream
, _("\n\
2235 For the options above, the following values are supported for \"ABI\":\n\
2237 for (i
= 0; i
< ARRAY_SIZE (mips_abi_choices
); i
++)
2238 fprintf (stream
, " %s", mips_abi_choices
[i
].name
);
2239 fprintf (stream
, _("\n"));
2241 fprintf (stream
, _("\n\
2242 For the options above, The following values are supported for \"ARCH\":\n\
2244 for (i
= 0; i
< ARRAY_SIZE (mips_arch_choices
); i
++)
2245 if (*mips_arch_choices
[i
].name
!= '\0')
2246 fprintf (stream
, " %s", mips_arch_choices
[i
].name
);
2247 fprintf (stream
, _("\n"));
2249 fprintf (stream
, _("\n"));