* Makefile.am (mips-opc.lo): Add rules to create automatic
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
CommitLineData
252b5132 1/* Print mips instructions for GDB, the GNU debugger, or for objdump.
060d22b0 2 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
8b99bf0b 3 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2012
73da6b6b 4 Free Software Foundation, Inc.
252b5132
RH
5 Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
6
9b201bb5 7 This file is part of the GNU opcodes library.
252b5132 8
9b201bb5 9 This library is free software; you can redistribute it and/or modify
47b0e7ad 10 it under the terms of the GNU General Public License as published by
9b201bb5
NC
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
252b5132 13
9b201bb5
NC
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
252b5132 18
47b0e7ad
NC
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
252b5132 23
252b5132
RH
24#include "sysdep.h"
25#include "dis-asm.h"
640c0ccd 26#include "libiberty.h"
252b5132
RH
27#include "opcode/mips.h"
28#include "opintl.h"
29
30/* FIXME: These are needed to figure out if the code is mips16 or
31 not. The low bit of the address is often a good indicator. No
32 symbol table is available when this code runs out in an embedded
7f6621cd 33 system as when it is used for disassembler support in a monitor. */
252b5132
RH
34
35#if !defined(EMBEDDED_ENV)
36#define SYMTAB_AVAILABLE 1
37#include "elf-bfd.h"
38#include "elf/mips.h"
39#endif
40
aa5f19f2
NC
41/* Mips instructions are at maximum this many bytes long. */
42#define INSNLEN 4
43
252b5132 44\f
aa5f19f2 45/* FIXME: These should be shared with gdb somehow. */
252b5132 46
47b0e7ad
NC
47struct mips_cp0sel_name
48{
49 unsigned int cp0reg;
50 unsigned int sel;
51 const char * const name;
bbcc0807
CD
52};
53
654c225a
TS
54/* The mips16 registers. */
55static const unsigned int mips16_to_32_reg_map[] =
47b0e7ad 56{
654c225a 57 16, 17, 2, 3, 4, 5, 6, 7
252b5132 58};
fb48caed 59
df58fc94
RS
60/* The microMIPS registers with type b. */
61#define micromips_to_32_reg_b_map mips16_to_32_reg_map
62
63/* The microMIPS registers with type c. */
64#define micromips_to_32_reg_c_map mips16_to_32_reg_map
65
66/* The microMIPS registers with type d. */
67#define micromips_to_32_reg_d_map mips16_to_32_reg_map
68
69/* The microMIPS registers with type e. */
70#define micromips_to_32_reg_e_map mips16_to_32_reg_map
71
72/* The microMIPS registers with type f. */
73#define micromips_to_32_reg_f_map mips16_to_32_reg_map
74
75/* The microMIPS registers with type g. */
76#define micromips_to_32_reg_g_map mips16_to_32_reg_map
77
78/* The microMIPS registers with type h. */
79static const unsigned int micromips_to_32_reg_h_map[] =
80{
81 5, 5, 6, 4, 4, 4, 4, 4
82};
83
84/* The microMIPS registers with type i. */
85static const unsigned int micromips_to_32_reg_i_map[] =
86{
87 6, 7, 7, 21, 22, 5, 6, 7
88};
89
90/* The microMIPS registers with type j: 32 registers. */
91
92/* The microMIPS registers with type l. */
93#define micromips_to_32_reg_l_map mips16_to_32_reg_map
94
95/* The microMIPS registers with type m. */
96static const unsigned int micromips_to_32_reg_m_map[] =
97{
98 0, 17, 2, 3, 16, 18, 19, 20
99};
100
101/* The microMIPS registers with type n. */
102#define micromips_to_32_reg_n_map micromips_to_32_reg_m_map
103
104/* The microMIPS registers with type p: 32 registers. */
105
106/* The microMIPS registers with type q. */
107static const unsigned int micromips_to_32_reg_q_map[] =
108{
109 0, 17, 2, 3, 4, 5, 6, 7
110};
111
112/* reg type s is $29. */
113
114/* reg type t is the same as the last register. */
115
116/* reg type y is $31. */
117
118/* reg type z is $0. */
119
120/* micromips imm B type. */
121static const int micromips_imm_b_map[8] =
122{
123 1, 4, 8, 12, 16, 20, 24, -1
124};
125
126/* micromips imm C type. */
127static const int micromips_imm_c_map[16] =
128{
129 128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 255, 32768, 65535
130};
131
132/* micromips imm D type: (-512..511)<<1. */
133/* micromips imm E type: (-64..63)<<1. */
134/* micromips imm F type: (0..63). */
135/* micromips imm G type: (-1..14). */
136/* micromips imm H type: (0..15)<<1. */
137/* micromips imm I type: (-1..126). */
138/* micromips imm J type: (0..15)<<2. */
139/* micromips imm L type: (0..15). */
140/* micromips imm M type: (1..8). */
141/* micromips imm W type: (0..63)<<2. */
142/* micromips imm X type: (-8..7). */
143/* micromips imm Y type: (-258..-3, 2..257)<<2. */
144
654c225a
TS
145#define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]]
146
147
47b0e7ad
NC
148static const char * const mips_gpr_names_numeric[32] =
149{
640c0ccd
CD
150 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
151 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
152 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
153 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
aa5f19f2
NC
154};
155
47b0e7ad
NC
156static const char * const mips_gpr_names_oldabi[32] =
157{
640c0ccd
CD
158 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
159 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
160 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
161 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
aa5f19f2
NC
162};
163
47b0e7ad
NC
164static const char * const mips_gpr_names_newabi[32] =
165{
640c0ccd 166 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
0b14f26e 167 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
640c0ccd
CD
168 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
169 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
170};
171
47b0e7ad
NC
172static const char * const mips_fpr_names_numeric[32] =
173{
640c0ccd
CD
174 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
175 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
176 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
177 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
178};
179
47b0e7ad
NC
180static const char * const mips_fpr_names_32[32] =
181{
640c0ccd
CD
182 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
183 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
184 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
185 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
186};
187
47b0e7ad
NC
188static const char * const mips_fpr_names_n32[32] =
189{
640c0ccd
CD
190 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
191 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
192 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
193 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
194};
195
47b0e7ad
NC
196static const char * const mips_fpr_names_64[32] =
197{
640c0ccd
CD
198 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
199 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
200 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
201 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
202};
203
47b0e7ad
NC
204static const char * const mips_cp0_names_numeric[32] =
205{
640c0ccd
CD
206 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
207 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
208 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
209 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
210};
211
f409fd1e
MR
212static const char * const mips_cp0_names_r3000[32] =
213{
214 "c0_index", "c0_random", "c0_entrylo", "$3",
215 "c0_context", "$5", "$6", "$7",
216 "c0_badvaddr", "$9", "c0_entryhi", "$11",
217 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
218 "$16", "$17", "$18", "$19",
219 "$20", "$21", "$22", "$23",
220 "$24", "$25", "$26", "$27",
221 "$28", "$29", "$30", "$31",
222};
223
224static const char * const mips_cp0_names_r4000[32] =
225{
226 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
227 "c0_context", "c0_pagemask", "c0_wired", "$7",
228 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
229 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
230 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
231 "c0_xcontext", "$21", "$22", "$23",
232 "$24", "$25", "c0_ecc", "c0_cacheerr",
233 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
234};
235
e407c74b
NC
236static const char * const mips_cp0_names_r5900[32] =
237{
238 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
239 "c0_context", "c0_pagemask", "c0_wired", "$7",
240 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
241 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
242 "c0_config", "$17", "$18", "$19",
243 "$20", "$21", "$22", "c0_badpaddr",
244 "c0_depc", "c0_perfcnt", "$26", "$27",
245 "c0_taglo", "c0_taghi", "c0_errorepc", "$31"
246};
247
248static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900[] =
249{
250 { 24, 2, "c0_iab" },
251 { 24, 3, "c0_iabm" },
252 { 24, 4, "c0_dab" },
253 { 24, 5, "c0_dabm" },
254 { 24, 6, "c0_dvb" },
255 { 24, 7, "c0_dvbm" },
256 { 25, 1, "c0_perfcnt,1" },
257 { 25, 2, "c0_perfcnt,2" }
258};
259
47b0e7ad
NC
260static const char * const mips_cp0_names_mips3264[32] =
261{
640c0ccd
CD
262 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
263 "c0_context", "c0_pagemask", "c0_wired", "$7",
264 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
265 "c0_status", "c0_cause", "c0_epc", "c0_prid",
266 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
267 "c0_xcontext", "$21", "$22", "c0_debug",
268 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
269 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
270};
271
47b0e7ad
NC
272static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
273{
bbcc0807
CD
274 { 16, 1, "c0_config1" },
275 { 16, 2, "c0_config2" },
276 { 16, 3, "c0_config3" },
277 { 18, 1, "c0_watchlo,1" },
278 { 18, 2, "c0_watchlo,2" },
279 { 18, 3, "c0_watchlo,3" },
280 { 18, 4, "c0_watchlo,4" },
281 { 18, 5, "c0_watchlo,5" },
282 { 18, 6, "c0_watchlo,6" },
283 { 18, 7, "c0_watchlo,7" },
284 { 19, 1, "c0_watchhi,1" },
285 { 19, 2, "c0_watchhi,2" },
286 { 19, 3, "c0_watchhi,3" },
287 { 19, 4, "c0_watchhi,4" },
288 { 19, 5, "c0_watchhi,5" },
289 { 19, 6, "c0_watchhi,6" },
290 { 19, 7, "c0_watchhi,7" },
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 { 29, 1, "c0_datahi" }
303};
304
47b0e7ad
NC
305static const char * const mips_cp0_names_mips3264r2[32] =
306{
af7ee8bf
CD
307 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
308 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
309 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
310 "c0_status", "c0_cause", "c0_epc", "c0_prid",
311 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
312 "c0_xcontext", "$21", "$22", "c0_debug",
313 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
314 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
315};
316
47b0e7ad
NC
317static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
318{
bbcc0807 319 { 4, 1, "c0_contextconfig" },
59c455b3
TS
320 { 0, 1, "c0_mvpcontrol" },
321 { 0, 2, "c0_mvpconf0" },
322 { 0, 3, "c0_mvpconf1" },
323 { 1, 1, "c0_vpecontrol" },
324 { 1, 2, "c0_vpeconf0" },
325 { 1, 3, "c0_vpeconf1" },
326 { 1, 4, "c0_yqmask" },
327 { 1, 5, "c0_vpeschedule" },
328 { 1, 6, "c0_vpeschefback" },
329 { 2, 1, "c0_tcstatus" },
330 { 2, 2, "c0_tcbind" },
331 { 2, 3, "c0_tcrestart" },
332 { 2, 4, "c0_tchalt" },
333 { 2, 5, "c0_tccontext" },
334 { 2, 6, "c0_tcschedule" },
335 { 2, 7, "c0_tcschefback" },
bbcc0807 336 { 5, 1, "c0_pagegrain" },
59c455b3
TS
337 { 6, 1, "c0_srsconf0" },
338 { 6, 2, "c0_srsconf1" },
339 { 6, 3, "c0_srsconf2" },
340 { 6, 4, "c0_srsconf3" },
341 { 6, 5, "c0_srsconf4" },
bbcc0807
CD
342 { 12, 1, "c0_intctl" },
343 { 12, 2, "c0_srsctl" },
344 { 12, 3, "c0_srsmap" },
345 { 15, 1, "c0_ebase" },
346 { 16, 1, "c0_config1" },
347 { 16, 2, "c0_config2" },
348 { 16, 3, "c0_config3" },
349 { 18, 1, "c0_watchlo,1" },
350 { 18, 2, "c0_watchlo,2" },
351 { 18, 3, "c0_watchlo,3" },
352 { 18, 4, "c0_watchlo,4" },
353 { 18, 5, "c0_watchlo,5" },
354 { 18, 6, "c0_watchlo,6" },
355 { 18, 7, "c0_watchlo,7" },
356 { 19, 1, "c0_watchhi,1" },
357 { 19, 2, "c0_watchhi,2" },
358 { 19, 3, "c0_watchhi,3" },
359 { 19, 4, "c0_watchhi,4" },
360 { 19, 5, "c0_watchhi,5" },
361 { 19, 6, "c0_watchhi,6" },
362 { 19, 7, "c0_watchhi,7" },
363 { 23, 1, "c0_tracecontrol" },
364 { 23, 2, "c0_tracecontrol2" },
365 { 23, 3, "c0_usertracedata" },
366 { 23, 4, "c0_tracebpc" },
367 { 25, 1, "c0_perfcnt,1" },
368 { 25, 2, "c0_perfcnt,2" },
369 { 25, 3, "c0_perfcnt,3" },
370 { 25, 4, "c0_perfcnt,4" },
371 { 25, 5, "c0_perfcnt,5" },
372 { 25, 6, "c0_perfcnt,6" },
373 { 25, 7, "c0_perfcnt,7" },
374 { 27, 1, "c0_cacheerr,1" },
375 { 27, 2, "c0_cacheerr,2" },
376 { 27, 3, "c0_cacheerr,3" },
377 { 28, 1, "c0_datalo" },
378 { 28, 2, "c0_taglo1" },
379 { 28, 3, "c0_datalo1" },
380 { 28, 4, "c0_taglo2" },
381 { 28, 5, "c0_datalo2" },
382 { 28, 6, "c0_taglo3" },
383 { 28, 7, "c0_datalo3" },
384 { 29, 1, "c0_datahi" },
385 { 29, 2, "c0_taghi1" },
386 { 29, 3, "c0_datahi1" },
387 { 29, 4, "c0_taghi2" },
388 { 29, 5, "c0_datahi2" },
389 { 29, 6, "c0_taghi3" },
390 { 29, 7, "c0_datahi3" },
391};
392
640c0ccd 393/* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
47b0e7ad
NC
394static const char * const mips_cp0_names_sb1[32] =
395{
640c0ccd
CD
396 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
397 "c0_context", "c0_pagemask", "c0_wired", "$7",
398 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
399 "c0_status", "c0_cause", "c0_epc", "c0_prid",
400 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
401 "c0_xcontext", "$21", "$22", "c0_debug",
402 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
403 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
404};
405
47b0e7ad
NC
406static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
407{
bbcc0807
CD
408 { 16, 1, "c0_config1" },
409 { 18, 1, "c0_watchlo,1" },
410 { 19, 1, "c0_watchhi,1" },
411 { 22, 0, "c0_perftrace" },
412 { 23, 3, "c0_edebug" },
413 { 25, 1, "c0_perfcnt,1" },
414 { 25, 2, "c0_perfcnt,2" },
415 { 25, 3, "c0_perfcnt,3" },
416 { 25, 4, "c0_perfcnt,4" },
417 { 25, 5, "c0_perfcnt,5" },
418 { 25, 6, "c0_perfcnt,6" },
419 { 25, 7, "c0_perfcnt,7" },
420 { 26, 1, "c0_buserr_pa" },
421 { 27, 1, "c0_cacheerr_d" },
422 { 27, 3, "c0_cacheerr_d_pa" },
423 { 28, 1, "c0_datalo_i" },
424 { 28, 2, "c0_taglo_d" },
425 { 28, 3, "c0_datalo_d" },
426 { 29, 1, "c0_datahi_i" },
427 { 29, 2, "c0_taghi_d" },
428 { 29, 3, "c0_datahi_d" },
429};
430
52b6b6b9
JM
431/* Xlr cop0 register names. */
432static const char * const mips_cp0_names_xlr[32] = {
433 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
434 "c0_context", "c0_pagemask", "c0_wired", "$7",
435 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
436 "c0_status", "c0_cause", "c0_epc", "c0_prid",
437 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
438 "c0_xcontext", "$21", "$22", "c0_debug",
439 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
440 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
441};
442
443/* XLR's CP0 Select Registers. */
444
445static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
446 { 9, 6, "c0_extintreq" },
447 { 9, 7, "c0_extintmask" },
448 { 15, 1, "c0_ebase" },
449 { 16, 1, "c0_config1" },
450 { 16, 2, "c0_config2" },
451 { 16, 3, "c0_config3" },
452 { 16, 7, "c0_procid2" },
453 { 18, 1, "c0_watchlo,1" },
454 { 18, 2, "c0_watchlo,2" },
455 { 18, 3, "c0_watchlo,3" },
456 { 18, 4, "c0_watchlo,4" },
457 { 18, 5, "c0_watchlo,5" },
458 { 18, 6, "c0_watchlo,6" },
459 { 18, 7, "c0_watchlo,7" },
460 { 19, 1, "c0_watchhi,1" },
461 { 19, 2, "c0_watchhi,2" },
462 { 19, 3, "c0_watchhi,3" },
463 { 19, 4, "c0_watchhi,4" },
464 { 19, 5, "c0_watchhi,5" },
465 { 19, 6, "c0_watchhi,6" },
466 { 19, 7, "c0_watchhi,7" },
467 { 25, 1, "c0_perfcnt,1" },
468 { 25, 2, "c0_perfcnt,2" },
469 { 25, 3, "c0_perfcnt,3" },
470 { 25, 4, "c0_perfcnt,4" },
471 { 25, 5, "c0_perfcnt,5" },
472 { 25, 6, "c0_perfcnt,6" },
473 { 25, 7, "c0_perfcnt,7" },
474 { 27, 1, "c0_cacheerr,1" },
475 { 27, 2, "c0_cacheerr,2" },
476 { 27, 3, "c0_cacheerr,3" },
477 { 28, 1, "c0_datalo" },
478 { 29, 1, "c0_datahi" }
479};
480
47b0e7ad
NC
481static const char * const mips_hwr_names_numeric[32] =
482{
af7ee8bf
CD
483 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
484 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
485 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
486 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
487};
488
47b0e7ad
NC
489static const char * const mips_hwr_names_mips3264r2[32] =
490{
af7ee8bf
CD
491 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
492 "$4", "$5", "$6", "$7",
493 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
494 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
495 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
496};
497
47b0e7ad
NC
498struct mips_abi_choice
499{
500 const char * name;
640c0ccd
CD
501 const char * const *gpr_names;
502 const char * const *fpr_names;
503};
504
47b0e7ad
NC
505struct mips_abi_choice mips_abi_choices[] =
506{
640c0ccd
CD
507 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
508 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
509 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
510 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
511};
512
47b0e7ad
NC
513struct mips_arch_choice
514{
640c0ccd
CD
515 const char *name;
516 int bfd_mach_valid;
517 unsigned long bfd_mach;
518 int processor;
519 int isa;
d301a56b 520 int ase;
640c0ccd 521 const char * const *cp0_names;
bbcc0807
CD
522 const struct mips_cp0sel_name *cp0sel_names;
523 unsigned int cp0sel_names_len;
af7ee8bf 524 const char * const *hwr_names;
640c0ccd
CD
525};
526
47b0e7ad
NC
527const struct mips_arch_choice mips_arch_choices[] =
528{
d301a56b 529 { "numeric", 0, 0, 0, 0, 0,
bbcc0807
CD
530 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
531
d301a56b 532 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
f409fd1e 533 mips_cp0_names_r3000, NULL, 0, mips_hwr_names_numeric },
d301a56b 534 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
bbcc0807 535 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 536 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
f409fd1e 537 mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
d301a56b 538 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
bbcc0807 539 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 540 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
bbcc0807 541 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 542 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
bbcc0807 543 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 544 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
bbcc0807 545 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 546 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
bbcc0807 547 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 548 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
f409fd1e 549 mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
d301a56b 550 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
bbcc0807 551 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 552 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
bbcc0807 553 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 554 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
bbcc0807 555 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 556 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
bbcc0807 557 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 558 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
bbcc0807 559 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 560 { "r5900", 1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
e407c74b 561 mips_cp0_names_r5900, NULL, 0, mips_hwr_names_numeric },
d301a56b 562 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
bbcc0807 563 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 564 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
5a7ea749 565 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 566 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
5a7ea749 567 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 568 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
bbcc0807 569 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 570 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
bbcc0807 571 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 572 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
bbcc0807 573 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 574 { "r14000", 1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
3aa3176b 575 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 576 { "r16000", 1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
3aa3176b 577 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
d301a56b 578 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
bbcc0807
CD
579 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
580
640c0ccd
CD
581 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
582 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
583 _MIPS32 Architecture For Programmers Volume I: Introduction to the
584 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
585 page 1. */
586 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
d301a56b 587 ISA_MIPS32, ASE_SMARTMIPS,
bbcc0807
CD
588 mips_cp0_names_mips3264,
589 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
590 mips_hwr_names_numeric },
591
af7ee8bf 592 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
d301a56b
RS
593 ISA_MIPS32R2,
594 (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_MIPS3D | ASE_MT
595 | ASE_MCU | ASE_VIRT),
bbcc0807
CD
596 mips_cp0_names_mips3264r2,
597 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
598 mips_hwr_names_mips3264r2 },
599
640c0ccd
CD
600 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
601 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
d301a56b 602 ISA_MIPS64, ASE_MIPS3D | ASE_MDMX,
bbcc0807
CD
603 mips_cp0_names_mips3264,
604 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
605 mips_hwr_names_numeric },
606
5f74bc13 607 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
d301a56b
RS
608 ISA_MIPS64R2,
609 (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_MT | ASE_MDMX
610 | ASE_MCU | ASE_VIRT | ASE_VIRT64),
5f74bc13
CD
611 mips_cp0_names_mips3264r2,
612 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
613 mips_hwr_names_mips3264r2 },
614
640c0ccd 615 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
d301a56b 616 ISA_MIPS64 | INSN_SB1, ASE_MIPS3D,
bbcc0807
CD
617 mips_cp0_names_sb1,
618 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
619 mips_hwr_names_numeric },
640c0ccd 620
350cc38d 621 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
d301a56b 622 ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
350cc38d
MS
623 NULL, 0, mips_hwr_names_numeric },
624
625 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
d301a56b 626 ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
350cc38d
MS
627 NULL, 0, mips_hwr_names_numeric },
628
fd503541 629 { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
d301a56b 630 ISA_MIPS64 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
fd503541
NC
631 NULL, 0, mips_hwr_names_numeric },
632
57b592a3 633 { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
d301a56b 634 ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
57b592a3
AN
635 mips_hwr_names_numeric },
636
dd6a37e7 637 { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
d301a56b 638 ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
432233b3
AP
639 NULL, 0, mips_hwr_names_numeric },
640
641 { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
d301a56b 642 ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
dd6a37e7
AP
643 NULL, 0, mips_hwr_names_numeric },
644
52b6b6b9 645 { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 646 ISA_MIPS64 | INSN_XLR, 0,
52b6b6b9
JM
647 mips_cp0_names_xlr,
648 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
649 mips_hwr_names_numeric },
650
55a36193
MK
651 /* XLP is mostly like XLR, with the prominent exception it is being
652 MIPS64R2. */
653 { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
d301a56b 654 ISA_MIPS64R2 | INSN_XLR, 0,
55a36193
MK
655 mips_cp0_names_xlr,
656 mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
657 mips_hwr_names_numeric },
658
640c0ccd
CD
659 /* This entry, mips16, is here only for ISA/processor selection; do
660 not print its name. */
d301a56b 661 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0,
bbcc0807 662 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd
CD
663};
664
665/* ISA and processor type to disassemble for, and register names to use.
666 set_default_mips_dis_options and parse_mips_dis_options fill in these
667 values. */
668static int mips_processor;
669static int mips_isa;
d301a56b 670static int mips_ase;
df58fc94 671static int micromips_ase;
640c0ccd
CD
672static const char * const *mips_gpr_names;
673static const char * const *mips_fpr_names;
674static const char * const *mips_cp0_names;
bbcc0807
CD
675static const struct mips_cp0sel_name *mips_cp0sel_names;
676static int mips_cp0sel_names_len;
af7ee8bf 677static const char * const *mips_hwr_names;
640c0ccd 678
986e18a5 679/* Other options */
47b0e7ad 680static int no_aliases; /* If set disassemble as most general inst. */
640c0ccd
CD
681\f
682static const struct mips_abi_choice *
47b0e7ad 683choose_abi_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
684{
685 const struct mips_abi_choice *c;
686 unsigned int i;
687
688 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
47b0e7ad
NC
689 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
690 && strlen (mips_abi_choices[i].name) == namelen)
691 c = &mips_abi_choices[i];
692
640c0ccd
CD
693 return c;
694}
695
696static const struct mips_arch_choice *
47b0e7ad 697choose_arch_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
698{
699 const struct mips_arch_choice *c = NULL;
700 unsigned int i;
701
702 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
47b0e7ad
NC
703 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
704 && strlen (mips_arch_choices[i].name) == namelen)
705 c = &mips_arch_choices[i];
706
640c0ccd
CD
707 return c;
708}
709
710static const struct mips_arch_choice *
47b0e7ad 711choose_arch_by_number (unsigned long mach)
640c0ccd
CD
712{
713 static unsigned long hint_bfd_mach;
714 static const struct mips_arch_choice *hint_arch_choice;
715 const struct mips_arch_choice *c;
716 unsigned int i;
717
718 /* We optimize this because even if the user specifies no
719 flags, this will be done for every instruction! */
720 if (hint_bfd_mach == mach
721 && hint_arch_choice != NULL
722 && hint_arch_choice->bfd_mach == hint_bfd_mach)
723 return hint_arch_choice;
724
725 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
726 {
727 if (mips_arch_choices[i].bfd_mach_valid
728 && mips_arch_choices[i].bfd_mach == mach)
729 {
730 c = &mips_arch_choices[i];
731 hint_bfd_mach = mach;
732 hint_arch_choice = c;
733 }
734 }
735 return c;
736}
737
47b0e7ad
NC
738/* Check if the object uses NewABI conventions. */
739
740static int
741is_newabi (Elf_Internal_Ehdr *header)
742{
743 /* There are no old-style ABIs which use 64-bit ELF. */
744 if (header->e_ident[EI_CLASS] == ELFCLASS64)
745 return 1;
746
747 /* If a 32-bit ELF file, n32 is a new-style ABI. */
748 if ((header->e_flags & EF_MIPS_ABI2) != 0)
749 return 1;
750
751 return 0;
752}
753
df58fc94
RS
754/* Check if the object has microMIPS ASE code. */
755
756static int
757is_micromips (Elf_Internal_Ehdr *header)
758{
759 if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
760 return 1;
761
762 return 0;
763}
764
47b0e7ad
NC
765static void
766set_default_mips_dis_options (struct disassemble_info *info)
640c0ccd
CD
767{
768 const struct mips_arch_choice *chosen_arch;
769
df58fc94
RS
770 /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
771 is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
772 CP0 register, and HWR names. */
640c0ccd 773 mips_isa = ISA_MIPS3;
df58fc94
RS
774 mips_processor = CPU_R3000;
775 micromips_ase = 0;
d301a56b 776 mips_ase = 0;
640c0ccd
CD
777 mips_gpr_names = mips_gpr_names_oldabi;
778 mips_fpr_names = mips_fpr_names_numeric;
779 mips_cp0_names = mips_cp0_names_numeric;
bbcc0807
CD
780 mips_cp0sel_names = NULL;
781 mips_cp0sel_names_len = 0;
af7ee8bf 782 mips_hwr_names = mips_hwr_names_numeric;
986e18a5 783 no_aliases = 0;
640c0ccd 784
df58fc94 785 /* Update settings according to the ELF file header flags. */
fec06546 786 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
640c0ccd
CD
787 {
788 Elf_Internal_Ehdr *header;
789
fec06546 790 header = elf_elfheader (info->section->owner);
df58fc94 791 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
640c0ccd
CD
792 if (is_newabi (header))
793 mips_gpr_names = mips_gpr_names_newabi;
df58fc94
RS
794 /* If a microMIPS binary, then don't use MIPS16 bindings. */
795 micromips_ase = is_micromips (header);
640c0ccd
CD
796 }
797
798 /* Set ISA, architecture, and cp0 register names as best we can. */
799#if ! SYMTAB_AVAILABLE
800 /* This is running out on a target machine, not in a host tool.
801 FIXME: Where does mips_target_info come from? */
802 target_processor = mips_target_info.processor;
803 mips_isa = mips_target_info.isa;
d301a56b 804 mips_ase = mips_target_info.ase;
640c0ccd
CD
805#else
806 chosen_arch = choose_arch_by_number (info->mach);
807 if (chosen_arch != NULL)
808 {
809 mips_processor = chosen_arch->processor;
810 mips_isa = chosen_arch->isa;
d301a56b 811 mips_ase = chosen_arch->ase;
bbcc0807
CD
812 mips_cp0_names = chosen_arch->cp0_names;
813 mips_cp0sel_names = chosen_arch->cp0sel_names;
814 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
815 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
816 }
817#endif
818}
819
47b0e7ad
NC
820static void
821parse_mips_dis_option (const char *option, unsigned int len)
640c0ccd
CD
822{
823 unsigned int i, optionlen, vallen;
824 const char *val;
825 const struct mips_abi_choice *chosen_abi;
826 const struct mips_arch_choice *chosen_arch;
827
986e18a5 828 /* Try to match options that are simple flags */
0112cd26 829 if (CONST_STRNEQ (option, "no-aliases"))
986e18a5
FF
830 {
831 no_aliases = 1;
832 return;
833 }
b015e599
AP
834
835 if (CONST_STRNEQ (option, "virt"))
836 {
d301a56b 837 mips_ase |= ASE_VIRT;
b015e599 838 if (mips_isa & ISA_MIPS64R2)
d301a56b 839 mips_ase |= ASE_VIRT64;
b015e599
AP
840 return;
841 }
986e18a5 842
640c0ccd
CD
843 /* Look for the = that delimits the end of the option name. */
844 for (i = 0; i < len; i++)
47b0e7ad
NC
845 if (option[i] == '=')
846 break;
847
640c0ccd
CD
848 if (i == 0) /* Invalid option: no name before '='. */
849 return;
850 if (i == len) /* Invalid option: no '='. */
851 return;
852 if (i == (len - 1)) /* Invalid option: no value after '='. */
853 return;
854
855 optionlen = i;
856 val = option + (optionlen + 1);
857 vallen = len - (optionlen + 1);
858
47b0e7ad
NC
859 if (strncmp ("gpr-names", option, optionlen) == 0
860 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
861 {
862 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 863 if (chosen_abi != NULL)
640c0ccd
CD
864 mips_gpr_names = chosen_abi->gpr_names;
865 return;
866 }
867
47b0e7ad
NC
868 if (strncmp ("fpr-names", option, optionlen) == 0
869 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
870 {
871 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 872 if (chosen_abi != NULL)
640c0ccd
CD
873 mips_fpr_names = chosen_abi->fpr_names;
874 return;
875 }
876
47b0e7ad
NC
877 if (strncmp ("cp0-names", option, optionlen) == 0
878 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
879 {
880 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
881 if (chosen_arch != NULL)
882 {
883 mips_cp0_names = chosen_arch->cp0_names;
884 mips_cp0sel_names = chosen_arch->cp0sel_names;
885 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
886 }
640c0ccd
CD
887 return;
888 }
889
47b0e7ad
NC
890 if (strncmp ("hwr-names", option, optionlen) == 0
891 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
892 {
893 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 894 if (chosen_arch != NULL)
af7ee8bf
CD
895 mips_hwr_names = chosen_arch->hwr_names;
896 return;
897 }
898
47b0e7ad
NC
899 if (strncmp ("reg-names", option, optionlen) == 0
900 && strlen ("reg-names") == optionlen)
640c0ccd
CD
901 {
902 /* We check both ABI and ARCH here unconditionally, so
903 that "numeric" will do the desirable thing: select
904 numeric register names for all registers. Other than
905 that, a given name probably won't match both. */
906 chosen_abi = choose_abi_by_name (val, vallen);
907 if (chosen_abi != NULL)
908 {
bbcc0807
CD
909 mips_gpr_names = chosen_abi->gpr_names;
910 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
911 }
912 chosen_arch = choose_arch_by_name (val, vallen);
913 if (chosen_arch != NULL)
914 {
bbcc0807
CD
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;
918 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
919 }
920 return;
921 }
922
923 /* Invalid option. */
924}
925
47b0e7ad
NC
926static void
927parse_mips_dis_options (const char *options)
640c0ccd
CD
928{
929 const char *option_end;
930
931 if (options == NULL)
932 return;
933
934 while (*options != '\0')
935 {
936 /* Skip empty options. */
937 if (*options == ',')
938 {
939 options++;
940 continue;
941 }
942
943 /* We know that *options is neither NUL or a comma. */
944 option_end = options + 1;
945 while (*option_end != ',' && *option_end != '\0')
946 option_end++;
947
948 parse_mips_dis_option (options, option_end - options);
949
950 /* Go on to the next one. If option_end points to a comma, it
951 will be skipped above. */
952 options = option_end;
953 }
954}
955
bbcc0807 956static const struct mips_cp0sel_name *
47b0e7ad
NC
957lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
958 unsigned int len,
959 unsigned int cp0reg,
960 unsigned int sel)
bbcc0807
CD
961{
962 unsigned int i;
963
964 for (i = 0; i < len; i++)
965 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
966 return &names[i];
967 return NULL;
968}
252b5132 969\f
7f6621cd 970/* Print insn arguments for 32/64-bit code. */
aa5f19f2 971
794ac9d0 972static void
47b0e7ad 973print_insn_args (const char *d,
fc8c4fd1 974 int l,
47b0e7ad 975 bfd_vma pc,
cc0ca239
TS
976 struct disassemble_info *info,
977 const struct mips_opcode *opp)
252b5132 978{
fc8c4fd1 979 const fprintf_ftype infprintf = info->fprintf_func;
440cc0bc 980 unsigned int lsb, msb, msbd;
fc8c4fd1
MR
981 void *is = info->stream;
982 int op;
440cc0bc
CD
983
984 lsb = 0;
252b5132 985
fc8c4fd1
MR
986#define GET_OP(insn, field) \
987 (((insn) >> OP_SH_##field) & OP_MASK_##field)
988#define GET_OP_S(insn, field) \
989 ((GET_OP (insn, field) ^ ((OP_MASK_##field >> 1) + 1)) \
990 - ((OP_MASK_##field >> 1) + 1))
794ac9d0 991 for (; *d != '\0'; d++)
252b5132 992 {
af7ee8bf
CD
993 switch (*d)
994 {
794ac9d0
CD
995 case ',':
996 case '(':
997 case ')':
998 case '[':
999 case ']':
fc8c4fd1 1000 infprintf (is, "%c", *d);
794ac9d0
CD
1001 break;
1002
1003 case '+':
1004 /* Extension character; switch for second char. */
1005 d++;
1006 switch (*d)
1007 {
1008 case '\0':
1009 /* xgettext:c-format */
fc8c4fd1
MR
1010 infprintf (is,
1011 _("# internal error, "
1012 "incomplete extension sequence (+)"));
794ac9d0
CD
1013 return;
1014
1015 case 'A':
fc8c4fd1
MR
1016 lsb = GET_OP (l, SHAMT);
1017 infprintf (is, "0x%x", lsb);
794ac9d0
CD
1018 break;
1019
1020 case 'B':
fc8c4fd1
MR
1021 msb = GET_OP (l, INSMSB);
1022 infprintf (is, "0x%x", msb - lsb + 1);
794ac9d0
CD
1023 break;
1024
9bcd4f99 1025 case '1':
fc8c4fd1 1026 infprintf (is, "0x%x", GET_OP (l, UDI1));
9bcd4f99
TS
1027 break;
1028
1029 case '2':
fc8c4fd1 1030 infprintf (is, "0x%x", GET_OP (l, UDI2));
9bcd4f99
TS
1031 break;
1032
1033 case '3':
fc8c4fd1 1034 infprintf (is, "0x%x", GET_OP (l, UDI3));
9bcd4f99
TS
1035 break;
1036
1037 case '4':
fc8c4fd1 1038 infprintf (is, "0x%x", GET_OP (l, UDI4));
9bcd4f99
TS
1039 break;
1040
794ac9d0 1041 case 'C':
5f74bc13 1042 case 'H':
fc8c4fd1
MR
1043 msbd = GET_OP (l, EXTMSBD);
1044 infprintf (is, "0x%x", msbd + 1);
794ac9d0
CD
1045 break;
1046
1047 case 'D':
1048 {
1049 const struct mips_cp0sel_name *n;
1050 unsigned int cp0reg, sel;
1051
fc8c4fd1
MR
1052 cp0reg = GET_OP (l, RD);
1053 sel = GET_OP (l, SEL);
794ac9d0
CD
1054
1055 /* CP0 register including 'sel' code for mtcN (et al.), to be
1056 printed textually if known. If not known, print both
1057 CP0 register name and sel numerically since CP0 register
1058 with sel 0 may have a name unrelated to register being
1059 printed. */
1060 n = lookup_mips_cp0sel_name(mips_cp0sel_names,
1061 mips_cp0sel_names_len, cp0reg, sel);
1062 if (n != NULL)
fc8c4fd1 1063 infprintf (is, "%s", n->name);
794ac9d0 1064 else
fc8c4fd1 1065 infprintf (is, "$%d,%d", cp0reg, sel);
794ac9d0
CD
1066 break;
1067 }
1068
5f74bc13 1069 case 'E':
fc8c4fd1
MR
1070 lsb = GET_OP (l, SHAMT) + 32;
1071 infprintf (is, "0x%x", lsb);
5f74bc13
CD
1072 break;
1073
1074 case 'F':
fc8c4fd1
MR
1075 msb = GET_OP (l, INSMSB) + 32;
1076 infprintf (is, "0x%x", msb - lsb + 1);
5f74bc13
CD
1077 break;
1078
1079 case 'G':
fc8c4fd1
MR
1080 msbd = GET_OP (l, EXTMSBD) + 32;
1081 infprintf (is, "0x%x", msbd + 1);
5f74bc13
CD
1082 break;
1083
b015e599
AP
1084 case 'J': /* hypcall operand */
1085 infprintf (is, "0x%x", GET_OP (l, CODE10));
1086 break;
1087
61cc0267 1088 case 't': /* Coprocessor 0 reg name */
fc8c4fd1 1089 infprintf (is, "%s", mips_cp0_names[GET_OP (l, RT)]);
61cc0267
CF
1090 break;
1091
1092 case 'T': /* Coprocessor 0 reg name */
1093 {
1094 const struct mips_cp0sel_name *n;
1095 unsigned int cp0reg, sel;
1096
fc8c4fd1
MR
1097 cp0reg = GET_OP (l, RT);
1098 sel = GET_OP (l, SEL);
61cc0267
CF
1099
1100 /* CP0 register including 'sel' code for mftc0, to be
1101 printed textually if known. If not known, print both
1102 CP0 register name and sel numerically since CP0 register
1103 with sel 0 may have a name unrelated to register being
1104 printed. */
1105 n = lookup_mips_cp0sel_name(mips_cp0sel_names,
1106 mips_cp0sel_names_len, cp0reg, sel);
1107 if (n != NULL)
fc8c4fd1 1108 infprintf (is, "%s", n->name);
61cc0267 1109 else
fc8c4fd1 1110 infprintf (is, "$%d,%d", cp0reg, sel);
61cc0267
CF
1111 break;
1112 }
1113
bb35fb24 1114 case 'x': /* bbit bit index */
fc8c4fd1 1115 infprintf (is, "0x%x", GET_OP (l, BBITIND));
bb35fb24
NC
1116 break;
1117
1118 case 'p': /* cins, cins32, exts and exts32 position */
fc8c4fd1 1119 infprintf (is, "0x%x", GET_OP (l, CINSPOS));
bb35fb24
NC
1120 break;
1121
1122 case 's': /* cins and exts length-minus-one */
fc8c4fd1 1123 infprintf (is, "0x%x", GET_OP (l, CINSLM1));
bb35fb24
NC
1124 break;
1125
1126 case 'S': /* cins32 and exts32 length-minus-one field */
fc8c4fd1 1127 infprintf (is, "0x%x", GET_OP (l, CINSLM1));
bb35fb24
NC
1128 break;
1129
dd3cbb7e 1130 case 'Q': /* seqi/snei immediate field */
fc8c4fd1 1131 infprintf (is, "%d", GET_OP_S (l, SEQI));
dd3cbb7e
NC
1132 break;
1133
98675402 1134 case 'a': /* 8-bit signed offset in bit 6 */
fc8c4fd1 1135 infprintf (is, "%d", GET_OP_S (l, OFFSET_A));
98675402
RS
1136 break;
1137
1138 case 'b': /* 8-bit signed offset in bit 3 */
fc8c4fd1 1139 infprintf (is, "%d", GET_OP_S (l, OFFSET_B));
98675402
RS
1140 break;
1141
1142 case 'c': /* 9-bit signed offset in bit 6 */
c95354ed 1143 /* Left shift 4 bits to print the real offset. */
fc8c4fd1 1144 infprintf (is, "%d", GET_OP_S (l, OFFSET_C) << 4);
98675402
RS
1145 break;
1146
1147 case 'z':
fc8c4fd1 1148 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RZ)]);
98675402
RS
1149 break;
1150
1151 case 'Z':
fc8c4fd1 1152 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FZ)]);
98675402
RS
1153 break;
1154
794ac9d0
CD
1155 default:
1156 /* xgettext:c-format */
fc8c4fd1
MR
1157 infprintf (is,
1158 _("# internal error, "
1159 "undefined extension sequence (+%c)"),
1160 *d);
794ac9d0
CD
1161 return;
1162 }
1163 break;
1164
8b082fb1 1165 case '2':
fc8c4fd1 1166 infprintf (is, "0x%x", GET_OP (l, BP));
8b082fb1
TS
1167 break;
1168
fd25c5a9 1169 case '3':
fc8c4fd1 1170 infprintf (is, "0x%x", GET_OP (l, SA3));
fd25c5a9
CF
1171 break;
1172
1173 case '4':
fc8c4fd1 1174 infprintf (is, "0x%x", GET_OP (l, SA4));
fd25c5a9
CF
1175 break;
1176
1177 case '5':
fc8c4fd1 1178 infprintf (is, "0x%x", GET_OP (l, IMM8));
fd25c5a9
CF
1179 break;
1180
1181 case '6':
fc8c4fd1 1182 infprintf (is, "0x%x", GET_OP (l, RS));
fd25c5a9
CF
1183 break;
1184
1185 case '7':
fc8c4fd1 1186 infprintf (is, "$ac%d", GET_OP (l, DSPACC));
fd25c5a9
CF
1187 break;
1188
1189 case '8':
fc8c4fd1 1190 infprintf (is, "0x%x", GET_OP (l, WRDSP));
fd25c5a9
CF
1191 break;
1192
1193 case '9':
fc8c4fd1 1194 infprintf (is, "$ac%d", GET_OP (l, DSPACC_S));
fd25c5a9
CF
1195 break;
1196
1197 case '0': /* dsp 6-bit signed immediate in bit 20 */
fc8c4fd1 1198 infprintf (is, "%d", GET_OP_S (l, DSPSFT));
fd25c5a9
CF
1199 break;
1200
1201 case ':': /* dsp 7-bit signed immediate in bit 19 */
fc8c4fd1 1202 infprintf (is, "%d", GET_OP_S (l, DSPSFT_7));
fd25c5a9
CF
1203 break;
1204
dec0624d 1205 case '~':
fc8c4fd1 1206 infprintf (is, "%d", GET_OP_S (l, OFFSET12));
dec0624d
MR
1207 break;
1208
1209 case '\\':
fc8c4fd1 1210 infprintf (is, "0x%x", GET_OP (l, 3BITPOS));
dec0624d
MR
1211 break;
1212
fd25c5a9 1213 case '\'':
fc8c4fd1 1214 infprintf (is, "0x%x", GET_OP (l, RDDSP));
fd25c5a9
CF
1215 break;
1216
1217 case '@': /* dsp 10-bit signed immediate in bit 16 */
fc8c4fd1 1218 infprintf (is, "%d", GET_OP_S (l, IMM10));
fd25c5a9
CF
1219 break;
1220
61cc0267 1221 case '!':
fc8c4fd1 1222 infprintf (is, "%d", GET_OP (l, MT_U));
61cc0267
CF
1223 break;
1224
1225 case '$':
fc8c4fd1 1226 infprintf (is, "%d", GET_OP (l, MT_H));
61cc0267
CF
1227 break;
1228
1229 case '*':
fc8c4fd1 1230 infprintf (is, "$ac%d", GET_OP (l, MTACC_T));
61cc0267
CF
1231 break;
1232
1233 case '&':
fc8c4fd1 1234 infprintf (is, "$ac%d", GET_OP (l, MTACC_D));
61cc0267
CF
1235 break;
1236
1237 case 'g':
1238 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
fc8c4fd1 1239 infprintf (is, "$%d", GET_OP (l, RD));
61cc0267
CF
1240 break;
1241
794ac9d0
CD
1242 case 's':
1243 case 'b':
1244 case 'r':
1245 case 'v':
fc8c4fd1 1246 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RS)]);
794ac9d0
CD
1247 break;
1248
1249 case 't':
1250 case 'w':
fc8c4fd1 1251 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RT)]);
794ac9d0
CD
1252 break;
1253
1254 case 'i':
1255 case 'u':
fc8c4fd1 1256 infprintf (is, "0x%x", GET_OP (l, IMMEDIATE));
794ac9d0
CD
1257 break;
1258
1259 case 'j': /* Same as i, but sign-extended. */
1260 case 'o':
fc8c4fd1 1261 infprintf (is, "%d", GET_OP_S (l, DELTA));
794ac9d0
CD
1262 break;
1263
1264 case 'h':
fc8c4fd1 1265 infprintf (is, "0x%x", GET_OP (l, PREFX));
794ac9d0
CD
1266 break;
1267
1268 case 'k':
fc8c4fd1 1269 infprintf (is, "0x%x", GET_OP (l, CACHE));
794ac9d0
CD
1270 break;
1271
1272 case 'a':
1273 info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
fc8c4fd1 1274 | (GET_OP (l, TARGET) << 2));
022fac6d
TS
1275 /* For gdb disassembler, force odd address on jalx. */
1276 if (info->flavour == bfd_target_unknown_flavour
1277 && strcmp (opp->name, "jalx") == 0)
1278 info->target |= 1;
794ac9d0
CD
1279 (*info->print_address_func) (info->target, info);
1280 break;
1281
1282 case 'p':
1283 /* Sign extend the displacement. */
fc8c4fd1 1284 info->target = (GET_OP_S (l, DELTA) << 2) + pc + INSNLEN;
794ac9d0
CD
1285 (*info->print_address_func) (info->target, info);
1286 break;
1287
1288 case 'd':
fc8c4fd1 1289 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RD)]);
794ac9d0
CD
1290 break;
1291
1292 case 'U':
1293 {
1294 /* First check for both rd and rt being equal. */
314d60dd
ME
1295 unsigned int reg;
1296
1297 reg = GET_OP (l, RD);
fc8c4fd1
MR
1298 if (reg == GET_OP (l, RT))
1299 infprintf (is, "%s", mips_gpr_names[reg]);
794ac9d0
CD
1300 else
1301 {
1302 /* If one is zero use the other. */
1303 if (reg == 0)
fc8c4fd1
MR
1304 infprintf (is, "%s", mips_gpr_names[GET_OP (l, RT)]);
1305 else if (GET_OP (l, RT) == 0)
1306 infprintf (is, "%s", mips_gpr_names[reg]);
794ac9d0 1307 else /* Bogus, result depends on processor. */
fc8c4fd1
MR
1308 infprintf (is, "%s or %s",
1309 mips_gpr_names[reg],
1310 mips_gpr_names[GET_OP (l, RT)]);
794ac9d0
CD
1311 }
1312 }
1313 break;
1314
1315 case 'z':
fc8c4fd1 1316 infprintf (is, "%s", mips_gpr_names[0]);
794ac9d0
CD
1317 break;
1318
1319 case '<':
4dc48ef6 1320 case '1':
fc8c4fd1 1321 infprintf (is, "0x%x", GET_OP (l, SHAMT));
af7ee8bf 1322 break;
794ac9d0
CD
1323
1324 case 'c':
fc8c4fd1 1325 infprintf (is, "0x%x", GET_OP (l, CODE));
794ac9d0
CD
1326 break;
1327
1328 case 'q':
fc8c4fd1 1329 infprintf (is, "0x%x", GET_OP (l, CODE2));
af7ee8bf
CD
1330 break;
1331
1332 case 'C':
fc8c4fd1 1333 infprintf (is, "0x%x", GET_OP (l, COPZ));
794ac9d0
CD
1334 break;
1335
1336 case 'B':
fc8c4fd1 1337 infprintf (is, "0x%x", GET_OP (l, CODE20));
794ac9d0
CD
1338 break;
1339
1340 case 'J':
fc8c4fd1 1341 infprintf (is, "0x%x", GET_OP (l, CODE19));
794ac9d0
CD
1342 break;
1343
1344 case 'S':
1345 case 'V':
fc8c4fd1 1346 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FS)]);
794ac9d0
CD
1347 break;
1348
1349 case 'T':
1350 case 'W':
fc8c4fd1 1351 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FT)]);
af7ee8bf
CD
1352 break;
1353
bbcc0807 1354 case 'D':
fc8c4fd1 1355 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FD)]);
794ac9d0
CD
1356 break;
1357
1358 case 'R':
fc8c4fd1 1359 infprintf (is, "%s", mips_fpr_names[GET_OP (l, FR)]);
794ac9d0
CD
1360 break;
1361
1362 case 'E':
1363 /* Coprocessor register for lwcN instructions, et al.
1364
1365 Note that there is no load/store cp0 instructions, and
1366 that FPU (cp1) instructions disassemble this field using
1367 'T' format. Therefore, until we gain understanding of
1368 cp2 register names, we can simply print the register
1369 numbers. */
fc8c4fd1 1370 infprintf (is, "$%d", GET_OP (l, RT));
794ac9d0
CD
1371 break;
1372
1373 case 'G':
1374 /* Coprocessor register for mtcN instructions, et al. Note
1375 that FPU (cp1) instructions disassemble this field using
1376 'S' format. Therefore, we only need to worry about cp0,
1377 cp2, and cp3. */
fc8c4fd1 1378 op = GET_OP (l, OP);
794ac9d0 1379 if (op == OP_OP_COP0)
fc8c4fd1 1380 infprintf (is, "%s", mips_cp0_names[GET_OP (l, RD)]);
794ac9d0 1381 else
fc8c4fd1 1382 infprintf (is, "$%d", GET_OP (l, RD));
794ac9d0
CD
1383 break;
1384
1385 case 'K':
fc8c4fd1 1386 infprintf (is, "%s", mips_hwr_names[GET_OP (l, RD)]);
794ac9d0
CD
1387 break;
1388
1389 case 'N':
fc8c4fd1
MR
1390 infprintf (is,
1391 (opp->pinfo & (FP_D | FP_S)) != 0 ? "$fcc%d" : "$cc%d",
1392 GET_OP (l, BCC));
794ac9d0
CD
1393 break;
1394
1395 case 'M':
fc8c4fd1 1396 infprintf (is, "$fcc%d", GET_OP (l, CCC));
794ac9d0
CD
1397 break;
1398
1399 case 'P':
fc8c4fd1 1400 infprintf (is, "%d", GET_OP (l, PERFREG));
794ac9d0
CD
1401 break;
1402
1403 case 'e':
fc8c4fd1 1404 infprintf (is, "%d", GET_OP (l, VECBYTE));
794ac9d0
CD
1405 break;
1406
1407 case '%':
fc8c4fd1 1408 infprintf (is, "%d", GET_OP (l, VECALIGN));
794ac9d0
CD
1409 break;
1410
1411 case 'H':
fc8c4fd1 1412 infprintf (is, "%d", GET_OP (l, SEL));
794ac9d0
CD
1413 break;
1414
1415 case 'O':
fc8c4fd1 1416 infprintf (is, "%d", GET_OP (l, ALN));
794ac9d0
CD
1417 break;
1418
1419 case 'Q':
bbcc0807 1420 {
fc8c4fd1 1421 unsigned int vsel = GET_OP (l, VSEL);
47b0e7ad 1422
794ac9d0
CD
1423 if ((vsel & 0x10) == 0)
1424 {
1425 int fmt;
47b0e7ad 1426
794ac9d0
CD
1427 vsel &= 0x0f;
1428 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1429 if ((vsel & 1) == 0)
1430 break;
fc8c4fd1 1431 infprintf (is, "$v%d[%d]", GET_OP (l, FT), vsel >> 1);
794ac9d0
CD
1432 }
1433 else if ((vsel & 0x08) == 0)
1434 {
fc8c4fd1 1435 infprintf (is, "$v%d", GET_OP (l, FT));
794ac9d0 1436 }
bbcc0807 1437 else
794ac9d0 1438 {
fc8c4fd1 1439 infprintf (is, "0x%x", GET_OP (l, FT));
794ac9d0 1440 }
bbcc0807 1441 }
794ac9d0
CD
1442 break;
1443
1444 case 'X':
fc8c4fd1 1445 infprintf (is, "$v%d", GET_OP (l, FD));
794ac9d0
CD
1446 break;
1447
1448 case 'Y':
fc8c4fd1 1449 infprintf (is, "$v%d", GET_OP (l, FS));
794ac9d0
CD
1450 break;
1451
1452 case 'Z':
fc8c4fd1 1453 infprintf (is, "$v%d", GET_OP (l, FT));
794ac9d0 1454 break;
bbcc0807 1455
af7ee8bf
CD
1456 default:
1457 /* xgettext:c-format */
fc8c4fd1 1458 infprintf (is, _("# internal error, undefined modifier (%c)"), *d);
794ac9d0 1459 return;
af7ee8bf 1460 }
252b5132
RH
1461 }
1462}
1463\f
252b5132
RH
1464/* Print the mips instruction at address MEMADDR in debugged memory,
1465 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1466 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1467 this is little-endian code. */
1468
1469static int
47b0e7ad 1470print_insn_mips (bfd_vma memaddr,
fc8c4fd1 1471 int word,
47b0e7ad 1472 struct disassemble_info *info)
252b5132 1473{
fc8c4fd1
MR
1474 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1475 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad 1476 const struct mips_opcode *op;
b34976b6 1477 static bfd_boolean init = 0;
fc8c4fd1 1478 void *is = info->stream;
252b5132
RH
1479
1480 /* Build a hash table to shorten the search time. */
1481 if (! init)
1482 {
1483 unsigned int i;
1484
1485 for (i = 0; i <= OP_MASK_OP; i++)
1486 {
1487 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1488 {
986e18a5 1489 if (op->pinfo == INSN_MACRO
9e836e3d 1490 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132 1491 continue;
fc8c4fd1 1492 if (i == GET_OP (op->match, OP))
252b5132
RH
1493 {
1494 mips_hash[i] = op;
1495 break;
1496 }
1497 }
7f6621cd 1498 }
252b5132
RH
1499
1500 init = 1;
1501 }
1502
aa5f19f2 1503 info->bytes_per_chunk = INSNLEN;
252b5132 1504 info->display_endian = info->endian;
9bb28706
CD
1505 info->insn_info_valid = 1;
1506 info->branch_delay_insns = 0;
def7143b 1507 info->data_size = 0;
9bb28706
CD
1508 info->insn_type = dis_nonbranch;
1509 info->target = 0;
1510 info->target2 = 0;
252b5132 1511
fc8c4fd1 1512 op = mips_hash[GET_OP (word, OP)];
252b5132
RH
1513 if (op != NULL)
1514 {
1515 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1516 {
986e18a5 1517 if (op->pinfo != INSN_MACRO
9e836e3d 1518 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1519 && (word & op->mask) == op->match)
252b5132 1520 {
47b0e7ad 1521 const char *d;
2bd7f1f3 1522
3396de36 1523 /* We always allow to disassemble the jalx instruction. */
d301a56b 1524 if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
3396de36 1525 && strcmp (op->name, "jalx"))
252b5132
RH
1526 continue;
1527
9bb28706
CD
1528 /* Figure out instruction type and branch delay information. */
1529 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1530 {
c680e7f6
MR
1531 if ((op->pinfo & (INSN_WRITE_GPR_31
1532 | INSN_WRITE_GPR_D)) != 0)
9bb28706
CD
1533 info->insn_type = dis_jsr;
1534 else
1535 info->insn_type = dis_branch;
1536 info->branch_delay_insns = 1;
1537 }
1538 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1539 | INSN_COND_BRANCH_LIKELY)) != 0)
1540 {
c680e7f6 1541 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
9bb28706
CD
1542 info->insn_type = dis_condjsr;
1543 else
1544 info->insn_type = dis_condbranch;
1545 info->branch_delay_insns = 1;
1546 }
1547 else if ((op->pinfo & (INSN_STORE_MEMORY
1548 | INSN_LOAD_MEMORY_DELAY)) != 0)
1549 info->insn_type = dis_dref;
1550
fc8c4fd1 1551 infprintf (is, "%s", op->name);
252b5132
RH
1552
1553 d = op->args;
1554 if (d != NULL && *d != '\0')
1555 {
fc8c4fd1 1556 infprintf (is, "\t");
cc0ca239 1557 print_insn_args (d, word, memaddr, info, op);
252b5132
RH
1558 }
1559
aa5f19f2 1560 return INSNLEN;
252b5132
RH
1561 }
1562 }
1563 }
fc8c4fd1
MR
1564#undef GET_OP_S
1565#undef GET_OP
252b5132
RH
1566
1567 /* Handle undefined instructions. */
9bb28706 1568 info->insn_type = dis_noninsn;
fc8c4fd1 1569 infprintf (is, "0x%x", word);
aa5f19f2 1570 return INSNLEN;
252b5132 1571}
aa5f19f2 1572\f
252b5132
RH
1573/* Disassemble an operand for a mips16 instruction. */
1574
1575static void
47b0e7ad
NC
1576print_mips16_insn_arg (char type,
1577 const struct mips_opcode *op,
1578 int l,
1579 bfd_boolean use_extend,
1580 int extend,
1581 bfd_vma memaddr,
1582 struct disassemble_info *info)
252b5132 1583{
fc8c4fd1
MR
1584 const fprintf_ftype infprintf = info->fprintf_func;
1585 void *is = info->stream;
1586
1587#define GET_OP(insn, field) \
1588 (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
1589#define GET_OP_S(insn, field) \
1590 ((GET_OP (insn, field) ^ ((MIPS16OP_MASK_##field >> 1) + 1)) \
1591 - ((MIPS16OP_MASK_##field >> 1) + 1))
252b5132
RH
1592 switch (type)
1593 {
1594 case ',':
1595 case '(':
1596 case ')':
fc8c4fd1 1597 infprintf (is, "%c", type);
252b5132
RH
1598 break;
1599
1600 case 'y':
1601 case 'w':
fc8c4fd1 1602 infprintf (is, "%s", mips16_reg_names (GET_OP (l, RY)));
252b5132
RH
1603 break;
1604
1605 case 'x':
1606 case 'v':
fc8c4fd1 1607 infprintf (is, "%s", mips16_reg_names (GET_OP (l, RX)));
252b5132
RH
1608 break;
1609
1610 case 'z':
fc8c4fd1 1611 infprintf (is, "%s", mips16_reg_names (GET_OP (l, RZ)));
252b5132
RH
1612 break;
1613
1614 case 'Z':
fc8c4fd1 1615 infprintf (is, "%s", mips16_reg_names (GET_OP (l, MOVE32Z)));
252b5132
RH
1616 break;
1617
1618 case '0':
fc8c4fd1 1619 infprintf (is, "%s", mips_gpr_names[0]);
252b5132
RH
1620 break;
1621
1622 case 'S':
fc8c4fd1 1623 infprintf (is, "%s", mips_gpr_names[29]);
252b5132
RH
1624 break;
1625
1626 case 'P':
fc8c4fd1 1627 infprintf (is, "$pc");
252b5132
RH
1628 break;
1629
1630 case 'R':
fc8c4fd1 1631 infprintf (is, "%s", mips_gpr_names[31]);
252b5132
RH
1632 break;
1633
1634 case 'X':
fc8c4fd1 1635 infprintf (is, "%s", mips_gpr_names[GET_OP (l, REGR32)]);
252b5132
RH
1636 break;
1637
1638 case 'Y':
fc8c4fd1 1639 infprintf (is, "%s", mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
252b5132
RH
1640 break;
1641
1642 case '<':
1643 case '>':
1644 case '[':
1645 case ']':
1646 case '4':
1647 case '5':
1648 case 'H':
1649 case 'W':
1650 case 'D':
1651 case 'j':
1652 case '6':
1653 case '8':
1654 case 'V':
1655 case 'C':
1656 case 'U':
1657 case 'k':
1658 case 'K':
1659 case 'p':
1660 case 'q':
1661 case 'A':
1662 case 'B':
1663 case 'E':
1664 {
1665 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
1666
1667 shift = 0;
1668 signedp = 0;
1669 extbits = 16;
1670 pcrel = 0;
1671 extu = 0;
1672 branch = 0;
1673 switch (type)
1674 {
1675 case '<':
1676 nbits = 3;
fc8c4fd1 1677 immed = GET_OP (l, RZ);
252b5132
RH
1678 extbits = 5;
1679 extu = 1;
1680 break;
1681 case '>':
1682 nbits = 3;
fc8c4fd1 1683 immed = GET_OP (l, RX);
252b5132
RH
1684 extbits = 5;
1685 extu = 1;
1686 break;
1687 case '[':
1688 nbits = 3;
fc8c4fd1 1689 immed = GET_OP (l, RZ);
252b5132
RH
1690 extbits = 6;
1691 extu = 1;
1692 break;
1693 case ']':
1694 nbits = 3;
fc8c4fd1 1695 immed = GET_OP (l, RX);
252b5132
RH
1696 extbits = 6;
1697 extu = 1;
1698 break;
1699 case '4':
1700 nbits = 4;
fc8c4fd1 1701 immed = GET_OP (l, IMM4);
252b5132
RH
1702 signedp = 1;
1703 extbits = 15;
1704 break;
1705 case '5':
1706 nbits = 5;
fc8c4fd1 1707 immed = GET_OP (l, IMM5);
252b5132
RH
1708 info->insn_type = dis_dref;
1709 info->data_size = 1;
1710 break;
1711 case 'H':
1712 nbits = 5;
1713 shift = 1;
fc8c4fd1 1714 immed = GET_OP (l, IMM5);
252b5132
RH
1715 info->insn_type = dis_dref;
1716 info->data_size = 2;
1717 break;
1718 case 'W':
1719 nbits = 5;
1720 shift = 2;
fc8c4fd1 1721 immed = GET_OP (l, IMM5);
252b5132
RH
1722 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1723 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1724 {
1725 info->insn_type = dis_dref;
1726 info->data_size = 4;
1727 }
1728 break;
1729 case 'D':
1730 nbits = 5;
1731 shift = 3;
fc8c4fd1 1732 immed = GET_OP (l, IMM5);
252b5132
RH
1733 info->insn_type = dis_dref;
1734 info->data_size = 8;
1735 break;
1736 case 'j':
1737 nbits = 5;
fc8c4fd1 1738 immed = GET_OP (l, IMM5);
252b5132
RH
1739 signedp = 1;
1740 break;
1741 case '6':
1742 nbits = 6;
fc8c4fd1 1743 immed = GET_OP (l, IMM6);
252b5132
RH
1744 break;
1745 case '8':
1746 nbits = 8;
fc8c4fd1 1747 immed = GET_OP (l, IMM8);
252b5132
RH
1748 break;
1749 case 'V':
1750 nbits = 8;
1751 shift = 2;
fc8c4fd1 1752 immed = GET_OP (l, IMM8);
252b5132
RH
1753 /* FIXME: This might be lw, or it might be addiu to $sp or
1754 $pc. We assume it's load. */
1755 info->insn_type = dis_dref;
1756 info->data_size = 4;
1757 break;
1758 case 'C':
1759 nbits = 8;
1760 shift = 3;
fc8c4fd1 1761 immed = GET_OP (l, IMM8);
252b5132
RH
1762 info->insn_type = dis_dref;
1763 info->data_size = 8;
1764 break;
1765 case 'U':
1766 nbits = 8;
fc8c4fd1 1767 immed = GET_OP (l, IMM8);
252b5132
RH
1768 extu = 1;
1769 break;
1770 case 'k':
1771 nbits = 8;
fc8c4fd1 1772 immed = GET_OP (l, IMM8);
252b5132
RH
1773 signedp = 1;
1774 break;
1775 case 'K':
1776 nbits = 8;
1777 shift = 3;
fc8c4fd1 1778 immed = GET_OP (l, IMM8);
252b5132
RH
1779 signedp = 1;
1780 break;
1781 case 'p':
1782 nbits = 8;
fc8c4fd1 1783 immed = GET_OP (l, IMM8);
252b5132
RH
1784 signedp = 1;
1785 pcrel = 1;
1786 branch = 1;
252b5132
RH
1787 break;
1788 case 'q':
1789 nbits = 11;
fc8c4fd1 1790 immed = GET_OP (l, IMM11);
252b5132
RH
1791 signedp = 1;
1792 pcrel = 1;
1793 branch = 1;
252b5132
RH
1794 break;
1795 case 'A':
1796 nbits = 8;
1797 shift = 2;
fc8c4fd1 1798 immed = GET_OP (l, IMM8);
252b5132
RH
1799 pcrel = 1;
1800 /* FIXME: This can be lw or la. We assume it is lw. */
1801 info->insn_type = dis_dref;
1802 info->data_size = 4;
1803 break;
1804 case 'B':
1805 nbits = 5;
1806 shift = 3;
fc8c4fd1 1807 immed = GET_OP (l, IMM5);
252b5132
RH
1808 pcrel = 1;
1809 info->insn_type = dis_dref;
1810 info->data_size = 8;
1811 break;
1812 case 'E':
1813 nbits = 5;
1814 shift = 2;
fc8c4fd1 1815 immed = GET_OP (l, IMM5);
252b5132
RH
1816 pcrel = 1;
1817 break;
1818 default:
1819 abort ();
1820 }
1821
1822 if (! use_extend)
1823 {
1824 if (signedp && immed >= (1 << (nbits - 1)))
1825 immed -= 1 << nbits;
1826 immed <<= shift;
1827 if ((type == '<' || type == '>' || type == '[' || type == ']')
1828 && immed == 0)
1829 immed = 8;
1830 }
1831 else
1832 {
1833 if (extbits == 16)
1834 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1835 else if (extbits == 15)
1836 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1837 else
1838 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1839 immed &= (1 << extbits) - 1;
1840 if (! extu && immed >= (1 << (extbits - 1)))
1841 immed -= 1 << extbits;
1842 }
1843
1844 if (! pcrel)
fc8c4fd1 1845 infprintf (is, "%d", immed);
252b5132
RH
1846 else
1847 {
1848 bfd_vma baseaddr;
252b5132
RH
1849
1850 if (branch)
1851 {
1852 immed *= 2;
1853 baseaddr = memaddr + 2;
1854 }
1855 else if (use_extend)
1856 baseaddr = memaddr - 2;
1857 else
1858 {
1859 int status;
1860 bfd_byte buffer[2];
1861
1862 baseaddr = memaddr;
1863
1864 /* If this instruction is in the delay slot of a jr
1865 instruction, the base address is the address of the
1866 jr instruction. If it is in the delay slot of jalr
1867 instruction, the base address is the address of the
1868 jalr instruction. This test is unreliable: we have
1869 no way of knowing whether the previous word is
1870 instruction or data. */
1871 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1872 info);
1873 if (status == 0
1874 && (((info->endian == BFD_ENDIAN_BIG
1875 ? bfd_getb16 (buffer)
1876 : bfd_getl16 (buffer))
1877 & 0xf800) == 0x1800))
1878 baseaddr = memaddr - 4;
1879 else
1880 {
1881 status = (*info->read_memory_func) (memaddr - 2, buffer,
1882 2, info);
1883 if (status == 0
1884 && (((info->endian == BFD_ENDIAN_BIG
1885 ? bfd_getb16 (buffer)
1886 : bfd_getl16 (buffer))
1887 & 0xf81f) == 0xe800))
1888 baseaddr = memaddr - 2;
1889 }
1890 }
9bb28706 1891 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
022fac6d
TS
1892 if (pcrel && branch
1893 && info->flavour == bfd_target_unknown_flavour)
1894 /* For gdb disassembler, maintain odd address. */
1895 info->target |= 1;
9bb28706 1896 (*info->print_address_func) (info->target, info);
252b5132
RH
1897 }
1898 }
1899 break;
1900
1901 case 'a':
022fac6d
TS
1902 {
1903 int jalx = l & 0x400;
1904
1905 if (! use_extend)
1906 extend = 0;
1907 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1908 if (!jalx && info->flavour == bfd_target_unknown_flavour)
1909 /* For gdb disassembler, maintain odd address. */
1910 l |= 1;
1911 }
9bb28706
CD
1912 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1913 (*info->print_address_func) (info->target, info);
252b5132
RH
1914 break;
1915
1916 case 'l':
1917 case 'L':
1918 {
1919 int need_comma, amask, smask;
1920
1921 need_comma = 0;
1922
fc8c4fd1 1923 l = GET_OP (l, IMM6);
252b5132
RH
1924
1925 amask = (l >> 3) & 7;
1926
1927 if (amask > 0 && amask < 5)
1928 {
fc8c4fd1 1929 infprintf (is, "%s", mips_gpr_names[4]);
252b5132 1930 if (amask > 1)
fc8c4fd1 1931 infprintf (is, "-%s", mips_gpr_names[amask + 3]);
252b5132
RH
1932 need_comma = 1;
1933 }
1934
1935 smask = (l >> 1) & 3;
1936 if (smask == 3)
1937 {
fc8c4fd1 1938 infprintf (is, "%s??", need_comma ? "," : "");
252b5132
RH
1939 need_comma = 1;
1940 }
1941 else if (smask > 0)
1942 {
fc8c4fd1 1943 infprintf (is, "%s%s", need_comma ? "," : "", mips_gpr_names[16]);
252b5132 1944 if (smask > 1)
fc8c4fd1 1945 infprintf (is, "-%s", mips_gpr_names[smask + 15]);
252b5132
RH
1946 need_comma = 1;
1947 }
1948
1949 if (l & 1)
1950 {
fc8c4fd1 1951 infprintf (is, "%s%s", need_comma ? "," : "", mips_gpr_names[31]);
252b5132
RH
1952 need_comma = 1;
1953 }
1954
1955 if (amask == 5 || amask == 6)
1956 {
fc8c4fd1 1957 infprintf (is, "%s$f0", need_comma ? "," : "");
252b5132 1958 if (amask == 6)
fc8c4fd1 1959 infprintf (is, "-$f1");
252b5132
RH
1960 }
1961 }
1962 break;
1963
0499d65b
TS
1964 case 'm':
1965 case 'M':
1966 /* MIPS16e save/restore. */
1967 {
1968 int need_comma = 0;
1969 int amask, args, statics;
1970 int nsreg, smask;
1971 int framesz;
1972 int i, j;
1973
1974 l = l & 0x7f;
1975 if (use_extend)
1976 l |= extend << 16;
1977
1978 amask = (l >> 16) & 0xf;
1979 if (amask == MIPS16_ALL_ARGS)
1980 {
1981 args = 4;
1982 statics = 0;
1983 }
1984 else if (amask == MIPS16_ALL_STATICS)
1985 {
1986 args = 0;
1987 statics = 4;
1988 }
1989 else
1990 {
1991 args = amask >> 2;
1992 statics = amask & 3;
1993 }
1994
1995 if (args > 0) {
fc8c4fd1 1996 infprintf (is, "%s", mips_gpr_names[4]);
0499d65b 1997 if (args > 1)
fc8c4fd1 1998 infprintf (is, "-%s", mips_gpr_names[4 + args - 1]);
0499d65b
TS
1999 need_comma = 1;
2000 }
2001
2002 framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
2003 if (framesz == 0 && !use_extend)
2004 framesz = 128;
2005
fc8c4fd1 2006 infprintf (is, "%s%d", need_comma ? "," : "", framesz);
0499d65b
TS
2007
2008 if (l & 0x40) /* $ra */
fc8c4fd1 2009 infprintf (is, ",%s", mips_gpr_names[31]);
0499d65b
TS
2010
2011 nsreg = (l >> 24) & 0x7;
2012 smask = 0;
2013 if (l & 0x20) /* $s0 */
2014 smask |= 1 << 0;
2015 if (l & 0x10) /* $s1 */
2016 smask |= 1 << 1;
2017 if (nsreg > 0) /* $s2-$s8 */
2018 smask |= ((1 << nsreg) - 1) << 2;
2019
2020 /* Find first set static reg bit. */
2021 for (i = 0; i < 9; i++)
2022 {
2023 if (smask & (1 << i))
2024 {
fc8c4fd1 2025 infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
0499d65b
TS
2026 /* Skip over string of set bits. */
2027 for (j = i; smask & (2 << j); j++)
2028 continue;
2029 if (j > i)
fc8c4fd1 2030 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
0499d65b
TS
2031 i = j + 1;
2032 }
2033 }
2034
2035 /* Statics $ax - $a3. */
2036 if (statics == 1)
fc8c4fd1 2037 infprintf (is, ",%s", mips_gpr_names[7]);
0499d65b 2038 else if (statics > 0)
fc8c4fd1
MR
2039 infprintf (is, ",%s-%s",
2040 mips_gpr_names[7 - statics + 1],
2041 mips_gpr_names[7]);
0499d65b
TS
2042 }
2043 break;
2044
252b5132 2045 default:
aa5f19f2 2046 /* xgettext:c-format */
fc8c4fd1
MR
2047 infprintf (is,
2048 _("# internal disassembler error, "
2049 "unrecognised modifier (%c)"),
2050 type);
252b5132
RH
2051 abort ();
2052 }
2053}
640c0ccd 2054
47b0e7ad
NC
2055/* Disassemble mips16 instructions. */
2056
2057static int
2058print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
2059{
fc8c4fd1 2060 const fprintf_ftype infprintf = info->fprintf_func;
47b0e7ad
NC
2061 int status;
2062 bfd_byte buffer[2];
2063 int length;
2064 int insn;
2065 bfd_boolean use_extend;
2066 int extend = 0;
2067 const struct mips_opcode *op, *opend;
fc8c4fd1 2068 void *is = info->stream;
47b0e7ad
NC
2069
2070 info->bytes_per_chunk = 2;
2071 info->display_endian = info->endian;
2072 info->insn_info_valid = 1;
2073 info->branch_delay_insns = 0;
2074 info->data_size = 0;
2075 info->insn_type = dis_nonbranch;
2076 info->target = 0;
2077 info->target2 = 0;
2078
2079 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2080 if (status != 0)
2081 {
2082 (*info->memory_error_func) (status, memaddr, info);
2083 return -1;
2084 }
2085
2086 length = 2;
2087
2088 if (info->endian == BFD_ENDIAN_BIG)
2089 insn = bfd_getb16 (buffer);
2090 else
2091 insn = bfd_getl16 (buffer);
2092
2093 /* Handle the extend opcode specially. */
2094 use_extend = FALSE;
2095 if ((insn & 0xf800) == 0xf000)
2096 {
2097 use_extend = TRUE;
2098 extend = insn & 0x7ff;
2099
2100 memaddr += 2;
2101
2102 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2103 if (status != 0)
2104 {
fc8c4fd1 2105 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
2106 (*info->memory_error_func) (status, memaddr, info);
2107 return -1;
2108 }
2109
2110 if (info->endian == BFD_ENDIAN_BIG)
2111 insn = bfd_getb16 (buffer);
2112 else
2113 insn = bfd_getl16 (buffer);
2114
2115 /* Check for an extend opcode followed by an extend opcode. */
2116 if ((insn & 0xf800) == 0xf000)
2117 {
fc8c4fd1 2118 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
2119 info->insn_type = dis_noninsn;
2120 return length;
2121 }
2122
2123 length += 2;
2124 }
2125
2126 /* FIXME: Should probably use a hash table on the major opcode here. */
2127
2128 opend = mips16_opcodes + bfd_mips16_num_opcodes;
2129 for (op = mips16_opcodes; op < opend; op++)
2130 {
2131 if (op->pinfo != INSN_MACRO
2132 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2133 && (insn & op->mask) == op->match)
2134 {
2135 const char *s;
2136
2137 if (strchr (op->args, 'a') != NULL)
2138 {
2139 if (use_extend)
2140 {
fc8c4fd1 2141 infprintf (is, "extend 0x%x", (unsigned int) extend);
47b0e7ad
NC
2142 info->insn_type = dis_noninsn;
2143 return length - 2;
2144 }
2145
2146 use_extend = FALSE;
2147
2148 memaddr += 2;
2149
2150 status = (*info->read_memory_func) (memaddr, buffer, 2,
2151 info);
2152 if (status == 0)
2153 {
2154 use_extend = TRUE;
2155 if (info->endian == BFD_ENDIAN_BIG)
2156 extend = bfd_getb16 (buffer);
2157 else
2158 extend = bfd_getl16 (buffer);
2159 length += 2;
2160 }
2161 }
2162
fc8c4fd1 2163 infprintf (is, "%s", op->name);
47b0e7ad 2164 if (op->args[0] != '\0')
fc8c4fd1 2165 infprintf (is, "\t");
47b0e7ad
NC
2166
2167 for (s = op->args; *s != '\0'; s++)
2168 {
2169 if (*s == ','
2170 && s[1] == 'w'
fc8c4fd1 2171 && GET_OP (insn, RX) == GET_OP (insn, RY))
47b0e7ad
NC
2172 {
2173 /* Skip the register and the comma. */
2174 ++s;
2175 continue;
2176 }
2177 if (*s == ','
2178 && s[1] == 'v'
fc8c4fd1 2179 && GET_OP (insn, RZ) == GET_OP (insn, RX))
47b0e7ad
NC
2180 {
2181 /* Skip the register and the comma. */
2182 ++s;
2183 continue;
2184 }
2185 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
2186 info);
2187 }
2188
9a2c7088 2189 /* Figure out branch instruction type and delay slot information. */
47b0e7ad 2190 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
9a2c7088
MR
2191 info->branch_delay_insns = 1;
2192 if ((op->pinfo & (INSN_UNCOND_BRANCH_DELAY
2193 | MIPS16_INSN_UNCOND_BRANCH)) != 0)
47b0e7ad 2194 {
9a2c7088
MR
2195 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2196 info->insn_type = dis_jsr;
2197 else
47b0e7ad
NC
2198 info->insn_type = dis_branch;
2199 }
9a2c7088
MR
2200 else if ((op->pinfo & MIPS16_INSN_COND_BRANCH) != 0)
2201 info->insn_type = dis_condbranch;
47b0e7ad
NC
2202
2203 return length;
2204 }
2205 }
fc8c4fd1
MR
2206#undef GET_OP_S
2207#undef GET_OP
47b0e7ad
NC
2208
2209 if (use_extend)
fc8c4fd1
MR
2210 infprintf (is, "0x%x", extend | 0xf000);
2211 infprintf (is, "0x%x", insn);
47b0e7ad
NC
2212 info->insn_type = dis_noninsn;
2213
2214 return length;
2215}
2216
df58fc94
RS
2217/* Disassemble microMIPS instructions. */
2218
2219static int
2220print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2221{
0c7533d3 2222 const fprintf_ftype infprintf = info->fprintf_func;
df58fc94
RS
2223 const struct mips_opcode *op, *opend;
2224 unsigned int lsb, msbd, msb;
2225 void *is = info->stream;
2226 unsigned int regno;
2227 bfd_byte buffer[2];
2228 int lastregno = 0;
2229 int higher;
2230 int length;
2231 int status;
2232 int delta;
2233 int immed;
2234 int insn;
2235
2236 lsb = 0;
2237
2238 info->bytes_per_chunk = 2;
2239 info->display_endian = info->endian;
2240 info->insn_info_valid = 1;
2241 info->branch_delay_insns = 0;
2242 info->data_size = 0;
2243 info->insn_type = dis_nonbranch;
2244 info->target = 0;
2245 info->target2 = 0;
2246
2247 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2248 if (status != 0)
2249 {
2250 (*info->memory_error_func) (status, memaddr, info);
2251 return -1;
2252 }
2253
2254 length = 2;
2255
2256 if (info->endian == BFD_ENDIAN_BIG)
2257 insn = bfd_getb16 (buffer);
2258 else
2259 insn = bfd_getl16 (buffer);
2260
2261 if ((insn & 0xfc00) == 0x7c00)
2262 {
2263 /* This is a 48-bit microMIPS instruction. */
2264 higher = insn;
2265
2266 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2267 if (status != 0)
2268 {
0c7533d3 2269 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2270 (*info->memory_error_func) (status, memaddr + 2, info);
2271 return -1;
2272 }
2273 if (info->endian == BFD_ENDIAN_BIG)
2274 insn = bfd_getb16 (buffer);
2275 else
2276 insn = bfd_getl16 (buffer);
2277 higher = (higher << 16) | insn;
2278
2279 status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
2280 if (status != 0)
2281 {
0c7533d3 2282 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2283 (*info->memory_error_func) (status, memaddr + 4, info);
2284 return -1;
2285 }
2286 if (info->endian == BFD_ENDIAN_BIG)
2287 insn = bfd_getb16 (buffer);
2288 else
2289 insn = bfd_getl16 (buffer);
0c7533d3 2290 infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
df58fc94
RS
2291
2292 info->insn_type = dis_noninsn;
2293 return 6;
2294 }
2295 else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2296 {
2297 /* This is a 32-bit microMIPS instruction. */
2298 higher = insn;
2299
2300 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2301 if (status != 0)
2302 {
0c7533d3 2303 infprintf (is, "micromips 0x%x", higher);
df58fc94
RS
2304 (*info->memory_error_func) (status, memaddr + 2, info);
2305 return -1;
2306 }
2307
2308 if (info->endian == BFD_ENDIAN_BIG)
2309 insn = bfd_getb16 (buffer);
2310 else
2311 insn = bfd_getl16 (buffer);
2312
2313 insn = insn | (higher << 16);
2314
2315 length += 2;
2316 }
2317
2318 /* FIXME: Should probably use a hash table on the major opcode here. */
2319
2320#define GET_OP(insn, field) \
2321 (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
fc8c4fd1
MR
2322#define GET_OP_S(insn, field) \
2323 ((GET_OP (insn, field) ^ ((MICROMIPSOP_MASK_##field >> 1) + 1)) \
2324 - ((MICROMIPSOP_MASK_##field >> 1) + 1))
df58fc94
RS
2325 opend = micromips_opcodes + bfd_micromips_num_opcodes;
2326 for (op = micromips_opcodes; op < opend; op++)
2327 {
2328 if (op->pinfo != INSN_MACRO
2329 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2330 && (insn & op->mask) == op->match
2331 && ((length == 2 && (op->mask & 0xffff0000) == 0)
2332 || (length == 4 && (op->mask & 0xffff0000) != 0)))
2333 {
2334 const char *s;
2335
0c7533d3 2336 infprintf (is, "%s", op->name);
df58fc94 2337 if (op->args[0] != '\0')
0c7533d3 2338 infprintf (is, "\t");
df58fc94
RS
2339
2340 for (s = op->args; *s != '\0'; s++)
2341 {
2342 switch (*s)
2343 {
2344 case ',':
2345 case '(':
2346 case ')':
0c7533d3 2347 infprintf (is, "%c", *s);
df58fc94
RS
2348 break;
2349
2350 case '.':
fc8c4fd1 2351 infprintf (is, "%d", GET_OP_S (insn, OFFSET10));
df58fc94
RS
2352 break;
2353
2354 case '1':
d908c8af 2355 infprintf (is, "0x%x", GET_OP (insn, STYPE));
df58fc94
RS
2356 break;
2357
03f66e8a 2358 case '2':
48891606 2359 infprintf (is, "0x%x", GET_OP (insn, BP));
03f66e8a
MR
2360 break;
2361
2362 case '3':
48891606 2363 infprintf (is, "0x%x", GET_OP (insn, SA3));
03f66e8a
MR
2364 break;
2365
2366 case '4':
48891606 2367 infprintf (is, "0x%x", GET_OP (insn, SA4));
03f66e8a
MR
2368 break;
2369
2370 case '5':
48891606 2371 infprintf (is, "0x%x", GET_OP (insn, IMM8));
03f66e8a
MR
2372 break;
2373
2374 case '6':
48891606 2375 infprintf (is, "0x%x", GET_OP (insn, RS));
03f66e8a
MR
2376 break;
2377
2378 case '7':
48891606 2379 infprintf (is, "$ac%d", GET_OP (insn, DSPACC));
03f66e8a
MR
2380 break;
2381
2382 case '8':
48891606 2383 infprintf (is, "0x%x", GET_OP (insn, WRDSP));
03f66e8a
MR
2384 break;
2385
2386 case '0': /* DSP 6-bit signed immediate in bit 16. */
2387 delta = (GET_OP (insn, DSPSFT) ^ 0x20) - 0x20;
2388 infprintf (is, "%d", delta);
2389 break;
2390
df58fc94 2391 case '<':
d908c8af 2392 infprintf (is, "0x%x", GET_OP (insn, SHAMT));
df58fc94
RS
2393 break;
2394
dec0624d 2395 case '\\':
d908c8af 2396 infprintf (is, "0x%x", GET_OP (insn, 3BITPOS));
dec0624d
MR
2397 break;
2398
03f66e8a 2399 case '^':
48891606 2400 infprintf (is, "0x%x", GET_OP (insn, RD));
03f66e8a
MR
2401 break;
2402
df58fc94 2403 case '|':
d908c8af 2404 infprintf (is, "0x%x", GET_OP (insn, TRAP));
df58fc94
RS
2405 break;
2406
2407 case '~':
fc8c4fd1 2408 infprintf (is, "%d", GET_OP_S (insn, OFFSET12));
df58fc94
RS
2409 break;
2410
2411 case 'a':
2412 if (strcmp (op->name, "jalx") == 0)
2413 info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff)
2414 | (GET_OP (insn, TARGET) << 2));
2415 else
2416 info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff)
fc8c4fd1 2417 | (GET_OP (insn, TARGET) << 1));
df58fc94
RS
2418 /* For gdb disassembler, force odd address on jalx. */
2419 if (info->flavour == bfd_target_unknown_flavour
2420 && strcmp (op->name, "jalx") == 0)
2421 info->target |= 1;
2422 (*info->print_address_func) (info->target, info);
2423 break;
2424
2425 case 'b':
2426 case 'r':
2427 case 's':
2428 case 'v':
0c7533d3 2429 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]);
df58fc94
RS
2430 break;
2431
2432 case 'c':
d908c8af 2433 infprintf (is, "0x%x", GET_OP (insn, CODE));
df58fc94
RS
2434 break;
2435
2436 case 'd':
0c7533d3 2437 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]);
df58fc94
RS
2438 break;
2439
2440 case 'h':
d908c8af 2441 infprintf (is, "0x%x", GET_OP (insn, PREFX));
df58fc94
RS
2442 break;
2443
2444 case 'i':
2445 case 'u':
d908c8af 2446 infprintf (is, "0x%x", GET_OP (insn, IMMEDIATE));
df58fc94
RS
2447 break;
2448
2449 case 'j': /* Same as i, but sign-extended. */
2450 case 'o':
fc8c4fd1 2451 infprintf (is, "%d", GET_OP_S (insn, DELTA));
df58fc94
RS
2452 break;
2453
2454 case 'k':
0c7533d3 2455 infprintf (is, "0x%x", GET_OP (insn, CACHE));
df58fc94
RS
2456 break;
2457
2458 case 'n':
2459 {
2460 int s_reg_encode;
2461
2462 immed = GET_OP (insn, RT);
2463 s_reg_encode = immed & 0xf;
2464 if (s_reg_encode != 0)
2465 {
2466 if (s_reg_encode == 1)
0c7533d3 2467 infprintf (is, "%s", mips_gpr_names[16]);
df58fc94 2468 else if (s_reg_encode < 9)
0c7533d3 2469 infprintf (is, "%s-%s",
df58fc94
RS
2470 mips_gpr_names[16],
2471 mips_gpr_names[15 + s_reg_encode]);
2472 else if (s_reg_encode == 9)
0c7533d3 2473 infprintf (is, "%s-%s,%s",
df58fc94
RS
2474 mips_gpr_names[16],
2475 mips_gpr_names[23],
2476 mips_gpr_names[30]);
2477 else
0c7533d3 2478 infprintf (is, "UNKNOWN");
df58fc94
RS
2479 }
2480
2481 if (immed & 0x10) /* For ra. */
2482 {
2483 if (s_reg_encode == 0)
0c7533d3 2484 infprintf (is, "%s", mips_gpr_names[31]);
df58fc94 2485 else
0c7533d3 2486 infprintf (is, ",%s", mips_gpr_names[31]);
df58fc94
RS
2487 }
2488 break;
2489 }
2490
2491 case 'p':
2492 /* Sign-extend the displacement. */
fc8c4fd1 2493 delta = GET_OP_S (insn, DELTA);
df58fc94
RS
2494 info->target = (delta << 1) + memaddr + length;
2495 (*info->print_address_func) (info->target, info);
2496 break;
2497
2498 case 'q':
d908c8af 2499 infprintf (is, "0x%x", GET_OP (insn, CODE2));
df58fc94
RS
2500 break;
2501
2502 case 't':
2503 case 'w':
0c7533d3 2504 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]);
df58fc94
RS
2505 break;
2506
2507 case 'y':
0c7533d3 2508 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]);
df58fc94
RS
2509 break;
2510
2511 case 'z':
0c7533d3 2512 infprintf (is, "%s", mips_gpr_names[0]);
df58fc94
RS
2513 break;
2514
03f66e8a
MR
2515 case '@': /* DSP 10-bit signed immediate in bit 16. */
2516 delta = (GET_OP (insn, IMM10) ^ 0x200) - 0x200;
2517 infprintf (is, "%d", delta);
2518 break;
2519
df58fc94 2520 case 'B':
d908c8af 2521 infprintf (is, "0x%x", GET_OP (insn, CODE10));
df58fc94
RS
2522 break;
2523
2524 case 'C':
d908c8af 2525 infprintf (is, "0x%x", GET_OP (insn, COPZ));
df58fc94
RS
2526 break;
2527
2528 case 'D':
0c7533d3 2529 infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]);
df58fc94
RS
2530 break;
2531
2532 case 'E':
2533 /* Coprocessor register for lwcN instructions, et al.
2534
2535 Note that there is no load/store cp0 instructions, and
2536 that FPU (cp1) instructions disassemble this field using
2537 'T' format. Therefore, until we gain understanding of
2538 cp2 register names, we can simply print the register
2539 numbers. */
d908c8af 2540 infprintf (is, "$%d", GET_OP (insn, RT));
df58fc94
RS
2541 break;
2542
2543 case 'G':
2544 /* Coprocessor register for mtcN instructions, et al. Note
2545 that FPU (cp1) instructions disassemble this field using
2546 'S' format. Therefore, we only need to worry about cp0,
2547 cp2, and cp3.
2548 The microMIPS encoding does not have a coprocessor
2549 identifier field as such, so we must work out the
2550 coprocessor number by looking at the opcode. */
2551 switch (insn
2552 & ~((MICROMIPSOP_MASK_RT << MICROMIPSOP_SH_RT)
2553 | (MICROMIPSOP_MASK_RS << MICROMIPSOP_SH_RS)))
2554 {
2555 case 0x000000fc: /* mfc0 */
2556 case 0x000002fc: /* mtc0 */
ba92f7fb
CF
2557 case 0x000004fc: /* mfgc0 */
2558 case 0x000006fc: /* mtgc0 */
df58fc94
RS
2559 case 0x580000fc: /* dmfc0 */
2560 case 0x580002fc: /* dmtc0 */
ba92f7fb
CF
2561 case 0x580000e7: /* dmfgc0 */
2562 case 0x580002e7: /* dmtgc0 */
0c7533d3 2563 infprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]);
df58fc94
RS
2564 break;
2565 default:
d908c8af 2566 infprintf (is, "$%d", GET_OP (insn, RS));
df58fc94
RS
2567 break;
2568 }
2569 break;
2570
2571 case 'H':
d908c8af 2572 infprintf (is, "%d", GET_OP (insn, SEL));
df58fc94
RS
2573 break;
2574
2575 case 'K':
0c7533d3 2576 infprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]);
df58fc94
RS
2577 break;
2578
2579 case 'M':
d908c8af 2580 infprintf (is, "$fcc%d", GET_OP (insn, CCC));
df58fc94
RS
2581 break;
2582
2583 case 'N':
0c7533d3 2584 infprintf (is,
df58fc94 2585 (op->pinfo & (FP_D | FP_S)) != 0
d908c8af 2586 ? "$fcc%d" : "$cc%d",
df58fc94
RS
2587 GET_OP (insn, BCC));
2588 break;
2589
2590 case 'R':
0c7533d3 2591 infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]);
df58fc94
RS
2592 break;
2593
2594 case 'S':
2595 case 'V':
0c7533d3 2596 infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]);
df58fc94
RS
2597 break;
2598
2599 case 'T':
0c7533d3 2600 infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]);
df58fc94
RS
2601 break;
2602
2603 case '+':
2604 /* Extension character; switch for second char. */
2605 s++;
2606 switch (*s)
2607 {
2608 case 'A':
2609 lsb = GET_OP (insn, EXTLSB);
0c7533d3 2610 infprintf (is, "0x%x", lsb);
df58fc94
RS
2611 break;
2612
2613 case 'B':
2614 msb = GET_OP (insn, INSMSB);
0c7533d3 2615 infprintf (is, "0x%x", msb - lsb + 1);
df58fc94
RS
2616 break;
2617
2618 case 'C':
2619 case 'H':
2620 msbd = GET_OP (insn, EXTMSBD);
0c7533d3 2621 infprintf (is, "0x%x", msbd + 1);
df58fc94
RS
2622 break;
2623
2624 case 'D':
2625 {
2626 const struct mips_cp0sel_name *n;
2627 unsigned int cp0reg, sel;
2628
2629 cp0reg = GET_OP (insn, RS);
2630 sel = GET_OP (insn, SEL);
2631
2632 /* CP0 register including 'sel' code for mtcN
2633 (et al.), to be printed textually if known.
2634 If not known, print both CP0 register name and
2635 sel numerically since CP0 register with sel 0 may
2636 have a name unrelated to register being printed. */
2637 n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2638 mips_cp0sel_names_len,
2639 cp0reg, sel);
2640 if (n != NULL)
0c7533d3 2641 infprintf (is, "%s", n->name);
df58fc94 2642 else
0c7533d3 2643 infprintf (is, "$%d,%d", cp0reg, sel);
df58fc94
RS
2644 break;
2645 }
2646
2647 case 'E':
2648 lsb = GET_OP (insn, EXTLSB) + 32;
0c7533d3 2649 infprintf (is, "0x%x", lsb);
df58fc94
RS
2650 break;
2651
2652 case 'F':
2653 msb = GET_OP (insn, INSMSB) + 32;
0c7533d3 2654 infprintf (is, "0x%x", msb - lsb + 1);
df58fc94
RS
2655 break;
2656
2657 case 'G':
2658 msbd = GET_OP (insn, EXTMSBD) + 32;
0c7533d3 2659 infprintf (is, "0x%x", msbd + 1);
df58fc94
RS
2660 break;
2661
2662 default:
2663 /* xgettext:c-format */
0c7533d3 2664 infprintf (is,
df58fc94
RS
2665 _("# internal disassembler error, "
2666 "unrecognized modifier (+%c)"),
2667 *s);
2668 abort ();
2669 }
2670 break;
2671
2672 case 'm':
2673 /* Extension character; switch for second char. */
2674 s++;
2675 switch (*s)
2676 {
2677 case 'a': /* global pointer. */
0c7533d3 2678 infprintf (is, "%s", mips_gpr_names[28]);
df58fc94
RS
2679 break;
2680
2681 case 'b':
2682 regno = micromips_to_32_reg_b_map[GET_OP (insn, MB)];
0c7533d3 2683 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2684 break;
2685
2686 case 'c':
2687 regno = micromips_to_32_reg_c_map[GET_OP (insn, MC)];
0c7533d3 2688 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2689 break;
2690
2691 case 'd':
2692 regno = micromips_to_32_reg_d_map[GET_OP (insn, MD)];
0c7533d3 2693 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2694 break;
2695
2696 case 'e':
2697 regno = micromips_to_32_reg_e_map[GET_OP (insn, ME)];
0c7533d3 2698 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2699 break;
2700
2701 case 'f':
2702 /* Save lastregno for "mt" to print out later. */
2703 lastregno = micromips_to_32_reg_f_map[GET_OP (insn, MF)];
0c7533d3 2704 infprintf (is, "%s", mips_gpr_names[lastregno]);
df58fc94
RS
2705 break;
2706
2707 case 'g':
2708 regno = micromips_to_32_reg_g_map[GET_OP (insn, MG)];
0c7533d3 2709 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2710 break;
2711
2712 case 'h':
2713 regno = micromips_to_32_reg_h_map[GET_OP (insn, MH)];
0c7533d3 2714 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2715 break;
2716
2717 case 'i':
2718 regno = micromips_to_32_reg_i_map[GET_OP (insn, MI)];
0c7533d3 2719 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2720 break;
2721
2722 case 'j':
0c7533d3 2723 infprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]);
df58fc94
RS
2724 break;
2725
2726 case 'l':
2727 regno = micromips_to_32_reg_l_map[GET_OP (insn, ML)];
0c7533d3 2728 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2729 break;
2730
2731 case 'm':
2732 regno = micromips_to_32_reg_m_map[GET_OP (insn, MM)];
0c7533d3 2733 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2734 break;
2735
2736 case 'n':
2737 regno = micromips_to_32_reg_n_map[GET_OP (insn, MN)];
0c7533d3 2738 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2739 break;
2740
2741 case 'p':
2742 /* Save lastregno for "mt" to print out later. */
2743 lastregno = GET_OP (insn, MP);
0c7533d3 2744 infprintf (is, "%s", mips_gpr_names[lastregno]);
df58fc94
RS
2745 break;
2746
2747 case 'q':
2748 regno = micromips_to_32_reg_q_map[GET_OP (insn, MQ)];
0c7533d3 2749 infprintf (is, "%s", mips_gpr_names[regno]);
df58fc94
RS
2750 break;
2751
2752 case 'r': /* program counter. */
0c7533d3 2753 infprintf (is, "$pc");
df58fc94
RS
2754 break;
2755
2756 case 's': /* stack pointer. */
2757 lastregno = 29;
0c7533d3 2758 infprintf (is, "%s", mips_gpr_names[29]);
df58fc94
RS
2759 break;
2760
2761 case 't':
0c7533d3 2762 infprintf (is, "%s", mips_gpr_names[lastregno]);
df58fc94
RS
2763 break;
2764
2765 case 'z': /* $0. */
0c7533d3 2766 infprintf (is, "%s", mips_gpr_names[0]);
df58fc94
RS
2767 break;
2768
2769 case 'A':
2770 /* Sign-extend the immediate. */
fc8c4fd1 2771 immed = GET_OP_S (insn, IMMA) << 2;
0c7533d3 2772 infprintf (is, "%d", immed);
df58fc94
RS
2773 break;
2774
2775 case 'B':
2776 immed = micromips_imm_b_map[GET_OP (insn, IMMB)];
0c7533d3 2777 infprintf (is, "%d", immed);
df58fc94
RS
2778 break;
2779
2780 case 'C':
2781 immed = micromips_imm_c_map[GET_OP (insn, IMMC)];
d908c8af 2782 infprintf (is, "0x%x", immed);
df58fc94
RS
2783 break;
2784
2785 case 'D':
2786 /* Sign-extend the displacement. */
fc8c4fd1 2787 delta = GET_OP_S (insn, IMMD);
df58fc94
RS
2788 info->target = (delta << 1) + memaddr + length;
2789 (*info->print_address_func) (info->target, info);
2790 break;
2791
2792 case 'E':
2793 /* Sign-extend the displacement. */
fc8c4fd1 2794 delta = GET_OP_S (insn, IMME);
df58fc94
RS
2795 info->target = (delta << 1) + memaddr + length;
2796 (*info->print_address_func) (info->target, info);
2797 break;
2798
2799 case 'F':
2800 immed = GET_OP (insn, IMMF);
0c7533d3 2801 infprintf (is, "0x%x", immed);
df58fc94
RS
2802 break;
2803
2804 case 'G':
2805 immed = (insn >> MICROMIPSOP_SH_IMMG) + 1;
2806 immed = (immed & MICROMIPSOP_MASK_IMMG) - 1;
0c7533d3 2807 infprintf (is, "%d", immed);
df58fc94
RS
2808 break;
2809
2810 case 'H':
2811 immed = GET_OP (insn, IMMH) << 1;
0c7533d3 2812 infprintf (is, "%d", immed);
df58fc94
RS
2813 break;
2814
2815 case 'I':
2816 immed = (insn >> MICROMIPSOP_SH_IMMI) + 1;
2817 immed = (immed & MICROMIPSOP_MASK_IMMI) - 1;
0c7533d3 2818 infprintf (is, "%d", immed);
df58fc94
RS
2819 break;
2820
2821 case 'J':
2822 immed = GET_OP (insn, IMMJ) << 2;
0c7533d3 2823 infprintf (is, "%d", immed);
df58fc94
RS
2824 break;
2825
2826 case 'L':
2827 immed = GET_OP (insn, IMML);
0c7533d3 2828 infprintf (is, "%d", immed);
df58fc94
RS
2829 break;
2830
2831 case 'M':
2832 immed = (insn >> MICROMIPSOP_SH_IMMM) - 1;
2833 immed = (immed & MICROMIPSOP_MASK_IMMM) + 1;
0c7533d3 2834 infprintf (is, "%d", immed);
df58fc94
RS
2835 break;
2836
2837 case 'N':
2838 immed = GET_OP (insn, IMMN);
2839 if (immed == 0)
0c7533d3 2840 infprintf (is, "%s,%s",
df58fc94
RS
2841 mips_gpr_names[16],
2842 mips_gpr_names[31]);
2843 else
0c7533d3 2844 infprintf (is, "%s-%s,%s",
df58fc94
RS
2845 mips_gpr_names[16],
2846 mips_gpr_names[16 + immed],
2847 mips_gpr_names[31]);
2848 break;
2849
2850 case 'O':
2851 immed = GET_OP (insn, IMMO);
0c7533d3 2852 infprintf (is, "0x%x", immed);
df58fc94
RS
2853 break;
2854
2855 case 'P':
2856 immed = GET_OP (insn, IMMP) << 2;
0c7533d3 2857 infprintf (is, "%d", immed);
df58fc94
RS
2858 break;
2859
2860 case 'Q':
2861 /* Sign-extend the immediate. */
fc8c4fd1 2862 immed = GET_OP_S (insn, IMMQ) << 2;
0c7533d3 2863 infprintf (is, "%d", immed);
df58fc94
RS
2864 break;
2865
2866 case 'U':
2867 immed = GET_OP (insn, IMMU) << 2;
0c7533d3 2868 infprintf (is, "%d", immed);
df58fc94
RS
2869 break;
2870
2871 case 'W':
2872 immed = GET_OP (insn, IMMW) << 2;
0c7533d3 2873 infprintf (is, "%d", immed);
df58fc94
RS
2874 break;
2875
2876 case 'X':
2877 /* Sign-extend the immediate. */
fc8c4fd1 2878 immed = GET_OP_S (insn, IMMX);
0c7533d3 2879 infprintf (is, "%d", immed);
df58fc94
RS
2880 break;
2881
2882 case 'Y':
2883 /* Sign-extend the immediate. */
fc8c4fd1
MR
2884 immed = GET_OP_S (insn, IMMY) << 2;
2885 if ((unsigned int) (immed + 8) < 16)
2886 immed ^= 0x400;
0c7533d3 2887 infprintf (is, "%d", immed);
df58fc94
RS
2888 break;
2889
2890 default:
2891 /* xgettext:c-format */
0c7533d3 2892 infprintf (is,
df58fc94
RS
2893 _("# internal disassembler error, "
2894 "unrecognized modifier (m%c)"),
2895 *s);
2896 abort ();
2897 }
2898 break;
2899
2900 default:
2901 /* xgettext:c-format */
0c7533d3 2902 infprintf (is,
df58fc94
RS
2903 _("# internal disassembler error, "
2904 "unrecognized modifier (%c)"),
2905 *s);
2906 abort ();
2907 }
2908 }
2909
2910 /* Figure out instruction type and branch delay information. */
2911 if ((op->pinfo
2912 & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2913 info->branch_delay_insns = 1;
2914 if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2915 | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2916 {
2917 if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_GPR_T)) != 0)
2918 info->insn_type = dis_jsr;
2919 else
2920 info->insn_type = dis_branch;
2921 }
2922 else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2923 | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2924 {
2925 if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2926 info->insn_type = dis_condjsr;
2927 else
2928 info->insn_type = dis_condbranch;
2929 }
2930 else if ((op->pinfo
2931 & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY_DELAY)) != 0)
2932 info->insn_type = dis_dref;
2933
2934 return length;
2935 }
2936 }
fc8c4fd1 2937#undef GET_OP_S
df58fc94
RS
2938#undef GET_OP
2939
0c7533d3 2940 infprintf (is, "0x%x", insn);
df58fc94
RS
2941 info->insn_type = dis_noninsn;
2942
2943 return length;
2944}
2945
2946/* Return 1 if a symbol associated with the location being disassembled
2947 indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2948 all the symbols at the address being considered assuming if at least
2949 one of them indicates code compression, then such code has been
2950 genuinely produced here (other symbols could have been derived from
2951 function symbols defined elsewhere or could define data). Otherwise,
2952 return 0. */
2953
2954static bfd_boolean
2955is_compressed_mode_p (struct disassemble_info *info)
2956{
2957 elf_symbol_type *symbol;
2958 int pos;
2959 int i;
2960
2961 for (i = 0; i < info->num_symbols; i++)
2962 {
2963 pos = info->symtab_pos + i;
2964
2965 if (bfd_asymbol_flavour (info->symtab[pos]) != bfd_target_elf_flavour)
2966 continue;
2967
5417f71e
MR
2968 if (info->symtab[pos]->section != info->section)
2969 continue;
2970
df58fc94
RS
2971 symbol = (elf_symbol_type *) info->symtab[pos];
2972 if ((!micromips_ase
2973 && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2974 || (micromips_ase
2975 && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2976 return 1;
2977 }
2978
2979 return 0;
2980}
2981
47b0e7ad
NC
2982/* In an environment where we do not know the symbol type of the
2983 instruction we are forced to assume that the low order bit of the
2984 instructions' address may mark it as a mips16 instruction. If we
2985 are single stepping, or the pc is within the disassembled function,
2986 this works. Otherwise, we need a clue. Sometimes. */
2987
2988static int
2989_print_insn_mips (bfd_vma memaddr,
2990 struct disassemble_info *info,
2991 enum bfd_endian endianness)
2992{
df58fc94 2993 int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
47b0e7ad
NC
2994 bfd_byte buffer[INSNLEN];
2995 int status;
2996
2997 set_default_mips_dis_options (info);
2998 parse_mips_dis_options (info->disassembler_options);
2999
df58fc94
RS
3000 if (info->mach == bfd_mach_mips16)
3001 return print_insn_mips16 (memaddr, info);
3002 if (info->mach == bfd_mach_mips_micromips)
3003 return print_insn_micromips (memaddr, info);
3004
3005 print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
3006
47b0e7ad 3007#if 1
df58fc94 3008 /* FIXME: If odd address, this is CLEARLY a compressed instruction. */
47b0e7ad
NC
3009 /* Only a few tools will work this way. */
3010 if (memaddr & 0x01)
df58fc94 3011 return print_insn_compr (memaddr, info);
47b0e7ad
NC
3012#endif
3013
3014#if SYMTAB_AVAILABLE
df58fc94
RS
3015 if (is_compressed_mode_p (info))
3016 return print_insn_compr (memaddr, info);
47b0e7ad
NC
3017#endif
3018
3019 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
3020 if (status == 0)
3021 {
fc8c4fd1 3022 int insn;
47b0e7ad
NC
3023
3024 if (endianness == BFD_ENDIAN_BIG)
fc8c4fd1 3025 insn = bfd_getb32 (buffer);
47b0e7ad 3026 else
fc8c4fd1 3027 insn = bfd_getl32 (buffer);
47b0e7ad
NC
3028
3029 return print_insn_mips (memaddr, insn, info);
3030 }
3031 else
3032 {
3033 (*info->memory_error_func) (status, memaddr, info);
3034 return -1;
3035 }
3036}
3037
3038int
3039print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
3040{
3041 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
3042}
3043
3044int
3045print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
3046{
3047 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
3048}
3049\f
640c0ccd 3050void
47b0e7ad 3051print_mips_disassembler_options (FILE *stream)
640c0ccd 3052{
4a9a3c54 3053 unsigned int i;
640c0ccd
CD
3054
3055 fprintf (stream, _("\n\
3056The following MIPS specific disassembler options are supported for use\n\
3057with the -M switch (multiple options should be separated by commas):\n"));
3058
b015e599
AP
3059 fprintf (stream, _("\n\
3060 virt Recognize the virtualization ASE instructions.\n"));
3061
640c0ccd
CD
3062 fprintf (stream, _("\n\
3063 gpr-names=ABI Print GPR names according to specified ABI.\n\
3064 Default: based on binary being disassembled.\n"));
3065
3066 fprintf (stream, _("\n\
3067 fpr-names=ABI Print FPR names according to specified ABI.\n\
3068 Default: numeric.\n"));
3069
3070 fprintf (stream, _("\n\
3071 cp0-names=ARCH Print CP0 register names according to\n\
3072 specified architecture.\n\
3073 Default: based on binary being disassembled.\n"));
3074
af7ee8bf
CD
3075 fprintf (stream, _("\n\
3076 hwr-names=ARCH Print HWR names according to specified \n\
3077 architecture.\n\
3078 Default: based on binary being disassembled.\n"));
3079
640c0ccd
CD
3080 fprintf (stream, _("\n\
3081 reg-names=ABI Print GPR and FPR names according to\n\
3082 specified ABI.\n"));
3083
3084 fprintf (stream, _("\n\
af7ee8bf 3085 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
3086 specified architecture.\n"));
3087
3088 fprintf (stream, _("\n\
3089 For the options above, the following values are supported for \"ABI\":\n\
3090 "));
4a9a3c54 3091 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
3092 fprintf (stream, " %s", mips_abi_choices[i].name);
3093 fprintf (stream, _("\n"));
3094
3095 fprintf (stream, _("\n\
3096 For the options above, The following values are supported for \"ARCH\":\n\
3097 "));
4a9a3c54 3098 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
3099 if (*mips_arch_choices[i].name != '\0')
3100 fprintf (stream, " %s", mips_arch_choices[i].name);
3101 fprintf (stream, _("\n"));
3102
3103 fprintf (stream, _("\n"));
3104}
This page took 0.875252 seconds and 4 git commands to generate.