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 { "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
577 (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
579 mips_cp0_names_mips3264r2,
580 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
581 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
583 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
584 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
585 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
586 mips_cp0_names_mips3264,
587 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
588 mips_cp1_names_mips3264, mips_hwr_names_numeric },
590 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
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 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
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 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
608 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
609 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
610 mips_cp0_names_mips3264r2,
611 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
612 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
614 { "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
616 (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
617 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2),
618 mips_cp0_names_mips3264r2,
619 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
620 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
622 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
623 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
625 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
626 mips_cp1_names_mips3264, mips_hwr_names_numeric },
628 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
629 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
630 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
632 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
633 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
634 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
636 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
637 ISA_MIPS64R2 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
638 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
640 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
641 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
642 mips_cp1_names_mips3264, mips_hwr_names_numeric },
644 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
645 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
646 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
648 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
649 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
650 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
652 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
653 ISA_MIPS64 | INSN_XLR, 0,
655 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
656 mips_cp1_names_mips3264, mips_hwr_names_numeric },
658 /* XLP is mostly like XLR, with the prominent exception it is being
660 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
661 ISA_MIPS64R2 | INSN_XLR, 0,
663 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
664 mips_cp1_names_mips3264, mips_hwr_names_numeric },
666 /* This entry, mips16, is here only for ISA/processor selection; do
667 not print its name. */
668 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0,
669 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
670 mips_hwr_names_numeric },
673 /* ISA and processor type to disassemble for, and register names to use.
674 set_default_mips_dis_options and parse_mips_dis_options fill in these
676 static int mips_processor;
679 static int micromips_ase;
680 static const char * const *mips_gpr_names;
681 static const char * const *mips_fpr_names;
682 static const char * const *mips_cp0_names;
683 static const struct mips_cp0sel_name *mips_cp0sel_names;
684 static int mips_cp0sel_names_len;
685 static const char * const *mips_cp1_names;
686 static const char * const *mips_hwr_names;
689 static int no_aliases; /* If set disassemble as most general inst. */
691 static const struct mips_abi_choice *
692 choose_abi_by_name (const char *name, unsigned int namelen)
694 const struct mips_abi_choice *c;
697 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
698 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
699 && strlen (mips_abi_choices[i].name) == namelen)
700 c = &mips_abi_choices[i];
705 static const struct mips_arch_choice *
706 choose_arch_by_name (const char *name, unsigned int namelen)
708 const struct mips_arch_choice *c = NULL;
711 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
712 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
713 && strlen (mips_arch_choices[i].name) == namelen)
714 c = &mips_arch_choices[i];
719 static const struct mips_arch_choice *
720 choose_arch_by_number (unsigned long mach)
722 static unsigned long hint_bfd_mach;
723 static const struct mips_arch_choice *hint_arch_choice;
724 const struct mips_arch_choice *c;
727 /* We optimize this because even if the user specifies no
728 flags, this will be done for every instruction! */
729 if (hint_bfd_mach == mach
730 && hint_arch_choice != NULL
731 && hint_arch_choice->bfd_mach == hint_bfd_mach)
732 return hint_arch_choice;
734 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
736 if (mips_arch_choices[i].bfd_mach_valid
737 && mips_arch_choices[i].bfd_mach == mach)
739 c = &mips_arch_choices[i];
740 hint_bfd_mach = mach;
741 hint_arch_choice = c;
747 /* Check if the object uses NewABI conventions. */
750 is_newabi (Elf_Internal_Ehdr *header)
752 /* There are no old-style ABIs which use 64-bit ELF. */
753 if (header->e_ident[EI_CLASS] == ELFCLASS64)
756 /* If a 32-bit ELF file, n32 is a new-style ABI. */
757 if ((header->e_flags & EF_MIPS_ABI2) != 0)
763 /* Check if the object has microMIPS ASE code. */
766 is_micromips (Elf_Internal_Ehdr *header)
768 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
775 set_default_mips_dis_options (struct disassemble_info *info)
777 const struct mips_arch_choice *chosen_arch;
779 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
780 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
781 CP0 register, and HWR names. */
782 mips_isa = ISA_MIPS3;
783 mips_processor = CPU_R3000;
786 mips_gpr_names = mips_gpr_names_oldabi;
787 mips_fpr_names = mips_fpr_names_numeric;
788 mips_cp0_names = mips_cp0_names_numeric;
789 mips_cp0sel_names = NULL;
790 mips_cp0sel_names_len = 0;
791 mips_cp1_names = mips_cp1_names_numeric;
792 mips_hwr_names = mips_hwr_names_numeric;
795 /* Update settings according to the ELF file header flags. */
796 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
798 Elf_Internal_Ehdr *header;
800 header = elf_elfheader (info->section->owner);
801 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
802 if (is_newabi (header))
803 mips_gpr_names = mips_gpr_names_newabi;
804 /* If a microMIPS binary, then don't use MIPS16 bindings. */
805 micromips_ase = is_micromips (header);
808 /* Set ISA, architecture, and cp0 register names as best we can. */
809 #if ! SYMTAB_AVAILABLE
810 /* This is running out on a target machine, not in a host tool.
811 FIXME: Where does mips_target_info come from? */
812 target_processor = mips_target_info.processor;
813 mips_isa = mips_target_info.isa;
814 mips_ase = mips_target_info.ase;
816 chosen_arch = choose_arch_by_number (info->mach);
817 if (chosen_arch != NULL)
819 mips_processor = chosen_arch->processor;
820 mips_isa = chosen_arch->isa;
821 mips_ase = chosen_arch->ase;
822 mips_cp0_names = chosen_arch->cp0_names;
823 mips_cp0sel_names = chosen_arch->cp0sel_names;
824 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
825 mips_cp1_names = chosen_arch->cp1_names;
826 mips_hwr_names = chosen_arch->hwr_names;
832 parse_mips_dis_option (const char *option, unsigned int len)
834 unsigned int i, optionlen, vallen;
836 const struct mips_abi_choice *chosen_abi;
837 const struct mips_arch_choice *chosen_arch;
839 /* Try to match options that are simple flags */
840 if (CONST_STRNEQ (option, "no-aliases"))
846 if (CONST_STRNEQ (option, "msa"))
849 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
850 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
851 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
852 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
853 mips_ase |= ASE_MSA64;
857 if (CONST_STRNEQ (option, "virt"))
859 mips_ase |= ASE_VIRT;
860 if (mips_isa & ISA_MIPS64R2
861 || mips_isa & ISA_MIPS64R3
862 || mips_isa & ISA_MIPS64R5
863 || mips_isa & ISA_MIPS64R6)
864 mips_ase |= ASE_VIRT64;
868 if (CONST_STRNEQ (option, "xpa"))
875 /* Look for the = that delimits the end of the option name. */
876 for (i = 0; i < len; i++)
877 if (option[i] == '=')
880 if (i == 0) /* Invalid option: no name before '='. */
882 if (i == len) /* Invalid option: no '='. */
884 if (i == (len - 1)) /* Invalid option: no value after '='. */
888 val = option + (optionlen + 1);
889 vallen = len - (optionlen + 1);
891 if (strncmp ("gpr-names", option, optionlen) == 0
892 && strlen ("gpr-names") == optionlen)
894 chosen_abi = choose_abi_by_name (val, vallen);
895 if (chosen_abi != NULL)
896 mips_gpr_names = chosen_abi->gpr_names;
900 if (strncmp ("fpr-names", option, optionlen) == 0
901 && strlen ("fpr-names") == optionlen)
903 chosen_abi = choose_abi_by_name (val, vallen);
904 if (chosen_abi != NULL)
905 mips_fpr_names = chosen_abi->fpr_names;
909 if (strncmp ("cp0-names", option, optionlen) == 0
910 && strlen ("cp0-names") == optionlen)
912 chosen_arch = choose_arch_by_name (val, vallen);
913 if (chosen_arch != NULL)
915 mips_cp0_names = chosen_arch->cp0_names;
916 mips_cp0sel_names = chosen_arch->cp0sel_names;
917 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
922 if (strncmp ("cp1-names", option, optionlen) == 0
923 && strlen ("cp1-names") == optionlen)
925 chosen_arch = choose_arch_by_name (val, vallen);
926 if (chosen_arch != NULL)
927 mips_cp1_names = chosen_arch->cp1_names;
931 if (strncmp ("hwr-names", option, optionlen) == 0
932 && strlen ("hwr-names") == optionlen)
934 chosen_arch = choose_arch_by_name (val, vallen);
935 if (chosen_arch != NULL)
936 mips_hwr_names = chosen_arch->hwr_names;
940 if (strncmp ("reg-names", option, optionlen) == 0
941 && strlen ("reg-names") == optionlen)
943 /* We check both ABI and ARCH here unconditionally, so
944 that "numeric" will do the desirable thing: select
945 numeric register names for all registers. Other than
946 that, a given name probably won't match both. */
947 chosen_abi = choose_abi_by_name (val, vallen);
948 if (chosen_abi != NULL)
950 mips_gpr_names = chosen_abi->gpr_names;
951 mips_fpr_names = chosen_abi->fpr_names;
953 chosen_arch = choose_arch_by_name (val, vallen);
954 if (chosen_arch != NULL)
956 mips_cp0_names = chosen_arch->cp0_names;
957 mips_cp0sel_names = chosen_arch->cp0sel_names;
958 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
959 mips_cp1_names = chosen_arch->cp1_names;
960 mips_hwr_names = chosen_arch->hwr_names;
965 /* Invalid option. */
969 parse_mips_dis_options (const char *options)
971 const char *option_end;
976 while (*options != '\0')
978 /* Skip empty options. */
985 /* We know that *options is neither NUL or a comma. */
986 option_end = options + 1;
987 while (*option_end != ',' && *option_end != '\0')
990 parse_mips_dis_option (options, option_end - options);
992 /* Go on to the next one. If option_end points to a comma, it
993 will be skipped above. */
994 options = option_end;
998 static const struct mips_cp0sel_name *
999 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1001 unsigned int cp0reg,
1006 for (i = 0; i < len; i++)
1007 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1012 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1015 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1016 enum mips_reg_operand_type type, int regno)
1021 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1025 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1029 if (opcode->pinfo & (FP_D | FP_S))
1030 info->fprintf_func (info->stream, "$fcc%d", regno);
1032 info->fprintf_func (info->stream, "$cc%d", regno);
1036 if (opcode->membership & INSN_5400)
1037 info->fprintf_func (info->stream, "$f%d", regno);
1039 info->fprintf_func (info->stream, "$v%d", regno);
1043 info->fprintf_func (info->stream, "$ac%d", regno);
1047 if (opcode->name[strlen (opcode->name) - 1] == '0')
1048 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
1049 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1050 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
1052 info->fprintf_func (info->stream, "$%d", regno);
1056 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1060 info->fprintf_func (info->stream, "$vf%d", regno);
1064 info->fprintf_func (info->stream, "$vi%d", regno);
1067 case OP_REG_R5900_I:
1068 info->fprintf_func (info->stream, "$I");
1071 case OP_REG_R5900_Q:
1072 info->fprintf_func (info->stream, "$Q");
1075 case OP_REG_R5900_R:
1076 info->fprintf_func (info->stream, "$R");
1079 case OP_REG_R5900_ACC:
1080 info->fprintf_func (info->stream, "$ACC");
1084 info->fprintf_func (info->stream, "$w%d", regno);
1087 case OP_REG_MSA_CTRL:
1088 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1094 /* Used to track the state carried over from previous operands in
1096 struct mips_print_arg_state {
1097 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1098 where the value is known to be unsigned and small. */
1099 unsigned int last_int;
1101 /* The type and number of the last OP_REG seen. We only use this for
1102 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1103 enum mips_reg_operand_type last_reg_type;
1104 unsigned int last_regno;
1105 unsigned int dest_regno;
1106 unsigned int seen_dest;
1109 /* Initialize STATE for the start of an instruction. */
1112 init_print_arg_state (struct mips_print_arg_state *state)
1114 memset (state, 0, sizeof (*state));
1117 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1118 whose value is given by UVAL. */
1121 print_vu0_channel (struct disassemble_info *info,
1122 const struct mips_operand *operand, unsigned int uval)
1124 if (operand->size == 4)
1125 info->fprintf_func (info->stream, "%s%s%s%s",
1126 uval & 8 ? "x" : "",
1127 uval & 4 ? "y" : "",
1128 uval & 2 ? "z" : "",
1129 uval & 1 ? "w" : "");
1130 else if (operand->size == 2)
1131 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1136 /* Record information about a register operand. */
1139 mips_seen_register (struct mips_print_arg_state *state,
1141 enum mips_reg_operand_type reg_type)
1143 state->last_reg_type = reg_type;
1144 state->last_regno = regno;
1146 if (!state->seen_dest)
1148 state->seen_dest = 1;
1149 state->dest_regno = regno;
1153 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1154 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1155 the base address for OP_PCREL operands. */
1158 print_insn_arg (struct disassemble_info *info,
1159 struct mips_print_arg_state *state,
1160 const struct mips_opcode *opcode,
1161 const struct mips_operand *operand,
1165 const fprintf_ftype infprintf = info->fprintf_func;
1166 void *is = info->stream;
1168 switch (operand->type)
1172 const struct mips_int_operand *int_op;
1174 int_op = (const struct mips_int_operand *) operand;
1175 uval = mips_decode_int_operand (int_op, uval);
1176 state->last_int = uval;
1177 if (int_op->print_hex)
1178 infprintf (is, "0x%x", uval);
1180 infprintf (is, "%d", uval);
1186 const struct mips_mapped_int_operand *mint_op;
1188 mint_op = (const struct mips_mapped_int_operand *) operand;
1189 uval = mint_op->int_map[uval];
1190 state->last_int = uval;
1191 if (mint_op->print_hex)
1192 infprintf (is, "0x%x", uval);
1194 infprintf (is, "%d", uval);
1200 const struct mips_msb_operand *msb_op;
1202 msb_op = (const struct mips_msb_operand *) operand;
1203 uval += msb_op->bias;
1204 if (msb_op->add_lsb)
1205 uval -= state->last_int;
1206 infprintf (is, "0x%x", uval);
1211 case OP_OPTIONAL_REG:
1213 const struct mips_reg_operand *reg_op;
1215 reg_op = (const struct mips_reg_operand *) operand;
1216 uval = mips_decode_reg_operand (reg_op, uval);
1217 print_reg (info, opcode, reg_op->reg_type, uval);
1219 mips_seen_register (state, uval, reg_op->reg_type);
1225 const struct mips_reg_pair_operand *pair_op;
1227 pair_op = (const struct mips_reg_pair_operand *) operand;
1228 print_reg (info, opcode, pair_op->reg_type,
1229 pair_op->reg1_map[uval]);
1230 infprintf (is, ",");
1231 print_reg (info, opcode, pair_op->reg_type,
1232 pair_op->reg2_map[uval]);
1238 const struct mips_pcrel_operand *pcrel_op;
1240 pcrel_op = (const struct mips_pcrel_operand *) operand;
1241 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1243 /* Preserve the ISA bit for the GDB disassembler,
1244 otherwise clear it. */
1245 if (info->flavour != bfd_target_unknown_flavour)
1248 (*info->print_address_func) (info->target, info);
1253 infprintf (is, "%d", uval);
1256 case OP_ADDIUSP_INT:
1260 sval = mips_signed_operand (operand, uval) * 4;
1261 if (sval >= -8 && sval < 8)
1263 infprintf (is, "%d", sval);
1267 case OP_CLO_CLZ_DEST:
1269 unsigned int reg1, reg2;
1273 /* If one is zero use the other. */
1274 if (reg1 == reg2 || reg2 == 0)
1275 infprintf (is, "%s", mips_gpr_names[reg1]);
1277 infprintf (is, "%s", mips_gpr_names[reg2]);
1279 /* Bogus, result depends on processor. */
1280 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1281 mips_gpr_names[reg2]);
1287 case OP_NON_ZERO_REG:
1289 print_reg (info, opcode, OP_REG_GP, uval & 31);
1290 mips_seen_register (state, uval, OP_REG_GP);
1294 case OP_LWM_SWM_LIST:
1295 if (operand->size == 2)
1298 infprintf (is, "%s,%s",
1300 mips_gpr_names[31]);
1302 infprintf (is, "%s-%s,%s",
1304 mips_gpr_names[16 + uval],
1305 mips_gpr_names[31]);
1311 s_reg_encode = uval & 0xf;
1312 if (s_reg_encode != 0)
1314 if (s_reg_encode == 1)
1315 infprintf (is, "%s", mips_gpr_names[16]);
1316 else if (s_reg_encode < 9)
1317 infprintf (is, "%s-%s",
1319 mips_gpr_names[15 + s_reg_encode]);
1320 else if (s_reg_encode == 9)
1321 infprintf (is, "%s-%s,%s",
1324 mips_gpr_names[30]);
1326 infprintf (is, "UNKNOWN");
1329 if (uval & 0x10) /* For ra. */
1331 if (s_reg_encode == 0)
1332 infprintf (is, "%s", mips_gpr_names[31]);
1334 infprintf (is, ",%s", mips_gpr_names[31]);
1339 case OP_ENTRY_EXIT_LIST:
1342 unsigned int amask, smask;
1345 amask = (uval >> 3) & 7;
1346 if (amask > 0 && amask < 5)
1348 infprintf (is, "%s", mips_gpr_names[4]);
1350 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1354 smask = (uval >> 1) & 3;
1357 infprintf (is, "%s??", sep);
1362 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1364 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1370 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1374 if (amask == 5 || amask == 6)
1376 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1378 infprintf (is, "-%s", mips_fpr_names[1]);
1383 case OP_SAVE_RESTORE_LIST:
1384 /* Should be handled by the caller due to extend behavior. */
1387 case OP_MDMX_IMM_REG:
1393 if ((vsel & 0x10) == 0)
1398 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1399 if ((vsel & 1) == 0)
1401 print_reg (info, opcode, OP_REG_VEC, uval);
1402 infprintf (is, "[%d]", vsel >> 1);
1404 else if ((vsel & 0x08) == 0)
1405 print_reg (info, opcode, OP_REG_VEC, uval);
1407 infprintf (is, "0x%x", uval);
1411 case OP_REPEAT_PREV_REG:
1412 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1415 case OP_REPEAT_DEST_REG:
1416 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1420 infprintf (is, "$pc");
1424 case OP_VU0_MATCH_SUFFIX:
1425 print_vu0_channel (info, operand, uval);
1429 infprintf (is, "[%d]", uval);
1433 infprintf (is, "[");
1434 print_reg (info, opcode, OP_REG_GP, uval);
1435 infprintf (is, "]");
1440 /* Validate the arguments for INSN, which is described by OPCODE.
1441 Use DECODE_OPERAND to get the encoding of each operand. */
1444 validate_insn_args (const struct mips_opcode *opcode,
1445 const struct mips_operand *(*decode_operand) (const char *),
1448 struct mips_print_arg_state state;
1449 const struct mips_operand *operand;
1453 init_print_arg_state (&state);
1454 for (s = opcode->args; *s; ++s)
1468 operand = decode_operand (s);
1472 uval = mips_extract_operand (operand, insn);
1473 switch (operand->type)
1476 case OP_OPTIONAL_REG:
1478 const struct mips_reg_operand *reg_op;
1480 reg_op = (const struct mips_reg_operand *) operand;
1481 uval = mips_decode_reg_operand (reg_op, uval);
1482 mips_seen_register (&state, uval, reg_op->reg_type);
1488 unsigned int reg1, reg2;
1493 if (reg1 != reg2 || reg1 == 0)
1500 const struct mips_check_prev_operand *prev_op;
1502 prev_op = (const struct mips_check_prev_operand *) operand;
1504 if (!prev_op->zero_ok && uval == 0)
1507 if (((prev_op->less_than_ok && uval < state.last_regno)
1508 || (prev_op->greater_than_ok && uval > state.last_regno)
1509 || (prev_op->equal_ok && uval == state.last_regno)))
1515 case OP_NON_ZERO_REG:
1528 case OP_ADDIUSP_INT:
1529 case OP_CLO_CLZ_DEST:
1530 case OP_LWM_SWM_LIST:
1531 case OP_ENTRY_EXIT_LIST:
1532 case OP_MDMX_IMM_REG:
1533 case OP_REPEAT_PREV_REG:
1534 case OP_REPEAT_DEST_REG:
1537 case OP_VU0_MATCH_SUFFIX:
1542 case OP_SAVE_RESTORE_LIST:
1543 /* Should be handled by the caller due to extend behavior. */
1547 if (*s == 'm' || *s == '+' || *s == '-')
1554 /* Print the arguments for INSN, which is described by OPCODE.
1555 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1556 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1557 operand is for a branch or jump. */
1560 print_insn_args (struct disassemble_info *info,
1561 const struct mips_opcode *opcode,
1562 const struct mips_operand *(*decode_operand) (const char *),
1563 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1565 const fprintf_ftype infprintf = info->fprintf_func;
1566 void *is = info->stream;
1567 struct mips_print_arg_state state;
1568 const struct mips_operand *operand;
1571 init_print_arg_state (&state);
1572 for (s = opcode->args; *s; ++s)
1579 infprintf (is, "%c", *s);
1584 infprintf (is, "%c%c", *s, *s);
1588 operand = decode_operand (s);
1591 /* xgettext:c-format */
1593 _("# internal error, undefined operand in `%s %s'"),
1594 opcode->name, opcode->args);
1597 if (operand->type == OP_REG
1600 && opcode->name[strlen (opcode->name) - 1] == '0')
1602 /* Coprocessor register 0 with sel field (MT ASE). */
1603 const struct mips_cp0sel_name *n;
1604 unsigned int reg, sel;
1606 reg = mips_extract_operand (operand, insn);
1608 operand = decode_operand (s);
1609 sel = mips_extract_operand (operand, insn);
1611 /* CP0 register including 'sel' code for mftc0, to be
1612 printed textually if known. If not known, print both
1613 CP0 register name and sel numerically since CP0 register
1614 with sel 0 may have a name unrelated to register being
1616 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1617 mips_cp0sel_names_len,
1620 infprintf (is, "%s", n->name);
1622 infprintf (is, "$%d,%d", reg, sel);
1626 bfd_vma base_pc = insn_pc;
1628 /* Adjust the PC relative base so that branch/jump insns use
1629 the following PC as the base but genuinely PC relative
1630 operands use the current PC. */
1631 if (operand->type == OP_PCREL)
1633 const struct mips_pcrel_operand *pcrel_op;
1635 pcrel_op = (const struct mips_pcrel_operand *) operand;
1636 /* The include_isa_bit flag is sufficient to distinguish
1637 branch/jump from other PC relative operands. */
1638 if (pcrel_op->include_isa_bit)
1642 print_insn_arg (info, &state, opcode, operand, base_pc,
1643 mips_extract_operand (operand, insn));
1645 if (*s == 'm' || *s == '+' || *s == '-')
1652 /* Print the mips instruction at address MEMADDR in debugged memory,
1653 on using INFO. Returns length of the instruction, in bytes, which is
1654 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1655 this is little-endian code. */
1658 print_insn_mips (bfd_vma memaddr,
1660 struct disassemble_info *info)
1662 #define GET_OP(insn, field) \
1663 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1664 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1665 const fprintf_ftype infprintf = info->fprintf_func;
1666 const struct mips_opcode *op;
1667 static bfd_boolean init = 0;
1668 void *is = info->stream;
1670 /* Build a hash table to shorten the search time. */
1675 for (i = 0; i <= OP_MASK_OP; i++)
1677 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1679 if (op->pinfo == INSN_MACRO
1680 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1682 if (i == GET_OP (op->match, OP))
1693 info->bytes_per_chunk = INSNLEN;
1694 info->display_endian = info->endian;
1695 info->insn_info_valid = 1;
1696 info->branch_delay_insns = 0;
1697 info->data_size = 0;
1698 info->insn_type = dis_nonbranch;
1702 op = mips_hash[GET_OP (word, OP)];
1705 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1707 if (op->pinfo != INSN_MACRO
1708 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1709 && (word & op->mask) == op->match)
1711 /* We always disassemble the jalx instruction, except for MIPS r6. */
1712 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1713 && (strcmp (op->name, "jalx")
1714 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1715 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
1718 /* Figure out instruction type and branch delay information. */
1719 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1721 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
1722 info->insn_type = dis_jsr;
1724 info->insn_type = dis_branch;
1725 info->branch_delay_insns = 1;
1727 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1728 | INSN_COND_BRANCH_LIKELY)) != 0)
1730 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1731 info->insn_type = dis_condjsr;
1733 info->insn_type = dis_condbranch;
1734 info->branch_delay_insns = 1;
1736 else if ((op->pinfo & (INSN_STORE_MEMORY
1737 | INSN_LOAD_MEMORY)) != 0)
1738 info->insn_type = dis_dref;
1740 if (!validate_insn_args (op, decode_mips_operand, word))
1743 infprintf (is, "%s", op->name);
1744 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1748 infprintf (is, ".");
1749 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1750 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1755 infprintf (is, "\t");
1756 print_insn_args (info, op, decode_mips_operand, word,
1766 /* Handle undefined instructions. */
1767 info->insn_type = dis_noninsn;
1768 infprintf (is, "0x%x", word);
1772 /* Disassemble an operand for a mips16 instruction. */
1775 print_mips16_insn_arg (struct disassemble_info *info,
1776 struct mips_print_arg_state *state,
1777 const struct mips_opcode *opcode,
1778 char type, bfd_vma memaddr,
1779 unsigned insn, bfd_boolean use_extend,
1780 unsigned extend, bfd_boolean is_offset)
1782 const fprintf_ftype infprintf = info->fprintf_func;
1783 void *is = info->stream;
1784 const struct mips_operand *operand, *ext_operand;
1796 infprintf (is, "%c", type);
1800 operand = decode_mips16_operand (type, FALSE);
1803 /* xgettext:c-format */
1804 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
1805 opcode->name, opcode->args);
1809 if (operand->type == OP_SAVE_RESTORE_LIST)
1811 /* Handle this case here because of the complex interation
1812 with the EXTEND opcode. */
1813 unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
1816 amask = extend & 0xf;
1817 if (amask == MIPS16_ALL_ARGS)
1822 else if (amask == MIPS16_ALL_STATICS)
1830 nstatics = amask & 3;
1836 infprintf (is, "%s", mips_gpr_names[4]);
1838 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1842 frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
1843 if (frame_size == 0 && !use_extend)
1845 infprintf (is, "%s%d", sep, frame_size);
1847 if (insn & 0x40) /* $ra */
1848 infprintf (is, ",%s", mips_gpr_names[31]);
1850 nsreg = (extend >> 8) & 0x7;
1852 if (insn & 0x20) /* $s0 */
1854 if (insn & 0x10) /* $s1 */
1856 if (nsreg > 0) /* $s2-$s8 */
1857 smask |= ((1 << nsreg) - 1) << 2;
1859 for (i = 0; i < 9; i++)
1860 if (smask & (1 << i))
1862 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1863 /* Skip over string of set bits. */
1864 for (j = i; smask & (2 << j); j++)
1867 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1870 /* Statics $ax - $a3. */
1872 infprintf (is, ",%s", mips_gpr_names[7]);
1873 else if (nstatics > 0)
1874 infprintf (is, ",%s-%s",
1875 mips_gpr_names[7 - nstatics + 1],
1880 if (is_offset && operand->type == OP_INT)
1882 const struct mips_int_operand *int_op;
1884 int_op = (const struct mips_int_operand *) operand;
1885 info->insn_type = dis_dref;
1886 info->data_size = 1 << int_op->shift;
1889 if (operand->size == 26)
1890 /* In this case INSN is the first two bytes of the instruction
1891 and EXTEND is the second two bytes. */
1892 uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
1895 /* Calculate the full field value. */
1896 uval = mips_extract_operand (operand, insn);
1899 ext_operand = decode_mips16_operand (type, TRUE);
1900 if (ext_operand != operand)
1902 operand = ext_operand;
1903 if (operand->size == 16)
1904 uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1905 else if (operand->size == 15)
1906 uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1908 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
1913 baseaddr = memaddr + 2;
1914 if (operand->type == OP_PCREL)
1916 const struct mips_pcrel_operand *pcrel_op;
1918 pcrel_op = (const struct mips_pcrel_operand *) operand;
1919 if (!pcrel_op->include_isa_bit && use_extend)
1920 baseaddr = memaddr - 2;
1921 else if (!pcrel_op->include_isa_bit)
1925 /* If this instruction is in the delay slot of a JR
1926 instruction, the base address is the address of the
1927 JR instruction. If it is in the delay slot of a JALR
1928 instruction, the base address is the address of the
1929 JALR instruction. This test is unreliable: we have
1930 no way of knowing whether the previous word is
1931 instruction or data. */
1932 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
1933 && (((info->endian == BFD_ENDIAN_BIG
1934 ? bfd_getb16 (buffer)
1935 : bfd_getl16 (buffer))
1936 & 0xf800) == 0x1800))
1937 baseaddr = memaddr - 4;
1938 else if (info->read_memory_func (memaddr - 2, buffer, 2,
1940 && (((info->endian == BFD_ENDIAN_BIG
1941 ? bfd_getb16 (buffer)
1942 : bfd_getl16 (buffer))
1943 & 0xf81f) == 0xe800))
1944 baseaddr = memaddr - 2;
1950 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
1956 /* Check if the given address is the last word of a MIPS16 PLT entry.
1957 This word is data and depending on the value it may interfere with
1958 disassembly of further PLT entries. We make use of the fact PLT
1959 symbols are marked BSF_SYNTHETIC. */
1961 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
1965 && (info->symbols[0]->flags & BSF_SYNTHETIC)
1966 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
1972 /* Disassemble mips16 instructions. */
1975 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1977 const fprintf_ftype infprintf = info->fprintf_func;
1982 bfd_boolean use_extend;
1984 const struct mips_opcode *op, *opend;
1985 struct mips_print_arg_state state;
1986 void *is = info->stream;
1988 info->bytes_per_chunk = 2;
1989 info->display_endian = info->endian;
1990 info->insn_info_valid = 1;
1991 info->branch_delay_insns = 0;
1992 info->data_size = 0;
1996 #define GET_OP(insn, field) \
1997 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1998 /* Decode PLT entry's GOT slot address word. */
1999 if (is_mips16_plt_tail (info, memaddr))
2001 info->insn_type = dis_noninsn;
2002 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2005 unsigned int gotslot;
2007 if (info->endian == BFD_ENDIAN_BIG)
2008 gotslot = bfd_getb32 (buffer);
2010 gotslot = bfd_getl32 (buffer);
2011 infprintf (is, ".word\t0x%x", gotslot);
2018 info->insn_type = dis_nonbranch;
2019 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2023 (*info->memory_error_func) (status, memaddr, info);
2029 if (info->endian == BFD_ENDIAN_BIG)
2030 insn = bfd_getb16 (buffer);
2032 insn = bfd_getl16 (buffer);
2034 /* Handle the extend opcode specially. */
2036 if ((insn & 0xf800) == 0xf000)
2039 extend = insn & 0x7ff;
2043 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2046 infprintf (is, "extend 0x%x", (unsigned int) extend);
2047 (*info->memory_error_func) (status, memaddr, info);
2051 if (info->endian == BFD_ENDIAN_BIG)
2052 insn = bfd_getb16 (buffer);
2054 insn = bfd_getl16 (buffer);
2056 /* Check for an extend opcode followed by an extend opcode. */
2057 if ((insn & 0xf800) == 0xf000)
2059 infprintf (is, "extend 0x%x", (unsigned int) extend);
2060 info->insn_type = dis_noninsn;
2067 /* FIXME: Should probably use a hash table on the major opcode here. */
2069 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2070 for (op = mips16_opcodes; op < opend; op++)
2072 if (op->pinfo != INSN_MACRO
2073 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2074 && (insn & op->mask) == op->match)
2078 if (op->args[0] == 'a' || op->args[0] == 'i')
2082 infprintf (is, "extend 0x%x", (unsigned int) extend);
2083 info->insn_type = dis_noninsn;
2091 status = (*info->read_memory_func) (memaddr, buffer, 2,
2096 if (info->endian == BFD_ENDIAN_BIG)
2097 extend = bfd_getb16 (buffer);
2099 extend = bfd_getl16 (buffer);
2104 infprintf (is, "%s", op->name);
2105 if (op->args[0] != '\0')
2106 infprintf (is, "\t");
2108 init_print_arg_state (&state);
2109 for (s = op->args; *s != '\0'; s++)
2113 && GET_OP (insn, RX) == GET_OP (insn, RY))
2115 /* Skip the register and the comma. */
2121 && GET_OP (insn, RZ) == GET_OP (insn, RX))
2123 /* Skip the register and the comma. */
2127 print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
2128 use_extend, extend, s[1] == '(');
2131 /* Figure out branch instruction type and delay slot information. */
2132 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2133 info->branch_delay_insns = 1;
2134 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2135 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2137 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2138 info->insn_type = dis_jsr;
2140 info->insn_type = dis_branch;
2142 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2143 info->insn_type = dis_condbranch;
2151 infprintf (is, "0x%x", extend | 0xf000);
2152 infprintf (is, "0x%x", insn);
2153 info->insn_type = dis_noninsn;
2158 /* Disassemble microMIPS instructions. */
2161 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2163 const fprintf_ftype infprintf = info->fprintf_func;
2164 const struct mips_opcode *op, *opend;
2165 void *is = info->stream;
2167 unsigned int higher;
2168 unsigned int length;
2172 info->bytes_per_chunk = 2;
2173 info->display_endian = info->endian;
2174 info->insn_info_valid = 1;
2175 info->branch_delay_insns = 0;
2176 info->data_size = 0;
2177 info->insn_type = dis_nonbranch;
2181 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2184 (*info->memory_error_func) (status, memaddr, info);
2190 if (info->endian == BFD_ENDIAN_BIG)
2191 insn = bfd_getb16 (buffer);
2193 insn = bfd_getl16 (buffer);
2195 if ((insn & 0xfc00) == 0x7c00)
2197 /* This is a 48-bit microMIPS instruction. */
2200 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2203 infprintf (is, "micromips 0x%x", higher);
2204 (*info->memory_error_func) (status, memaddr + 2, info);
2207 if (info->endian == BFD_ENDIAN_BIG)
2208 insn = bfd_getb16 (buffer);
2210 insn = bfd_getl16 (buffer);
2211 higher = (higher << 16) | insn;
2213 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
2216 infprintf (is, "micromips 0x%x", higher);
2217 (*info->memory_error_func) (status, memaddr + 4, info);
2220 if (info->endian == BFD_ENDIAN_BIG)
2221 insn = bfd_getb16 (buffer);
2223 insn = bfd_getl16 (buffer);
2224 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
2226 info->insn_type = dis_noninsn;
2229 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2231 /* This is a 32-bit microMIPS instruction. */
2234 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2237 infprintf (is, "micromips 0x%x", higher);
2238 (*info->memory_error_func) (status, memaddr + 2, info);
2242 if (info->endian == BFD_ENDIAN_BIG)
2243 insn = bfd_getb16 (buffer);
2245 insn = bfd_getl16 (buffer);
2247 insn = insn | (higher << 16);
2252 /* FIXME: Should probably use a hash table on the major opcode here. */
2254 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2255 for (op = micromips_opcodes; op < opend; op++)
2257 if (op->pinfo != INSN_MACRO
2258 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2259 && (insn & op->mask) == op->match
2260 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2261 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2263 if (!validate_insn_args (op, decode_micromips_operand, insn))
2266 infprintf (is, "%s", op->name);
2270 infprintf (is, "\t");
2271 print_insn_args (info, op, decode_micromips_operand, insn,
2272 memaddr + 1, length);
2275 /* Figure out instruction type and branch delay information. */
2277 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2278 info->branch_delay_insns = 1;
2279 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2280 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2282 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2283 info->insn_type = dis_jsr;
2285 info->insn_type = dis_branch;
2287 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2288 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2290 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2291 info->insn_type = dis_condjsr;
2293 info->insn_type = dis_condbranch;
2296 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2297 info->insn_type = dis_dref;
2303 infprintf (is, "0x%x", insn);
2304 info->insn_type = dis_noninsn;
2309 /* Return 1 if a symbol associated with the location being disassembled
2310 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2311 all the symbols at the address being considered assuming if at least
2312 one of them indicates code compression, then such code has been
2313 genuinely produced here (other symbols could have been derived from
2314 function symbols defined elsewhere or could define data). Otherwise,
2318 is_compressed_mode_p (struct disassemble_info *info)
2323 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2324 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2326 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2328 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2330 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2331 && info->symtab[i]->section == info->section)
2333 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2335 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2337 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2344 /* In an environment where we do not know the symbol type of the
2345 instruction we are forced to assume that the low order bit of the
2346 instructions' address may mark it as a mips16 instruction. If we
2347 are single stepping, or the pc is within the disassembled function,
2348 this works. Otherwise, we need a clue. Sometimes. */
2351 _print_insn_mips (bfd_vma memaddr,
2352 struct disassemble_info *info,
2353 enum bfd_endian endianness)
2355 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
2356 bfd_byte buffer[INSNLEN];
2359 set_default_mips_dis_options (info);
2360 parse_mips_dis_options (info->disassembler_options);
2362 if (info->mach == bfd_mach_mips16)
2363 return print_insn_mips16 (memaddr, info);
2364 if (info->mach == bfd_mach_mips_micromips)
2365 return print_insn_micromips (memaddr, info);
2367 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
2370 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2371 /* Only a few tools will work this way. */
2373 return print_insn_compr (memaddr, info);
2376 #if SYMTAB_AVAILABLE
2377 if (is_compressed_mode_p (info))
2378 return print_insn_compr (memaddr, info);
2381 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2386 if (endianness == BFD_ENDIAN_BIG)
2387 insn = bfd_getb32 (buffer);
2389 insn = bfd_getl32 (buffer);
2391 return print_insn_mips (memaddr, insn, info);
2395 (*info->memory_error_func) (status, memaddr, info);
2401 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2403 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2407 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2409 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2413 print_mips_disassembler_options (FILE *stream)
2417 fprintf (stream, _("\n\
2418 The following MIPS specific disassembler options are supported for use\n\
2419 with the -M switch (multiple options should be separated by commas):\n"));
2421 fprintf (stream, _("\n\
2422 msa Recognize MSA instructions.\n"));
2424 fprintf (stream, _("\n\
2425 virt Recognize the virtualization ASE instructions.\n"));
2427 fprintf (stream, _("\n\
2428 xpa Recognize the eXtended Physical Address (XPA) ASE instructions.\n"));
2430 fprintf (stream, _("\n\
2431 gpr-names=ABI Print GPR names according to specified ABI.\n\
2432 Default: based on binary being disassembled.\n"));
2434 fprintf (stream, _("\n\
2435 fpr-names=ABI Print FPR names according to specified ABI.\n\
2436 Default: numeric.\n"));
2438 fprintf (stream, _("\n\
2439 cp0-names=ARCH Print CP0 register names according to\n\
2440 specified architecture.\n\
2441 Default: based on binary being disassembled.\n"));
2443 fprintf (stream, _("\n\
2444 hwr-names=ARCH Print HWR names according to specified \n\
2446 Default: based on binary being disassembled.\n"));
2448 fprintf (stream, _("\n\
2449 reg-names=ABI Print GPR and FPR names according to\n\
2450 specified ABI.\n"));
2452 fprintf (stream, _("\n\
2453 reg-names=ARCH Print CP0 register and HWR names according to\n\
2454 specified architecture.\n"));
2456 fprintf (stream, _("\n\
2457 For the options above, the following values are supported for \"ABI\":\n\
2459 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2460 fprintf (stream, " %s", mips_abi_choices[i].name);
2461 fprintf (stream, _("\n"));
2463 fprintf (stream, _("\n\
2464 For the options above, The following values are supported for \"ARCH\":\n\
2466 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2467 if (*mips_arch_choices[i].name != '\0')
2468 fprintf (stream, " %s", mips_arch_choices[i].name);
2469 fprintf (stream, _("\n"));
2471 fprintf (stream, _("\n"));