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