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