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