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