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