1 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 Copyright (C) 1989-2018 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. */
23 #include "disassemble.h"
24 #include "libiberty.h"
25 #include "opcode/mips.h"
28 /* FIXME: These are needed to figure out if the code is mips16 or
29 not. The low bit of the address is often a good indicator. No
30 symbol table is available when this code runs out in an embedded
31 system as when it is used for disassembler support in a monitor. */
33 #if !defined(EMBEDDED_ENV)
34 #define SYMTAB_AVAILABLE 1
39 /* Mips instructions are at maximum this many bytes long. */
43 /* FIXME: These should be shared with gdb somehow. */
45 struct mips_cp0sel_name
49 const char * const name;
52 static const char * const mips_gpr_names_numeric[32] =
54 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
55 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
56 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
57 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
60 static const char * const mips_gpr_names_oldabi[32] =
62 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
63 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
64 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
65 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
68 static const char * const mips_gpr_names_newabi[32] =
70 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
71 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
72 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
73 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
76 static const char * const mips_fpr_names_numeric[32] =
78 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
79 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
80 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
81 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
84 static const char * const mips_fpr_names_32[32] =
86 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
87 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
88 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
89 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
92 static const char * const mips_fpr_names_n32[32] =
94 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
95 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
96 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
97 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
100 static const char * const mips_fpr_names_64[32] =
102 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
103 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
104 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
105 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
108 static const char * const mips_cp0_names_numeric[32] =
110 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
111 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
112 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
113 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
116 static const char * const mips_cp1_names_numeric[32] =
118 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
119 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
120 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
121 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
124 static const char * const mips_cp0_names_r3000[32] =
126 "c0_index", "c0_random", "c0_entrylo", "$3",
127 "c0_context", "$5", "$6", "$7",
128 "c0_badvaddr", "$9", "c0_entryhi", "$11",
129 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
130 "$16", "$17", "$18", "$19",
131 "$20", "$21", "$22", "$23",
132 "$24", "$25", "$26", "$27",
133 "$28", "$29", "$30", "$31",
136 static const char * const mips_cp0_names_r4000[32] =
138 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
139 "c0_context", "c0_pagemask", "c0_wired", "$7",
140 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
141 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
142 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
143 "c0_xcontext", "$21", "$22", "$23",
144 "$24", "$25", "c0_ecc", "c0_cacheerr",
145 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
148 static const char * const mips_cp0_names_r5900[32] =
150 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
151 "c0_context", "c0_pagemask", "c0_wired", "$7",
152 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
153 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
154 "c0_config", "$17", "$18", "$19",
155 "$20", "$21", "$22", "c0_badpaddr",
156 "c0_depc", "c0_perfcnt", "$26", "$27",
157 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
160 static const char * const mips_cp0_names_mips3264[32] =
162 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
163 "c0_context", "c0_pagemask", "c0_wired", "$7",
164 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
165 "c0_status", "c0_cause", "c0_epc", "c0_prid",
166 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
167 "c0_xcontext", "$21", "$22", "c0_debug",
168 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
169 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
172 static const char * const mips_cp1_names_mips3264[32] =
174 "c1_fir", "c1_ufr", "$2", "$3",
175 "c1_unfr", "$5", "$6", "$7",
176 "$8", "$9", "$10", "$11",
177 "$12", "$13", "$14", "$15",
178 "$16", "$17", "$18", "$19",
179 "$20", "$21", "$22", "$23",
180 "$24", "c1_fccr", "c1_fexr", "$27",
181 "c1_fenr", "$29", "$30", "c1_fcsr"
184 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
186 { 16, 1, "c0_config1" },
187 { 16, 2, "c0_config2" },
188 { 16, 3, "c0_config3" },
189 { 18, 1, "c0_watchlo,1" },
190 { 18, 2, "c0_watchlo,2" },
191 { 18, 3, "c0_watchlo,3" },
192 { 18, 4, "c0_watchlo,4" },
193 { 18, 5, "c0_watchlo,5" },
194 { 18, 6, "c0_watchlo,6" },
195 { 18, 7, "c0_watchlo,7" },
196 { 19, 1, "c0_watchhi,1" },
197 { 19, 2, "c0_watchhi,2" },
198 { 19, 3, "c0_watchhi,3" },
199 { 19, 4, "c0_watchhi,4" },
200 { 19, 5, "c0_watchhi,5" },
201 { 19, 6, "c0_watchhi,6" },
202 { 19, 7, "c0_watchhi,7" },
203 { 25, 1, "c0_perfcnt,1" },
204 { 25, 2, "c0_perfcnt,2" },
205 { 25, 3, "c0_perfcnt,3" },
206 { 25, 4, "c0_perfcnt,4" },
207 { 25, 5, "c0_perfcnt,5" },
208 { 25, 6, "c0_perfcnt,6" },
209 { 25, 7, "c0_perfcnt,7" },
210 { 27, 1, "c0_cacheerr,1" },
211 { 27, 2, "c0_cacheerr,2" },
212 { 27, 3, "c0_cacheerr,3" },
213 { 28, 1, "c0_datalo" },
214 { 29, 1, "c0_datahi" }
217 static const char * const mips_cp0_names_mips3264r2[32] =
219 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
220 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
221 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
222 "c0_status", "c0_cause", "c0_epc", "c0_prid",
223 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
224 "c0_xcontext", "$21", "$22", "c0_debug",
225 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
226 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
229 static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
231 { 4, 1, "c0_contextconfig" },
232 { 0, 1, "c0_mvpcontrol" },
233 { 0, 2, "c0_mvpconf0" },
234 { 0, 3, "c0_mvpconf1" },
235 { 1, 1, "c0_vpecontrol" },
236 { 1, 2, "c0_vpeconf0" },
237 { 1, 3, "c0_vpeconf1" },
238 { 1, 4, "c0_yqmask" },
239 { 1, 5, "c0_vpeschedule" },
240 { 1, 6, "c0_vpeschefback" },
241 { 2, 1, "c0_tcstatus" },
242 { 2, 2, "c0_tcbind" },
243 { 2, 3, "c0_tcrestart" },
244 { 2, 4, "c0_tchalt" },
245 { 2, 5, "c0_tccontext" },
246 { 2, 6, "c0_tcschedule" },
247 { 2, 7, "c0_tcschefback" },
248 { 5, 1, "c0_pagegrain" },
249 { 6, 1, "c0_srsconf0" },
250 { 6, 2, "c0_srsconf1" },
251 { 6, 3, "c0_srsconf2" },
252 { 6, 4, "c0_srsconf3" },
253 { 6, 5, "c0_srsconf4" },
254 { 12, 1, "c0_intctl" },
255 { 12, 2, "c0_srsctl" },
256 { 12, 3, "c0_srsmap" },
257 { 15, 1, "c0_ebase" },
258 { 16, 1, "c0_config1" },
259 { 16, 2, "c0_config2" },
260 { 16, 3, "c0_config3" },
261 { 18, 1, "c0_watchlo,1" },
262 { 18, 2, "c0_watchlo,2" },
263 { 18, 3, "c0_watchlo,3" },
264 { 18, 4, "c0_watchlo,4" },
265 { 18, 5, "c0_watchlo,5" },
266 { 18, 6, "c0_watchlo,6" },
267 { 18, 7, "c0_watchlo,7" },
268 { 19, 1, "c0_watchhi,1" },
269 { 19, 2, "c0_watchhi,2" },
270 { 19, 3, "c0_watchhi,3" },
271 { 19, 4, "c0_watchhi,4" },
272 { 19, 5, "c0_watchhi,5" },
273 { 19, 6, "c0_watchhi,6" },
274 { 19, 7, "c0_watchhi,7" },
275 { 23, 1, "c0_tracecontrol" },
276 { 23, 2, "c0_tracecontrol2" },
277 { 23, 3, "c0_usertracedata" },
278 { 23, 4, "c0_tracebpc" },
279 { 25, 1, "c0_perfcnt,1" },
280 { 25, 2, "c0_perfcnt,2" },
281 { 25, 3, "c0_perfcnt,3" },
282 { 25, 4, "c0_perfcnt,4" },
283 { 25, 5, "c0_perfcnt,5" },
284 { 25, 6, "c0_perfcnt,6" },
285 { 25, 7, "c0_perfcnt,7" },
286 { 27, 1, "c0_cacheerr,1" },
287 { 27, 2, "c0_cacheerr,2" },
288 { 27, 3, "c0_cacheerr,3" },
289 { 28, 1, "c0_datalo" },
290 { 28, 2, "c0_taglo1" },
291 { 28, 3, "c0_datalo1" },
292 { 28, 4, "c0_taglo2" },
293 { 28, 5, "c0_datalo2" },
294 { 28, 6, "c0_taglo3" },
295 { 28, 7, "c0_datalo3" },
296 { 29, 1, "c0_datahi" },
297 { 29, 2, "c0_taghi1" },
298 { 29, 3, "c0_datahi1" },
299 { 29, 4, "c0_taghi2" },
300 { 29, 5, "c0_datahi2" },
301 { 29, 6, "c0_taghi3" },
302 { 29, 7, "c0_datahi3" },
305 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
306 static const char * const mips_cp0_names_sb1[32] =
308 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
309 "c0_context", "c0_pagemask", "c0_wired", "$7",
310 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
311 "c0_status", "c0_cause", "c0_epc", "c0_prid",
312 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
313 "c0_xcontext", "$21", "$22", "c0_debug",
314 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
315 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
318 static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
320 { 16, 1, "c0_config1" },
321 { 18, 1, "c0_watchlo,1" },
322 { 19, 1, "c0_watchhi,1" },
323 { 22, 0, "c0_perftrace" },
324 { 23, 3, "c0_edebug" },
325 { 25, 1, "c0_perfcnt,1" },
326 { 25, 2, "c0_perfcnt,2" },
327 { 25, 3, "c0_perfcnt,3" },
328 { 25, 4, "c0_perfcnt,4" },
329 { 25, 5, "c0_perfcnt,5" },
330 { 25, 6, "c0_perfcnt,6" },
331 { 25, 7, "c0_perfcnt,7" },
332 { 26, 1, "c0_buserr_pa" },
333 { 27, 1, "c0_cacheerr_d" },
334 { 27, 3, "c0_cacheerr_d_pa" },
335 { 28, 1, "c0_datalo_i" },
336 { 28, 2, "c0_taglo_d" },
337 { 28, 3, "c0_datalo_d" },
338 { 29, 1, "c0_datahi_i" },
339 { 29, 2, "c0_taghi_d" },
340 { 29, 3, "c0_datahi_d" },
343 /* Xlr cop0 register names. */
344 static const char * const mips_cp0_names_xlr[32] = {
345 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
346 "c0_context", "c0_pagemask", "c0_wired", "$7",
347 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
348 "c0_status", "c0_cause", "c0_epc", "c0_prid",
349 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
350 "c0_xcontext", "$21", "$22", "c0_debug",
351 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
352 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
355 /* XLR's CP0 Select Registers. */
357 static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
358 { 9, 6, "c0_extintreq" },
359 { 9, 7, "c0_extintmask" },
360 { 15, 1, "c0_ebase" },
361 { 16, 1, "c0_config1" },
362 { 16, 2, "c0_config2" },
363 { 16, 3, "c0_config3" },
364 { 16, 7, "c0_procid2" },
365 { 18, 1, "c0_watchlo,1" },
366 { 18, 2, "c0_watchlo,2" },
367 { 18, 3, "c0_watchlo,3" },
368 { 18, 4, "c0_watchlo,4" },
369 { 18, 5, "c0_watchlo,5" },
370 { 18, 6, "c0_watchlo,6" },
371 { 18, 7, "c0_watchlo,7" },
372 { 19, 1, "c0_watchhi,1" },
373 { 19, 2, "c0_watchhi,2" },
374 { 19, 3, "c0_watchhi,3" },
375 { 19, 4, "c0_watchhi,4" },
376 { 19, 5, "c0_watchhi,5" },
377 { 19, 6, "c0_watchhi,6" },
378 { 19, 7, "c0_watchhi,7" },
379 { 25, 1, "c0_perfcnt,1" },
380 { 25, 2, "c0_perfcnt,2" },
381 { 25, 3, "c0_perfcnt,3" },
382 { 25, 4, "c0_perfcnt,4" },
383 { 25, 5, "c0_perfcnt,5" },
384 { 25, 6, "c0_perfcnt,6" },
385 { 25, 7, "c0_perfcnt,7" },
386 { 27, 1, "c0_cacheerr,1" },
387 { 27, 2, "c0_cacheerr,2" },
388 { 27, 3, "c0_cacheerr,3" },
389 { 28, 1, "c0_datalo" },
390 { 29, 1, "c0_datahi" }
393 static const char * const mips_hwr_names_numeric[32] =
395 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
396 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
397 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
398 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
401 static const char * const mips_hwr_names_mips3264r2[32] =
403 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
404 "$4", "$5", "$6", "$7",
405 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
406 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
407 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
410 static const char * const msa_control_names[32] =
412 "msa_ir", "msa_csr", "msa_access", "msa_save",
413 "msa_modify", "msa_request", "msa_map", "msa_unmap",
414 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
415 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
416 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
419 struct mips_abi_choice
422 const char * const *gpr_names;
423 const char * const *fpr_names;
426 struct mips_abi_choice mips_abi_choices[] =
428 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
429 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
430 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
431 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
434 struct mips_arch_choice
438 unsigned long bfd_mach;
442 const char * const *cp0_names;
443 const struct mips_cp0sel_name *cp0sel_names;
444 unsigned int cp0sel_names_len;
445 const char * const *cp1_names;
446 const char * const *hwr_names;
449 const struct mips_arch_choice mips_arch_choices[] =
451 { "numeric", 0, 0, 0, 0, 0,
452 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
453 mips_hwr_names_numeric },
455 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
456 mips_cp0_names_r3000, NULL, 0, mips_cp1_names_numeric,
457 mips_hwr_names_numeric },
458 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
459 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
460 mips_hwr_names_numeric },
461 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
462 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
463 mips_hwr_names_numeric },
464 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
465 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
466 mips_hwr_names_numeric },
467 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
468 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
469 mips_hwr_names_numeric },
470 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
471 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
472 mips_hwr_names_numeric },
473 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
474 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
475 mips_hwr_names_numeric },
476 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
477 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
478 mips_hwr_names_numeric },
479 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
480 mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
481 mips_hwr_names_numeric },
482 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
483 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
484 mips_hwr_names_numeric },
485 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
486 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
487 mips_hwr_names_numeric },
488 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
489 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
490 mips_hwr_names_numeric },
491 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
492 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
493 mips_hwr_names_numeric },
494 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
495 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
496 mips_hwr_names_numeric },
497 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
498 mips_cp0_names_r5900, NULL, 0, mips_cp1_names_numeric,
499 mips_hwr_names_numeric },
500 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
501 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
502 mips_hwr_names_numeric },
503 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
504 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
505 mips_hwr_names_numeric },
506 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
507 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
508 mips_hwr_names_numeric },
509 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
510 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
511 mips_hwr_names_numeric },
512 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
513 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
514 mips_hwr_names_numeric },
515 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
516 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
517 mips_hwr_names_numeric },
518 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
519 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
520 mips_hwr_names_numeric },
521 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
522 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
523 mips_hwr_names_numeric },
524 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
525 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
526 mips_hwr_names_numeric },
528 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
529 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
530 _MIPS32 Architecture For Programmers Volume I: Introduction to the
531 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
533 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
534 ISA_MIPS32, ASE_SMARTMIPS,
535 mips_cp0_names_mips3264,
536 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
537 mips_cp1_names_mips3264, mips_hwr_names_numeric },
539 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
541 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
542 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
543 mips_cp0_names_mips3264r2,
544 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
545 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
547 { "mips32r3", 1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
549 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
550 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
551 mips_cp0_names_mips3264r2,
552 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
553 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
555 { "mips32r5", 1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
557 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
558 | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
559 mips_cp0_names_mips3264r2,
560 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
561 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
563 { "mips32r6", 1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
565 (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
566 | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC | ASE_GINV),
567 mips_cp0_names_mips3264r2,
568 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
569 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
571 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
572 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
573 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
574 mips_cp0_names_mips3264,
575 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
576 mips_cp1_names_mips3264, mips_hwr_names_numeric },
578 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
580 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
581 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
582 mips_cp0_names_mips3264r2,
583 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
584 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
586 { "mips64r3", 1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
588 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
589 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
590 mips_cp0_names_mips3264r2,
591 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
592 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
594 { "mips64r5", 1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
596 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
597 | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
598 mips_cp0_names_mips3264r2,
599 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
600 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
602 { "mips64r6", 1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
604 (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
605 | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2 | ASE_DSPR3 | ASE_CRC
606 | ASE_CRC64 | ASE_GINV),
607 mips_cp0_names_mips3264r2,
608 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
609 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
611 { "interaptiv-mr2", 1, bfd_mach_mips_interaptiv_mr2, CPU_INTERAPTIV_MR2,
613 ASE_MT | ASE_EVA | ASE_DSP | ASE_DSPR2 | ASE_MIPS16E2 | ASE_MIPS16E2_MT,
614 mips_cp0_names_mips3264r2,
615 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
616 mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
618 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
619 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
621 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
622 mips_cp1_names_mips3264, mips_hwr_names_numeric },
624 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
625 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
626 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
628 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
629 ISA_MIPS3 | INSN_LOONGSON_2F, ASE_LOONGSON_MMI, mips_cp0_names_numeric,
630 NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
632 /* The loongson3a is an alias of gs464 for compatibility */
633 { "loongson3a", 1, bfd_mach_mips_gs464, CPU_GS464,
634 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
635 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
636 mips_hwr_names_numeric },
638 { "g464", 1, bfd_mach_mips_gs464, CPU_GS464,
639 ISA_MIPS64R2, ASE_LOONGSON_MMI | ASE_LOONGSON_CAM | ASE_LOONGSON_EXT,
640 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_mips3264,
641 mips_hwr_names_numeric },
643 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
644 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
645 mips_cp1_names_mips3264, mips_hwr_names_numeric },
647 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
648 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
649 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
651 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
652 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
653 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
655 { "octeon3", 1, bfd_mach_mips_octeon3, CPU_OCTEON3,
656 ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
657 mips_cp0_names_numeric,
658 NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
660 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
661 ISA_MIPS64 | INSN_XLR, 0,
663 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
664 mips_cp1_names_mips3264, mips_hwr_names_numeric },
666 /* XLP is mostly like XLR, with the prominent exception it is being
668 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
669 ISA_MIPS64R2 | INSN_XLR, 0,
671 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
672 mips_cp1_names_mips3264, mips_hwr_names_numeric },
674 /* This entry, mips16, is here only for ISA/processor selection; do
675 not print its name. */
676 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS64,
677 ASE_MIPS16E2 | ASE_MIPS16E2_MT,
678 mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
679 mips_hwr_names_numeric },
682 /* ISA and processor type to disassemble for, and register names to use.
683 set_default_mips_dis_options and parse_mips_dis_options fill in these
685 static int mips_processor;
688 static int micromips_ase;
689 static const char * const *mips_gpr_names;
690 static const char * const *mips_fpr_names;
691 static const char * const *mips_cp0_names;
692 static const struct mips_cp0sel_name *mips_cp0sel_names;
693 static int mips_cp0sel_names_len;
694 static const char * const *mips_cp1_names;
695 static const char * const *mips_hwr_names;
698 static int no_aliases; /* If set disassemble as most general inst. */
700 static const struct mips_abi_choice *
701 choose_abi_by_name (const char *name, unsigned int namelen)
703 const struct mips_abi_choice *c;
706 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
707 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
708 && strlen (mips_abi_choices[i].name) == namelen)
709 c = &mips_abi_choices[i];
714 static const struct mips_arch_choice *
715 choose_arch_by_name (const char *name, unsigned int namelen)
717 const struct mips_arch_choice *c = NULL;
720 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
721 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
722 && strlen (mips_arch_choices[i].name) == namelen)
723 c = &mips_arch_choices[i];
728 static const struct mips_arch_choice *
729 choose_arch_by_number (unsigned long mach)
731 static unsigned long hint_bfd_mach;
732 static const struct mips_arch_choice *hint_arch_choice;
733 const struct mips_arch_choice *c;
736 /* We optimize this because even if the user specifies no
737 flags, this will be done for every instruction! */
738 if (hint_bfd_mach == mach
739 && hint_arch_choice != NULL
740 && hint_arch_choice->bfd_mach == hint_bfd_mach)
741 return hint_arch_choice;
743 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
745 if (mips_arch_choices[i].bfd_mach_valid
746 && mips_arch_choices[i].bfd_mach == mach)
748 c = &mips_arch_choices[i];
749 hint_bfd_mach = mach;
750 hint_arch_choice = c;
756 /* Check if the object uses NewABI conventions. */
759 is_newabi (Elf_Internal_Ehdr *header)
761 /* There are no old-style ABIs which use 64-bit ELF. */
762 if (header->e_ident[EI_CLASS] == ELFCLASS64)
765 /* If a 32-bit ELF file, n32 is a new-style ABI. */
766 if ((header->e_flags & EF_MIPS_ABI2) != 0)
772 /* Check if the object has microMIPS ASE code. */
775 is_micromips (Elf_Internal_Ehdr *header)
777 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
783 /* Convert ASE flags from .MIPS.abiflags to internal values. */
786 mips_convert_abiflags_ases (unsigned long afl_ases)
788 unsigned long opcode_ases = 0;
790 if (afl_ases & AFL_ASE_DSP)
791 opcode_ases |= ASE_DSP;
792 if (afl_ases & AFL_ASE_DSPR2)
793 opcode_ases |= ASE_DSPR2;
794 if (afl_ases & AFL_ASE_EVA)
795 opcode_ases |= ASE_EVA;
796 if (afl_ases & AFL_ASE_MCU)
797 opcode_ases |= ASE_MCU;
798 if (afl_ases & AFL_ASE_MDMX)
799 opcode_ases |= ASE_MDMX;
800 if (afl_ases & AFL_ASE_MIPS3D)
801 opcode_ases |= ASE_MIPS3D;
802 if (afl_ases & AFL_ASE_MT)
803 opcode_ases |= ASE_MT;
804 if (afl_ases & AFL_ASE_SMARTMIPS)
805 opcode_ases |= ASE_SMARTMIPS;
806 if (afl_ases & AFL_ASE_VIRT)
807 opcode_ases |= ASE_VIRT;
808 if (afl_ases & AFL_ASE_MSA)
809 opcode_ases |= ASE_MSA;
810 if (afl_ases & AFL_ASE_XPA)
811 opcode_ases |= ASE_XPA;
812 if (afl_ases & AFL_ASE_DSPR3)
813 opcode_ases |= ASE_DSPR3;
814 if (afl_ases & AFL_ASE_MIPS16E2)
815 opcode_ases |= ASE_MIPS16E2;
819 /* Calculate combination ASE flags from regular ASE flags. */
822 mips_calculate_combination_ases (unsigned long opcode_ases)
824 unsigned long combination_ases = 0;
826 if ((opcode_ases & (ASE_XPA | ASE_VIRT)) == (ASE_XPA | ASE_VIRT))
827 combination_ases |= ASE_XPA_VIRT;
828 if ((opcode_ases & (ASE_MIPS16E2 | ASE_MT)) == (ASE_MIPS16E2 | ASE_MT))
829 combination_ases |= ASE_MIPS16E2_MT;
830 return combination_ases;
834 set_default_mips_dis_options (struct disassemble_info *info)
836 const struct mips_arch_choice *chosen_arch;
838 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
839 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
840 CP0 register, and HWR names. */
841 mips_isa = ISA_MIPS3;
842 mips_processor = CPU_R3000;
845 mips_gpr_names = mips_gpr_names_oldabi;
846 mips_fpr_names = mips_fpr_names_numeric;
847 mips_cp0_names = mips_cp0_names_numeric;
848 mips_cp0sel_names = NULL;
849 mips_cp0sel_names_len = 0;
850 mips_cp1_names = mips_cp1_names_numeric;
851 mips_hwr_names = mips_hwr_names_numeric;
854 /* Set ISA, architecture, and cp0 register names as best we can. */
855 #if ! SYMTAB_AVAILABLE
856 /* This is running out on a target machine, not in a host tool.
857 FIXME: Where does mips_target_info come from? */
858 target_processor = mips_target_info.processor;
859 mips_isa = mips_target_info.isa;
860 mips_ase = mips_target_info.ase;
862 chosen_arch = choose_arch_by_number (info->mach);
863 if (chosen_arch != NULL)
865 mips_processor = chosen_arch->processor;
866 mips_isa = chosen_arch->isa;
867 mips_ase = chosen_arch->ase;
868 mips_cp0_names = chosen_arch->cp0_names;
869 mips_cp0sel_names = chosen_arch->cp0sel_names;
870 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
871 mips_cp1_names = chosen_arch->cp1_names;
872 mips_hwr_names = chosen_arch->hwr_names;
875 /* Update settings according to the ELF file header flags. */
876 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
878 struct bfd *abfd = info->section->owner;
879 Elf_Internal_Ehdr *header = elf_elfheader (abfd);
880 Elf_Internal_ABIFlags_v0 *abiflags = NULL;
882 /* We won't ever get here if !HAVE_BFD_MIPS_ELF_GET_ABIFLAGS,
883 because we won't then have a MIPS/ELF BFD, however we need
884 to guard against a link error in a `--enable-targets=...'
885 configuration with a 32-bit host where the MIPS target is
886 a secondary, or with MIPS/ECOFF configurations. */
887 #ifdef HAVE_BFD_MIPS_ELF_GET_ABIFLAGS
888 abiflags = bfd_mips_elf_get_abiflags (abfd);
890 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
891 if (is_newabi (header))
892 mips_gpr_names = mips_gpr_names_newabi;
893 /* If a microMIPS binary, then don't use MIPS16 bindings. */
894 micromips_ase = is_micromips (header);
895 /* OR in any extra ASE flags set in ELF file structures. */
897 mips_ase |= mips_convert_abiflags_ases (abiflags->ases);
898 else if (header->e_flags & EF_MIPS_ARCH_ASE_MDMX)
899 mips_ase |= ASE_MDMX;
902 mips_ase |= mips_calculate_combination_ases (mips_ase);
905 /* Parse an ASE disassembler option and set the corresponding global
906 ASE flag(s). Return TRUE if successful, FALSE otherwise. */
909 parse_mips_ase_option (const char *option)
911 if (CONST_STRNEQ (option, "msa"))
914 if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
915 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
916 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
917 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
918 mips_ase |= ASE_MSA64;
922 if (CONST_STRNEQ (option, "virt"))
924 mips_ase |= ASE_VIRT;
925 if (mips_isa & ISA_MIPS64R2
926 || mips_isa & ISA_MIPS64R3
927 || mips_isa & ISA_MIPS64R5
928 || mips_isa & ISA_MIPS64R6)
929 mips_ase |= ASE_VIRT64;
933 if (CONST_STRNEQ (option, "xpa"))
939 if (CONST_STRNEQ (option, "ginv"))
941 mips_ase |= ASE_GINV;
945 if (CONST_STRNEQ (option, "loongson-mmi"))
947 mips_ase |= ASE_LOONGSON_MMI;
951 if (CONST_STRNEQ (option, "loongson-cam"))
953 mips_ase |= ASE_LOONGSON_CAM;
957 /* Put here for match ext2 frist */
958 if (CONST_STRNEQ (option, "loongson-ext2"))
960 mips_ase |= ASE_LOONGSON_EXT2;
964 if (CONST_STRNEQ (option, "loongson-ext"))
966 mips_ase |= ASE_LOONGSON_EXT;
974 parse_mips_dis_option (const char *option, unsigned int len)
976 unsigned int i, optionlen, vallen;
978 const struct mips_abi_choice *chosen_abi;
979 const struct mips_arch_choice *chosen_arch;
981 /* Try to match options that are simple flags */
982 if (CONST_STRNEQ (option, "no-aliases"))
988 if (parse_mips_ase_option (option))
990 mips_ase |= mips_calculate_combination_ases (mips_ase);
994 /* Look for the = that delimits the end of the option name. */
995 for (i = 0; i < len; i++)
996 if (option[i] == '=')
999 if (i == 0) /* Invalid option: no name before '='. */
1001 if (i == len) /* Invalid option: no '='. */
1003 if (i == (len - 1)) /* Invalid option: no value after '='. */
1007 val = option + (optionlen + 1);
1008 vallen = len - (optionlen + 1);
1010 if (strncmp ("gpr-names", option, optionlen) == 0
1011 && strlen ("gpr-names") == optionlen)
1013 chosen_abi = choose_abi_by_name (val, vallen);
1014 if (chosen_abi != NULL)
1015 mips_gpr_names = chosen_abi->gpr_names;
1019 if (strncmp ("fpr-names", option, optionlen) == 0
1020 && strlen ("fpr-names") == optionlen)
1022 chosen_abi = choose_abi_by_name (val, vallen);
1023 if (chosen_abi != NULL)
1024 mips_fpr_names = chosen_abi->fpr_names;
1028 if (strncmp ("cp0-names", option, optionlen) == 0
1029 && strlen ("cp0-names") == optionlen)
1031 chosen_arch = choose_arch_by_name (val, vallen);
1032 if (chosen_arch != NULL)
1034 mips_cp0_names = chosen_arch->cp0_names;
1035 mips_cp0sel_names = chosen_arch->cp0sel_names;
1036 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1041 if (strncmp ("cp1-names", option, optionlen) == 0
1042 && strlen ("cp1-names") == optionlen)
1044 chosen_arch = choose_arch_by_name (val, vallen);
1045 if (chosen_arch != NULL)
1046 mips_cp1_names = chosen_arch->cp1_names;
1050 if (strncmp ("hwr-names", option, optionlen) == 0
1051 && strlen ("hwr-names") == optionlen)
1053 chosen_arch = choose_arch_by_name (val, vallen);
1054 if (chosen_arch != NULL)
1055 mips_hwr_names = chosen_arch->hwr_names;
1059 if (strncmp ("reg-names", option, optionlen) == 0
1060 && strlen ("reg-names") == optionlen)
1062 /* We check both ABI and ARCH here unconditionally, so
1063 that "numeric" will do the desirable thing: select
1064 numeric register names for all registers. Other than
1065 that, a given name probably won't match both. */
1066 chosen_abi = choose_abi_by_name (val, vallen);
1067 if (chosen_abi != NULL)
1069 mips_gpr_names = chosen_abi->gpr_names;
1070 mips_fpr_names = chosen_abi->fpr_names;
1072 chosen_arch = choose_arch_by_name (val, vallen);
1073 if (chosen_arch != NULL)
1075 mips_cp0_names = chosen_arch->cp0_names;
1076 mips_cp0sel_names = chosen_arch->cp0sel_names;
1077 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
1078 mips_cp1_names = chosen_arch->cp1_names;
1079 mips_hwr_names = chosen_arch->hwr_names;
1084 /* Invalid option. */
1088 parse_mips_dis_options (const char *options)
1090 const char *option_end;
1092 if (options == NULL)
1095 while (*options != '\0')
1097 /* Skip empty options. */
1098 if (*options == ',')
1104 /* We know that *options is neither NUL or a comma. */
1105 option_end = options + 1;
1106 while (*option_end != ',' && *option_end != '\0')
1109 parse_mips_dis_option (options, option_end - options);
1111 /* Go on to the next one. If option_end points to a comma, it
1112 will be skipped above. */
1113 options = option_end;
1117 static const struct mips_cp0sel_name *
1118 lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
1120 unsigned int cp0reg,
1125 for (i = 0; i < len; i++)
1126 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
1131 /* Print register REGNO, of type TYPE, for instruction OPCODE. */
1134 print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
1135 enum mips_reg_operand_type type, int regno)
1140 info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
1144 info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
1148 if (opcode->pinfo & (FP_D | FP_S))
1149 info->fprintf_func (info->stream, "$fcc%d", regno);
1151 info->fprintf_func (info->stream, "$cc%d", regno);
1155 if (opcode->membership & INSN_5400)
1156 info->fprintf_func (info->stream, "$f%d", regno);
1158 info->fprintf_func (info->stream, "$v%d", regno);
1162 info->fprintf_func (info->stream, "$ac%d", regno);
1166 if (opcode->name[strlen (opcode->name) - 1] == '0')
1167 info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
1168 else if (opcode->name[strlen (opcode->name) - 1] == '1')
1169 info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
1171 info->fprintf_func (info->stream, "$%d", regno);
1175 info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
1179 info->fprintf_func (info->stream, "$vf%d", regno);
1183 info->fprintf_func (info->stream, "$vi%d", regno);
1186 case OP_REG_R5900_I:
1187 info->fprintf_func (info->stream, "$I");
1190 case OP_REG_R5900_Q:
1191 info->fprintf_func (info->stream, "$Q");
1194 case OP_REG_R5900_R:
1195 info->fprintf_func (info->stream, "$R");
1198 case OP_REG_R5900_ACC:
1199 info->fprintf_func (info->stream, "$ACC");
1203 info->fprintf_func (info->stream, "$w%d", regno);
1206 case OP_REG_MSA_CTRL:
1207 info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
1213 /* Used to track the state carried over from previous operands in
1215 struct mips_print_arg_state {
1216 /* The value of the last OP_INT seen. We only use this for OP_MSB,
1217 where the value is known to be unsigned and small. */
1218 unsigned int last_int;
1220 /* The type and number of the last OP_REG seen. We only use this for
1221 OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG. */
1222 enum mips_reg_operand_type last_reg_type;
1223 unsigned int last_regno;
1224 unsigned int dest_regno;
1225 unsigned int seen_dest;
1228 /* Initialize STATE for the start of an instruction. */
1231 init_print_arg_state (struct mips_print_arg_state *state)
1233 memset (state, 0, sizeof (*state));
1236 /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
1237 whose value is given by UVAL. */
1240 print_vu0_channel (struct disassemble_info *info,
1241 const struct mips_operand *operand, unsigned int uval)
1243 if (operand->size == 4)
1244 info->fprintf_func (info->stream, "%s%s%s%s",
1245 uval & 8 ? "x" : "",
1246 uval & 4 ? "y" : "",
1247 uval & 2 ? "z" : "",
1248 uval & 1 ? "w" : "");
1249 else if (operand->size == 2)
1250 info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
1255 /* Record information about a register operand. */
1258 mips_seen_register (struct mips_print_arg_state *state,
1260 enum mips_reg_operand_type reg_type)
1262 state->last_reg_type = reg_type;
1263 state->last_regno = regno;
1265 if (!state->seen_dest)
1267 state->seen_dest = 1;
1268 state->dest_regno = regno;
1272 /* Print SAVE/RESTORE instruction operands according to the argument
1273 register mask AMASK, the number of static registers saved NSREG,
1274 the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
1275 and the frame size FRAME_SIZE. */
1278 mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
1279 unsigned int nsreg, unsigned int ra,
1280 unsigned int s0, unsigned int s1,
1281 unsigned int frame_size)
1283 const fprintf_ftype infprintf = info->fprintf_func;
1284 unsigned int nargs, nstatics, smask, i, j;
1285 void *is = info->stream;
1288 if (amask == MIPS_SVRS_ALL_ARGS)
1293 else if (amask == MIPS_SVRS_ALL_STATICS)
1301 nstatics = amask & 3;
1307 infprintf (is, "%s", mips_gpr_names[4]);
1309 infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
1313 infprintf (is, "%s%d", sep, frame_size);
1316 infprintf (is, ",%s", mips_gpr_names[31]);
1323 if (nsreg > 0) /* $s2-$s8 */
1324 smask |= ((1 << nsreg) - 1) << 2;
1326 for (i = 0; i < 9; i++)
1327 if (smask & (1 << i))
1329 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1330 /* Skip over string of set bits. */
1331 for (j = i; smask & (2 << j); j++)
1334 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1337 /* Statics $ax - $a3. */
1339 infprintf (is, ",%s", mips_gpr_names[7]);
1340 else if (nstatics > 0)
1341 infprintf (is, ",%s-%s",
1342 mips_gpr_names[7 - nstatics + 1],
1347 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
1348 UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
1349 the base address for OP_PCREL operands. */
1352 print_insn_arg (struct disassemble_info *info,
1353 struct mips_print_arg_state *state,
1354 const struct mips_opcode *opcode,
1355 const struct mips_operand *operand,
1359 const fprintf_ftype infprintf = info->fprintf_func;
1360 void *is = info->stream;
1362 switch (operand->type)
1366 const struct mips_int_operand *int_op;
1368 int_op = (const struct mips_int_operand *) operand;
1369 uval = mips_decode_int_operand (int_op, uval);
1370 state->last_int = uval;
1371 if (int_op->print_hex)
1372 infprintf (is, "0x%x", uval);
1374 infprintf (is, "%d", uval);
1380 const struct mips_mapped_int_operand *mint_op;
1382 mint_op = (const struct mips_mapped_int_operand *) operand;
1383 uval = mint_op->int_map[uval];
1384 state->last_int = uval;
1385 if (mint_op->print_hex)
1386 infprintf (is, "0x%x", uval);
1388 infprintf (is, "%d", uval);
1394 const struct mips_msb_operand *msb_op;
1396 msb_op = (const struct mips_msb_operand *) operand;
1397 uval += msb_op->bias;
1398 if (msb_op->add_lsb)
1399 uval -= state->last_int;
1400 infprintf (is, "0x%x", uval);
1405 case OP_OPTIONAL_REG:
1407 const struct mips_reg_operand *reg_op;
1409 reg_op = (const struct mips_reg_operand *) operand;
1410 uval = mips_decode_reg_operand (reg_op, uval);
1411 print_reg (info, opcode, reg_op->reg_type, uval);
1413 mips_seen_register (state, uval, reg_op->reg_type);
1419 const struct mips_reg_pair_operand *pair_op;
1421 pair_op = (const struct mips_reg_pair_operand *) operand;
1422 print_reg (info, opcode, pair_op->reg_type,
1423 pair_op->reg1_map[uval]);
1424 infprintf (is, ",");
1425 print_reg (info, opcode, pair_op->reg_type,
1426 pair_op->reg2_map[uval]);
1432 const struct mips_pcrel_operand *pcrel_op;
1434 pcrel_op = (const struct mips_pcrel_operand *) operand;
1435 info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
1437 /* For jumps and branches clear the ISA bit except for
1438 the GDB disassembler. */
1439 if (pcrel_op->include_isa_bit
1440 && info->flavour != bfd_target_unknown_flavour)
1443 (*info->print_address_func) (info->target, info);
1448 infprintf (is, "%d", uval);
1451 case OP_ADDIUSP_INT:
1455 sval = mips_signed_operand (operand, uval) * 4;
1456 if (sval >= -8 && sval < 8)
1458 infprintf (is, "%d", sval);
1462 case OP_CLO_CLZ_DEST:
1464 unsigned int reg1, reg2;
1468 /* If one is zero use the other. */
1469 if (reg1 == reg2 || reg2 == 0)
1470 infprintf (is, "%s", mips_gpr_names[reg1]);
1472 infprintf (is, "%s", mips_gpr_names[reg2]);
1474 /* Bogus, result depends on processor. */
1475 infprintf (is, "%s or %s", mips_gpr_names[reg1],
1476 mips_gpr_names[reg2]);
1482 case OP_NON_ZERO_REG:
1484 print_reg (info, opcode, OP_REG_GP, uval & 31);
1485 mips_seen_register (state, uval, OP_REG_GP);
1489 case OP_LWM_SWM_LIST:
1490 if (operand->size == 2)
1493 infprintf (is, "%s,%s",
1495 mips_gpr_names[31]);
1497 infprintf (is, "%s-%s,%s",
1499 mips_gpr_names[16 + uval],
1500 mips_gpr_names[31]);
1506 s_reg_encode = uval & 0xf;
1507 if (s_reg_encode != 0)
1509 if (s_reg_encode == 1)
1510 infprintf (is, "%s", mips_gpr_names[16]);
1511 else if (s_reg_encode < 9)
1512 infprintf (is, "%s-%s",
1514 mips_gpr_names[15 + s_reg_encode]);
1515 else if (s_reg_encode == 9)
1516 infprintf (is, "%s-%s,%s",
1519 mips_gpr_names[30]);
1521 infprintf (is, "UNKNOWN");
1524 if (uval & 0x10) /* For ra. */
1526 if (s_reg_encode == 0)
1527 infprintf (is, "%s", mips_gpr_names[31]);
1529 infprintf (is, ",%s", mips_gpr_names[31]);
1534 case OP_ENTRY_EXIT_LIST:
1537 unsigned int amask, smask;
1540 amask = (uval >> 3) & 7;
1541 if (amask > 0 && amask < 5)
1543 infprintf (is, "%s", mips_gpr_names[4]);
1545 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
1549 smask = (uval >> 1) & 3;
1552 infprintf (is, "%s??", sep);
1557 infprintf (is, "%s%s", sep, mips_gpr_names[16]);
1559 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
1565 infprintf (is, "%s%s", sep, mips_gpr_names[31]);
1569 if (amask == 5 || amask == 6)
1571 infprintf (is, "%s%s", sep, mips_fpr_names[0]);
1573 infprintf (is, "-%s", mips_fpr_names[1]);
1578 case OP_SAVE_RESTORE_LIST:
1579 /* Should be handled by the caller due to complex behavior. */
1582 case OP_MDMX_IMM_REG:
1588 if ((vsel & 0x10) == 0)
1593 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1594 if ((vsel & 1) == 0)
1596 print_reg (info, opcode, OP_REG_VEC, uval);
1597 infprintf (is, "[%d]", vsel >> 1);
1599 else if ((vsel & 0x08) == 0)
1600 print_reg (info, opcode, OP_REG_VEC, uval);
1602 infprintf (is, "0x%x", uval);
1606 case OP_REPEAT_PREV_REG:
1607 print_reg (info, opcode, state->last_reg_type, state->last_regno);
1610 case OP_REPEAT_DEST_REG:
1611 print_reg (info, opcode, state->last_reg_type, state->dest_regno);
1615 infprintf (is, "$pc");
1619 print_reg (info, opcode, OP_REG_GP, 28);
1623 case OP_VU0_MATCH_SUFFIX:
1624 print_vu0_channel (info, operand, uval);
1628 infprintf (is, "[%d]", uval);
1632 infprintf (is, "[");
1633 print_reg (info, opcode, OP_REG_GP, uval);
1634 infprintf (is, "]");
1639 /* Validate the arguments for INSN, which is described by OPCODE.
1640 Use DECODE_OPERAND to get the encoding of each operand. */
1643 validate_insn_args (const struct mips_opcode *opcode,
1644 const struct mips_operand *(*decode_operand) (const char *),
1647 struct mips_print_arg_state state;
1648 const struct mips_operand *operand;
1652 init_print_arg_state (&state);
1653 for (s = opcode->args; *s; ++s)
1667 operand = decode_operand (s);
1671 uval = mips_extract_operand (operand, insn);
1672 switch (operand->type)
1675 case OP_OPTIONAL_REG:
1677 const struct mips_reg_operand *reg_op;
1679 reg_op = (const struct mips_reg_operand *) operand;
1680 uval = mips_decode_reg_operand (reg_op, uval);
1681 mips_seen_register (&state, uval, reg_op->reg_type);
1687 unsigned int reg1, reg2;
1692 if (reg1 != reg2 || reg1 == 0)
1699 const struct mips_check_prev_operand *prev_op;
1701 prev_op = (const struct mips_check_prev_operand *) operand;
1703 if (!prev_op->zero_ok && uval == 0)
1706 if (((prev_op->less_than_ok && uval < state.last_regno)
1707 || (prev_op->greater_than_ok && uval > state.last_regno)
1708 || (prev_op->equal_ok && uval == state.last_regno)))
1714 case OP_NON_ZERO_REG:
1727 case OP_ADDIUSP_INT:
1728 case OP_CLO_CLZ_DEST:
1729 case OP_LWM_SWM_LIST:
1730 case OP_ENTRY_EXIT_LIST:
1731 case OP_MDMX_IMM_REG:
1732 case OP_REPEAT_PREV_REG:
1733 case OP_REPEAT_DEST_REG:
1737 case OP_VU0_MATCH_SUFFIX:
1740 case OP_SAVE_RESTORE_LIST:
1744 if (*s == 'm' || *s == '+' || *s == '-')
1751 /* Print the arguments for INSN, which is described by OPCODE.
1752 Use DECODE_OPERAND to get the encoding of each operand. Use BASE_PC
1753 as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
1754 operand is for a branch or jump. */
1757 print_insn_args (struct disassemble_info *info,
1758 const struct mips_opcode *opcode,
1759 const struct mips_operand *(*decode_operand) (const char *),
1760 unsigned int insn, bfd_vma insn_pc, unsigned int length)
1762 const fprintf_ftype infprintf = info->fprintf_func;
1763 void *is = info->stream;
1764 struct mips_print_arg_state state;
1765 const struct mips_operand *operand;
1768 init_print_arg_state (&state);
1769 for (s = opcode->args; *s; ++s)
1776 infprintf (is, "%c", *s);
1781 infprintf (is, "%c%c", *s, *s);
1785 operand = decode_operand (s);
1788 /* xgettext:c-format */
1790 _("# internal error, undefined operand in `%s %s'"),
1791 opcode->name, opcode->args);
1795 if (operand->type == OP_SAVE_RESTORE_LIST)
1797 /* Handle this case here because of the complex behavior. */
1798 unsigned int amask = (insn >> 15) & 0xf;
1799 unsigned int nsreg = (insn >> 23) & 0x7;
1800 unsigned int ra = insn & 0x1000; /* $ra */
1801 unsigned int s0 = insn & 0x800; /* $s0 */
1802 unsigned int s1 = insn & 0x400; /* $s1 */
1803 unsigned int frame_size = (((insn >> 15) & 0xf0)
1804 | ((insn >> 6) & 0x0f)) * 8;
1805 mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
1808 else if (operand->type == OP_REG
1811 && opcode->name[strlen (opcode->name) - 1] == '0')
1813 /* Coprocessor register 0 with sel field. */
1814 const struct mips_cp0sel_name *n;
1815 unsigned int reg, sel;
1817 reg = mips_extract_operand (operand, insn);
1819 operand = decode_operand (s);
1820 sel = mips_extract_operand (operand, insn);
1822 /* CP0 register including 'sel' code for mftc0, to be
1823 printed textually if known. If not known, print both
1824 CP0 register name and sel numerically since CP0 register
1825 with sel 0 may have a name unrelated to register being
1827 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
1828 mips_cp0sel_names_len,
1831 infprintf (is, "%s", n->name);
1833 infprintf (is, "$%d,%d", reg, sel);
1837 bfd_vma base_pc = insn_pc;
1839 /* Adjust the PC relative base so that branch/jump insns use
1840 the following PC as the base but genuinely PC relative
1841 operands use the current PC. */
1842 if (operand->type == OP_PCREL)
1844 const struct mips_pcrel_operand *pcrel_op;
1846 pcrel_op = (const struct mips_pcrel_operand *) operand;
1847 /* The include_isa_bit flag is sufficient to distinguish
1848 branch/jump from other PC relative operands. */
1849 if (pcrel_op->include_isa_bit)
1853 print_insn_arg (info, &state, opcode, operand, base_pc,
1854 mips_extract_operand (operand, insn));
1856 if (*s == 'm' || *s == '+' || *s == '-')
1863 /* Print the mips instruction at address MEMADDR in debugged memory,
1864 on using INFO. Returns length of the instruction, in bytes, which is
1865 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1866 this is little-endian code. */
1869 print_insn_mips (bfd_vma memaddr,
1871 struct disassemble_info *info)
1873 #define GET_OP(insn, field) \
1874 (((insn) >> OP_SH_##field) & OP_MASK_##field)
1875 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1876 const fprintf_ftype infprintf = info->fprintf_func;
1877 const struct mips_opcode *op;
1878 static bfd_boolean init = 0;
1879 void *is = info->stream;
1881 /* Build a hash table to shorten the search time. */
1886 for (i = 0; i <= OP_MASK_OP; i++)
1888 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1890 if (op->pinfo == INSN_MACRO
1891 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1893 if (i == GET_OP (op->match, OP))
1904 info->bytes_per_chunk = INSNLEN;
1905 info->display_endian = info->endian;
1906 info->insn_info_valid = 1;
1907 info->branch_delay_insns = 0;
1908 info->data_size = 0;
1909 info->insn_type = dis_nonbranch;
1913 op = mips_hash[GET_OP (word, OP)];
1916 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1918 if (op->pinfo != INSN_MACRO
1919 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1920 && (word & op->mask) == op->match)
1922 /* We always disassemble the jalx instruction, except for MIPS r6. */
1923 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
1924 && (strcmp (op->name, "jalx")
1925 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
1926 || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
1929 /* Figure out instruction type and branch delay information. */
1930 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1932 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
1933 info->insn_type = dis_jsr;
1935 info->insn_type = dis_branch;
1936 info->branch_delay_insns = 1;
1938 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1939 | INSN_COND_BRANCH_LIKELY)) != 0)
1941 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
1942 info->insn_type = dis_condjsr;
1944 info->insn_type = dis_condbranch;
1945 info->branch_delay_insns = 1;
1947 else if ((op->pinfo & (INSN_STORE_MEMORY
1948 | INSN_LOAD_MEMORY)) != 0)
1949 info->insn_type = dis_dref;
1951 if (!validate_insn_args (op, decode_mips_operand, word))
1954 infprintf (is, "%s", op->name);
1955 if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
1959 infprintf (is, ".");
1960 uval = mips_extract_operand (&mips_vu0_channel_mask, word);
1961 print_vu0_channel (info, &mips_vu0_channel_mask, uval);
1966 infprintf (is, "\t");
1967 print_insn_args (info, op, decode_mips_operand, word,
1977 /* Handle undefined instructions. */
1978 info->insn_type = dis_noninsn;
1979 infprintf (is, "0x%x", word);
1983 /* Disassemble an operand for a mips16 instruction. */
1986 print_mips16_insn_arg (struct disassemble_info *info,
1987 struct mips_print_arg_state *state,
1988 const struct mips_opcode *opcode,
1989 char type, bfd_vma memaddr,
1990 unsigned insn, bfd_boolean use_extend,
1991 unsigned extend, bfd_boolean is_offset)
1993 const fprintf_ftype infprintf = info->fprintf_func;
1994 void *is = info->stream;
1995 const struct mips_operand *operand, *ext_operand;
1996 unsigned short ext_size;
2008 infprintf (is, "%c", type);
2012 operand = decode_mips16_operand (type, FALSE);
2015 /* xgettext:c-format */
2016 infprintf (is, _("# internal error, undefined operand in `%s %s'"),
2017 opcode->name, opcode->args);
2021 if (operand->type == OP_SAVE_RESTORE_LIST)
2023 /* Handle this case here because of the complex interaction
2024 with the EXTEND opcode. */
2025 unsigned int amask = extend & 0xf;
2026 unsigned int nsreg = (extend >> 8) & 0x7;
2027 unsigned int ra = insn & 0x40; /* $ra */
2028 unsigned int s0 = insn & 0x20; /* $s0 */
2029 unsigned int s1 = insn & 0x10; /* $s1 */
2030 unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
2031 if (frame_size == 0 && !use_extend)
2033 mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
2037 if (is_offset && operand->type == OP_INT)
2039 const struct mips_int_operand *int_op;
2041 int_op = (const struct mips_int_operand *) operand;
2042 info->insn_type = dis_dref;
2043 info->data_size = 1 << int_op->shift;
2049 ext_operand = decode_mips16_operand (type, TRUE);
2050 if (ext_operand != operand
2051 || (operand->type == OP_INT && operand->lsb == 0
2052 && mips_opcode_32bit_p (opcode)))
2054 ext_size = ext_operand->size;
2055 operand = ext_operand;
2058 if (operand->size == 26)
2059 uval = ((extend & 0x1f) << 21) | ((extend & 0x3e0) << 11) | insn;
2060 else if (ext_size == 16 || ext_size == 9)
2061 uval = ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
2062 else if (ext_size == 15)
2063 uval = ((extend & 0xf) << 11) | (extend & 0x7f0) | (insn & 0xf);
2064 else if (ext_size == 6)
2065 uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
2067 uval = mips_extract_operand (operand, (extend << 16) | insn);
2069 uval &= (1U << ext_size) - 1;
2071 baseaddr = memaddr + 2;
2072 if (operand->type == OP_PCREL)
2074 const struct mips_pcrel_operand *pcrel_op;
2076 pcrel_op = (const struct mips_pcrel_operand *) operand;
2077 if (!pcrel_op->include_isa_bit && use_extend)
2078 baseaddr = memaddr - 2;
2079 else if (!pcrel_op->include_isa_bit)
2083 /* If this instruction is in the delay slot of a JAL/JALX
2084 instruction, the base address is the address of the
2085 JAL/JALX instruction. If it is in the delay slot of
2086 a JR/JALR instruction, the base address is the address
2087 of the JR/JALR instruction. This test is unreliable:
2088 we have no way of knowing whether the previous word is
2089 instruction or data. */
2090 if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
2091 && (((info->endian == BFD_ENDIAN_BIG
2092 ? bfd_getb16 (buffer)
2093 : bfd_getl16 (buffer))
2094 & 0xf800) == 0x1800))
2095 baseaddr = memaddr - 4;
2096 else if (info->read_memory_func (memaddr - 2, buffer, 2,
2098 && (((info->endian == BFD_ENDIAN_BIG
2099 ? bfd_getb16 (buffer)
2100 : bfd_getl16 (buffer))
2101 & 0xf89f) == 0xe800)
2102 && (((info->endian == BFD_ENDIAN_BIG
2103 ? bfd_getb16 (buffer)
2104 : bfd_getl16 (buffer))
2105 & 0x0060) != 0x0060))
2106 baseaddr = memaddr - 2;
2112 print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
2118 /* Check if the given address is the last word of a MIPS16 PLT entry.
2119 This word is data and depending on the value it may interfere with
2120 disassembly of further PLT entries. We make use of the fact PLT
2121 symbols are marked BSF_SYNTHETIC. */
2123 is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
2127 && (info->symbols[0]->flags & BSF_SYNTHETIC)
2128 && addr == bfd_asymbol_value (info->symbols[0]) + 12)
2134 /* Whether none, a 32-bit or a 16-bit instruction match has been done. */
2143 /* Disassemble mips16 instructions. */
2146 print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2148 const fprintf_ftype infprintf = info->fprintf_func;
2151 const struct mips_opcode *op, *opend;
2152 struct mips_print_arg_state state;
2153 void *is = info->stream;
2154 bfd_boolean have_second;
2155 bfd_boolean extend_only;
2156 unsigned int second;
2160 info->bytes_per_chunk = 2;
2161 info->display_endian = info->endian;
2162 info->insn_info_valid = 1;
2163 info->branch_delay_insns = 0;
2164 info->data_size = 0;
2168 #define GET_OP(insn, field) \
2169 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
2170 /* Decode PLT entry's GOT slot address word. */
2171 if (is_mips16_plt_tail (info, memaddr))
2173 info->insn_type = dis_noninsn;
2174 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
2177 unsigned int gotslot;
2179 if (info->endian == BFD_ENDIAN_BIG)
2180 gotslot = bfd_getb32 (buffer);
2182 gotslot = bfd_getl32 (buffer);
2183 infprintf (is, ".word\t0x%x", gotslot);
2190 info->insn_type = dis_nonbranch;
2191 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2195 (*info->memory_error_func) (status, memaddr, info);
2199 extend_only = FALSE;
2201 if (info->endian == BFD_ENDIAN_BIG)
2202 first = bfd_getb16 (buffer);
2204 first = bfd_getl16 (buffer);
2206 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2210 if (info->endian == BFD_ENDIAN_BIG)
2211 second = bfd_getb16 (buffer);
2213 second = bfd_getl16 (buffer);
2214 full = (first << 16) | second;
2218 have_second = FALSE;
2223 /* FIXME: Should probably use a hash table on the major opcode here. */
2225 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2226 for (op = mips16_opcodes; op < opend; op++)
2228 enum match_kind match;
2230 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor))
2233 if (op->pinfo == INSN_MACRO
2234 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
2236 else if (mips_opcode_32bit_p (op))
2239 && (full & op->mask) == op->match)
2244 else if ((first & op->mask) == op->match)
2246 match = MATCH_SHORT;
2250 else if ((first & 0xf800) == 0xf000
2253 && (second & op->mask) == op->match)
2255 if (op->pinfo2 & INSN2_SHORT_ONLY)
2266 if (match != MATCH_NONE)
2270 infprintf (is, "%s", op->name);
2271 if (op->args[0] != '\0')
2272 infprintf (is, "\t");
2274 init_print_arg_state (&state);
2275 for (s = op->args; *s != '\0'; s++)
2279 && GET_OP (full, RX) == GET_OP (full, RY))
2281 /* Skip the register and the comma. */
2287 && GET_OP (full, RZ) == GET_OP (full, RX))
2289 /* Skip the register and the comma. */
2296 && op->name[strlen (op->name) - 1] == '0')
2298 /* Coprocessor register 0 with sel field. */
2299 const struct mips_cp0sel_name *n;
2300 const struct mips_operand *operand;
2301 unsigned int reg, sel;
2303 operand = decode_mips16_operand (*s, TRUE);
2304 reg = mips_extract_operand (operand, (first << 16) | second);
2306 operand = decode_mips16_operand (*s, TRUE);
2307 sel = mips_extract_operand (operand, (first << 16) | second);
2309 /* CP0 register including 'sel' code for mftc0, to be
2310 printed textually if known. If not known, print both
2311 CP0 register name and sel numerically since CP0 register
2312 with sel 0 may have a name unrelated to register being
2314 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2315 mips_cp0sel_names_len,
2318 infprintf (is, "%s", n->name);
2320 infprintf (is, "$%d,%d", reg, sel);
2326 print_mips16_insn_arg (info, &state, op, *s, memaddr + 2,
2327 second, TRUE, first, s[1] == '(');
2330 print_mips16_insn_arg (info, &state, op, *s, memaddr,
2331 first, FALSE, 0, s[1] == '(');
2333 case MATCH_NONE: /* Stop the compiler complaining. */
2338 /* Figure out branch instruction type and delay slot information. */
2339 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2340 info->branch_delay_insns = 1;
2341 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
2342 || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
2344 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2345 info->insn_type = dis_jsr;
2347 info->insn_type = dis_branch;
2349 else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
2350 info->insn_type = dis_condbranch;
2352 return match == MATCH_FULL ? 4 : 2;
2357 infprintf (is, "0x%x", first);
2358 info->insn_type = dis_noninsn;
2363 /* Disassemble microMIPS instructions. */
2366 print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2368 const fprintf_ftype infprintf = info->fprintf_func;
2369 const struct mips_opcode *op, *opend;
2370 void *is = info->stream;
2372 unsigned int higher;
2373 unsigned int length;
2377 info->bytes_per_chunk = 2;
2378 info->display_endian = info->endian;
2379 info->insn_info_valid = 1;
2380 info->branch_delay_insns = 0;
2381 info->data_size = 0;
2382 info->insn_type = dis_nonbranch;
2386 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2389 (*info->memory_error_func) (status, memaddr, info);
2395 if (info->endian == BFD_ENDIAN_BIG)
2396 insn = bfd_getb16 (buffer);
2398 insn = bfd_getl16 (buffer);
2400 if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2402 /* This is a 32-bit microMIPS instruction. */
2405 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2408 infprintf (is, "micromips 0x%x", higher);
2409 (*info->memory_error_func) (status, memaddr + 2, info);
2413 if (info->endian == BFD_ENDIAN_BIG)
2414 insn = bfd_getb16 (buffer);
2416 insn = bfd_getl16 (buffer);
2418 insn = insn | (higher << 16);
2423 /* FIXME: Should probably use a hash table on the major opcode here. */
2425 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2426 for (op = micromips_opcodes; op < opend; op++)
2428 if (op->pinfo != INSN_MACRO
2429 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2430 && (insn & op->mask) == op->match
2431 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2432 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2434 if (!validate_insn_args (op, decode_micromips_operand, insn))
2437 infprintf (is, "%s", op->name);
2441 infprintf (is, "\t");
2442 print_insn_args (info, op, decode_micromips_operand, insn,
2443 memaddr + 1, length);
2446 /* Figure out instruction type and branch delay information. */
2448 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2449 info->branch_delay_insns = 1;
2450 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2451 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2453 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
2454 info->insn_type = dis_jsr;
2456 info->insn_type = dis_branch;
2458 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2459 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2461 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2462 info->insn_type = dis_condjsr;
2464 info->insn_type = dis_condbranch;
2467 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
2468 info->insn_type = dis_dref;
2474 infprintf (is, "0x%x", insn);
2475 info->insn_type = dis_noninsn;
2480 /* Return 1 if a symbol associated with the location being disassembled
2481 indicates a compressed mode, either MIPS16 or microMIPS, according to
2482 MICROMIPS_P. We iterate over all the symbols at the address being
2483 considered assuming if at least one of them indicates code compression,
2484 then such code has been genuinely produced here (other symbols could
2485 have been derived from function symbols defined elsewhere or could
2486 define data). Otherwise, return 0. */
2489 is_compressed_mode_p (struct disassemble_info *info, bfd_boolean micromips_p)
2494 for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
2495 if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
2497 && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
2499 && ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
2501 else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
2502 && info->symtab[i]->section == info->section)
2504 elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
2506 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2508 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2515 /* In an environment where we do not know the symbol type of the
2516 instruction we are forced to assume that the low order bit of the
2517 instructions' address may mark it as a mips16 instruction. If we
2518 are single stepping, or the pc is within the disassembled function,
2519 this works. Otherwise, we need a clue. Sometimes. */
2522 _print_insn_mips (bfd_vma memaddr,
2523 struct disassemble_info *info,
2524 enum bfd_endian endianness)
2526 bfd_byte buffer[INSNLEN];
2529 set_default_mips_dis_options (info);
2530 parse_mips_dis_options (info->disassembler_options);
2532 if (info->mach == bfd_mach_mips16)
2533 return print_insn_mips16 (memaddr, info);
2534 if (info->mach == bfd_mach_mips_micromips)
2535 return print_insn_micromips (memaddr, info);
2538 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
2539 /* Only a few tools will work this way. */
2543 return print_insn_micromips (memaddr, info);
2545 return print_insn_mips16 (memaddr, info);
2549 #if SYMTAB_AVAILABLE
2550 if (is_compressed_mode_p (info, TRUE))
2551 return print_insn_micromips (memaddr, info);
2552 if (is_compressed_mode_p (info, FALSE))
2553 return print_insn_mips16 (memaddr, info);
2556 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2561 if (endianness == BFD_ENDIAN_BIG)
2562 insn = bfd_getb32 (buffer);
2564 insn = bfd_getl32 (buffer);
2566 return print_insn_mips (memaddr, insn, info);
2570 (*info->memory_error_func) (status, memaddr, info);
2576 print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2578 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2582 print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2584 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2587 /* Indices into option argument vector for options accepting an argument.
2588 Use MIPS_OPTION_ARG_NONE for options accepting no argument. */
2591 MIPS_OPTION_ARG_NONE = -1,
2592 MIPS_OPTION_ARG_ABI,
2593 MIPS_OPTION_ARG_ARCH,
2594 MIPS_OPTION_ARG_SIZE
2595 } mips_option_arg_t;
2597 /* Valid MIPS disassembler options. */
2601 const char *description;
2602 mips_option_arg_t arg;
2605 { "no-aliases", N_("Use canonical instruction forms.\n"),
2606 MIPS_OPTION_ARG_NONE },
2607 { "msa", N_("Recognize MSA instructions.\n"),
2608 MIPS_OPTION_ARG_NONE },
2609 { "virt", N_("Recognize the virtualization ASE instructions.\n"),
2610 MIPS_OPTION_ARG_NONE },
2611 { "xpa", N_("Recognize the eXtended Physical Address (XPA) ASE\n\
2613 MIPS_OPTION_ARG_NONE },
2614 { "ginv", N_("Recognize the Global INValidate (GINV) ASE "
2616 MIPS_OPTION_ARG_NONE },
2618 N_("Recognize the Loongson MultiMedia extensions "
2619 "Instructions (MMI) ASE instructions.\n"),
2620 MIPS_OPTION_ARG_NONE },
2622 N_("Recognize the Loongson Content Address Memory (CAM) "
2623 " instructions.\n"),
2624 MIPS_OPTION_ARG_NONE },
2626 N_("Recognize the Loongson EXTensions (EXT) "
2627 " instructions.\n"),
2628 MIPS_OPTION_ARG_NONE },
2630 N_("Recognize the Loongson EXTensions R2 (EXT2) "
2631 " instructions.\n"),
2632 MIPS_OPTION_ARG_NONE },
2633 { "gpr-names=", N_("Print GPR names according to specified ABI.\n\
2634 Default: based on binary being disassembled.\n"),
2635 MIPS_OPTION_ARG_ABI },
2636 { "fpr-names=", N_("Print FPR names according to specified ABI.\n\
2637 Default: numeric.\n"),
2638 MIPS_OPTION_ARG_ABI },
2639 { "cp0-names=", N_("Print CP0 register names according to specified "
2641 Default: based on binary being disassembled.\n"),
2642 MIPS_OPTION_ARG_ARCH },
2643 { "hwr-names=", N_("Print HWR names according to specified architecture.\n\
2644 Default: based on binary being disassembled.\n"),
2645 MIPS_OPTION_ARG_ARCH },
2646 { "reg-names=", N_("Print GPR and FPR names according to specified ABI.\n"),
2647 MIPS_OPTION_ARG_ABI },
2648 { "reg-names=", N_("Print CP0 register and HWR names according to "
2651 MIPS_OPTION_ARG_ARCH }
2654 /* Build the structure representing valid MIPS disassembler options.
2655 This is done dynamically for maintenance ease purpose; a static
2656 initializer would be unreadable. */
2658 const disasm_options_and_args_t *
2659 disassembler_options_mips (void)
2661 static disasm_options_and_args_t *opts_and_args;
2663 if (opts_and_args == NULL)
2665 size_t num_options = ARRAY_SIZE (mips_options);
2666 size_t num_args = MIPS_OPTION_ARG_SIZE;
2667 disasm_option_arg_t *args;
2668 disasm_options_t *opts;
2672 args = XNEWVEC (disasm_option_arg_t, num_args + 1);
2674 args[MIPS_OPTION_ARG_ABI].name = "ABI";
2675 args[MIPS_OPTION_ARG_ABI].values
2676 = XNEWVEC (const char *, ARRAY_SIZE (mips_abi_choices) + 1);
2677 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2678 args[MIPS_OPTION_ARG_ABI].values[i] = mips_abi_choices[i].name;
2679 /* The array we return must be NULL terminated. */
2680 args[MIPS_OPTION_ARG_ABI].values[i] = NULL;
2682 args[MIPS_OPTION_ARG_ARCH].name = "ARCH";
2683 args[MIPS_OPTION_ARG_ARCH].values
2684 = XNEWVEC (const char *, ARRAY_SIZE (mips_arch_choices) + 1);
2685 for (i = 0, j = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2686 if (*mips_arch_choices[i].name != '\0')
2687 args[MIPS_OPTION_ARG_ARCH].values[j++] = mips_arch_choices[i].name;
2688 /* The array we return must be NULL terminated. */
2689 args[MIPS_OPTION_ARG_ARCH].values[j] = NULL;
2691 /* The array we return must be NULL terminated. */
2692 args[MIPS_OPTION_ARG_SIZE].name = NULL;
2693 args[MIPS_OPTION_ARG_SIZE].values = NULL;
2695 opts_and_args = XNEW (disasm_options_and_args_t);
2696 opts_and_args->args = args;
2698 opts = &opts_and_args->options;
2699 opts->name = XNEWVEC (const char *, num_options + 1);
2700 opts->description = XNEWVEC (const char *, num_options + 1);
2701 opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
2702 for (i = 0; i < num_options; i++)
2704 opts->name[i] = mips_options[i].name;
2705 opts->description[i] = _(mips_options[i].description);
2706 if (mips_options[i].arg != MIPS_OPTION_ARG_NONE)
2707 opts->arg[i] = &args[mips_options[i].arg];
2709 opts->arg[i] = NULL;
2711 /* The array we return must be NULL terminated. */
2712 opts->name[i] = NULL;
2713 opts->description[i] = NULL;
2714 opts->arg[i] = NULL;
2717 return opts_and_args;
2721 print_mips_disassembler_options (FILE *stream)
2723 const disasm_options_and_args_t *opts_and_args;
2724 const disasm_option_arg_t *args;
2725 const disasm_options_t *opts;
2730 opts_and_args = disassembler_options_mips ();
2731 opts = &opts_and_args->options;
2732 args = opts_and_args->args;
2734 fprintf (stream, _("\n\
2735 The following MIPS specific disassembler options are supported for use\n\
2736 with the -M switch (multiple options should be separated by commas):\n\n"));
2738 /* Compute the length of the longest option name. */
2739 for (i = 0; opts->name[i] != NULL; i++)
2741 size_t len = strlen (opts->name[i]);
2743 if (opts->arg[i] != NULL)
2744 len += strlen (opts->arg[i]->name);
2749 for (i = 0, max_len++; opts->name[i] != NULL; i++)
2751 fprintf (stream, " %s", opts->name[i]);
2752 if (opts->arg[i] != NULL)
2753 fprintf (stream, "%s", opts->arg[i]->name);
2754 if (opts->description[i] != NULL)
2756 size_t len = strlen (opts->name[i]);
2758 if (opts->arg[i] != NULL)
2759 len += strlen (opts->arg[i]->name);
2761 "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
2763 fprintf (stream, _("\n"));
2766 for (i = 0; args[i].name != NULL; i++)
2768 fprintf (stream, _("\n\
2769 For the options above, the following values are supported for \"%s\":\n "),
2771 for (j = 0; args[i].values[j] != NULL; j++)
2772 fprintf (stream, " %s", args[i].values[j]);
2773 fprintf (stream, _("\n"));
2776 fprintf (stream, _("\n"));