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