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