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