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