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