* mips.h: Update copyright.
[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,
9b201bb5 3 2000, 2001, 2002, 2003, 2005, 2007
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
654c225a
TS
60#define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]]
61
62
47b0e7ad
NC
63static const char * const mips_gpr_names_numeric[32] =
64{
640c0ccd
CD
65 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
66 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
67 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
68 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
aa5f19f2
NC
69};
70
47b0e7ad
NC
71static const char * const mips_gpr_names_oldabi[32] =
72{
640c0ccd
CD
73 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
74 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
75 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
76 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
aa5f19f2
NC
77};
78
47b0e7ad
NC
79static const char * const mips_gpr_names_newabi[32] =
80{
640c0ccd 81 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
0b14f26e 82 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
640c0ccd
CD
83 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
84 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
85};
86
47b0e7ad
NC
87static const char * const mips_fpr_names_numeric[32] =
88{
640c0ccd
CD
89 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
90 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
91 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
92 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
93};
94
47b0e7ad
NC
95static const char * const mips_fpr_names_32[32] =
96{
640c0ccd
CD
97 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
98 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
99 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
100 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
101};
102
47b0e7ad
NC
103static const char * const mips_fpr_names_n32[32] =
104{
640c0ccd
CD
105 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
106 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
107 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
108 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
109};
110
47b0e7ad
NC
111static const char * const mips_fpr_names_64[32] =
112{
640c0ccd
CD
113 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
114 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
115 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
116 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
117};
118
47b0e7ad
NC
119static const char * const mips_cp0_names_numeric[32] =
120{
640c0ccd
CD
121 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
122 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
123 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
124 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
125};
126
f409fd1e
MR
127static const char * const mips_cp0_names_r3000[32] =
128{
129 "c0_index", "c0_random", "c0_entrylo", "$3",
130 "c0_context", "$5", "$6", "$7",
131 "c0_badvaddr", "$9", "c0_entryhi", "$11",
132 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
133 "$16", "$17", "$18", "$19",
134 "$20", "$21", "$22", "$23",
135 "$24", "$25", "$26", "$27",
136 "$28", "$29", "$30", "$31",
137};
138
139static const char * const mips_cp0_names_r4000[32] =
140{
141 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
142 "c0_context", "c0_pagemask", "c0_wired", "$7",
143 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
144 "c0_sr", "c0_cause", "c0_epc", "c0_prid",
145 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
146 "c0_xcontext", "$21", "$22", "$23",
147 "$24", "$25", "c0_ecc", "c0_cacheerr",
148 "c0_taglo", "c0_taghi", "c0_errorepc", "$31",
149};
150
47b0e7ad
NC
151static const char * const mips_cp0_names_mips3264[32] =
152{
640c0ccd
CD
153 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
154 "c0_context", "c0_pagemask", "c0_wired", "$7",
155 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
156 "c0_status", "c0_cause", "c0_epc", "c0_prid",
157 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
158 "c0_xcontext", "$21", "$22", "c0_debug",
159 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
160 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
161};
162
47b0e7ad
NC
163static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
164{
bbcc0807
CD
165 { 16, 1, "c0_config1" },
166 { 16, 2, "c0_config2" },
167 { 16, 3, "c0_config3" },
168 { 18, 1, "c0_watchlo,1" },
169 { 18, 2, "c0_watchlo,2" },
170 { 18, 3, "c0_watchlo,3" },
171 { 18, 4, "c0_watchlo,4" },
172 { 18, 5, "c0_watchlo,5" },
173 { 18, 6, "c0_watchlo,6" },
174 { 18, 7, "c0_watchlo,7" },
175 { 19, 1, "c0_watchhi,1" },
176 { 19, 2, "c0_watchhi,2" },
177 { 19, 3, "c0_watchhi,3" },
178 { 19, 4, "c0_watchhi,4" },
179 { 19, 5, "c0_watchhi,5" },
180 { 19, 6, "c0_watchhi,6" },
181 { 19, 7, "c0_watchhi,7" },
182 { 25, 1, "c0_perfcnt,1" },
183 { 25, 2, "c0_perfcnt,2" },
184 { 25, 3, "c0_perfcnt,3" },
185 { 25, 4, "c0_perfcnt,4" },
186 { 25, 5, "c0_perfcnt,5" },
187 { 25, 6, "c0_perfcnt,6" },
188 { 25, 7, "c0_perfcnt,7" },
189 { 27, 1, "c0_cacheerr,1" },
190 { 27, 2, "c0_cacheerr,2" },
191 { 27, 3, "c0_cacheerr,3" },
192 { 28, 1, "c0_datalo" },
193 { 29, 1, "c0_datahi" }
194};
195
47b0e7ad
NC
196static const char * const mips_cp0_names_mips3264r2[32] =
197{
af7ee8bf
CD
198 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
199 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
200 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
201 "c0_status", "c0_cause", "c0_epc", "c0_prid",
202 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
203 "c0_xcontext", "$21", "$22", "c0_debug",
204 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr",
205 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
206};
207
47b0e7ad
NC
208static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
209{
bbcc0807 210 { 4, 1, "c0_contextconfig" },
59c455b3
TS
211 { 0, 1, "c0_mvpcontrol" },
212 { 0, 2, "c0_mvpconf0" },
213 { 0, 3, "c0_mvpconf1" },
214 { 1, 1, "c0_vpecontrol" },
215 { 1, 2, "c0_vpeconf0" },
216 { 1, 3, "c0_vpeconf1" },
217 { 1, 4, "c0_yqmask" },
218 { 1, 5, "c0_vpeschedule" },
219 { 1, 6, "c0_vpeschefback" },
220 { 2, 1, "c0_tcstatus" },
221 { 2, 2, "c0_tcbind" },
222 { 2, 3, "c0_tcrestart" },
223 { 2, 4, "c0_tchalt" },
224 { 2, 5, "c0_tccontext" },
225 { 2, 6, "c0_tcschedule" },
226 { 2, 7, "c0_tcschefback" },
bbcc0807 227 { 5, 1, "c0_pagegrain" },
59c455b3
TS
228 { 6, 1, "c0_srsconf0" },
229 { 6, 2, "c0_srsconf1" },
230 { 6, 3, "c0_srsconf2" },
231 { 6, 4, "c0_srsconf3" },
232 { 6, 5, "c0_srsconf4" },
bbcc0807
CD
233 { 12, 1, "c0_intctl" },
234 { 12, 2, "c0_srsctl" },
235 { 12, 3, "c0_srsmap" },
236 { 15, 1, "c0_ebase" },
237 { 16, 1, "c0_config1" },
238 { 16, 2, "c0_config2" },
239 { 16, 3, "c0_config3" },
240 { 18, 1, "c0_watchlo,1" },
241 { 18, 2, "c0_watchlo,2" },
242 { 18, 3, "c0_watchlo,3" },
243 { 18, 4, "c0_watchlo,4" },
244 { 18, 5, "c0_watchlo,5" },
245 { 18, 6, "c0_watchlo,6" },
246 { 18, 7, "c0_watchlo,7" },
247 { 19, 1, "c0_watchhi,1" },
248 { 19, 2, "c0_watchhi,2" },
249 { 19, 3, "c0_watchhi,3" },
250 { 19, 4, "c0_watchhi,4" },
251 { 19, 5, "c0_watchhi,5" },
252 { 19, 6, "c0_watchhi,6" },
253 { 19, 7, "c0_watchhi,7" },
254 { 23, 1, "c0_tracecontrol" },
255 { 23, 2, "c0_tracecontrol2" },
256 { 23, 3, "c0_usertracedata" },
257 { 23, 4, "c0_tracebpc" },
258 { 25, 1, "c0_perfcnt,1" },
259 { 25, 2, "c0_perfcnt,2" },
260 { 25, 3, "c0_perfcnt,3" },
261 { 25, 4, "c0_perfcnt,4" },
262 { 25, 5, "c0_perfcnt,5" },
263 { 25, 6, "c0_perfcnt,6" },
264 { 25, 7, "c0_perfcnt,7" },
265 { 27, 1, "c0_cacheerr,1" },
266 { 27, 2, "c0_cacheerr,2" },
267 { 27, 3, "c0_cacheerr,3" },
268 { 28, 1, "c0_datalo" },
269 { 28, 2, "c0_taglo1" },
270 { 28, 3, "c0_datalo1" },
271 { 28, 4, "c0_taglo2" },
272 { 28, 5, "c0_datalo2" },
273 { 28, 6, "c0_taglo3" },
274 { 28, 7, "c0_datalo3" },
275 { 29, 1, "c0_datahi" },
276 { 29, 2, "c0_taghi1" },
277 { 29, 3, "c0_datahi1" },
278 { 29, 4, "c0_taghi2" },
279 { 29, 5, "c0_datahi2" },
280 { 29, 6, "c0_taghi3" },
281 { 29, 7, "c0_datahi3" },
282};
283
640c0ccd 284/* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
47b0e7ad
NC
285static const char * const mips_cp0_names_sb1[32] =
286{
640c0ccd
CD
287 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
288 "c0_context", "c0_pagemask", "c0_wired", "$7",
289 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
290 "c0_status", "c0_cause", "c0_epc", "c0_prid",
291 "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
292 "c0_xcontext", "$21", "$22", "c0_debug",
293 "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i",
294 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
295};
296
47b0e7ad
NC
297static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
298{
bbcc0807
CD
299 { 16, 1, "c0_config1" },
300 { 18, 1, "c0_watchlo,1" },
301 { 19, 1, "c0_watchhi,1" },
302 { 22, 0, "c0_perftrace" },
303 { 23, 3, "c0_edebug" },
304 { 25, 1, "c0_perfcnt,1" },
305 { 25, 2, "c0_perfcnt,2" },
306 { 25, 3, "c0_perfcnt,3" },
307 { 25, 4, "c0_perfcnt,4" },
308 { 25, 5, "c0_perfcnt,5" },
309 { 25, 6, "c0_perfcnt,6" },
310 { 25, 7, "c0_perfcnt,7" },
311 { 26, 1, "c0_buserr_pa" },
312 { 27, 1, "c0_cacheerr_d" },
313 { 27, 3, "c0_cacheerr_d_pa" },
314 { 28, 1, "c0_datalo_i" },
315 { 28, 2, "c0_taglo_d" },
316 { 28, 3, "c0_datalo_d" },
317 { 29, 1, "c0_datahi_i" },
318 { 29, 2, "c0_taghi_d" },
319 { 29, 3, "c0_datahi_d" },
320};
321
47b0e7ad
NC
322static const char * const mips_hwr_names_numeric[32] =
323{
af7ee8bf
CD
324 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
325 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
326 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
327 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
328};
329
47b0e7ad
NC
330static const char * const mips_hwr_names_mips3264r2[32] =
331{
af7ee8bf
CD
332 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
333 "$4", "$5", "$6", "$7",
334 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
335 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
336 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
337};
338
47b0e7ad
NC
339struct mips_abi_choice
340{
341 const char * name;
640c0ccd
CD
342 const char * const *gpr_names;
343 const char * const *fpr_names;
344};
345
47b0e7ad
NC
346struct mips_abi_choice mips_abi_choices[] =
347{
640c0ccd
CD
348 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
349 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
350 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
351 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
352};
353
47b0e7ad
NC
354struct mips_arch_choice
355{
640c0ccd
CD
356 const char *name;
357 int bfd_mach_valid;
358 unsigned long bfd_mach;
359 int processor;
360 int isa;
361 const char * const *cp0_names;
bbcc0807
CD
362 const struct mips_cp0sel_name *cp0sel_names;
363 unsigned int cp0sel_names_len;
af7ee8bf 364 const char * const *hwr_names;
640c0ccd
CD
365};
366
47b0e7ad
NC
367const struct mips_arch_choice mips_arch_choices[] =
368{
640c0ccd 369 { "numeric", 0, 0, 0, 0,
bbcc0807
CD
370 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
371
640c0ccd 372 { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1,
f409fd1e 373 mips_cp0_names_r3000, NULL, 0, mips_hwr_names_numeric },
640c0ccd 374 { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1,
bbcc0807 375 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 376 { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3,
f409fd1e 377 mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
640c0ccd 378 { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2,
bbcc0807 379 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 380 { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3,
bbcc0807 381 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 382 { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3,
bbcc0807 383 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 384 { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3,
bbcc0807 385 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 386 { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3,
bbcc0807 387 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 388 { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3,
f409fd1e 389 mips_cp0_names_r4000, NULL, 0, mips_hwr_names_numeric },
640c0ccd 390 { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3,
bbcc0807 391 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 392 { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3,
bbcc0807 393 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 394 { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4,
bbcc0807 395 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 396 { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4,
bbcc0807 397 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 398 { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4,
bbcc0807 399 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 400 { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2,
bbcc0807 401 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
5a7ea749
RS
402 { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
403 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
404 { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
405 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 406 { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4,
bbcc0807 407 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 408 { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4,
bbcc0807 409 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 410 { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4,
bbcc0807 411 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd 412 { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5,
bbcc0807
CD
413 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
414
640c0ccd
CD
415 /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
416 Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
417 _MIPS32 Architecture For Programmers Volume I: Introduction to the
418 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
419 page 1. */
420 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
39a7806d 421 ISA_MIPS32 | INSN_MIPS16 | INSN_SMARTMIPS,
bbcc0807
CD
422 mips_cp0_names_mips3264,
423 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
424 mips_hwr_names_numeric },
425
af7ee8bf 426 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
8b082fb1
TS
427 (ISA_MIPS32R2 | INSN_MIPS16 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
428 | INSN_MIPS3D | INSN_MT),
bbcc0807
CD
429 mips_cp0_names_mips3264r2,
430 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
431 mips_hwr_names_mips3264r2 },
432
640c0ccd
CD
433 /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
434 { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
39a7806d 435 ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX,
bbcc0807
CD
436 mips_cp0_names_mips3264,
437 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
438 mips_hwr_names_numeric },
439
5f74bc13 440 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
8b082fb1
TS
441 (ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
442 | INSN_DSP64 | INSN_MT | INSN_MDMX),
5f74bc13
CD
443 mips_cp0_names_mips3264r2,
444 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
445 mips_hwr_names_mips3264r2 },
446
640c0ccd
CD
447 { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
448 ISA_MIPS64 | INSN_MIPS3D | INSN_SB1,
bbcc0807
CD
449 mips_cp0_names_sb1,
450 mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
451 mips_hwr_names_numeric },
640c0ccd 452
350cc38d
MS
453 { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
454 ISA_MIPS3 | INSN_LOONGSON_2E, mips_cp0_names_numeric,
455 NULL, 0, mips_hwr_names_numeric },
456
457 { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
458 ISA_MIPS3 | INSN_LOONGSON_2F, mips_cp0_names_numeric,
459 NULL, 0, mips_hwr_names_numeric },
460
640c0ccd
CD
461 /* This entry, mips16, is here only for ISA/processor selection; do
462 not print its name. */
463 { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3 | INSN_MIPS16,
bbcc0807 464 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
640c0ccd
CD
465};
466
467/* ISA and processor type to disassemble for, and register names to use.
468 set_default_mips_dis_options and parse_mips_dis_options fill in these
469 values. */
470static int mips_processor;
471static int mips_isa;
472static const char * const *mips_gpr_names;
473static const char * const *mips_fpr_names;
474static const char * const *mips_cp0_names;
bbcc0807
CD
475static const struct mips_cp0sel_name *mips_cp0sel_names;
476static int mips_cp0sel_names_len;
af7ee8bf 477static const char * const *mips_hwr_names;
640c0ccd 478
986e18a5 479/* Other options */
47b0e7ad 480static int no_aliases; /* If set disassemble as most general inst. */
640c0ccd
CD
481\f
482static const struct mips_abi_choice *
47b0e7ad 483choose_abi_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
484{
485 const struct mips_abi_choice *c;
486 unsigned int i;
487
488 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
47b0e7ad
NC
489 if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
490 && strlen (mips_abi_choices[i].name) == namelen)
491 c = &mips_abi_choices[i];
492
640c0ccd
CD
493 return c;
494}
495
496static const struct mips_arch_choice *
47b0e7ad 497choose_arch_by_name (const char *name, unsigned int namelen)
640c0ccd
CD
498{
499 const struct mips_arch_choice *c = NULL;
500 unsigned int i;
501
502 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
47b0e7ad
NC
503 if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
504 && strlen (mips_arch_choices[i].name) == namelen)
505 c = &mips_arch_choices[i];
506
640c0ccd
CD
507 return c;
508}
509
510static const struct mips_arch_choice *
47b0e7ad 511choose_arch_by_number (unsigned long mach)
640c0ccd
CD
512{
513 static unsigned long hint_bfd_mach;
514 static const struct mips_arch_choice *hint_arch_choice;
515 const struct mips_arch_choice *c;
516 unsigned int i;
517
518 /* We optimize this because even if the user specifies no
519 flags, this will be done for every instruction! */
520 if (hint_bfd_mach == mach
521 && hint_arch_choice != NULL
522 && hint_arch_choice->bfd_mach == hint_bfd_mach)
523 return hint_arch_choice;
524
525 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
526 {
527 if (mips_arch_choices[i].bfd_mach_valid
528 && mips_arch_choices[i].bfd_mach == mach)
529 {
530 c = &mips_arch_choices[i];
531 hint_bfd_mach = mach;
532 hint_arch_choice = c;
533 }
534 }
535 return c;
536}
537
47b0e7ad
NC
538/* Check if the object uses NewABI conventions. */
539
540static int
541is_newabi (Elf_Internal_Ehdr *header)
542{
543 /* There are no old-style ABIs which use 64-bit ELF. */
544 if (header->e_ident[EI_CLASS] == ELFCLASS64)
545 return 1;
546
547 /* If a 32-bit ELF file, n32 is a new-style ABI. */
548 if ((header->e_flags & EF_MIPS_ABI2) != 0)
549 return 1;
550
551 return 0;
552}
553
554static void
555set_default_mips_dis_options (struct disassemble_info *info)
640c0ccd
CD
556{
557 const struct mips_arch_choice *chosen_arch;
558
559 /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names,
af7ee8bf 560 and numeric FPR, CP0 register, and HWR names. */
640c0ccd
CD
561 mips_isa = ISA_MIPS3;
562 mips_processor = CPU_R3000;
563 mips_gpr_names = mips_gpr_names_oldabi;
564 mips_fpr_names = mips_fpr_names_numeric;
565 mips_cp0_names = mips_cp0_names_numeric;
bbcc0807
CD
566 mips_cp0sel_names = NULL;
567 mips_cp0sel_names_len = 0;
af7ee8bf 568 mips_hwr_names = mips_hwr_names_numeric;
986e18a5 569 no_aliases = 0;
640c0ccd
CD
570
571 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
fec06546 572 if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
640c0ccd
CD
573 {
574 Elf_Internal_Ehdr *header;
575
fec06546 576 header = elf_elfheader (info->section->owner);
640c0ccd
CD
577 if (is_newabi (header))
578 mips_gpr_names = mips_gpr_names_newabi;
579 }
580
581 /* Set ISA, architecture, and cp0 register names as best we can. */
582#if ! SYMTAB_AVAILABLE
583 /* This is running out on a target machine, not in a host tool.
584 FIXME: Where does mips_target_info come from? */
585 target_processor = mips_target_info.processor;
586 mips_isa = mips_target_info.isa;
587#else
588 chosen_arch = choose_arch_by_number (info->mach);
589 if (chosen_arch != NULL)
590 {
591 mips_processor = chosen_arch->processor;
592 mips_isa = chosen_arch->isa;
bbcc0807
CD
593 mips_cp0_names = chosen_arch->cp0_names;
594 mips_cp0sel_names = chosen_arch->cp0sel_names;
595 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
596 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
597 }
598#endif
599}
600
47b0e7ad
NC
601static void
602parse_mips_dis_option (const char *option, unsigned int len)
640c0ccd
CD
603{
604 unsigned int i, optionlen, vallen;
605 const char *val;
606 const struct mips_abi_choice *chosen_abi;
607 const struct mips_arch_choice *chosen_arch;
608
986e18a5 609 /* Try to match options that are simple flags */
0112cd26 610 if (CONST_STRNEQ (option, "no-aliases"))
986e18a5
FF
611 {
612 no_aliases = 1;
613 return;
614 }
615
640c0ccd
CD
616 /* Look for the = that delimits the end of the option name. */
617 for (i = 0; i < len; i++)
47b0e7ad
NC
618 if (option[i] == '=')
619 break;
620
640c0ccd
CD
621 if (i == 0) /* Invalid option: no name before '='. */
622 return;
623 if (i == len) /* Invalid option: no '='. */
624 return;
625 if (i == (len - 1)) /* Invalid option: no value after '='. */
626 return;
627
628 optionlen = i;
629 val = option + (optionlen + 1);
630 vallen = len - (optionlen + 1);
631
47b0e7ad
NC
632 if (strncmp ("gpr-names", option, optionlen) == 0
633 && strlen ("gpr-names") == optionlen)
640c0ccd
CD
634 {
635 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 636 if (chosen_abi != NULL)
640c0ccd
CD
637 mips_gpr_names = chosen_abi->gpr_names;
638 return;
639 }
640
47b0e7ad
NC
641 if (strncmp ("fpr-names", option, optionlen) == 0
642 && strlen ("fpr-names") == optionlen)
640c0ccd
CD
643 {
644 chosen_abi = choose_abi_by_name (val, vallen);
bbcc0807 645 if (chosen_abi != NULL)
640c0ccd
CD
646 mips_fpr_names = chosen_abi->fpr_names;
647 return;
648 }
649
47b0e7ad
NC
650 if (strncmp ("cp0-names", option, optionlen) == 0
651 && strlen ("cp0-names") == optionlen)
640c0ccd
CD
652 {
653 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807
CD
654 if (chosen_arch != NULL)
655 {
656 mips_cp0_names = chosen_arch->cp0_names;
657 mips_cp0sel_names = chosen_arch->cp0sel_names;
658 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
659 }
640c0ccd
CD
660 return;
661 }
662
47b0e7ad
NC
663 if (strncmp ("hwr-names", option, optionlen) == 0
664 && strlen ("hwr-names") == optionlen)
af7ee8bf
CD
665 {
666 chosen_arch = choose_arch_by_name (val, vallen);
bbcc0807 667 if (chosen_arch != NULL)
af7ee8bf
CD
668 mips_hwr_names = chosen_arch->hwr_names;
669 return;
670 }
671
47b0e7ad
NC
672 if (strncmp ("reg-names", option, optionlen) == 0
673 && strlen ("reg-names") == optionlen)
640c0ccd
CD
674 {
675 /* We check both ABI and ARCH here unconditionally, so
676 that "numeric" will do the desirable thing: select
677 numeric register names for all registers. Other than
678 that, a given name probably won't match both. */
679 chosen_abi = choose_abi_by_name (val, vallen);
680 if (chosen_abi != NULL)
681 {
bbcc0807
CD
682 mips_gpr_names = chosen_abi->gpr_names;
683 mips_fpr_names = chosen_abi->fpr_names;
640c0ccd
CD
684 }
685 chosen_arch = choose_arch_by_name (val, vallen);
686 if (chosen_arch != NULL)
687 {
bbcc0807
CD
688 mips_cp0_names = chosen_arch->cp0_names;
689 mips_cp0sel_names = chosen_arch->cp0sel_names;
690 mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
691 mips_hwr_names = chosen_arch->hwr_names;
640c0ccd
CD
692 }
693 return;
694 }
695
696 /* Invalid option. */
697}
698
47b0e7ad
NC
699static void
700parse_mips_dis_options (const char *options)
640c0ccd
CD
701{
702 const char *option_end;
703
704 if (options == NULL)
705 return;
706
707 while (*options != '\0')
708 {
709 /* Skip empty options. */
710 if (*options == ',')
711 {
712 options++;
713 continue;
714 }
715
716 /* We know that *options is neither NUL or a comma. */
717 option_end = options + 1;
718 while (*option_end != ',' && *option_end != '\0')
719 option_end++;
720
721 parse_mips_dis_option (options, option_end - options);
722
723 /* Go on to the next one. If option_end points to a comma, it
724 will be skipped above. */
725 options = option_end;
726 }
727}
728
bbcc0807 729static const struct mips_cp0sel_name *
47b0e7ad
NC
730lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
731 unsigned int len,
732 unsigned int cp0reg,
733 unsigned int sel)
bbcc0807
CD
734{
735 unsigned int i;
736
737 for (i = 0; i < len; i++)
738 if (names[i].cp0reg == cp0reg && names[i].sel == sel)
739 return &names[i];
740 return NULL;
741}
252b5132 742\f
7f6621cd 743/* Print insn arguments for 32/64-bit code. */
aa5f19f2 744
794ac9d0 745static void
47b0e7ad
NC
746print_insn_args (const char *d,
747 register unsigned long int l,
748 bfd_vma pc,
cc0ca239
TS
749 struct disassemble_info *info,
750 const struct mips_opcode *opp)
252b5132 751{
794ac9d0 752 int op, delta;
440cc0bc
CD
753 unsigned int lsb, msb, msbd;
754
755 lsb = 0;
252b5132 756
794ac9d0 757 for (; *d != '\0'; d++)
252b5132 758 {
af7ee8bf
CD
759 switch (*d)
760 {
794ac9d0
CD
761 case ',':
762 case '(':
763 case ')':
764 case '[':
765 case ']':
766 (*info->fprintf_func) (info->stream, "%c", *d);
767 break;
768
769 case '+':
770 /* Extension character; switch for second char. */
771 d++;
772 switch (*d)
773 {
774 case '\0':
775 /* xgettext:c-format */
776 (*info->fprintf_func) (info->stream,
777 _("# internal error, incomplete extension sequence (+)"));
778 return;
779
780 case 'A':
440cc0bc
CD
781 lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT;
782 (*info->fprintf_func) (info->stream, "0x%x", lsb);
794ac9d0
CD
783 break;
784
785 case 'B':
440cc0bc
CD
786 msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB;
787 (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
794ac9d0
CD
788 break;
789
9bcd4f99
TS
790 case '1':
791 (*info->fprintf_func) (info->stream, "0x%lx",
792 (l >> OP_SH_UDI1) & OP_MASK_UDI1);
793 break;
794
795 case '2':
796 (*info->fprintf_func) (info->stream, "0x%lx",
797 (l >> OP_SH_UDI2) & OP_MASK_UDI2);
798 break;
799
800 case '3':
801 (*info->fprintf_func) (info->stream, "0x%lx",
802 (l >> OP_SH_UDI3) & OP_MASK_UDI3);
803 break;
804
805 case '4':
806 (*info->fprintf_func) (info->stream, "0x%lx",
807 (l >> OP_SH_UDI4) & OP_MASK_UDI4);
808 break;
809
794ac9d0 810 case 'C':
5f74bc13 811 case 'H':
440cc0bc
CD
812 msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
813 (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
794ac9d0
CD
814 break;
815
816 case 'D':
817 {
818 const struct mips_cp0sel_name *n;
819 unsigned int cp0reg, sel;
820
821 cp0reg = (l >> OP_SH_RD) & OP_MASK_RD;
822 sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
823
824 /* CP0 register including 'sel' code for mtcN (et al.), to be
825 printed textually if known. If not known, print both
826 CP0 register name and sel numerically since CP0 register
827 with sel 0 may have a name unrelated to register being
828 printed. */
829 n = lookup_mips_cp0sel_name(mips_cp0sel_names,
830 mips_cp0sel_names_len, cp0reg, sel);
831 if (n != NULL)
832 (*info->fprintf_func) (info->stream, "%s", n->name);
833 else
834 (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
835 break;
836 }
837
5f74bc13
CD
838 case 'E':
839 lsb = ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT) + 32;
840 (*info->fprintf_func) (info->stream, "0x%x", lsb);
841 break;
842
843 case 'F':
844 msb = ((l >> OP_SH_INSMSB) & OP_MASK_INSMSB) + 32;
845 (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
846 break;
847
848 case 'G':
849 msbd = ((l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD) + 32;
850 (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
851 break;
852
61cc0267
CF
853 case 't': /* Coprocessor 0 reg name */
854 (*info->fprintf_func) (info->stream, "%s",
855 mips_cp0_names[(l >> OP_SH_RT) &
856 OP_MASK_RT]);
857 break;
858
859 case 'T': /* Coprocessor 0 reg name */
860 {
861 const struct mips_cp0sel_name *n;
862 unsigned int cp0reg, sel;
863
864 cp0reg = (l >> OP_SH_RT) & OP_MASK_RT;
865 sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
866
867 /* CP0 register including 'sel' code for mftc0, to be
868 printed textually if known. If not known, print both
869 CP0 register name and sel numerically since CP0 register
870 with sel 0 may have a name unrelated to register being
871 printed. */
872 n = lookup_mips_cp0sel_name(mips_cp0sel_names,
873 mips_cp0sel_names_len, cp0reg, sel);
874 if (n != NULL)
875 (*info->fprintf_func) (info->stream, "%s", n->name);
876 else
877 (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
878 break;
879 }
880
794ac9d0
CD
881 default:
882 /* xgettext:c-format */
883 (*info->fprintf_func) (info->stream,
884 _("# internal error, undefined extension sequence (+%c)"),
885 *d);
886 return;
887 }
888 break;
889
8b082fb1
TS
890 case '2':
891 (*info->fprintf_func) (info->stream, "0x%lx",
892 (l >> OP_SH_BP) & OP_MASK_BP);
893 break;
894
fd25c5a9
CF
895 case '3':
896 (*info->fprintf_func) (info->stream, "0x%lx",
897 (l >> OP_SH_SA3) & OP_MASK_SA3);
898 break;
899
900 case '4':
901 (*info->fprintf_func) (info->stream, "0x%lx",
902 (l >> OP_SH_SA4) & OP_MASK_SA4);
903 break;
904
905 case '5':
906 (*info->fprintf_func) (info->stream, "0x%lx",
907 (l >> OP_SH_IMM8) & OP_MASK_IMM8);
908 break;
909
910 case '6':
911 (*info->fprintf_func) (info->stream, "0x%lx",
912 (l >> OP_SH_RS) & OP_MASK_RS);
913 break;
914
915 case '7':
916 (*info->fprintf_func) (info->stream, "$ac%ld",
917 (l >> OP_SH_DSPACC) & OP_MASK_DSPACC);
918 break;
919
920 case '8':
921 (*info->fprintf_func) (info->stream, "0x%lx",
922 (l >> OP_SH_WRDSP) & OP_MASK_WRDSP);
923 break;
924
925 case '9':
926 (*info->fprintf_func) (info->stream, "$ac%ld",
927 (l >> OP_SH_DSPACC_S) & OP_MASK_DSPACC_S);
928 break;
929
930 case '0': /* dsp 6-bit signed immediate in bit 20 */
931 delta = ((l >> OP_SH_DSPSFT) & OP_MASK_DSPSFT);
932 if (delta & 0x20) /* test sign bit */
933 delta |= ~OP_MASK_DSPSFT;
934 (*info->fprintf_func) (info->stream, "%d", delta);
935 break;
936
937 case ':': /* dsp 7-bit signed immediate in bit 19 */
938 delta = ((l >> OP_SH_DSPSFT_7) & OP_MASK_DSPSFT_7);
939 if (delta & 0x40) /* test sign bit */
940 delta |= ~OP_MASK_DSPSFT_7;
941 (*info->fprintf_func) (info->stream, "%d", delta);
942 break;
943
944 case '\'':
945 (*info->fprintf_func) (info->stream, "0x%lx",
946 (l >> OP_SH_RDDSP) & OP_MASK_RDDSP);
947 break;
948
949 case '@': /* dsp 10-bit signed immediate in bit 16 */
950 delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
951 if (delta & 0x200) /* test sign bit */
952 delta |= ~OP_MASK_IMM10;
953 (*info->fprintf_func) (info->stream, "%d", delta);
954 break;
955
61cc0267
CF
956 case '!':
957 (*info->fprintf_func) (info->stream, "%ld",
958 (l >> OP_SH_MT_U) & OP_MASK_MT_U);
959 break;
960
961 case '$':
962 (*info->fprintf_func) (info->stream, "%ld",
963 (l >> OP_SH_MT_H) & OP_MASK_MT_H);
964 break;
965
966 case '*':
967 (*info->fprintf_func) (info->stream, "$ac%ld",
968 (l >> OP_SH_MTACC_T) & OP_MASK_MTACC_T);
969 break;
970
971 case '&':
972 (*info->fprintf_func) (info->stream, "$ac%ld",
973 (l >> OP_SH_MTACC_D) & OP_MASK_MTACC_D);
974 break;
975
976 case 'g':
977 /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
978 (*info->fprintf_func) (info->stream, "$%ld",
979 (l >> OP_SH_RD) & OP_MASK_RD);
980 break;
981
794ac9d0
CD
982 case 's':
983 case 'b':
984 case 'r':
985 case 'v':
986 (*info->fprintf_func) (info->stream, "%s",
987 mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
988 break;
989
990 case 't':
991 case 'w':
992 (*info->fprintf_func) (info->stream, "%s",
993 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
994 break;
995
996 case 'i':
997 case 'u':
0fd3a477 998 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
999 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
1000 break;
1001
1002 case 'j': /* Same as i, but sign-extended. */
1003 case 'o':
1004 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
1005 if (delta & 0x8000)
1006 delta |= ~0xffff;
1007 (*info->fprintf_func) (info->stream, "%d",
1008 delta);
1009 break;
1010
1011 case 'h':
1012 (*info->fprintf_func) (info->stream, "0x%x",
1013 (unsigned int) ((l >> OP_SH_PREFX)
1014 & OP_MASK_PREFX));
1015 break;
1016
1017 case 'k':
1018 (*info->fprintf_func) (info->stream, "0x%x",
1019 (unsigned int) ((l >> OP_SH_CACHE)
1020 & OP_MASK_CACHE));
1021 break;
1022
1023 case 'a':
1024 info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
1025 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
022fac6d
TS
1026 /* For gdb disassembler, force odd address on jalx. */
1027 if (info->flavour == bfd_target_unknown_flavour
1028 && strcmp (opp->name, "jalx") == 0)
1029 info->target |= 1;
794ac9d0
CD
1030 (*info->print_address_func) (info->target, info);
1031 break;
1032
1033 case 'p':
1034 /* Sign extend the displacement. */
1035 delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
1036 if (delta & 0x8000)
1037 delta |= ~0xffff;
1038 info->target = (delta << 2) + pc + INSNLEN;
1039 (*info->print_address_func) (info->target, info);
1040 break;
1041
1042 case 'd':
1043 (*info->fprintf_func) (info->stream, "%s",
1044 mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1045 break;
1046
1047 case 'U':
1048 {
1049 /* First check for both rd and rt being equal. */
1050 unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
1051 if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
1052 (*info->fprintf_func) (info->stream, "%s",
1053 mips_gpr_names[reg]);
1054 else
1055 {
1056 /* If one is zero use the other. */
1057 if (reg == 0)
1058 (*info->fprintf_func) (info->stream, "%s",
1059 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
1060 else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
1061 (*info->fprintf_func) (info->stream, "%s",
1062 mips_gpr_names[reg]);
1063 else /* Bogus, result depends on processor. */
1064 (*info->fprintf_func) (info->stream, "%s or %s",
1065 mips_gpr_names[reg],
1066 mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
1067 }
1068 }
1069 break;
1070
1071 case 'z':
1072 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
1073 break;
1074
1075 case '<':
0fd3a477 1076 (*info->fprintf_func) (info->stream, "0x%lx",
af7ee8bf
CD
1077 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
1078 break;
794ac9d0
CD
1079
1080 case 'c':
0fd3a477 1081 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
1082 (l >> OP_SH_CODE) & OP_MASK_CODE);
1083 break;
1084
1085 case 'q':
0fd3a477 1086 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0 1087 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
af7ee8bf
CD
1088 break;
1089
1090 case 'C':
0fd3a477 1091 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
1092 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
1093 break;
1094
1095 case 'B':
0fd3a477
JW
1096 (*info->fprintf_func) (info->stream, "0x%lx",
1097
794ac9d0
CD
1098 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
1099 break;
1100
1101 case 'J':
0fd3a477 1102 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
1103 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
1104 break;
1105
1106 case 'S':
1107 case 'V':
1108 (*info->fprintf_func) (info->stream, "%s",
1109 mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
1110 break;
1111
1112 case 'T':
1113 case 'W':
1114 (*info->fprintf_func) (info->stream, "%s",
1115 mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
af7ee8bf
CD
1116 break;
1117
bbcc0807 1118 case 'D':
794ac9d0
CD
1119 (*info->fprintf_func) (info->stream, "%s",
1120 mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
1121 break;
1122
1123 case 'R':
1124 (*info->fprintf_func) (info->stream, "%s",
1125 mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
1126 break;
1127
1128 case 'E':
1129 /* Coprocessor register for lwcN instructions, et al.
1130
1131 Note that there is no load/store cp0 instructions, and
1132 that FPU (cp1) instructions disassemble this field using
1133 'T' format. Therefore, until we gain understanding of
1134 cp2 register names, we can simply print the register
1135 numbers. */
0fd3a477 1136 (*info->fprintf_func) (info->stream, "$%ld",
794ac9d0
CD
1137 (l >> OP_SH_RT) & OP_MASK_RT);
1138 break;
1139
1140 case 'G':
1141 /* Coprocessor register for mtcN instructions, et al. Note
1142 that FPU (cp1) instructions disassemble this field using
1143 'S' format. Therefore, we only need to worry about cp0,
1144 cp2, and cp3. */
1145 op = (l >> OP_SH_OP) & OP_MASK_OP;
1146 if (op == OP_OP_COP0)
1147 (*info->fprintf_func) (info->stream, "%s",
1148 mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1149 else
0fd3a477 1150 (*info->fprintf_func) (info->stream, "$%ld",
794ac9d0
CD
1151 (l >> OP_SH_RD) & OP_MASK_RD);
1152 break;
1153
1154 case 'K':
1155 (*info->fprintf_func) (info->stream, "%s",
1156 mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1157 break;
1158
1159 case 'N':
0d09bfe6
TS
1160 (*info->fprintf_func) (info->stream,
1161 ((opp->pinfo & (FP_D | FP_S)) != 0
1162 ? "$fcc%ld" : "$cc%ld"),
794ac9d0
CD
1163 (l >> OP_SH_BCC) & OP_MASK_BCC);
1164 break;
1165
1166 case 'M':
0fd3a477 1167 (*info->fprintf_func) (info->stream, "$fcc%ld",
794ac9d0
CD
1168 (l >> OP_SH_CCC) & OP_MASK_CCC);
1169 break;
1170
1171 case 'P':
0fd3a477 1172 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1173 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
1174 break;
1175
1176 case 'e':
0fd3a477 1177 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1178 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
1179 break;
1180
1181 case '%':
0fd3a477 1182 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1183 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
1184 break;
1185
1186 case 'H':
0fd3a477 1187 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1188 (l >> OP_SH_SEL) & OP_MASK_SEL);
1189 break;
1190
1191 case 'O':
0fd3a477 1192 (*info->fprintf_func) (info->stream, "%ld",
794ac9d0
CD
1193 (l >> OP_SH_ALN) & OP_MASK_ALN);
1194 break;
1195
1196 case 'Q':
bbcc0807 1197 {
794ac9d0 1198 unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
47b0e7ad 1199
794ac9d0
CD
1200 if ((vsel & 0x10) == 0)
1201 {
1202 int fmt;
47b0e7ad 1203
794ac9d0
CD
1204 vsel &= 0x0f;
1205 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1206 if ((vsel & 1) == 0)
1207 break;
0fd3a477 1208 (*info->fprintf_func) (info->stream, "$v%ld[%d]",
794ac9d0
CD
1209 (l >> OP_SH_FT) & OP_MASK_FT,
1210 vsel >> 1);
1211 }
1212 else if ((vsel & 0x08) == 0)
1213 {
0fd3a477 1214 (*info->fprintf_func) (info->stream, "$v%ld",
794ac9d0
CD
1215 (l >> OP_SH_FT) & OP_MASK_FT);
1216 }
bbcc0807 1217 else
794ac9d0 1218 {
0fd3a477 1219 (*info->fprintf_func) (info->stream, "0x%lx",
794ac9d0
CD
1220 (l >> OP_SH_FT) & OP_MASK_FT);
1221 }
bbcc0807 1222 }
794ac9d0
CD
1223 break;
1224
1225 case 'X':
0fd3a477 1226 (*info->fprintf_func) (info->stream, "$v%ld",
794ac9d0
CD
1227 (l >> OP_SH_FD) & OP_MASK_FD);
1228 break;
1229
1230 case 'Y':
0fd3a477 1231 (*info->fprintf_func) (info->stream, "$v%ld",
794ac9d0
CD
1232 (l >> OP_SH_FS) & OP_MASK_FS);
1233 break;
1234
1235 case 'Z':
0fd3a477 1236 (*info->fprintf_func) (info->stream, "$v%ld",
794ac9d0
CD
1237 (l >> OP_SH_FT) & OP_MASK_FT);
1238 break;
bbcc0807 1239
af7ee8bf
CD
1240 default:
1241 /* xgettext:c-format */
1242 (*info->fprintf_func) (info->stream,
168411b1 1243 _("# internal error, undefined modifier (%c)"),
af7ee8bf 1244 *d);
794ac9d0 1245 return;
af7ee8bf 1246 }
252b5132
RH
1247 }
1248}
1249\f
252b5132
RH
1250/* Print the mips instruction at address MEMADDR in debugged memory,
1251 on using INFO. Returns length of the instruction, in bytes, which is
aa5f19f2 1252 always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
252b5132
RH
1253 this is little-endian code. */
1254
1255static int
47b0e7ad
NC
1256print_insn_mips (bfd_vma memaddr,
1257 unsigned long int word,
1258 struct disassemble_info *info)
252b5132 1259{
47b0e7ad 1260 const struct mips_opcode *op;
b34976b6 1261 static bfd_boolean init = 0;
252b5132
RH
1262 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1263
1264 /* Build a hash table to shorten the search time. */
1265 if (! init)
1266 {
1267 unsigned int i;
1268
1269 for (i = 0; i <= OP_MASK_OP; i++)
1270 {
1271 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1272 {
986e18a5 1273 if (op->pinfo == INSN_MACRO
9e836e3d 1274 || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
252b5132
RH
1275 continue;
1276 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
1277 {
1278 mips_hash[i] = op;
1279 break;
1280 }
1281 }
7f6621cd 1282 }
252b5132
RH
1283
1284 init = 1;
1285 }
1286
aa5f19f2 1287 info->bytes_per_chunk = INSNLEN;
252b5132 1288 info->display_endian = info->endian;
9bb28706
CD
1289 info->insn_info_valid = 1;
1290 info->branch_delay_insns = 0;
def7143b 1291 info->data_size = 0;
9bb28706
CD
1292 info->insn_type = dis_nonbranch;
1293 info->target = 0;
1294 info->target2 = 0;
252b5132
RH
1295
1296 op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
1297 if (op != NULL)
1298 {
1299 for (; op < &mips_opcodes[NUMOPCODES]; op++)
1300 {
986e18a5 1301 if (op->pinfo != INSN_MACRO
9e836e3d 1302 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
986e18a5 1303 && (word & op->mask) == op->match)
252b5132 1304 {
47b0e7ad 1305 const char *d;
2bd7f1f3 1306
3396de36 1307 /* We always allow to disassemble the jalx instruction. */
640c0ccd 1308 if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
3396de36 1309 && strcmp (op->name, "jalx"))
252b5132
RH
1310 continue;
1311
9bb28706
CD
1312 /* Figure out instruction type and branch delay information. */
1313 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1314 {
1315 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1316 info->insn_type = dis_jsr;
1317 else
1318 info->insn_type = dis_branch;
1319 info->branch_delay_insns = 1;
1320 }
1321 else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1322 | INSN_COND_BRANCH_LIKELY)) != 0)
1323 {
1324 if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1325 info->insn_type = dis_condjsr;
1326 else
1327 info->insn_type = dis_condbranch;
1328 info->branch_delay_insns = 1;
1329 }
1330 else if ((op->pinfo & (INSN_STORE_MEMORY
1331 | INSN_LOAD_MEMORY_DELAY)) != 0)
1332 info->insn_type = dis_dref;
1333
252b5132
RH
1334 (*info->fprintf_func) (info->stream, "%s", op->name);
1335
1336 d = op->args;
1337 if (d != NULL && *d != '\0')
1338 {
7f6621cd 1339 (*info->fprintf_func) (info->stream, "\t");
cc0ca239 1340 print_insn_args (d, word, memaddr, info, op);
252b5132
RH
1341 }
1342
aa5f19f2 1343 return INSNLEN;
252b5132
RH
1344 }
1345 }
1346 }
1347
1348 /* Handle undefined instructions. */
9bb28706 1349 info->insn_type = dis_noninsn;
0fd3a477 1350 (*info->fprintf_func) (info->stream, "0x%lx", word);
aa5f19f2 1351 return INSNLEN;
252b5132 1352}
aa5f19f2 1353\f
252b5132
RH
1354/* Disassemble an operand for a mips16 instruction. */
1355
1356static void
47b0e7ad
NC
1357print_mips16_insn_arg (char type,
1358 const struct mips_opcode *op,
1359 int l,
1360 bfd_boolean use_extend,
1361 int extend,
1362 bfd_vma memaddr,
1363 struct disassemble_info *info)
252b5132
RH
1364{
1365 switch (type)
1366 {
1367 case ',':
1368 case '(':
1369 case ')':
1370 (*info->fprintf_func) (info->stream, "%c", type);
1371 break;
1372
1373 case 'y':
1374 case 'w':
aa5f19f2 1375 (*info->fprintf_func) (info->stream, "%s",
654c225a
TS
1376 mips16_reg_names(((l >> MIPS16OP_SH_RY)
1377 & MIPS16OP_MASK_RY)));
252b5132
RH
1378 break;
1379
1380 case 'x':
1381 case 'v':
aa5f19f2 1382 (*info->fprintf_func) (info->stream, "%s",
654c225a
TS
1383 mips16_reg_names(((l >> MIPS16OP_SH_RX)
1384 & MIPS16OP_MASK_RX)));
252b5132
RH
1385 break;
1386
1387 case 'z':
aa5f19f2 1388 (*info->fprintf_func) (info->stream, "%s",
654c225a
TS
1389 mips16_reg_names(((l >> MIPS16OP_SH_RZ)
1390 & MIPS16OP_MASK_RZ)));
252b5132
RH
1391 break;
1392
1393 case 'Z':
aa5f19f2 1394 (*info->fprintf_func) (info->stream, "%s",
654c225a
TS
1395 mips16_reg_names(((l >> MIPS16OP_SH_MOVE32Z)
1396 & MIPS16OP_MASK_MOVE32Z)));
252b5132
RH
1397 break;
1398
1399 case '0':
640c0ccd 1400 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
252b5132
RH
1401 break;
1402
1403 case 'S':
640c0ccd 1404 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]);
252b5132
RH
1405 break;
1406
1407 case 'P':
1408 (*info->fprintf_func) (info->stream, "$pc");
1409 break;
1410
1411 case 'R':
640c0ccd 1412 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]);
252b5132
RH
1413 break;
1414
1415 case 'X':
aa5f19f2 1416 (*info->fprintf_func) (info->stream, "%s",
640c0ccd
CD
1417 mips_gpr_names[((l >> MIPS16OP_SH_REGR32)
1418 & MIPS16OP_MASK_REGR32)]);
252b5132
RH
1419 break;
1420
1421 case 'Y':
aa5f19f2 1422 (*info->fprintf_func) (info->stream, "%s",
640c0ccd 1423 mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
252b5132
RH
1424 break;
1425
1426 case '<':
1427 case '>':
1428 case '[':
1429 case ']':
1430 case '4':
1431 case '5':
1432 case 'H':
1433 case 'W':
1434 case 'D':
1435 case 'j':
1436 case '6':
1437 case '8':
1438 case 'V':
1439 case 'C':
1440 case 'U':
1441 case 'k':
1442 case 'K':
1443 case 'p':
1444 case 'q':
1445 case 'A':
1446 case 'B':
1447 case 'E':
1448 {
1449 int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
1450
1451 shift = 0;
1452 signedp = 0;
1453 extbits = 16;
1454 pcrel = 0;
1455 extu = 0;
1456 branch = 0;
1457 switch (type)
1458 {
1459 case '<':
1460 nbits = 3;
1461 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1462 extbits = 5;
1463 extu = 1;
1464 break;
1465 case '>':
1466 nbits = 3;
1467 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1468 extbits = 5;
1469 extu = 1;
1470 break;
1471 case '[':
1472 nbits = 3;
1473 immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1474 extbits = 6;
1475 extu = 1;
1476 break;
1477 case ']':
1478 nbits = 3;
1479 immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
1480 extbits = 6;
1481 extu = 1;
1482 break;
1483 case '4':
1484 nbits = 4;
1485 immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
1486 signedp = 1;
1487 extbits = 15;
1488 break;
1489 case '5':
1490 nbits = 5;
1491 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1492 info->insn_type = dis_dref;
1493 info->data_size = 1;
1494 break;
1495 case 'H':
1496 nbits = 5;
1497 shift = 1;
1498 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1499 info->insn_type = dis_dref;
1500 info->data_size = 2;
1501 break;
1502 case 'W':
1503 nbits = 5;
1504 shift = 2;
1505 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1506 if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1507 && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1508 {
1509 info->insn_type = dis_dref;
1510 info->data_size = 4;
1511 }
1512 break;
1513 case 'D':
1514 nbits = 5;
1515 shift = 3;
1516 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1517 info->insn_type = dis_dref;
1518 info->data_size = 8;
1519 break;
1520 case 'j':
1521 nbits = 5;
1522 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1523 signedp = 1;
1524 break;
1525 case '6':
1526 nbits = 6;
1527 immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1528 break;
1529 case '8':
1530 nbits = 8;
1531 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1532 break;
1533 case 'V':
1534 nbits = 8;
1535 shift = 2;
1536 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1537 /* FIXME: This might be lw, or it might be addiu to $sp or
1538 $pc. We assume it's load. */
1539 info->insn_type = dis_dref;
1540 info->data_size = 4;
1541 break;
1542 case 'C':
1543 nbits = 8;
1544 shift = 3;
1545 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1546 info->insn_type = dis_dref;
1547 info->data_size = 8;
1548 break;
1549 case 'U':
1550 nbits = 8;
1551 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1552 extu = 1;
1553 break;
1554 case 'k':
1555 nbits = 8;
1556 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1557 signedp = 1;
1558 break;
1559 case 'K':
1560 nbits = 8;
1561 shift = 3;
1562 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1563 signedp = 1;
1564 break;
1565 case 'p':
1566 nbits = 8;
1567 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1568 signedp = 1;
1569 pcrel = 1;
1570 branch = 1;
1571 info->insn_type = dis_condbranch;
1572 break;
1573 case 'q':
1574 nbits = 11;
1575 immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1576 signedp = 1;
1577 pcrel = 1;
1578 branch = 1;
1579 info->insn_type = dis_branch;
1580 break;
1581 case 'A':
1582 nbits = 8;
1583 shift = 2;
1584 immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1585 pcrel = 1;
1586 /* FIXME: This can be lw or la. We assume it is lw. */
1587 info->insn_type = dis_dref;
1588 info->data_size = 4;
1589 break;
1590 case 'B':
1591 nbits = 5;
1592 shift = 3;
1593 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1594 pcrel = 1;
1595 info->insn_type = dis_dref;
1596 info->data_size = 8;
1597 break;
1598 case 'E':
1599 nbits = 5;
1600 shift = 2;
1601 immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1602 pcrel = 1;
1603 break;
1604 default:
1605 abort ();
1606 }
1607
1608 if (! use_extend)
1609 {
1610 if (signedp && immed >= (1 << (nbits - 1)))
1611 immed -= 1 << nbits;
1612 immed <<= shift;
1613 if ((type == '<' || type == '>' || type == '[' || type == ']')
1614 && immed == 0)
1615 immed = 8;
1616 }
1617 else
1618 {
1619 if (extbits == 16)
1620 immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1621 else if (extbits == 15)
1622 immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1623 else
1624 immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1625 immed &= (1 << extbits) - 1;
1626 if (! extu && immed >= (1 << (extbits - 1)))
1627 immed -= 1 << extbits;
1628 }
1629
1630 if (! pcrel)
1631 (*info->fprintf_func) (info->stream, "%d", immed);
1632 else
1633 {
1634 bfd_vma baseaddr;
252b5132
RH
1635
1636 if (branch)
1637 {
1638 immed *= 2;
1639 baseaddr = memaddr + 2;
1640 }
1641 else if (use_extend)
1642 baseaddr = memaddr - 2;
1643 else
1644 {
1645 int status;
1646 bfd_byte buffer[2];
1647
1648 baseaddr = memaddr;
1649
1650 /* If this instruction is in the delay slot of a jr
1651 instruction, the base address is the address of the
1652 jr instruction. If it is in the delay slot of jalr
1653 instruction, the base address is the address of the
1654 jalr instruction. This test is unreliable: we have
1655 no way of knowing whether the previous word is
1656 instruction or data. */
1657 status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1658 info);
1659 if (status == 0
1660 && (((info->endian == BFD_ENDIAN_BIG
1661 ? bfd_getb16 (buffer)
1662 : bfd_getl16 (buffer))
1663 & 0xf800) == 0x1800))
1664 baseaddr = memaddr - 4;
1665 else
1666 {
1667 status = (*info->read_memory_func) (memaddr - 2, buffer,
1668 2, info);
1669 if (status == 0
1670 && (((info->endian == BFD_ENDIAN_BIG
1671 ? bfd_getb16 (buffer)
1672 : bfd_getl16 (buffer))
1673 & 0xf81f) == 0xe800))
1674 baseaddr = memaddr - 2;
1675 }
1676 }
9bb28706 1677 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
022fac6d
TS
1678 if (pcrel && branch
1679 && info->flavour == bfd_target_unknown_flavour)
1680 /* For gdb disassembler, maintain odd address. */
1681 info->target |= 1;
9bb28706 1682 (*info->print_address_func) (info->target, info);
252b5132
RH
1683 }
1684 }
1685 break;
1686
1687 case 'a':
022fac6d
TS
1688 {
1689 int jalx = l & 0x400;
1690
1691 if (! use_extend)
1692 extend = 0;
1693 l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1694 if (!jalx && info->flavour == bfd_target_unknown_flavour)
1695 /* For gdb disassembler, maintain odd address. */
1696 l |= 1;
1697 }
9bb28706
CD
1698 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1699 (*info->print_address_func) (info->target, info);
252b5132 1700 info->insn_type = dis_jsr;
252b5132
RH
1701 info->branch_delay_insns = 1;
1702 break;
1703
1704 case 'l':
1705 case 'L':
1706 {
1707 int need_comma, amask, smask;
1708
1709 need_comma = 0;
1710
1711 l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1712
1713 amask = (l >> 3) & 7;
1714
1715 if (amask > 0 && amask < 5)
1716 {
640c0ccd 1717 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
252b5132 1718 if (amask > 1)
aa5f19f2 1719 (*info->fprintf_func) (info->stream, "-%s",
640c0ccd 1720 mips_gpr_names[amask + 3]);
252b5132
RH
1721 need_comma = 1;
1722 }
1723
1724 smask = (l >> 1) & 3;
1725 if (smask == 3)
1726 {
1727 (*info->fprintf_func) (info->stream, "%s??",
1728 need_comma ? "," : "");
1729 need_comma = 1;
1730 }
1731 else if (smask > 0)
1732 {
aa5f19f2 1733 (*info->fprintf_func) (info->stream, "%s%s",
252b5132 1734 need_comma ? "," : "",
640c0ccd 1735 mips_gpr_names[16]);
252b5132 1736 if (smask > 1)
aa5f19f2 1737 (*info->fprintf_func) (info->stream, "-%s",
640c0ccd 1738 mips_gpr_names[smask + 15]);
252b5132
RH
1739 need_comma = 1;
1740 }
1741
1742 if (l & 1)
1743 {
aa5f19f2 1744 (*info->fprintf_func) (info->stream, "%s%s",
252b5132 1745 need_comma ? "," : "",
640c0ccd 1746 mips_gpr_names[31]);
252b5132
RH
1747 need_comma = 1;
1748 }
1749
1750 if (amask == 5 || amask == 6)
1751 {
1752 (*info->fprintf_func) (info->stream, "%s$f0",
1753 need_comma ? "," : "");
1754 if (amask == 6)
1755 (*info->fprintf_func) (info->stream, "-$f1");
1756 }
1757 }
1758 break;
1759
0499d65b
TS
1760 case 'm':
1761 case 'M':
1762 /* MIPS16e save/restore. */
1763 {
1764 int need_comma = 0;
1765 int amask, args, statics;
1766 int nsreg, smask;
1767 int framesz;
1768 int i, j;
1769
1770 l = l & 0x7f;
1771 if (use_extend)
1772 l |= extend << 16;
1773
1774 amask = (l >> 16) & 0xf;
1775 if (amask == MIPS16_ALL_ARGS)
1776 {
1777 args = 4;
1778 statics = 0;
1779 }
1780 else if (amask == MIPS16_ALL_STATICS)
1781 {
1782 args = 0;
1783 statics = 4;
1784 }
1785 else
1786 {
1787 args = amask >> 2;
1788 statics = amask & 3;
1789 }
1790
1791 if (args > 0) {
1792 (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
1793 if (args > 1)
1794 (*info->fprintf_func) (info->stream, "-%s",
1795 mips_gpr_names[4 + args - 1]);
1796 need_comma = 1;
1797 }
1798
1799 framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
1800 if (framesz == 0 && !use_extend)
1801 framesz = 128;
1802
1803 (*info->fprintf_func) (info->stream, "%s%d",
1804 need_comma ? "," : "",
1805 framesz);
1806
1807 if (l & 0x40) /* $ra */
1808 (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[31]);
1809
1810 nsreg = (l >> 24) & 0x7;
1811 smask = 0;
1812 if (l & 0x20) /* $s0 */
1813 smask |= 1 << 0;
1814 if (l & 0x10) /* $s1 */
1815 smask |= 1 << 1;
1816 if (nsreg > 0) /* $s2-$s8 */
1817 smask |= ((1 << nsreg) - 1) << 2;
1818
1819 /* Find first set static reg bit. */
1820 for (i = 0; i < 9; i++)
1821 {
1822 if (smask & (1 << i))
1823 {
1824 (*info->fprintf_func) (info->stream, ",%s",
1825 mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1826 /* Skip over string of set bits. */
1827 for (j = i; smask & (2 << j); j++)
1828 continue;
1829 if (j > i)
1830 (*info->fprintf_func) (info->stream, "-%s",
1831 mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1832 i = j + 1;
1833 }
1834 }
1835
1836 /* Statics $ax - $a3. */
1837 if (statics == 1)
1838 (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[7]);
1839 else if (statics > 0)
1840 (*info->fprintf_func) (info->stream, ",%s-%s",
1841 mips_gpr_names[7 - statics + 1],
1842 mips_gpr_names[7]);
1843 }
1844 break;
1845
252b5132 1846 default:
aa5f19f2
NC
1847 /* xgettext:c-format */
1848 (*info->fprintf_func)
1849 (info->stream,
1850 _("# internal disassembler error, unrecognised modifier (%c)"),
1851 type);
252b5132
RH
1852 abort ();
1853 }
1854}
640c0ccd 1855
47b0e7ad
NC
1856/* Disassemble mips16 instructions. */
1857
1858static int
1859print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1860{
1861 int status;
1862 bfd_byte buffer[2];
1863 int length;
1864 int insn;
1865 bfd_boolean use_extend;
1866 int extend = 0;
1867 const struct mips_opcode *op, *opend;
1868
1869 info->bytes_per_chunk = 2;
1870 info->display_endian = info->endian;
1871 info->insn_info_valid = 1;
1872 info->branch_delay_insns = 0;
1873 info->data_size = 0;
1874 info->insn_type = dis_nonbranch;
1875 info->target = 0;
1876 info->target2 = 0;
1877
1878 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1879 if (status != 0)
1880 {
1881 (*info->memory_error_func) (status, memaddr, info);
1882 return -1;
1883 }
1884
1885 length = 2;
1886
1887 if (info->endian == BFD_ENDIAN_BIG)
1888 insn = bfd_getb16 (buffer);
1889 else
1890 insn = bfd_getl16 (buffer);
1891
1892 /* Handle the extend opcode specially. */
1893 use_extend = FALSE;
1894 if ((insn & 0xf800) == 0xf000)
1895 {
1896 use_extend = TRUE;
1897 extend = insn & 0x7ff;
1898
1899 memaddr += 2;
1900
1901 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1902 if (status != 0)
1903 {
1904 (*info->fprintf_func) (info->stream, "extend 0x%x",
1905 (unsigned int) extend);
1906 (*info->memory_error_func) (status, memaddr, info);
1907 return -1;
1908 }
1909
1910 if (info->endian == BFD_ENDIAN_BIG)
1911 insn = bfd_getb16 (buffer);
1912 else
1913 insn = bfd_getl16 (buffer);
1914
1915 /* Check for an extend opcode followed by an extend opcode. */
1916 if ((insn & 0xf800) == 0xf000)
1917 {
1918 (*info->fprintf_func) (info->stream, "extend 0x%x",
1919 (unsigned int) extend);
1920 info->insn_type = dis_noninsn;
1921 return length;
1922 }
1923
1924 length += 2;
1925 }
1926
1927 /* FIXME: Should probably use a hash table on the major opcode here. */
1928
1929 opend = mips16_opcodes + bfd_mips16_num_opcodes;
1930 for (op = mips16_opcodes; op < opend; op++)
1931 {
1932 if (op->pinfo != INSN_MACRO
1933 && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1934 && (insn & op->mask) == op->match)
1935 {
1936 const char *s;
1937
1938 if (strchr (op->args, 'a') != NULL)
1939 {
1940 if (use_extend)
1941 {
1942 (*info->fprintf_func) (info->stream, "extend 0x%x",
1943 (unsigned int) extend);
1944 info->insn_type = dis_noninsn;
1945 return length - 2;
1946 }
1947
1948 use_extend = FALSE;
1949
1950 memaddr += 2;
1951
1952 status = (*info->read_memory_func) (memaddr, buffer, 2,
1953 info);
1954 if (status == 0)
1955 {
1956 use_extend = TRUE;
1957 if (info->endian == BFD_ENDIAN_BIG)
1958 extend = bfd_getb16 (buffer);
1959 else
1960 extend = bfd_getl16 (buffer);
1961 length += 2;
1962 }
1963 }
1964
1965 (*info->fprintf_func) (info->stream, "%s", op->name);
1966 if (op->args[0] != '\0')
1967 (*info->fprintf_func) (info->stream, "\t");
1968
1969 for (s = op->args; *s != '\0'; s++)
1970 {
1971 if (*s == ','
1972 && s[1] == 'w'
1973 && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
1974 == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
1975 {
1976 /* Skip the register and the comma. */
1977 ++s;
1978 continue;
1979 }
1980 if (*s == ','
1981 && s[1] == 'v'
1982 && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
1983 == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
1984 {
1985 /* Skip the register and the comma. */
1986 ++s;
1987 continue;
1988 }
1989 print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
1990 info);
1991 }
1992
1993 if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1994 {
1995 info->branch_delay_insns = 1;
1996 if (info->insn_type != dis_jsr)
1997 info->insn_type = dis_branch;
1998 }
1999
2000 return length;
2001 }
2002 }
2003
2004 if (use_extend)
2005 (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
2006 (*info->fprintf_func) (info->stream, "0x%x", insn);
2007 info->insn_type = dis_noninsn;
2008
2009 return length;
2010}
2011
2012/* In an environment where we do not know the symbol type of the
2013 instruction we are forced to assume that the low order bit of the
2014 instructions' address may mark it as a mips16 instruction. If we
2015 are single stepping, or the pc is within the disassembled function,
2016 this works. Otherwise, we need a clue. Sometimes. */
2017
2018static int
2019_print_insn_mips (bfd_vma memaddr,
2020 struct disassemble_info *info,
2021 enum bfd_endian endianness)
2022{
2023 bfd_byte buffer[INSNLEN];
2024 int status;
2025
2026 set_default_mips_dis_options (info);
2027 parse_mips_dis_options (info->disassembler_options);
2028
2029#if 1
2030 /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
2031 /* Only a few tools will work this way. */
2032 if (memaddr & 0x01)
2033 return print_insn_mips16 (memaddr, info);
2034#endif
2035
2036#if SYMTAB_AVAILABLE
2037 if (info->mach == bfd_mach_mips16
2038 || (info->flavour == bfd_target_elf_flavour
2039 && info->symbols != NULL
2040 && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
2041 == STO_MIPS16)))
2042 return print_insn_mips16 (memaddr, info);
2043#endif
2044
2045 status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2046 if (status == 0)
2047 {
2048 unsigned long insn;
2049
2050 if (endianness == BFD_ENDIAN_BIG)
2051 insn = (unsigned long) bfd_getb32 (buffer);
2052 else
2053 insn = (unsigned long) bfd_getl32 (buffer);
2054
2055 return print_insn_mips (memaddr, insn, info);
2056 }
2057 else
2058 {
2059 (*info->memory_error_func) (status, memaddr, info);
2060 return -1;
2061 }
2062}
2063
2064int
2065print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2066{
2067 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2068}
2069
2070int
2071print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2072{
2073 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2074}
2075\f
640c0ccd 2076void
47b0e7ad 2077print_mips_disassembler_options (FILE *stream)
640c0ccd 2078{
4a9a3c54 2079 unsigned int i;
640c0ccd
CD
2080
2081 fprintf (stream, _("\n\
2082The following MIPS specific disassembler options are supported for use\n\
2083with the -M switch (multiple options should be separated by commas):\n"));
2084
2085 fprintf (stream, _("\n\
2086 gpr-names=ABI Print GPR names according to specified ABI.\n\
2087 Default: based on binary being disassembled.\n"));
2088
2089 fprintf (stream, _("\n\
2090 fpr-names=ABI Print FPR names according to specified ABI.\n\
2091 Default: numeric.\n"));
2092
2093 fprintf (stream, _("\n\
2094 cp0-names=ARCH Print CP0 register names according to\n\
2095 specified architecture.\n\
2096 Default: based on binary being disassembled.\n"));
2097
af7ee8bf
CD
2098 fprintf (stream, _("\n\
2099 hwr-names=ARCH Print HWR names according to specified \n\
2100 architecture.\n\
2101 Default: based on binary being disassembled.\n"));
2102
640c0ccd
CD
2103 fprintf (stream, _("\n\
2104 reg-names=ABI Print GPR and FPR names according to\n\
2105 specified ABI.\n"));
2106
2107 fprintf (stream, _("\n\
af7ee8bf 2108 reg-names=ARCH Print CP0 register and HWR names according to\n\
640c0ccd
CD
2109 specified architecture.\n"));
2110
2111 fprintf (stream, _("\n\
2112 For the options above, the following values are supported for \"ABI\":\n\
2113 "));
4a9a3c54 2114 for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
640c0ccd
CD
2115 fprintf (stream, " %s", mips_abi_choices[i].name);
2116 fprintf (stream, _("\n"));
2117
2118 fprintf (stream, _("\n\
2119 For the options above, The following values are supported for \"ARCH\":\n\
2120 "));
4a9a3c54 2121 for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
640c0ccd
CD
2122 if (*mips_arch_choices[i].name != '\0')
2123 fprintf (stream, " %s", mips_arch_choices[i].name);
2124 fprintf (stream, _("\n"));
2125
2126 fprintf (stream, _("\n"));
2127}
This page took 0.5243 seconds and 4 git commands to generate.