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