mips-dis.c revision 1.2 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.1 skrll 2000, 2001, 2002, 2003, 2005, 2007, 2008
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.2 matt "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
326 1.2 matt "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
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.2 matt "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi",
330 1.2 matt "c0_xcontext", "$21", "c0_osscratch", "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.1 skrll mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
463 1.1 skrll { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5,
464 1.1 skrll mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
465 1.1 skrll
466 1.1 skrll /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
467 1.1 skrll Note that MIPS-3D and MDMX are not applicable to MIPS32. (See
468 1.1 skrll _MIPS32 Architecture For Programmers Volume I: Introduction to the
469 1.1 skrll MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
470 1.1 skrll page 1. */
471 1.1 skrll { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
472 1.1 skrll ISA_MIPS32 | INSN_MIPS16 | INSN_SMARTMIPS,
473 1.1 skrll mips_cp0_names_mips3264,
474 1.1 skrll mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
475 1.1 skrll mips_hwr_names_numeric },
476 1.1 skrll
477 1.1 skrll { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
478 1.1 skrll (ISA_MIPS32R2 | INSN_MIPS16 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
479 1.1 skrll | INSN_MIPS3D | INSN_MT),
480 1.1 skrll mips_cp0_names_mips3264r2,
481 1.1 skrll mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
482 1.1 skrll mips_hwr_names_mips3264r2 },
483 1.1 skrll
484 1.1 skrll /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */
485 1.1 skrll { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64,
486 1.1 skrll ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX,
487 1.1 skrll mips_cp0_names_mips3264,
488 1.1 skrll mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
489 1.1 skrll mips_hwr_names_numeric },
490 1.1 skrll
491 1.1 skrll { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
492 1.1 skrll (ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
493 1.1 skrll | INSN_DSP64 | INSN_MT | INSN_MDMX),
494 1.1 skrll mips_cp0_names_mips3264r2,
495 1.1 skrll mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
496 1.1 skrll mips_hwr_names_mips3264r2 },
497 1.1 skrll
498 1.1 skrll { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1,
499 1.1 skrll ISA_MIPS64 | INSN_MIPS3D | INSN_SB1,
500 1.1 skrll mips_cp0_names_sb1,
501 1.1 skrll mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
502 1.1 skrll mips_hwr_names_numeric },
503 1.1 skrll
504 1.1 skrll { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
505 1.1 skrll ISA_MIPS3 | INSN_LOONGSON_2E, mips_cp0_names_numeric,
506 1.1 skrll NULL, 0, mips_hwr_names_numeric },
507 1.1 skrll
508 1.1 skrll { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
509 1.1 skrll ISA_MIPS3 | INSN_LOONGSON_2F, mips_cp0_names_numeric,
510 1.1 skrll NULL, 0, mips_hwr_names_numeric },
511 1.1 skrll
512 1.1 skrll { "octeon", 1, bfd_mach_mips_octeon, CPU_OCTEON,
513 1.1 skrll ISA_MIPS64R2 | INSN_OCTEON, mips_cp0_names_numeric, NULL, 0,
514 1.1 skrll mips_hwr_names_numeric },
515 1.2 matt
516 1.2 matt { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
517 1.2 matt ISA_MIPS64 | INSN_XLR,
518 1.2 matt mips_cp0_names_xlr,
519 1.2 matt mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
520 1.2 matt mips_hwr_names_numeric },
521 1.1 skrll
522 1.1 skrll /* This entry, mips16, is here only for ISA/processor selection; do
523 1.1 skrll not print its name. */
524 1.1 skrll { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3 | INSN_MIPS16,
525 1.1 skrll mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
526 1.1 skrll };
527 1.1 skrll
528 1.1 skrll /* ISA and processor type to disassemble for, and register names to use.
529 1.1 skrll set_default_mips_dis_options and parse_mips_dis_options fill in these
530 1.1 skrll values. */
531 1.1 skrll static int mips_processor;
532 1.1 skrll static int mips_isa;
533 1.1 skrll static const char * const *mips_gpr_names;
534 1.1 skrll static const char * const *mips_fpr_names;
535 1.1 skrll static const char * const *mips_cp0_names;
536 1.1 skrll static const struct mips_cp0sel_name *mips_cp0sel_names;
537 1.1 skrll static int mips_cp0sel_names_len;
538 1.1 skrll static const char * const *mips_hwr_names;
539 1.1 skrll
540 1.1 skrll /* Other options */
541 1.1 skrll static int no_aliases; /* If set disassemble as most general inst. */
542 1.1 skrll
543 1.1 skrll static const struct mips_abi_choice *
545 1.1 skrll choose_abi_by_name (const char *name, unsigned int namelen)
546 1.1 skrll {
547 1.1 skrll const struct mips_abi_choice *c;
548 1.1 skrll unsigned int i;
549 1.1 skrll
550 1.1 skrll for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
551 1.1 skrll if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
552 1.1 skrll && strlen (mips_abi_choices[i].name) == namelen)
553 1.1 skrll c = &mips_abi_choices[i];
554 1.1 skrll
555 1.1 skrll return c;
556 1.1 skrll }
557 1.1 skrll
558 1.1 skrll static const struct mips_arch_choice *
559 1.1 skrll choose_arch_by_name (const char *name, unsigned int namelen)
560 1.1 skrll {
561 1.1 skrll const struct mips_arch_choice *c = NULL;
562 1.1 skrll unsigned int i;
563 1.1 skrll
564 1.1 skrll for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
565 1.1 skrll if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
566 1.1 skrll && strlen (mips_arch_choices[i].name) == namelen)
567 1.1 skrll c = &mips_arch_choices[i];
568 1.1 skrll
569 1.1 skrll return c;
570 1.1 skrll }
571 1.1 skrll
572 1.1 skrll static const struct mips_arch_choice *
573 1.1 skrll choose_arch_by_number (unsigned long mach)
574 1.1 skrll {
575 1.1 skrll static unsigned long hint_bfd_mach;
576 1.1 skrll static const struct mips_arch_choice *hint_arch_choice;
577 1.1 skrll const struct mips_arch_choice *c;
578 1.1 skrll unsigned int i;
579 1.1 skrll
580 1.1 skrll /* We optimize this because even if the user specifies no
581 1.1 skrll flags, this will be done for every instruction! */
582 1.1 skrll if (hint_bfd_mach == mach
583 1.1 skrll && hint_arch_choice != NULL
584 1.1 skrll && hint_arch_choice->bfd_mach == hint_bfd_mach)
585 1.1 skrll return hint_arch_choice;
586 1.1 skrll
587 1.1 skrll for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
588 1.1 skrll {
589 1.1 skrll if (mips_arch_choices[i].bfd_mach_valid
590 1.1 skrll && mips_arch_choices[i].bfd_mach == mach)
591 1.1 skrll {
592 1.1 skrll c = &mips_arch_choices[i];
593 1.1 skrll hint_bfd_mach = mach;
594 1.1 skrll hint_arch_choice = c;
595 1.1 skrll }
596 1.1 skrll }
597 1.1 skrll return c;
598 1.1 skrll }
599 1.1 skrll
600 1.1 skrll /* Check if the object uses NewABI conventions. */
601 1.1 skrll
602 1.1 skrll static int
603 1.1 skrll is_newabi (Elf_Internal_Ehdr *header)
604 1.1 skrll {
605 1.1 skrll /* There are no old-style ABIs which use 64-bit ELF. */
606 1.1 skrll if (header->e_ident[EI_CLASS] == ELFCLASS64)
607 1.1 skrll return 1;
608 1.1 skrll
609 1.1 skrll /* If a 32-bit ELF file, n32 is a new-style ABI. */
610 1.1 skrll if ((header->e_flags & EF_MIPS_ABI2) != 0)
611 1.1 skrll return 1;
612 1.1 skrll
613 1.1 skrll return 0;
614 1.1 skrll }
615 1.1 skrll
616 1.1 skrll static void
617 1.1 skrll set_default_mips_dis_options (struct disassemble_info *info)
618 1.1 skrll {
619 1.1 skrll const struct mips_arch_choice *chosen_arch;
620 1.1 skrll
621 1.1 skrll /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names,
622 1.1 skrll and numeric FPR, CP0 register, and HWR names. */
623 1.1 skrll mips_isa = ISA_MIPS3;
624 1.1 skrll mips_processor = CPU_R3000;
625 1.1 skrll mips_gpr_names = mips_gpr_names_oldabi;
626 1.1 skrll mips_fpr_names = mips_fpr_names_numeric;
627 1.1 skrll mips_cp0_names = mips_cp0_names_numeric;
628 1.1 skrll mips_cp0sel_names = NULL;
629 1.1 skrll mips_cp0sel_names_len = 0;
630 1.1 skrll mips_hwr_names = mips_hwr_names_numeric;
631 1.1 skrll no_aliases = 0;
632 1.1 skrll
633 1.1 skrll /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
634 1.1 skrll if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
635 1.1 skrll {
636 1.1 skrll Elf_Internal_Ehdr *header;
637 1.1 skrll
638 1.1 skrll header = elf_elfheader (info->section->owner);
639 1.1 skrll if (is_newabi (header))
640 1.1 skrll mips_gpr_names = mips_gpr_names_newabi;
641 1.1 skrll }
642 1.1 skrll
643 1.1 skrll /* Set ISA, architecture, and cp0 register names as best we can. */
644 1.1 skrll #if ! SYMTAB_AVAILABLE
645 1.1 skrll /* This is running out on a target machine, not in a host tool.
646 1.1 skrll FIXME: Where does mips_target_info come from? */
647 1.1 skrll target_processor = mips_target_info.processor;
648 1.1 skrll mips_isa = mips_target_info.isa;
649 1.1 skrll #else
650 1.1 skrll chosen_arch = choose_arch_by_number (info->mach);
651 1.1 skrll if (chosen_arch != NULL)
652 1.1 skrll {
653 1.1 skrll mips_processor = chosen_arch->processor;
654 1.1 skrll mips_isa = chosen_arch->isa;
655 1.1 skrll mips_cp0_names = chosen_arch->cp0_names;
656 1.1 skrll mips_cp0sel_names = chosen_arch->cp0sel_names;
657 1.1 skrll mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
658 1.1 skrll mips_hwr_names = chosen_arch->hwr_names;
659 1.1 skrll }
660 1.1 skrll #endif
661 1.1 skrll }
662 1.1 skrll
663 1.1 skrll static void
664 1.1 skrll parse_mips_dis_option (const char *option, unsigned int len)
665 1.1 skrll {
666 1.1 skrll unsigned int i, optionlen, vallen;
667 1.1 skrll const char *val;
668 1.1 skrll const struct mips_abi_choice *chosen_abi;
669 1.1 skrll const struct mips_arch_choice *chosen_arch;
670 1.1 skrll
671 1.1 skrll /* Try to match options that are simple flags */
672 1.1 skrll if (CONST_STRNEQ (option, "no-aliases"))
673 1.1 skrll {
674 1.1 skrll no_aliases = 1;
675 1.1 skrll return;
676 1.1 skrll }
677 1.1 skrll
678 1.1 skrll /* Look for the = that delimits the end of the option name. */
679 1.1 skrll for (i = 0; i < len; i++)
680 1.1 skrll if (option[i] == '=')
681 1.1 skrll break;
682 1.1 skrll
683 1.1 skrll if (i == 0) /* Invalid option: no name before '='. */
684 1.1 skrll return;
685 1.1 skrll if (i == len) /* Invalid option: no '='. */
686 1.1 skrll return;
687 1.1 skrll if (i == (len - 1)) /* Invalid option: no value after '='. */
688 1.1 skrll return;
689 1.1 skrll
690 1.1 skrll optionlen = i;
691 1.1 skrll val = option + (optionlen + 1);
692 1.1 skrll vallen = len - (optionlen + 1);
693 1.1 skrll
694 1.1 skrll if (strncmp ("gpr-names", option, optionlen) == 0
695 1.1 skrll && strlen ("gpr-names") == optionlen)
696 1.1 skrll {
697 1.1 skrll chosen_abi = choose_abi_by_name (val, vallen);
698 1.1 skrll if (chosen_abi != NULL)
699 1.1 skrll mips_gpr_names = chosen_abi->gpr_names;
700 1.1 skrll return;
701 1.1 skrll }
702 1.1 skrll
703 1.1 skrll if (strncmp ("fpr-names", option, optionlen) == 0
704 1.1 skrll && strlen ("fpr-names") == optionlen)
705 1.1 skrll {
706 1.1 skrll chosen_abi = choose_abi_by_name (val, vallen);
707 1.1 skrll if (chosen_abi != NULL)
708 1.1 skrll mips_fpr_names = chosen_abi->fpr_names;
709 1.1 skrll return;
710 1.1 skrll }
711 1.1 skrll
712 1.1 skrll if (strncmp ("cp0-names", option, optionlen) == 0
713 1.1 skrll && strlen ("cp0-names") == optionlen)
714 1.1 skrll {
715 1.1 skrll chosen_arch = choose_arch_by_name (val, vallen);
716 1.1 skrll if (chosen_arch != NULL)
717 1.1 skrll {
718 1.1 skrll mips_cp0_names = chosen_arch->cp0_names;
719 1.1 skrll mips_cp0sel_names = chosen_arch->cp0sel_names;
720 1.1 skrll mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
721 1.1 skrll }
722 1.1 skrll return;
723 1.1 skrll }
724 1.1 skrll
725 1.1 skrll if (strncmp ("hwr-names", option, optionlen) == 0
726 1.1 skrll && strlen ("hwr-names") == optionlen)
727 1.1 skrll {
728 1.1 skrll chosen_arch = choose_arch_by_name (val, vallen);
729 1.1 skrll if (chosen_arch != NULL)
730 1.1 skrll mips_hwr_names = chosen_arch->hwr_names;
731 1.1 skrll return;
732 1.1 skrll }
733 1.1 skrll
734 1.1 skrll if (strncmp ("reg-names", option, optionlen) == 0
735 1.1 skrll && strlen ("reg-names") == optionlen)
736 1.1 skrll {
737 1.1 skrll /* We check both ABI and ARCH here unconditionally, so
738 1.1 skrll that "numeric" will do the desirable thing: select
739 1.1 skrll numeric register names for all registers. Other than
740 1.1 skrll that, a given name probably won't match both. */
741 1.1 skrll chosen_abi = choose_abi_by_name (val, vallen);
742 1.1 skrll if (chosen_abi != NULL)
743 1.1 skrll {
744 1.1 skrll mips_gpr_names = chosen_abi->gpr_names;
745 1.1 skrll mips_fpr_names = chosen_abi->fpr_names;
746 1.1 skrll }
747 1.1 skrll chosen_arch = choose_arch_by_name (val, vallen);
748 1.1 skrll if (chosen_arch != NULL)
749 1.1 skrll {
750 1.1 skrll mips_cp0_names = chosen_arch->cp0_names;
751 1.1 skrll mips_cp0sel_names = chosen_arch->cp0sel_names;
752 1.1 skrll mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
753 1.1 skrll mips_hwr_names = chosen_arch->hwr_names;
754 1.1 skrll }
755 1.1 skrll return;
756 1.1 skrll }
757 1.1 skrll
758 1.1 skrll /* Invalid option. */
759 1.1 skrll }
760 1.1 skrll
761 1.1 skrll static void
762 1.1 skrll parse_mips_dis_options (const char *options)
763 1.1 skrll {
764 1.1 skrll const char *option_end;
765 1.1 skrll
766 1.1 skrll if (options == NULL)
767 1.1 skrll return;
768 1.1 skrll
769 1.1 skrll while (*options != '\0')
770 1.1 skrll {
771 1.1 skrll /* Skip empty options. */
772 1.1 skrll if (*options == ',')
773 1.1 skrll {
774 1.1 skrll options++;
775 1.1 skrll continue;
776 1.1 skrll }
777 1.1 skrll
778 1.1 skrll /* We know that *options is neither NUL or a comma. */
779 1.1 skrll option_end = options + 1;
780 1.1 skrll while (*option_end != ',' && *option_end != '\0')
781 1.1 skrll option_end++;
782 1.1 skrll
783 1.1 skrll parse_mips_dis_option (options, option_end - options);
784 1.1 skrll
785 1.1 skrll /* Go on to the next one. If option_end points to a comma, it
786 1.1 skrll will be skipped above. */
787 1.1 skrll options = option_end;
788 1.1 skrll }
789 1.1 skrll }
790 1.1 skrll
791 1.1 skrll static const struct mips_cp0sel_name *
792 1.1 skrll lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
793 1.1 skrll unsigned int len,
794 1.1 skrll unsigned int cp0reg,
795 1.1 skrll unsigned int sel)
796 1.1 skrll {
797 1.1 skrll unsigned int i;
798 1.1 skrll
799 1.1 skrll for (i = 0; i < len; i++)
800 1.1 skrll if (names[i].cp0reg == cp0reg && names[i].sel == sel)
801 1.1 skrll return &names[i];
802 1.1 skrll return NULL;
803 1.1 skrll }
804 1.1 skrll
805 1.1 skrll /* Print insn arguments for 32/64-bit code. */
807 1.1 skrll
808 1.1 skrll static void
809 1.1 skrll print_insn_args (const char *d,
810 1.1 skrll register unsigned long int l,
811 1.1 skrll bfd_vma pc,
812 1.1 skrll struct disassemble_info *info,
813 1.1 skrll const struct mips_opcode *opp)
814 1.1 skrll {
815 1.1 skrll int op, delta;
816 1.1 skrll unsigned int lsb, msb, msbd;
817 1.1 skrll
818 1.1 skrll lsb = 0;
819 1.1 skrll
820 1.1 skrll for (; *d != '\0'; d++)
821 1.1 skrll {
822 1.1 skrll switch (*d)
823 1.1 skrll {
824 1.1 skrll case ',':
825 1.1 skrll case '(':
826 1.1 skrll case ')':
827 1.1 skrll case '[':
828 1.1 skrll case ']':
829 1.1 skrll (*info->fprintf_func) (info->stream, "%c", *d);
830 1.1 skrll break;
831 1.1 skrll
832 1.1 skrll case '+':
833 1.1 skrll /* Extension character; switch for second char. */
834 1.1 skrll d++;
835 1.1 skrll switch (*d)
836 1.1 skrll {
837 1.1 skrll case '\0':
838 1.1 skrll /* xgettext:c-format */
839 1.1 skrll (*info->fprintf_func) (info->stream,
840 1.1 skrll _("# internal error, incomplete extension sequence (+)"));
841 1.1 skrll return;
842 1.1 skrll
843 1.1 skrll case 'A':
844 1.1 skrll lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT;
845 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x", lsb);
846 1.1 skrll break;
847 1.1 skrll
848 1.1 skrll case 'B':
849 1.1 skrll msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB;
850 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
851 1.1 skrll break;
852 1.1 skrll
853 1.1 skrll case '1':
854 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
855 1.1 skrll (l >> OP_SH_UDI1) & OP_MASK_UDI1);
856 1.1 skrll break;
857 1.1 skrll
858 1.1 skrll case '2':
859 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
860 1.1 skrll (l >> OP_SH_UDI2) & OP_MASK_UDI2);
861 1.1 skrll break;
862 1.1 skrll
863 1.1 skrll case '3':
864 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
865 1.1 skrll (l >> OP_SH_UDI3) & OP_MASK_UDI3);
866 1.1 skrll break;
867 1.1 skrll
868 1.1 skrll case '4':
869 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
870 1.1 skrll (l >> OP_SH_UDI4) & OP_MASK_UDI4);
871 1.1 skrll break;
872 1.1 skrll
873 1.1 skrll case 'C':
874 1.1 skrll case 'H':
875 1.1 skrll msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
876 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
877 1.1 skrll break;
878 1.1 skrll
879 1.1 skrll case 'D':
880 1.1 skrll {
881 1.1 skrll const struct mips_cp0sel_name *n;
882 1.1 skrll unsigned int cp0reg, sel;
883 1.1 skrll
884 1.1 skrll cp0reg = (l >> OP_SH_RD) & OP_MASK_RD;
885 1.1 skrll sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
886 1.1 skrll
887 1.1 skrll /* CP0 register including 'sel' code for mtcN (et al.), to be
888 1.1 skrll printed textually if known. If not known, print both
889 1.1 skrll CP0 register name and sel numerically since CP0 register
890 1.1 skrll with sel 0 may have a name unrelated to register being
891 1.1 skrll printed. */
892 1.1 skrll n = lookup_mips_cp0sel_name(mips_cp0sel_names,
893 1.1 skrll mips_cp0sel_names_len, cp0reg, sel);
894 1.1 skrll if (n != NULL)
895 1.1 skrll (*info->fprintf_func) (info->stream, "%s", n->name);
896 1.1 skrll else
897 1.1 skrll (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
898 1.1 skrll break;
899 1.1 skrll }
900 1.1 skrll
901 1.1 skrll case 'E':
902 1.1 skrll lsb = ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT) + 32;
903 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x", lsb);
904 1.1 skrll break;
905 1.1 skrll
906 1.1 skrll case 'F':
907 1.1 skrll msb = ((l >> OP_SH_INSMSB) & OP_MASK_INSMSB) + 32;
908 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
909 1.1 skrll break;
910 1.1 skrll
911 1.1 skrll case 'G':
912 1.1 skrll msbd = ((l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD) + 32;
913 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
914 1.1 skrll break;
915 1.1 skrll
916 1.1 skrll case 't': /* Coprocessor 0 reg name */
917 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
918 1.1 skrll mips_cp0_names[(l >> OP_SH_RT) &
919 1.1 skrll OP_MASK_RT]);
920 1.1 skrll break;
921 1.1 skrll
922 1.1 skrll case 'T': /* Coprocessor 0 reg name */
923 1.1 skrll {
924 1.1 skrll const struct mips_cp0sel_name *n;
925 1.1 skrll unsigned int cp0reg, sel;
926 1.1 skrll
927 1.1 skrll cp0reg = (l >> OP_SH_RT) & OP_MASK_RT;
928 1.1 skrll sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
929 1.1 skrll
930 1.1 skrll /* CP0 register including 'sel' code for mftc0, to be
931 1.1 skrll printed textually if known. If not known, print both
932 1.1 skrll CP0 register name and sel numerically since CP0 register
933 1.1 skrll with sel 0 may have a name unrelated to register being
934 1.1 skrll printed. */
935 1.1 skrll n = lookup_mips_cp0sel_name(mips_cp0sel_names,
936 1.1 skrll mips_cp0sel_names_len, cp0reg, sel);
937 1.1 skrll if (n != NULL)
938 1.1 skrll (*info->fprintf_func) (info->stream, "%s", n->name);
939 1.1 skrll else
940 1.1 skrll (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
941 1.1 skrll break;
942 1.1 skrll }
943 1.1 skrll
944 1.1 skrll case 'x': /* bbit bit index */
945 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
946 1.1 skrll (l >> OP_SH_BBITIND) & OP_MASK_BBITIND);
947 1.1 skrll break;
948 1.1 skrll
949 1.1 skrll case 'p': /* cins, cins32, exts and exts32 position */
950 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
951 1.1 skrll (l >> OP_SH_CINSPOS) & OP_MASK_CINSPOS);
952 1.1 skrll break;
953 1.1 skrll
954 1.1 skrll case 's': /* cins and exts length-minus-one */
955 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
956 1.1 skrll (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1);
957 1.1 skrll break;
958 1.1 skrll
959 1.1 skrll case 'S': /* cins32 and exts32 length-minus-one field */
960 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
961 1.1 skrll (l >> OP_SH_CINSLM1) & OP_MASK_CINSLM1);
962 1.1 skrll break;
963 1.1 skrll
964 1.1 skrll case 'Q': /* seqi/snei immediate field */
965 1.1 skrll op = (l >> OP_SH_SEQI) & OP_MASK_SEQI;
966 1.1 skrll /* Sign-extend it. */
967 1.1 skrll op = (op ^ 512) - 512;
968 1.1 skrll (*info->fprintf_func) (info->stream, "%d", op);
969 1.1 skrll break;
970 1.1 skrll
971 1.1 skrll default:
972 1.1 skrll /* xgettext:c-format */
973 1.1 skrll (*info->fprintf_func) (info->stream,
974 1.1 skrll _("# internal error, undefined extension sequence (+%c)"),
975 1.1 skrll *d);
976 1.1 skrll return;
977 1.1 skrll }
978 1.1 skrll break;
979 1.1 skrll
980 1.1 skrll case '2':
981 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
982 1.1 skrll (l >> OP_SH_BP) & OP_MASK_BP);
983 1.1 skrll break;
984 1.1 skrll
985 1.1 skrll case '3':
986 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
987 1.1 skrll (l >> OP_SH_SA3) & OP_MASK_SA3);
988 1.1 skrll break;
989 1.1 skrll
990 1.1 skrll case '4':
991 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
992 1.1 skrll (l >> OP_SH_SA4) & OP_MASK_SA4);
993 1.1 skrll break;
994 1.1 skrll
995 1.1 skrll case '5':
996 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
997 1.1 skrll (l >> OP_SH_IMM8) & OP_MASK_IMM8);
998 1.1 skrll break;
999 1.1 skrll
1000 1.1 skrll case '6':
1001 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1002 1.1 skrll (l >> OP_SH_RS) & OP_MASK_RS);
1003 1.1 skrll break;
1004 1.1 skrll
1005 1.1 skrll case '7':
1006 1.1 skrll (*info->fprintf_func) (info->stream, "$ac%ld",
1007 1.1 skrll (l >> OP_SH_DSPACC) & OP_MASK_DSPACC);
1008 1.1 skrll break;
1009 1.1 skrll
1010 1.1 skrll case '8':
1011 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1012 1.1 skrll (l >> OP_SH_WRDSP) & OP_MASK_WRDSP);
1013 1.1 skrll break;
1014 1.1 skrll
1015 1.1 skrll case '9':
1016 1.1 skrll (*info->fprintf_func) (info->stream, "$ac%ld",
1017 1.1 skrll (l >> OP_SH_DSPACC_S) & OP_MASK_DSPACC_S);
1018 1.1 skrll break;
1019 1.1 skrll
1020 1.1 skrll case '0': /* dsp 6-bit signed immediate in bit 20 */
1021 1.1 skrll delta = ((l >> OP_SH_DSPSFT) & OP_MASK_DSPSFT);
1022 1.1 skrll if (delta & 0x20) /* test sign bit */
1023 1.1 skrll delta |= ~OP_MASK_DSPSFT;
1024 1.1 skrll (*info->fprintf_func) (info->stream, "%d", delta);
1025 1.1 skrll break;
1026 1.1 skrll
1027 1.1 skrll case ':': /* dsp 7-bit signed immediate in bit 19 */
1028 1.1 skrll delta = ((l >> OP_SH_DSPSFT_7) & OP_MASK_DSPSFT_7);
1029 1.1 skrll if (delta & 0x40) /* test sign bit */
1030 1.1 skrll delta |= ~OP_MASK_DSPSFT_7;
1031 1.1 skrll (*info->fprintf_func) (info->stream, "%d", delta);
1032 1.1 skrll break;
1033 1.1 skrll
1034 1.1 skrll case '\'':
1035 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1036 1.1 skrll (l >> OP_SH_RDDSP) & OP_MASK_RDDSP);
1037 1.1 skrll break;
1038 1.1 skrll
1039 1.1 skrll case '@': /* dsp 10-bit signed immediate in bit 16 */
1040 1.1 skrll delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
1041 1.1 skrll if (delta & 0x200) /* test sign bit */
1042 1.1 skrll delta |= ~OP_MASK_IMM10;
1043 1.1 skrll (*info->fprintf_func) (info->stream, "%d", delta);
1044 1.1 skrll break;
1045 1.1 skrll
1046 1.1 skrll case '!':
1047 1.1 skrll (*info->fprintf_func) (info->stream, "%ld",
1048 1.1 skrll (l >> OP_SH_MT_U) & OP_MASK_MT_U);
1049 1.1 skrll break;
1050 1.1 skrll
1051 1.1 skrll case '$':
1052 1.1 skrll (*info->fprintf_func) (info->stream, "%ld",
1053 1.1 skrll (l >> OP_SH_MT_H) & OP_MASK_MT_H);
1054 1.1 skrll break;
1055 1.1 skrll
1056 1.1 skrll case '*':
1057 1.1 skrll (*info->fprintf_func) (info->stream, "$ac%ld",
1058 1.1 skrll (l >> OP_SH_MTACC_T) & OP_MASK_MTACC_T);
1059 1.1 skrll break;
1060 1.1 skrll
1061 1.1 skrll case '&':
1062 1.1 skrll (*info->fprintf_func) (info->stream, "$ac%ld",
1063 1.1 skrll (l >> OP_SH_MTACC_D) & OP_MASK_MTACC_D);
1064 1.1 skrll break;
1065 1.1 skrll
1066 1.1 skrll case 'g':
1067 1.1 skrll /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
1068 1.1 skrll (*info->fprintf_func) (info->stream, "$%ld",
1069 1.1 skrll (l >> OP_SH_RD) & OP_MASK_RD);
1070 1.1 skrll break;
1071 1.1 skrll
1072 1.1 skrll case 's':
1073 1.1 skrll case 'b':
1074 1.1 skrll case 'r':
1075 1.1 skrll case 'v':
1076 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1077 1.1 skrll mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
1078 1.1 skrll break;
1079 1.1 skrll
1080 1.1 skrll case 't':
1081 1.1 skrll case 'w':
1082 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1083 1.1 skrll mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
1084 1.1 skrll break;
1085 1.1 skrll
1086 1.1 skrll case 'i':
1087 1.1 skrll case 'u':
1088 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1089 1.1 skrll (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
1090 1.1 skrll break;
1091 1.1 skrll
1092 1.1 skrll case 'j': /* Same as i, but sign-extended. */
1093 1.1 skrll case 'o':
1094 1.1 skrll delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
1095 1.1 skrll if (delta & 0x8000)
1096 1.1 skrll delta |= ~0xffff;
1097 1.1 skrll (*info->fprintf_func) (info->stream, "%d",
1098 1.1 skrll delta);
1099 1.1 skrll break;
1100 1.1 skrll
1101 1.1 skrll case 'h':
1102 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x",
1103 1.1 skrll (unsigned int) ((l >> OP_SH_PREFX)
1104 1.1 skrll & OP_MASK_PREFX));
1105 1.1 skrll break;
1106 1.1 skrll
1107 1.1 skrll case 'k':
1108 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x",
1109 1.1 skrll (unsigned int) ((l >> OP_SH_CACHE)
1110 1.1 skrll & OP_MASK_CACHE));
1111 1.1 skrll break;
1112 1.1 skrll
1113 1.1 skrll case 'a':
1114 1.1 skrll info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
1115 1.1 skrll | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
1116 1.1 skrll /* For gdb disassembler, force odd address on jalx. */
1117 1.1 skrll if (info->flavour == bfd_target_unknown_flavour
1118 1.1 skrll && strcmp (opp->name, "jalx") == 0)
1119 1.1 skrll info->target |= 1;
1120 1.1 skrll (*info->print_address_func) (info->target, info);
1121 1.1 skrll break;
1122 1.1 skrll
1123 1.1 skrll case 'p':
1124 1.1 skrll /* Sign extend the displacement. */
1125 1.1 skrll delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
1126 1.1 skrll if (delta & 0x8000)
1127 1.1 skrll delta |= ~0xffff;
1128 1.1 skrll info->target = (delta << 2) + pc + INSNLEN;
1129 1.1 skrll (*info->print_address_func) (info->target, info);
1130 1.1 skrll break;
1131 1.1 skrll
1132 1.1 skrll case 'd':
1133 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1134 1.1 skrll mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1135 1.1 skrll break;
1136 1.1 skrll
1137 1.1 skrll case 'U':
1138 1.1 skrll {
1139 1.1 skrll /* First check for both rd and rt being equal. */
1140 1.1 skrll unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
1141 1.1 skrll if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
1142 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1143 1.1 skrll mips_gpr_names[reg]);
1144 1.1 skrll else
1145 1.1 skrll {
1146 1.1 skrll /* If one is zero use the other. */
1147 1.1 skrll if (reg == 0)
1148 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1149 1.1 skrll mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
1150 1.1 skrll else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
1151 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1152 1.1 skrll mips_gpr_names[reg]);
1153 1.1 skrll else /* Bogus, result depends on processor. */
1154 1.1 skrll (*info->fprintf_func) (info->stream, "%s or %s",
1155 1.1 skrll mips_gpr_names[reg],
1156 1.1 skrll mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
1157 1.1 skrll }
1158 1.1 skrll }
1159 1.1 skrll break;
1160 1.1 skrll
1161 1.1 skrll case 'z':
1162 1.1 skrll (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
1163 1.1 skrll break;
1164 1.1 skrll
1165 1.1 skrll case '<':
1166 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1167 1.1 skrll (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
1168 1.1 skrll break;
1169 1.1 skrll
1170 1.1 skrll case 'c':
1171 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1172 1.1 skrll (l >> OP_SH_CODE) & OP_MASK_CODE);
1173 1.1 skrll break;
1174 1.1 skrll
1175 1.1 skrll case 'q':
1176 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1177 1.1 skrll (l >> OP_SH_CODE2) & OP_MASK_CODE2);
1178 1.1 skrll break;
1179 1.1 skrll
1180 1.1 skrll case 'C':
1181 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1182 1.1 skrll (l >> OP_SH_COPZ) & OP_MASK_COPZ);
1183 1.1 skrll break;
1184 1.1 skrll
1185 1.1 skrll case 'B':
1186 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1187 1.1 skrll
1188 1.1 skrll (l >> OP_SH_CODE20) & OP_MASK_CODE20);
1189 1.1 skrll break;
1190 1.1 skrll
1191 1.1 skrll case 'J':
1192 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1193 1.1 skrll (l >> OP_SH_CODE19) & OP_MASK_CODE19);
1194 1.1 skrll break;
1195 1.1 skrll
1196 1.1 skrll case 'S':
1197 1.1 skrll case 'V':
1198 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1199 1.1 skrll mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
1200 1.1 skrll break;
1201 1.1 skrll
1202 1.1 skrll case 'T':
1203 1.1 skrll case 'W':
1204 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1205 1.1 skrll mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
1206 1.1 skrll break;
1207 1.1 skrll
1208 1.1 skrll case 'D':
1209 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1210 1.1 skrll mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
1211 1.1 skrll break;
1212 1.1 skrll
1213 1.1 skrll case 'R':
1214 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1215 1.1 skrll mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
1216 1.1 skrll break;
1217 1.1 skrll
1218 1.1 skrll case 'E':
1219 1.1 skrll /* Coprocessor register for lwcN instructions, et al.
1220 1.1 skrll
1221 1.1 skrll Note that there is no load/store cp0 instructions, and
1222 1.1 skrll that FPU (cp1) instructions disassemble this field using
1223 1.1 skrll 'T' format. Therefore, until we gain understanding of
1224 1.1 skrll cp2 register names, we can simply print the register
1225 1.1 skrll numbers. */
1226 1.1 skrll (*info->fprintf_func) (info->stream, "$%ld",
1227 1.1 skrll (l >> OP_SH_RT) & OP_MASK_RT);
1228 1.1 skrll break;
1229 1.1 skrll
1230 1.1 skrll case 'G':
1231 1.1 skrll /* Coprocessor register for mtcN instructions, et al. Note
1232 1.1 skrll that FPU (cp1) instructions disassemble this field using
1233 1.1 skrll 'S' format. Therefore, we only need to worry about cp0,
1234 1.1 skrll cp2, and cp3. */
1235 1.1 skrll op = (l >> OP_SH_OP) & OP_MASK_OP;
1236 1.1 skrll if (op == OP_OP_COP0)
1237 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1238 1.1 skrll mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1239 1.1 skrll else
1240 1.1 skrll (*info->fprintf_func) (info->stream, "$%ld",
1241 1.1 skrll (l >> OP_SH_RD) & OP_MASK_RD);
1242 1.1 skrll break;
1243 1.1 skrll
1244 1.1 skrll case 'K':
1245 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1246 1.1 skrll mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
1247 1.1 skrll break;
1248 1.1 skrll
1249 1.1 skrll case 'N':
1250 1.1 skrll (*info->fprintf_func) (info->stream,
1251 1.1 skrll ((opp->pinfo & (FP_D | FP_S)) != 0
1252 1.1 skrll ? "$fcc%ld" : "$cc%ld"),
1253 1.1 skrll (l >> OP_SH_BCC) & OP_MASK_BCC);
1254 1.1 skrll break;
1255 1.1 skrll
1256 1.1 skrll case 'M':
1257 1.1 skrll (*info->fprintf_func) (info->stream, "$fcc%ld",
1258 1.1 skrll (l >> OP_SH_CCC) & OP_MASK_CCC);
1259 1.1 skrll break;
1260 1.1 skrll
1261 1.1 skrll case 'P':
1262 1.1 skrll (*info->fprintf_func) (info->stream, "%ld",
1263 1.1 skrll (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
1264 1.1 skrll break;
1265 1.1 skrll
1266 1.1 skrll case 'e':
1267 1.1 skrll (*info->fprintf_func) (info->stream, "%ld",
1268 1.1 skrll (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
1269 1.1 skrll break;
1270 1.1 skrll
1271 1.1 skrll case '%':
1272 1.1 skrll (*info->fprintf_func) (info->stream, "%ld",
1273 1.1 skrll (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
1274 1.1 skrll break;
1275 1.1 skrll
1276 1.1 skrll case 'H':
1277 1.1 skrll (*info->fprintf_func) (info->stream, "%ld",
1278 1.1 skrll (l >> OP_SH_SEL) & OP_MASK_SEL);
1279 1.1 skrll break;
1280 1.1 skrll
1281 1.1 skrll case 'O':
1282 1.1 skrll (*info->fprintf_func) (info->stream, "%ld",
1283 1.1 skrll (l >> OP_SH_ALN) & OP_MASK_ALN);
1284 1.1 skrll break;
1285 1.1 skrll
1286 1.1 skrll case 'Q':
1287 1.1 skrll {
1288 1.1 skrll unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
1289 1.1 skrll
1290 1.1 skrll if ((vsel & 0x10) == 0)
1291 1.1 skrll {
1292 1.1 skrll int fmt;
1293 1.1 skrll
1294 1.1 skrll vsel &= 0x0f;
1295 1.1 skrll for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
1296 1.1 skrll if ((vsel & 1) == 0)
1297 1.1 skrll break;
1298 1.1 skrll (*info->fprintf_func) (info->stream, "$v%ld[%d]",
1299 1.1 skrll (l >> OP_SH_FT) & OP_MASK_FT,
1300 1.1 skrll vsel >> 1);
1301 1.1 skrll }
1302 1.1 skrll else if ((vsel & 0x08) == 0)
1303 1.1 skrll {
1304 1.1 skrll (*info->fprintf_func) (info->stream, "$v%ld",
1305 1.1 skrll (l >> OP_SH_FT) & OP_MASK_FT);
1306 1.1 skrll }
1307 1.1 skrll else
1308 1.1 skrll {
1309 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx",
1310 1.1 skrll (l >> OP_SH_FT) & OP_MASK_FT);
1311 1.1 skrll }
1312 1.1 skrll }
1313 1.1 skrll break;
1314 1.1 skrll
1315 1.1 skrll case 'X':
1316 1.1 skrll (*info->fprintf_func) (info->stream, "$v%ld",
1317 1.1 skrll (l >> OP_SH_FD) & OP_MASK_FD);
1318 1.1 skrll break;
1319 1.1 skrll
1320 1.1 skrll case 'Y':
1321 1.1 skrll (*info->fprintf_func) (info->stream, "$v%ld",
1322 1.1 skrll (l >> OP_SH_FS) & OP_MASK_FS);
1323 1.1 skrll break;
1324 1.1 skrll
1325 1.1 skrll case 'Z':
1326 1.1 skrll (*info->fprintf_func) (info->stream, "$v%ld",
1327 1.1 skrll (l >> OP_SH_FT) & OP_MASK_FT);
1328 1.1 skrll break;
1329 1.1 skrll
1330 1.1 skrll default:
1331 1.1 skrll /* xgettext:c-format */
1332 1.1 skrll (*info->fprintf_func) (info->stream,
1333 1.1 skrll _("# internal error, undefined modifier (%c)"),
1334 1.1 skrll *d);
1335 1.1 skrll return;
1336 1.1 skrll }
1337 1.1 skrll }
1338 1.1 skrll }
1339 1.1 skrll
1340 1.1 skrll /* Print the mips instruction at address MEMADDR in debugged memory,
1342 1.1 skrll on using INFO. Returns length of the instruction, in bytes, which is
1343 1.1 skrll always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if
1344 1.1 skrll this is little-endian code. */
1345 1.1 skrll
1346 1.1 skrll static int
1347 1.1 skrll print_insn_mips (bfd_vma memaddr,
1348 1.1 skrll unsigned long int word,
1349 1.1 skrll struct disassemble_info *info)
1350 1.1 skrll {
1351 1.1 skrll const struct mips_opcode *op;
1352 1.1 skrll static bfd_boolean init = 0;
1353 1.1 skrll static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
1354 1.1 skrll
1355 1.1 skrll /* Build a hash table to shorten the search time. */
1356 1.1 skrll if (! init)
1357 1.1 skrll {
1358 1.1 skrll unsigned int i;
1359 1.1 skrll
1360 1.1 skrll for (i = 0; i <= OP_MASK_OP; i++)
1361 1.1 skrll {
1362 1.1 skrll for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
1363 1.1 skrll {
1364 1.1 skrll if (op->pinfo == INSN_MACRO
1365 1.1 skrll || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
1366 1.1 skrll continue;
1367 1.1 skrll if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
1368 1.1 skrll {
1369 1.1 skrll mips_hash[i] = op;
1370 1.1 skrll break;
1371 1.1 skrll }
1372 1.1 skrll }
1373 1.1 skrll }
1374 1.1 skrll
1375 1.1 skrll init = 1;
1376 1.1 skrll }
1377 1.1 skrll
1378 1.1 skrll info->bytes_per_chunk = INSNLEN;
1379 1.1 skrll info->display_endian = info->endian;
1380 1.1 skrll info->insn_info_valid = 1;
1381 1.1 skrll info->branch_delay_insns = 0;
1382 1.1 skrll info->data_size = 0;
1383 1.1 skrll info->insn_type = dis_nonbranch;
1384 1.1 skrll info->target = 0;
1385 1.1 skrll info->target2 = 0;
1386 1.1 skrll
1387 1.1 skrll op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
1388 1.1 skrll if (op != NULL)
1389 1.1 skrll {
1390 1.1 skrll for (; op < &mips_opcodes[NUMOPCODES]; op++)
1391 1.1 skrll {
1392 1.1 skrll if (op->pinfo != INSN_MACRO
1393 1.1 skrll && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
1394 1.1 skrll && (word & op->mask) == op->match)
1395 1.1 skrll {
1396 1.1 skrll const char *d;
1397 1.1 skrll
1398 1.1 skrll /* We always allow to disassemble the jalx instruction. */
1399 1.1 skrll if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
1400 1.1 skrll && strcmp (op->name, "jalx"))
1401 1.1 skrll continue;
1402 1.1 skrll
1403 1.1 skrll /* Figure out instruction type and branch delay information. */
1404 1.1 skrll if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
1405 1.1 skrll {
1406 1.1 skrll if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1407 1.1 skrll info->insn_type = dis_jsr;
1408 1.1 skrll else
1409 1.1 skrll info->insn_type = dis_branch;
1410 1.1 skrll info->branch_delay_insns = 1;
1411 1.1 skrll }
1412 1.1 skrll else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
1413 1.1 skrll | INSN_COND_BRANCH_LIKELY)) != 0)
1414 1.1 skrll {
1415 1.1 skrll if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
1416 1.1 skrll info->insn_type = dis_condjsr;
1417 1.1 skrll else
1418 1.1 skrll info->insn_type = dis_condbranch;
1419 1.1 skrll info->branch_delay_insns = 1;
1420 1.1 skrll }
1421 1.1 skrll else if ((op->pinfo & (INSN_STORE_MEMORY
1422 1.1 skrll | INSN_LOAD_MEMORY_DELAY)) != 0)
1423 1.1 skrll info->insn_type = dis_dref;
1424 1.1 skrll
1425 1.1 skrll (*info->fprintf_func) (info->stream, "%s", op->name);
1426 1.1 skrll
1427 1.1 skrll d = op->args;
1428 1.1 skrll if (d != NULL && *d != '\0')
1429 1.1 skrll {
1430 1.1 skrll (*info->fprintf_func) (info->stream, "\t");
1431 1.1 skrll print_insn_args (d, word, memaddr, info, op);
1432 1.1 skrll }
1433 1.1 skrll
1434 1.1 skrll return INSNLEN;
1435 1.1 skrll }
1436 1.1 skrll }
1437 1.1 skrll }
1438 1.1 skrll
1439 1.1 skrll /* Handle undefined instructions. */
1440 1.1 skrll info->insn_type = dis_noninsn;
1441 1.1 skrll (*info->fprintf_func) (info->stream, "0x%lx", word);
1442 1.1 skrll return INSNLEN;
1443 1.1 skrll }
1444 1.1 skrll
1445 1.1 skrll /* Disassemble an operand for a mips16 instruction. */
1447 1.1 skrll
1448 1.1 skrll static void
1449 1.1 skrll print_mips16_insn_arg (char type,
1450 1.1 skrll const struct mips_opcode *op,
1451 1.1 skrll int l,
1452 1.1 skrll bfd_boolean use_extend,
1453 1.1 skrll int extend,
1454 1.1 skrll bfd_vma memaddr,
1455 1.1 skrll struct disassemble_info *info)
1456 1.1 skrll {
1457 1.1 skrll switch (type)
1458 1.1 skrll {
1459 1.1 skrll case ',':
1460 1.1 skrll case '(':
1461 1.1 skrll case ')':
1462 1.1 skrll (*info->fprintf_func) (info->stream, "%c", type);
1463 1.1 skrll break;
1464 1.1 skrll
1465 1.1 skrll case 'y':
1466 1.1 skrll case 'w':
1467 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1468 1.1 skrll mips16_reg_names(((l >> MIPS16OP_SH_RY)
1469 1.1 skrll & MIPS16OP_MASK_RY)));
1470 1.1 skrll break;
1471 1.1 skrll
1472 1.1 skrll case 'x':
1473 1.1 skrll case 'v':
1474 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1475 1.1 skrll mips16_reg_names(((l >> MIPS16OP_SH_RX)
1476 1.1 skrll & MIPS16OP_MASK_RX)));
1477 1.1 skrll break;
1478 1.1 skrll
1479 1.1 skrll case 'z':
1480 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1481 1.1 skrll mips16_reg_names(((l >> MIPS16OP_SH_RZ)
1482 1.1 skrll & MIPS16OP_MASK_RZ)));
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_MOVE32Z)
1488 1.1 skrll & MIPS16OP_MASK_MOVE32Z)));
1489 1.1 skrll break;
1490 1.1 skrll
1491 1.1 skrll case '0':
1492 1.1 skrll (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
1493 1.1 skrll break;
1494 1.1 skrll
1495 1.1 skrll case 'S':
1496 1.1 skrll (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]);
1497 1.1 skrll break;
1498 1.1 skrll
1499 1.1 skrll case 'P':
1500 1.1 skrll (*info->fprintf_func) (info->stream, "$pc");
1501 1.1 skrll break;
1502 1.1 skrll
1503 1.1 skrll case 'R':
1504 1.1 skrll (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]);
1505 1.1 skrll break;
1506 1.1 skrll
1507 1.1 skrll case 'X':
1508 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1509 1.1 skrll mips_gpr_names[((l >> MIPS16OP_SH_REGR32)
1510 1.1 skrll & MIPS16OP_MASK_REGR32)]);
1511 1.1 skrll break;
1512 1.1 skrll
1513 1.1 skrll case 'Y':
1514 1.1 skrll (*info->fprintf_func) (info->stream, "%s",
1515 1.1 skrll mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]);
1516 1.1 skrll break;
1517 1.1 skrll
1518 1.1 skrll case '<':
1519 1.1 skrll case '>':
1520 1.1 skrll case '[':
1521 1.1 skrll case ']':
1522 1.1 skrll case '4':
1523 1.1 skrll case '5':
1524 1.1 skrll case 'H':
1525 1.1 skrll case 'W':
1526 1.1 skrll case 'D':
1527 1.1 skrll case 'j':
1528 1.1 skrll case '6':
1529 1.1 skrll case '8':
1530 1.1 skrll case 'V':
1531 1.1 skrll case 'C':
1532 1.1 skrll case 'U':
1533 1.1 skrll case 'k':
1534 1.1 skrll case 'K':
1535 1.1 skrll case 'p':
1536 1.1 skrll case 'q':
1537 1.1 skrll case 'A':
1538 1.1 skrll case 'B':
1539 1.1 skrll case 'E':
1540 1.1 skrll {
1541 1.1 skrll int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
1542 1.1 skrll
1543 1.1 skrll shift = 0;
1544 1.1 skrll signedp = 0;
1545 1.1 skrll extbits = 16;
1546 1.1 skrll pcrel = 0;
1547 1.1 skrll extu = 0;
1548 1.1 skrll branch = 0;
1549 1.1 skrll switch (type)
1550 1.1 skrll {
1551 1.1 skrll case '<':
1552 1.1 skrll nbits = 3;
1553 1.1 skrll immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
1554 1.1 skrll extbits = 5;
1555 1.1 skrll extu = 1;
1556 1.1 skrll break;
1557 1.1 skrll case '>':
1558 1.1 skrll nbits = 3;
1559 1.1 skrll immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
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_RZ) & MIPS16OP_MASK_RZ;
1566 1.1 skrll extbits = 6;
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_RX) & MIPS16OP_MASK_RX;
1572 1.1 skrll extbits = 6;
1573 1.1 skrll extu = 1;
1574 1.1 skrll break;
1575 1.1 skrll case '4':
1576 1.1 skrll nbits = 4;
1577 1.1 skrll immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
1578 1.1 skrll signedp = 1;
1579 1.1 skrll extbits = 15;
1580 1.1 skrll break;
1581 1.1 skrll case '5':
1582 1.1 skrll nbits = 5;
1583 1.1 skrll immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1584 1.1 skrll info->insn_type = dis_dref;
1585 1.1 skrll info->data_size = 1;
1586 1.1 skrll break;
1587 1.1 skrll case 'H':
1588 1.1 skrll nbits = 5;
1589 1.1 skrll shift = 1;
1590 1.1 skrll immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1591 1.1 skrll info->insn_type = dis_dref;
1592 1.1 skrll info->data_size = 2;
1593 1.1 skrll break;
1594 1.1 skrll case 'W':
1595 1.1 skrll nbits = 5;
1596 1.1 skrll shift = 2;
1597 1.1 skrll immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1598 1.1 skrll if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
1599 1.1 skrll && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
1600 1.1 skrll {
1601 1.1 skrll info->insn_type = dis_dref;
1602 1.1 skrll info->data_size = 4;
1603 1.1 skrll }
1604 1.1 skrll break;
1605 1.1 skrll case 'D':
1606 1.1 skrll nbits = 5;
1607 1.1 skrll shift = 3;
1608 1.1 skrll immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1609 1.1 skrll info->insn_type = dis_dref;
1610 1.1 skrll info->data_size = 8;
1611 1.1 skrll break;
1612 1.1 skrll case 'j':
1613 1.1 skrll nbits = 5;
1614 1.1 skrll immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1615 1.1 skrll signedp = 1;
1616 1.1 skrll break;
1617 1.1 skrll case '6':
1618 1.1 skrll nbits = 6;
1619 1.1 skrll immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1620 1.1 skrll break;
1621 1.1 skrll case '8':
1622 1.1 skrll nbits = 8;
1623 1.1 skrll immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1624 1.1 skrll break;
1625 1.1 skrll case 'V':
1626 1.1 skrll nbits = 8;
1627 1.1 skrll shift = 2;
1628 1.1 skrll immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1629 1.1 skrll /* FIXME: This might be lw, or it might be addiu to $sp or
1630 1.1 skrll $pc. We assume it's load. */
1631 1.1 skrll info->insn_type = dis_dref;
1632 1.1 skrll info->data_size = 4;
1633 1.1 skrll break;
1634 1.1 skrll case 'C':
1635 1.1 skrll nbits = 8;
1636 1.1 skrll shift = 3;
1637 1.1 skrll immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1638 1.1 skrll info->insn_type = dis_dref;
1639 1.1 skrll info->data_size = 8;
1640 1.1 skrll break;
1641 1.1 skrll case 'U':
1642 1.1 skrll nbits = 8;
1643 1.1 skrll immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1644 1.1 skrll extu = 1;
1645 1.1 skrll break;
1646 1.1 skrll case 'k':
1647 1.1 skrll nbits = 8;
1648 1.1 skrll immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1649 1.1 skrll signedp = 1;
1650 1.1 skrll break;
1651 1.1 skrll case 'K':
1652 1.1 skrll nbits = 8;
1653 1.1 skrll shift = 3;
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 'p':
1658 1.1 skrll nbits = 8;
1659 1.1 skrll immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1660 1.1 skrll signedp = 1;
1661 1.1 skrll pcrel = 1;
1662 1.1 skrll branch = 1;
1663 1.1 skrll info->insn_type = dis_condbranch;
1664 1.1 skrll break;
1665 1.1 skrll case 'q':
1666 1.1 skrll nbits = 11;
1667 1.1 skrll immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1668 1.1 skrll signedp = 1;
1669 1.1 skrll pcrel = 1;
1670 1.1 skrll branch = 1;
1671 1.1 skrll info->insn_type = dis_branch;
1672 1.1 skrll break;
1673 1.1 skrll case 'A':
1674 1.1 skrll nbits = 8;
1675 1.1 skrll shift = 2;
1676 1.1 skrll immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1677 1.1 skrll pcrel = 1;
1678 1.1 skrll /* FIXME: This can be lw or la. We assume it is lw. */
1679 1.1 skrll info->insn_type = dis_dref;
1680 1.1 skrll info->data_size = 4;
1681 1.1 skrll break;
1682 1.1 skrll case 'B':
1683 1.1 skrll nbits = 5;
1684 1.1 skrll shift = 3;
1685 1.1 skrll immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1686 1.1 skrll pcrel = 1;
1687 1.1 skrll info->insn_type = dis_dref;
1688 1.1 skrll info->data_size = 8;
1689 1.1 skrll break;
1690 1.1 skrll case 'E':
1691 1.1 skrll nbits = 5;
1692 1.1 skrll shift = 2;
1693 1.1 skrll immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1694 1.1 skrll pcrel = 1;
1695 1.1 skrll break;
1696 1.1 skrll default:
1697 1.1 skrll abort ();
1698 1.1 skrll }
1699 1.1 skrll
1700 1.1 skrll if (! use_extend)
1701 1.1 skrll {
1702 1.1 skrll if (signedp && immed >= (1 << (nbits - 1)))
1703 1.1 skrll immed -= 1 << nbits;
1704 1.1 skrll immed <<= shift;
1705 1.1 skrll if ((type == '<' || type == '>' || type == '[' || type == ']')
1706 1.1 skrll && immed == 0)
1707 1.1 skrll immed = 8;
1708 1.1 skrll }
1709 1.1 skrll else
1710 1.1 skrll {
1711 1.1 skrll if (extbits == 16)
1712 1.1 skrll immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1713 1.1 skrll else if (extbits == 15)
1714 1.1 skrll immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1715 1.1 skrll else
1716 1.1 skrll immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1717 1.1 skrll immed &= (1 << extbits) - 1;
1718 1.1 skrll if (! extu && immed >= (1 << (extbits - 1)))
1719 1.1 skrll immed -= 1 << extbits;
1720 1.1 skrll }
1721 1.1 skrll
1722 1.1 skrll if (! pcrel)
1723 1.1 skrll (*info->fprintf_func) (info->stream, "%d", immed);
1724 1.1 skrll else
1725 1.1 skrll {
1726 1.1 skrll bfd_vma baseaddr;
1727 1.1 skrll
1728 1.1 skrll if (branch)
1729 1.1 skrll {
1730 1.1 skrll immed *= 2;
1731 1.1 skrll baseaddr = memaddr + 2;
1732 1.1 skrll }
1733 1.1 skrll else if (use_extend)
1734 1.1 skrll baseaddr = memaddr - 2;
1735 1.1 skrll else
1736 1.1 skrll {
1737 1.1 skrll int status;
1738 1.1 skrll bfd_byte buffer[2];
1739 1.1 skrll
1740 1.1 skrll baseaddr = memaddr;
1741 1.1 skrll
1742 1.1 skrll /* If this instruction is in the delay slot of a jr
1743 1.1 skrll instruction, the base address is the address of the
1744 1.1 skrll jr instruction. If it is in the delay slot of jalr
1745 1.1 skrll instruction, the base address is the address of the
1746 1.1 skrll jalr instruction. This test is unreliable: we have
1747 1.1 skrll no way of knowing whether the previous word is
1748 1.1 skrll instruction or data. */
1749 1.1 skrll status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1750 1.1 skrll info);
1751 1.1 skrll if (status == 0
1752 1.1 skrll && (((info->endian == BFD_ENDIAN_BIG
1753 1.1 skrll ? bfd_getb16 (buffer)
1754 1.1 skrll : bfd_getl16 (buffer))
1755 1.1 skrll & 0xf800) == 0x1800))
1756 1.1 skrll baseaddr = memaddr - 4;
1757 1.1 skrll else
1758 1.1 skrll {
1759 1.1 skrll status = (*info->read_memory_func) (memaddr - 2, buffer,
1760 1.1 skrll 2, info);
1761 1.1 skrll if (status == 0
1762 1.1 skrll && (((info->endian == BFD_ENDIAN_BIG
1763 1.1 skrll ? bfd_getb16 (buffer)
1764 1.1 skrll : bfd_getl16 (buffer))
1765 1.1 skrll & 0xf81f) == 0xe800))
1766 1.1 skrll baseaddr = memaddr - 2;
1767 1.1 skrll }
1768 1.1 skrll }
1769 1.1 skrll info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1770 1.1 skrll if (pcrel && branch
1771 1.1 skrll && info->flavour == bfd_target_unknown_flavour)
1772 1.1 skrll /* For gdb disassembler, maintain odd address. */
1773 1.1 skrll info->target |= 1;
1774 1.1 skrll (*info->print_address_func) (info->target, info);
1775 1.1 skrll }
1776 1.1 skrll }
1777 1.1 skrll break;
1778 1.1 skrll
1779 1.1 skrll case 'a':
1780 1.1 skrll {
1781 1.1 skrll int jalx = l & 0x400;
1782 1.1 skrll
1783 1.1 skrll if (! use_extend)
1784 1.1 skrll extend = 0;
1785 1.1 skrll l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1786 1.1 skrll if (!jalx && info->flavour == bfd_target_unknown_flavour)
1787 1.1 skrll /* For gdb disassembler, maintain odd address. */
1788 1.1 skrll l |= 1;
1789 1.1 skrll }
1790 1.1 skrll info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1791 1.1 skrll (*info->print_address_func) (info->target, info);
1792 1.1 skrll info->insn_type = dis_jsr;
1793 1.1 skrll info->branch_delay_insns = 1;
1794 1.1 skrll break;
1795 1.1 skrll
1796 1.1 skrll case 'l':
1797 1.1 skrll case 'L':
1798 1.1 skrll {
1799 1.1 skrll int need_comma, amask, smask;
1800 1.1 skrll
1801 1.1 skrll need_comma = 0;
1802 1.1 skrll
1803 1.1 skrll l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1804 1.1 skrll
1805 1.1 skrll amask = (l >> 3) & 7;
1806 1.1 skrll
1807 1.1 skrll if (amask > 0 && amask < 5)
1808 1.1 skrll {
1809 1.1 skrll (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
1810 1.1 skrll if (amask > 1)
1811 1.1 skrll (*info->fprintf_func) (info->stream, "-%s",
1812 1.1 skrll mips_gpr_names[amask + 3]);
1813 1.1 skrll need_comma = 1;
1814 1.1 skrll }
1815 1.1 skrll
1816 1.1 skrll smask = (l >> 1) & 3;
1817 1.1 skrll if (smask == 3)
1818 1.1 skrll {
1819 1.1 skrll (*info->fprintf_func) (info->stream, "%s??",
1820 1.1 skrll need_comma ? "," : "");
1821 1.1 skrll need_comma = 1;
1822 1.1 skrll }
1823 1.1 skrll else if (smask > 0)
1824 1.1 skrll {
1825 1.1 skrll (*info->fprintf_func) (info->stream, "%s%s",
1826 1.1 skrll need_comma ? "," : "",
1827 1.1 skrll mips_gpr_names[16]);
1828 1.1 skrll if (smask > 1)
1829 1.1 skrll (*info->fprintf_func) (info->stream, "-%s",
1830 1.1 skrll mips_gpr_names[smask + 15]);
1831 1.1 skrll need_comma = 1;
1832 1.1 skrll }
1833 1.1 skrll
1834 1.1 skrll if (l & 1)
1835 1.1 skrll {
1836 1.1 skrll (*info->fprintf_func) (info->stream, "%s%s",
1837 1.1 skrll need_comma ? "," : "",
1838 1.1 skrll mips_gpr_names[31]);
1839 1.1 skrll need_comma = 1;
1840 1.1 skrll }
1841 1.1 skrll
1842 1.1 skrll if (amask == 5 || amask == 6)
1843 1.1 skrll {
1844 1.1 skrll (*info->fprintf_func) (info->stream, "%s$f0",
1845 1.1 skrll need_comma ? "," : "");
1846 1.1 skrll if (amask == 6)
1847 1.1 skrll (*info->fprintf_func) (info->stream, "-$f1");
1848 1.1 skrll }
1849 1.1 skrll }
1850 1.1 skrll break;
1851 1.1 skrll
1852 1.1 skrll case 'm':
1853 1.1 skrll case 'M':
1854 1.1 skrll /* MIPS16e save/restore. */
1855 1.1 skrll {
1856 1.1 skrll int need_comma = 0;
1857 1.1 skrll int amask, args, statics;
1858 1.1 skrll int nsreg, smask;
1859 1.1 skrll int framesz;
1860 1.1 skrll int i, j;
1861 1.1 skrll
1862 1.1 skrll l = l & 0x7f;
1863 1.1 skrll if (use_extend)
1864 1.1 skrll l |= extend << 16;
1865 1.1 skrll
1866 1.1 skrll amask = (l >> 16) & 0xf;
1867 1.1 skrll if (amask == MIPS16_ALL_ARGS)
1868 1.1 skrll {
1869 1.1 skrll args = 4;
1870 1.1 skrll statics = 0;
1871 1.1 skrll }
1872 1.1 skrll else if (amask == MIPS16_ALL_STATICS)
1873 1.1 skrll {
1874 1.1 skrll args = 0;
1875 1.1 skrll statics = 4;
1876 1.1 skrll }
1877 1.1 skrll else
1878 1.1 skrll {
1879 1.1 skrll args = amask >> 2;
1880 1.1 skrll statics = amask & 3;
1881 1.1 skrll }
1882 1.1 skrll
1883 1.1 skrll if (args > 0) {
1884 1.1 skrll (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
1885 1.1 skrll if (args > 1)
1886 1.1 skrll (*info->fprintf_func) (info->stream, "-%s",
1887 1.1 skrll mips_gpr_names[4 + args - 1]);
1888 1.1 skrll need_comma = 1;
1889 1.1 skrll }
1890 1.1 skrll
1891 1.1 skrll framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
1892 1.1 skrll if (framesz == 0 && !use_extend)
1893 1.1 skrll framesz = 128;
1894 1.1 skrll
1895 1.1 skrll (*info->fprintf_func) (info->stream, "%s%d",
1896 1.1 skrll need_comma ? "," : "",
1897 1.1 skrll framesz);
1898 1.1 skrll
1899 1.1 skrll if (l & 0x40) /* $ra */
1900 1.1 skrll (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[31]);
1901 1.1 skrll
1902 1.1 skrll nsreg = (l >> 24) & 0x7;
1903 1.1 skrll smask = 0;
1904 1.1 skrll if (l & 0x20) /* $s0 */
1905 1.1 skrll smask |= 1 << 0;
1906 1.1 skrll if (l & 0x10) /* $s1 */
1907 1.1 skrll smask |= 1 << 1;
1908 1.1 skrll if (nsreg > 0) /* $s2-$s8 */
1909 1.1 skrll smask |= ((1 << nsreg) - 1) << 2;
1910 1.1 skrll
1911 1.1 skrll /* Find first set static reg bit. */
1912 1.1 skrll for (i = 0; i < 9; i++)
1913 1.1 skrll {
1914 1.1 skrll if (smask & (1 << i))
1915 1.1 skrll {
1916 1.1 skrll (*info->fprintf_func) (info->stream, ",%s",
1917 1.1 skrll mips_gpr_names[i == 8 ? 30 : (16 + i)]);
1918 1.1 skrll /* Skip over string of set bits. */
1919 1.1 skrll for (j = i; smask & (2 << j); j++)
1920 1.1 skrll continue;
1921 1.1 skrll if (j > i)
1922 1.1 skrll (*info->fprintf_func) (info->stream, "-%s",
1923 1.1 skrll mips_gpr_names[j == 8 ? 30 : (16 + j)]);
1924 1.1 skrll i = j + 1;
1925 1.1 skrll }
1926 1.1 skrll }
1927 1.1 skrll
1928 1.1 skrll /* Statics $ax - $a3. */
1929 1.1 skrll if (statics == 1)
1930 1.1 skrll (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[7]);
1931 1.1 skrll else if (statics > 0)
1932 1.1 skrll (*info->fprintf_func) (info->stream, ",%s-%s",
1933 1.1 skrll mips_gpr_names[7 - statics + 1],
1934 1.1 skrll mips_gpr_names[7]);
1935 1.1 skrll }
1936 1.1 skrll break;
1937 1.1 skrll
1938 1.1 skrll default:
1939 1.1 skrll /* xgettext:c-format */
1940 1.1 skrll (*info->fprintf_func)
1941 1.1 skrll (info->stream,
1942 1.1 skrll _("# internal disassembler error, unrecognised modifier (%c)"),
1943 1.1 skrll type);
1944 1.1 skrll abort ();
1945 1.1 skrll }
1946 1.1 skrll }
1947 1.1 skrll
1948 1.1 skrll /* Disassemble mips16 instructions. */
1949 1.1 skrll
1950 1.1 skrll static int
1951 1.1 skrll print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
1952 1.1 skrll {
1953 1.1 skrll int status;
1954 1.1 skrll bfd_byte buffer[2];
1955 1.1 skrll int length;
1956 1.1 skrll int insn;
1957 1.1 skrll bfd_boolean use_extend;
1958 1.1 skrll int extend = 0;
1959 1.1 skrll const struct mips_opcode *op, *opend;
1960 1.1 skrll
1961 1.1 skrll info->bytes_per_chunk = 2;
1962 1.1 skrll info->display_endian = info->endian;
1963 1.1 skrll info->insn_info_valid = 1;
1964 1.1 skrll info->branch_delay_insns = 0;
1965 1.1 skrll info->data_size = 0;
1966 1.1 skrll info->insn_type = dis_nonbranch;
1967 1.1 skrll info->target = 0;
1968 1.1 skrll info->target2 = 0;
1969 1.1 skrll
1970 1.1 skrll status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1971 1.1 skrll if (status != 0)
1972 1.1 skrll {
1973 1.1 skrll (*info->memory_error_func) (status, memaddr, info);
1974 1.1 skrll return -1;
1975 1.1 skrll }
1976 1.1 skrll
1977 1.1 skrll length = 2;
1978 1.1 skrll
1979 1.1 skrll if (info->endian == BFD_ENDIAN_BIG)
1980 1.1 skrll insn = bfd_getb16 (buffer);
1981 1.1 skrll else
1982 1.1 skrll insn = bfd_getl16 (buffer);
1983 1.1 skrll
1984 1.1 skrll /* Handle the extend opcode specially. */
1985 1.1 skrll use_extend = FALSE;
1986 1.1 skrll if ((insn & 0xf800) == 0xf000)
1987 1.1 skrll {
1988 1.1 skrll use_extend = TRUE;
1989 1.1 skrll extend = insn & 0x7ff;
1990 1.1 skrll
1991 1.1 skrll memaddr += 2;
1992 1.1 skrll
1993 1.1 skrll status = (*info->read_memory_func) (memaddr, buffer, 2, info);
1994 1.1 skrll if (status != 0)
1995 1.1 skrll {
1996 1.1 skrll (*info->fprintf_func) (info->stream, "extend 0x%x",
1997 1.1 skrll (unsigned int) extend);
1998 1.1 skrll (*info->memory_error_func) (status, memaddr, info);
1999 1.1 skrll return -1;
2000 1.1 skrll }
2001 1.1 skrll
2002 1.1 skrll if (info->endian == BFD_ENDIAN_BIG)
2003 1.1 skrll insn = bfd_getb16 (buffer);
2004 1.1 skrll else
2005 1.1 skrll insn = bfd_getl16 (buffer);
2006 1.1 skrll
2007 1.1 skrll /* Check for an extend opcode followed by an extend opcode. */
2008 1.1 skrll if ((insn & 0xf800) == 0xf000)
2009 1.1 skrll {
2010 1.1 skrll (*info->fprintf_func) (info->stream, "extend 0x%x",
2011 1.1 skrll (unsigned int) extend);
2012 1.1 skrll info->insn_type = dis_noninsn;
2013 1.1 skrll return length;
2014 1.1 skrll }
2015 1.1 skrll
2016 1.1 skrll length += 2;
2017 1.1 skrll }
2018 1.1 skrll
2019 1.1 skrll /* FIXME: Should probably use a hash table on the major opcode here. */
2020 1.1 skrll
2021 1.1 skrll opend = mips16_opcodes + bfd_mips16_num_opcodes;
2022 1.1 skrll for (op = mips16_opcodes; op < opend; op++)
2023 1.1 skrll {
2024 1.1 skrll if (op->pinfo != INSN_MACRO
2025 1.1 skrll && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2026 1.1 skrll && (insn & op->mask) == op->match)
2027 1.1 skrll {
2028 1.1 skrll const char *s;
2029 1.1 skrll
2030 1.1 skrll if (strchr (op->args, 'a') != NULL)
2031 1.1 skrll {
2032 1.1 skrll if (use_extend)
2033 1.1 skrll {
2034 1.1 skrll (*info->fprintf_func) (info->stream, "extend 0x%x",
2035 1.1 skrll (unsigned int) extend);
2036 1.1 skrll info->insn_type = dis_noninsn;
2037 1.1 skrll return length - 2;
2038 1.1 skrll }
2039 1.1 skrll
2040 1.1 skrll use_extend = FALSE;
2041 1.1 skrll
2042 1.1 skrll memaddr += 2;
2043 1.1 skrll
2044 1.1 skrll status = (*info->read_memory_func) (memaddr, buffer, 2,
2045 1.1 skrll info);
2046 1.1 skrll if (status == 0)
2047 1.1 skrll {
2048 1.1 skrll use_extend = TRUE;
2049 1.1 skrll if (info->endian == BFD_ENDIAN_BIG)
2050 1.1 skrll extend = bfd_getb16 (buffer);
2051 1.1 skrll else
2052 1.1 skrll extend = bfd_getl16 (buffer);
2053 1.1 skrll length += 2;
2054 1.1 skrll }
2055 1.1 skrll }
2056 1.1 skrll
2057 1.1 skrll (*info->fprintf_func) (info->stream, "%s", op->name);
2058 1.1 skrll if (op->args[0] != '\0')
2059 1.1 skrll (*info->fprintf_func) (info->stream, "\t");
2060 1.1 skrll
2061 1.1 skrll for (s = op->args; *s != '\0'; s++)
2062 1.1 skrll {
2063 1.1 skrll if (*s == ','
2064 1.1 skrll && s[1] == 'w'
2065 1.1 skrll && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
2066 1.1 skrll == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
2067 1.1 skrll {
2068 1.1 skrll /* Skip the register and the comma. */
2069 1.1 skrll ++s;
2070 1.1 skrll continue;
2071 1.1 skrll }
2072 1.1 skrll if (*s == ','
2073 1.1 skrll && s[1] == 'v'
2074 1.1 skrll && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
2075 1.1 skrll == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
2076 1.1 skrll {
2077 1.1 skrll /* Skip the register and the comma. */
2078 1.1 skrll ++s;
2079 1.1 skrll continue;
2080 1.1 skrll }
2081 1.1 skrll print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
2082 1.1 skrll info);
2083 1.1 skrll }
2084 1.1 skrll
2085 1.1 skrll if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
2086 1.1 skrll {
2087 1.1 skrll info->branch_delay_insns = 1;
2088 1.1 skrll if (info->insn_type != dis_jsr)
2089 1.1 skrll info->insn_type = dis_branch;
2090 1.1 skrll }
2091 1.1 skrll
2092 1.1 skrll return length;
2093 1.1 skrll }
2094 1.1 skrll }
2095 1.1 skrll
2096 1.1 skrll if (use_extend)
2097 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
2098 1.1 skrll (*info->fprintf_func) (info->stream, "0x%x", insn);
2099 1.1 skrll info->insn_type = dis_noninsn;
2100 1.1 skrll
2101 1.1 skrll return length;
2102 1.1 skrll }
2103 1.1 skrll
2104 1.1 skrll /* In an environment where we do not know the symbol type of the
2105 1.1 skrll instruction we are forced to assume that the low order bit of the
2106 1.1 skrll instructions' address may mark it as a mips16 instruction. If we
2107 1.1 skrll are single stepping, or the pc is within the disassembled function,
2108 1.1 skrll this works. Otherwise, we need a clue. Sometimes. */
2109 1.1 skrll
2110 1.1 skrll static int
2111 1.1 skrll _print_insn_mips (bfd_vma memaddr,
2112 1.1 skrll struct disassemble_info *info,
2113 1.1 skrll enum bfd_endian endianness)
2114 1.1 skrll {
2115 1.1 skrll bfd_byte buffer[INSNLEN];
2116 1.1 skrll int status;
2117 1.1 skrll
2118 1.1 skrll set_default_mips_dis_options (info);
2119 1.1 skrll parse_mips_dis_options (info->disassembler_options);
2120 1.1 skrll
2121 1.1 skrll #if 1
2122 1.1 skrll /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */
2123 1.1 skrll /* Only a few tools will work this way. */
2124 1.1 skrll if (memaddr & 0x01)
2125 1.1 skrll return print_insn_mips16 (memaddr, info);
2126 1.1 skrll #endif
2127 1.1 skrll
2128 1.1 skrll #if SYMTAB_AVAILABLE
2129 1.1 skrll if (info->mach == bfd_mach_mips16
2130 1.1 skrll || (info->symbols != NULL
2131 1.1 skrll && bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
2132 1.1 skrll && ELF_ST_IS_MIPS16 ((*(elf_symbol_type **) info->symbols)
2133 1.1 skrll ->internal_elf_sym.st_other)))
2134 1.1 skrll return print_insn_mips16 (memaddr, info);
2135 1.1 skrll #endif
2136 1.1 skrll
2137 1.1 skrll status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2138 1.1 skrll if (status == 0)
2139 1.1 skrll {
2140 1.1 skrll unsigned long insn;
2141 1.1 skrll
2142 1.1 skrll if (endianness == BFD_ENDIAN_BIG)
2143 1.1 skrll insn = (unsigned long) bfd_getb32 (buffer);
2144 1.1 skrll else
2145 1.1 skrll insn = (unsigned long) bfd_getl32 (buffer);
2146 1.1 skrll
2147 1.1 skrll return print_insn_mips (memaddr, insn, info);
2148 1.1 skrll }
2149 1.1 skrll else
2150 1.1 skrll {
2151 1.1 skrll (*info->memory_error_func) (status, memaddr, info);
2152 1.1 skrll return -1;
2153 1.1 skrll }
2154 1.1 skrll }
2155 1.1 skrll
2156 1.1 skrll int
2157 1.1 skrll print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
2158 1.1 skrll {
2159 1.1 skrll return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
2160 1.1 skrll }
2161 1.1 skrll
2162 1.1 skrll int
2163 1.1 skrll print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
2164 1.1 skrll {
2165 1.1 skrll return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
2166 1.1 skrll }
2167 1.1 skrll
2168 1.1 skrll void
2170 1.1 skrll print_mips_disassembler_options (FILE *stream)
2171 1.1 skrll {
2172 1.1 skrll unsigned int i;
2173 1.1 skrll
2174 1.1 skrll fprintf (stream, _("\n\
2175 1.1 skrll The following MIPS specific disassembler options are supported for use\n\
2176 1.1 skrll with the -M switch (multiple options should be separated by commas):\n"));
2177 1.1 skrll
2178 1.1 skrll fprintf (stream, _("\n\
2179 1.1 skrll gpr-names=ABI Print GPR names according to specified ABI.\n\
2180 1.1 skrll Default: based on binary being disassembled.\n"));
2181 1.1 skrll
2182 1.1 skrll fprintf (stream, _("\n\
2183 1.1 skrll fpr-names=ABI Print FPR names according to specified ABI.\n\
2184 1.1 skrll Default: numeric.\n"));
2185 1.1 skrll
2186 1.1 skrll fprintf (stream, _("\n\
2187 1.1 skrll cp0-names=ARCH Print CP0 register names according to\n\
2188 1.1 skrll specified architecture.\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 hwr-names=ARCH Print HWR names according to specified \n\
2193 1.1 skrll architecture.\n\
2194 1.1 skrll Default: based on binary being disassembled.\n"));
2195 1.1 skrll
2196 1.1 skrll fprintf (stream, _("\n\
2197 1.1 skrll reg-names=ABI Print GPR and FPR names according to\n\
2198 1.1 skrll specified ABI.\n"));
2199 1.1 skrll
2200 1.1 skrll fprintf (stream, _("\n\
2201 1.1 skrll reg-names=ARCH Print CP0 register and HWR names according to\n\
2202 1.1 skrll specified architecture.\n"));
2203 1.1 skrll
2204 1.1 skrll fprintf (stream, _("\n\
2205 1.1 skrll For the options above, the following values are supported for \"ABI\":\n\
2206 1.1 skrll "));
2207 1.1 skrll for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
2208 1.1 skrll fprintf (stream, " %s", mips_abi_choices[i].name);
2209 1.1 skrll fprintf (stream, _("\n"));
2210 1.1 skrll
2211 1.1 skrll fprintf (stream, _("\n\
2212 1.1 skrll For the options above, The following values are supported for \"ARCH\":\n\
2213 1.1 skrll "));
2214 1.1 skrll for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
2215 if (*mips_arch_choices[i].name != '\0')
2216 fprintf (stream, " %s", mips_arch_choices[i].name);
2217 fprintf (stream, _("\n"));
2218
2219 fprintf (stream, _("\n"));
2220 }
2221