mips-dis.c revision 1.3.8.1 1 1.1 skrll /* Print mips instructions for GDB, the GNU debugger, or for objdump.
2 1.1 skrll Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 1.3.8.1 tls 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.3.8.1 tls
61 1.3.8.1 tls /* The microMIPS registers with type b. */
62 1.3.8.1 tls #define micromips_to_32_reg_b_map mips16_to_32_reg_map
63 1.3.8.1 tls
64 1.3.8.1 tls /* The microMIPS registers with type c. */
65 1.3.8.1 tls #define micromips_to_32_reg_c_map mips16_to_32_reg_map
66 1.3.8.1 tls
67 1.3.8.1 tls /* The microMIPS registers with type d. */
68 1.3.8.1 tls #define micromips_to_32_reg_d_map mips16_to_32_reg_map
69 1.3.8.1 tls
70 1.3.8.1 tls /* The microMIPS registers with type e. */
71 1.3.8.1 tls #define micromips_to_32_reg_e_map mips16_to_32_reg_map
72 1.3.8.1 tls
73 1.3.8.1 tls /* The microMIPS registers with type f. */
74 1.3.8.1 tls #define micromips_to_32_reg_f_map mips16_to_32_reg_map
75 1.3.8.1 tls
76 1.3.8.1 tls /* The microMIPS registers with type g. */
77 1.3.8.1 tls #define micromips_to_32_reg_g_map mips16_to_32_reg_map
78 1.3.8.1 tls
79 1.3.8.1 tls /* The microMIPS registers with type h. */
80 1.3.8.1 tls static const unsigned int micromips_to_32_reg_h_map[] =
81 1.3.8.1 tls {
82 1.3.8.1 tls 5, 5, 6, 4, 4, 4, 4, 4
83 1.3.8.1 tls };
84 1.3.8.1 tls
85 1.3.8.1 tls /* The microMIPS registers with type i. */
86 1.3.8.1 tls static const unsigned int micromips_to_32_reg_i_map[] =
87 1.3.8.1 tls {
88 1.3.8.1 tls 6, 7, 7, 21, 22, 5, 6, 7
89 1.3.8.1 tls };
90 1.3.8.1 tls
91 1.3.8.1 tls /* The microMIPS registers with type j: 32 registers. */
92 1.3.8.1 tls
93 1.3.8.1 tls /* The microMIPS registers with type l. */
94 1.3.8.1 tls #define micromips_to_32_reg_l_map mips16_to_32_reg_map
95 1.3.8.1 tls
96 1.3.8.1 tls /* The microMIPS registers with type m. */
97 1.3.8.1 tls static const unsigned int micromips_to_32_reg_m_map[] =
98 1.3.8.1 tls {
99 1.3.8.1 tls 0, 17, 2, 3, 16, 18, 19, 20
100 1.3.8.1 tls };
101 1.3.8.1 tls
102 1.3.8.1 tls /* The microMIPS registers with type n. */
103 1.3.8.1 tls #define micromips_to_32_reg_n_map micromips_to_32_reg_m_map
104 1.3.8.1 tls
105 1.3.8.1 tls /* The microMIPS registers with type p: 32 registers. */
106 1.3.8.1 tls
107 1.3.8.1 tls /* The microMIPS registers with type q. */
108 1.3.8.1 tls static const unsigned int micromips_to_32_reg_q_map[] =
109 1.3.8.1 tls {
110 1.3.8.1 tls 0, 17, 2, 3, 4, 5, 6, 7
111 1.3.8.1 tls };
112 1.3.8.1 tls
113 1.3.8.1 tls /* reg type s is $29. */
114 1.3.8.1 tls
115 1.3.8.1 tls /* reg type t is the same as the last register. */
116 1.3.8.1 tls
117 1.3.8.1 tls /* reg type y is $31. */
118 1.3.8.1 tls
119 1.3.8.1 tls /* reg type z is $0. */
120 1.3.8.1 tls
121 1.3.8.1 tls /* micromips imm B type. */
122 1.3.8.1 tls static const int micromips_imm_b_map[8] =
123 1.3.8.1 tls {
124 1.3.8.1 tls 1, 4, 8, 12, 16, 20, 24, -1
125 1.3.8.1 tls };
126 1.3.8.1 tls
127 1.3.8.1 tls /* micromips imm C type. */
128 1.3.8.1 tls static const int micromips_imm_c_map[16] =
129 1.3.8.1 tls {
130 1.3.8.1 tls 128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 255, 32768, 65535
131 1.3.8.1 tls };
132 1.3.8.1 tls
133 1.3.8.1 tls /* micromips imm D type: (-512..511)<<1. */
134 1.3.8.1 tls /* micromips imm E type: (-64..63)<<1. */
135 1.3.8.1 tls /* micromips imm F type: (0..63). */
136 1.3.8.1 tls /* micromips imm G type: (-1..14). */
137 1.3.8.1 tls /* micromips imm H type: (0..15)<<1. */
138 1.3.8.1 tls /* micromips imm I type: (-1..126). */
139 1.3.8.1 tls /* micromips imm J type: (0..15)<<2. */
140 1.3.8.1 tls /* micromips imm L type: (0..15). */
141 1.3.8.1 tls /* micromips imm M type: (1..8). */
142 1.3.8.1 tls /* micromips imm W type: (0..63)<<2. */
143 1.3.8.1 tls /* micromips imm X type: (-8..7). */
144 1.3.8.1 tls /* 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.3.8.1 tls (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.3.8.1 tls (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.3.8.1 tls
601 1.3.8.1 tls { "loongson3a", 1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
602 1.3.8.1 tls ISA_MIPS64 | INSN_LOONGSON_3A, mips_cp0_names_numeric,
603 1.3.8.1 tls 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.3.8.1 tls
609 1.3.8.1 tls { "octeon+", 1, bfd_mach_mips_octeonp, CPU_OCTEONP,
610 1.3.8.1 tls ISA_MIPS64R2 | INSN_OCTEONP, mips_cp0_names_numeric,
611 1.3.8.1 tls NULL, 0, mips_hwr_names_numeric },
612 1.3.8.1 tls
613 1.3.8.1 tls { "octeon2", 1, bfd_mach_mips_octeon2, CPU_OCTEON2,
614 1.3.8.1 tls ISA_MIPS64R2 | INSN_OCTEON2, mips_cp0_names_numeric,
615 1.3.8.1 tls 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.3.8.1 tls
623 1.3.8.1 tls /* XLP is mostly like XLR, with the prominent exception it is being
624 1.3.8.1 tls MIPS64R2. */
625 1.3.8.1 tls { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
626 1.3.8.1 tls ISA_MIPS64R2 | INSN_XLR,
627 1.3.8.1 tls mips_cp0_names_xlr,
628 1.3.8.1 tls mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
629 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls }
725 1.3.8.1 tls
726 1.3.8.1 tls /* Check if the object has microMIPS ASE code. */
727 1.3.8.1 tls
728 1.3.8.1 tls static int
729 1.3.8.1 tls is_micromips (Elf_Internal_Ehdr *header)
730 1.3.8.1 tls {
731 1.3.8.1 tls if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
732 1.3.8.1 tls return 1;
733 1.3.8.1 tls
734 1.3.8.1 tls 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.3.8.1 tls const struct mips_arch_choice *chosen_arch;
741 1.3.8.1 tls
742 1.3.8.1 tls /* 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.3.8.1 tls CP0 register, and HWR names. */
745 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls if (is_newabi (header))
764 1.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls struct disassemble_info *info,
939 1.1 skrll const struct mips_opcode *opp)
940 1.3.8.1 tls {
941 1.3.8.1 tls 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.3.8.1 tls
946 1.3.8.1 tls lsb = 0;
947 1.3.8.1 tls
948 1.3.8.1 tls #define GET_OP(insn, field) \
949 1.3.8.1 tls (((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.3.8.1 tls 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.3.8.1 tls {
970 1.3.8.1 tls case '\0':
971 1.3.8.1 tls /* xgettext:c-format */
972 1.1 skrll infprintf (is,
973 1.1 skrll _("# internal error, "
974 1.1 skrll "incomplete extension sequence (+)"));
975 1.3.8.1 tls return;
976 1.3.8.1 tls
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.3.8.1 tls break;
981 1.3.8.1 tls
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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls
1003 1.3.8.1 tls 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.3.8.1 tls const struct mips_cp0sel_name *n;
1012 1.3.8.1 tls 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.3.8.1 tls n = lookup_mips_cp0sel_name(mips_cp0sel_names,
1023 1.1 skrll mips_cp0sel_names_len, cp0reg, sel);
1024 1.3.8.1 tls 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.3.8.1 tls }
1030 1.3.8.1 tls
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.3.8.1 tls break;
1035 1.3.8.1 tls
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.3.8.1 tls break;
1040 1.3.8.1 tls
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.3.8.1 tls 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.3.8.1 tls const struct mips_cp0sel_name *n;
1053 1.3.8.1 tls 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.3.8.1 tls n = lookup_mips_cp0sel_name(mips_cp0sel_names,
1064 1.1 skrll mips_cp0sel_names_len, cp0reg, sel);
1065 1.3.8.1 tls 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.3.8.1 tls }
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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls break;
1087 1.3.8.1 tls
1088 1.3.8.1 tls case 'Q': /* seqi/snei immediate field */
1089 1.3.8.1 tls infprintf (is, "%d", GET_OP_S (l, SEQI));
1090 1.3.8.1 tls break;
1091 1.3.8.1 tls
1092 1.3.8.1 tls case 'a': /* 8-bit signed offset in bit 6 */
1093 1.3.8.1 tls infprintf (is, "%d", GET_OP_S (l, OFFSET_A));
1094 1.3.8.1 tls break;
1095 1.3.8.1 tls
1096 1.3.8.1 tls case 'b': /* 8-bit signed offset in bit 3 */
1097 1.3.8.1 tls infprintf (is, "%d", GET_OP_S (l, OFFSET_B));
1098 1.3.8.1 tls break;
1099 1.3.8.1 tls
1100 1.3.8.1 tls case 'c': /* 9-bit signed offset in bit 6 */
1101 1.3.8.1 tls /* Left shift 4 bits to print the real offset. */
1102 1.3.8.1 tls infprintf (is, "%d", GET_OP_S (l, OFFSET_C) << 4);
1103 1.3.8.1 tls break;
1104 1.3.8.1 tls
1105 1.3.8.1 tls case 'z':
1106 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[GET_OP (l, RZ)]);
1107 1.3.8.1 tls 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.3.8.1 tls
1113 1.3.8.1 tls default:
1114 1.3.8.1 tls /* xgettext:c-format */
1115 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls break;
1158 1.3.8.1 tls
1159 1.3.8.1 tls case ':': /* dsp 7-bit signed immediate in bit 19 */
1160 1.3.8.1 tls infprintf (is, "%d", GET_OP_S (l, DSPSFT_7));
1161 1.3.8.1 tls break;
1162 1.3.8.1 tls
1163 1.3.8.1 tls case '~':
1164 1.3.8.1 tls infprintf (is, "%d", GET_OP_S (l, OFFSET12));
1165 1.3.8.1 tls break;
1166 1.1 skrll
1167 1.1 skrll case '\\':
1168 1.1 skrll infprintf (is, "0x%x", GET_OP (l, 3BITPOS));
1169 1.3.8.1 tls break;
1170 1.1 skrll
1171 1.1 skrll case '\'':
1172 1.1 skrll infprintf (is, "0x%x", GET_OP (l, RDDSP));
1173 1.3.8.1 tls 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.3.8.1 tls break;
1178 1.1 skrll
1179 1.1 skrll case '!':
1180 1.1 skrll infprintf (is, "%d", GET_OP (l, MT_U));
1181 1.3.8.1 tls break;
1182 1.1 skrll
1183 1.1 skrll case '$':
1184 1.1 skrll infprintf (is, "%d", GET_OP (l, MT_H));
1185 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls
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.3.8.1 tls
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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls
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.3.8.1 tls 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.3.8.1 tls case 'U':
1251 1.3.8.1 tls {
1252 1.3.8.1 tls /* 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.3.8.1 tls {
1258 1.3.8.1 tls /* If one is zero use the other. */
1259 1.3.8.1 tls if (reg == 0)
1260 1.1 skrll infprintf (is, "%s", mips_gpr_names[GET_OP (l, RT)]);
1261 1.3.8.1 tls else if (GET_OP (l, RT) == 0)
1262 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[reg]);
1263 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls
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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls '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.3.8.1 tls that FPU (cp1) instructions disassemble this field using
1332 1.1 skrll 'S' format. Therefore, we only need to worry about cp0,
1333 1.3.8.1 tls cp2, and cp3. */
1334 1.1 skrll op = GET_OP (l, OP);
1335 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls break;
1344 1.3.8.1 tls
1345 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls break;
1354 1.1 skrll
1355 1.1 skrll case 'P':
1356 1.1 skrll infprintf (is, "%d", GET_OP (l, PERFREG));
1357 1.3.8.1 tls break;
1358 1.1 skrll
1359 1.1 skrll case 'e':
1360 1.1 skrll infprintf (is, "%d", GET_OP (l, VECBYTE));
1361 1.3.8.1 tls break;
1362 1.1 skrll
1363 1.1 skrll case '%':
1364 1.1 skrll infprintf (is, "%d", GET_OP (l, VECALIGN));
1365 1.3.8.1 tls break;
1366 1.1 skrll
1367 1.1 skrll case 'H':
1368 1.1 skrll infprintf (is, "%d", GET_OP (l, SEL));
1369 1.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls 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.3.8.1 tls }
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.3.8.1 tls }
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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls this is little-endian code. */
1425 1.1 skrll
1426 1.1 skrll static int
1427 1.3.8.1 tls print_insn_mips (bfd_vma memaddr,
1428 1.3.8.1 tls int word,
1429 1.1 skrll struct disassemble_info *info)
1430 1.1 skrll {
1431 1.3.8.1 tls 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.3.8.1 tls {
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.3.8.1 tls 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.3.8.1 tls {
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.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls return INSNLEN;
1518 1.3.8.1 tls }
1519 1.1 skrll }
1520 1.1 skrll }
1521 1.1 skrll #undef GET_OP_S
1522 1.3.8.1 tls #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.3.8.1 tls bfd_boolean use_extend,
1538 1.3.8.1 tls int extend,
1539 1.3.8.1 tls bfd_vma memaddr,
1540 1.3.8.1 tls struct disassemble_info *info)
1541 1.3.8.1 tls {
1542 1.3.8.1 tls const fprintf_ftype infprintf = info->fprintf_func;
1543 1.3.8.1 tls void *is = info->stream;
1544 1.3.8.1 tls
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.3.8.1 tls switch (type)
1551 1.1 skrll {
1552 1.1 skrll case ',':
1553 1.1 skrll case '(':
1554 1.1 skrll case ')':
1555 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls case '0':
1577 1.1 skrll infprintf (is, "%s", mips_gpr_names[0]);
1578 1.1 skrll break;
1579 1.1 skrll
1580 1.3.8.1 tls case 'S':
1581 1.1 skrll infprintf (is, "%s", mips_gpr_names[29]);
1582 1.1 skrll break;
1583 1.1 skrll
1584 1.3.8.1 tls case 'P':
1585 1.1 skrll infprintf (is, "$pc");
1586 1.1 skrll break;
1587 1.1 skrll
1588 1.3.8.1 tls case 'R':
1589 1.1 skrll infprintf (is, "%s", mips_gpr_names[31]);
1590 1.1 skrll break;
1591 1.1 skrll
1592 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls }
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.3.8.1 tls 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.3.8.1 tls immed = GET_OP (l, IMM5);
1697 1.1 skrll signedp = 1;
1698 1.1 skrll break;
1699 1.1 skrll case '6':
1700 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls {
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.3.8.1 tls
1883 1.1 skrll amask = (l >> 3) & 7;
1884 1.3.8.1 tls
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.3.8.1 tls }
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.3.8.1 tls infprintf (is, "%s??", need_comma ? "," : "");
1897 1.1 skrll need_comma = 1;
1898 1.3.8.1 tls }
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.3.8.1 tls 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.3.8.1 tls need_comma = 1;
1911 1.1 skrll }
1912 1.3.8.1 tls
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.3.8.1 tls args = amask >> 2;
1950 1.1 skrll statics = amask & 3;
1951 1.3.8.1 tls }
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.3.8.1 tls
1960 1.1 skrll framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
1961 1.1 skrll if (framesz == 0 && !use_extend)
1962 1.3.8.1 tls 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.3.8.1 tls /* 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.3.8.1 tls 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.3.8.1 tls }
1991 1.1 skrll }
1992 1.3.8.1 tls
1993 1.3.8.1 tls /* Statics $ax - $a3. */
1994 1.3.8.1 tls 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.3.8.1 tls }
2001 1.3.8.1 tls break;
2002 1.3.8.1 tls
2003 1.3.8.1 tls 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.3.8.1 tls /* 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls extend = bfd_getl16 (buffer);
2117 1.1 skrll length += 2;
2118 1.3.8.1 tls }
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.3.8.1 tls
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.3.8.1 tls ++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.3.8.1 tls info->insn_type = dis_condbranch;
2160 1.3.8.1 tls
2161 1.1 skrll return length;
2162 1.1 skrll }
2163 1.3.8.1 tls }
2164 1.3.8.1 tls #undef GET_OP_S
2165 1.3.8.1 tls #undef GET_OP
2166 1.3.8.1 tls
2167 1.3.8.1 tls if (use_extend)
2168 1.3.8.1 tls infprintf (is, "0x%x", extend | 0xf000);
2169 1.3.8.1 tls infprintf (is, "0x%x", insn);
2170 1.3.8.1 tls info->insn_type = dis_noninsn;
2171 1.3.8.1 tls
2172 1.3.8.1 tls return length;
2173 1.3.8.1 tls }
2174 1.3.8.1 tls
2175 1.3.8.1 tls /* Disassemble microMIPS instructions. */
2176 1.3.8.1 tls
2177 1.3.8.1 tls static int
2178 1.3.8.1 tls print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
2179 1.3.8.1 tls {
2180 1.3.8.1 tls const fprintf_ftype infprintf = info->fprintf_func;
2181 1.3.8.1 tls const struct mips_opcode *op, *opend;
2182 1.3.8.1 tls unsigned int lsb, msbd, msb;
2183 1.3.8.1 tls void *is = info->stream;
2184 1.3.8.1 tls unsigned int regno;
2185 1.3.8.1 tls bfd_byte buffer[2];
2186 1.3.8.1 tls int lastregno = 0;
2187 1.3.8.1 tls int higher;
2188 1.3.8.1 tls int length;
2189 1.3.8.1 tls int status;
2190 1.3.8.1 tls int delta;
2191 1.3.8.1 tls int immed;
2192 1.3.8.1 tls int insn;
2193 1.3.8.1 tls
2194 1.3.8.1 tls lsb = 0;
2195 1.3.8.1 tls
2196 1.3.8.1 tls info->bytes_per_chunk = 2;
2197 1.3.8.1 tls info->display_endian = info->endian;
2198 1.3.8.1 tls info->insn_info_valid = 1;
2199 1.3.8.1 tls info->branch_delay_insns = 0;
2200 1.3.8.1 tls info->data_size = 0;
2201 1.3.8.1 tls info->insn_type = dis_nonbranch;
2202 1.3.8.1 tls info->target = 0;
2203 1.3.8.1 tls info->target2 = 0;
2204 1.3.8.1 tls
2205 1.3.8.1 tls status = (*info->read_memory_func) (memaddr, buffer, 2, info);
2206 1.3.8.1 tls if (status != 0)
2207 1.3.8.1 tls {
2208 1.3.8.1 tls (*info->memory_error_func) (status, memaddr, info);
2209 1.3.8.1 tls return -1;
2210 1.3.8.1 tls }
2211 1.3.8.1 tls
2212 1.3.8.1 tls length = 2;
2213 1.3.8.1 tls
2214 1.3.8.1 tls if (info->endian == BFD_ENDIAN_BIG)
2215 1.3.8.1 tls insn = bfd_getb16 (buffer);
2216 1.3.8.1 tls else
2217 1.3.8.1 tls insn = bfd_getl16 (buffer);
2218 1.3.8.1 tls
2219 1.3.8.1 tls if ((insn & 0xfc00) == 0x7c00)
2220 1.3.8.1 tls {
2221 1.3.8.1 tls /* This is a 48-bit microMIPS instruction. */
2222 1.3.8.1 tls higher = insn;
2223 1.3.8.1 tls
2224 1.3.8.1 tls status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2225 1.3.8.1 tls if (status != 0)
2226 1.3.8.1 tls {
2227 1.3.8.1 tls infprintf (is, "micromips 0x%x", higher);
2228 1.3.8.1 tls (*info->memory_error_func) (status, memaddr + 2, info);
2229 1.3.8.1 tls return -1;
2230 1.3.8.1 tls }
2231 1.3.8.1 tls if (info->endian == BFD_ENDIAN_BIG)
2232 1.3.8.1 tls insn = bfd_getb16 (buffer);
2233 1.3.8.1 tls else
2234 1.3.8.1 tls insn = bfd_getl16 (buffer);
2235 1.3.8.1 tls higher = (higher << 16) | insn;
2236 1.3.8.1 tls
2237 1.3.8.1 tls status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
2238 1.3.8.1 tls if (status != 0)
2239 1.3.8.1 tls {
2240 1.3.8.1 tls infprintf (is, "micromips 0x%x", higher);
2241 1.3.8.1 tls (*info->memory_error_func) (status, memaddr + 4, info);
2242 1.3.8.1 tls return -1;
2243 1.3.8.1 tls }
2244 1.3.8.1 tls if (info->endian == BFD_ENDIAN_BIG)
2245 1.3.8.1 tls insn = bfd_getb16 (buffer);
2246 1.3.8.1 tls else
2247 1.3.8.1 tls insn = bfd_getl16 (buffer);
2248 1.3.8.1 tls infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
2249 1.3.8.1 tls
2250 1.3.8.1 tls info->insn_type = dis_noninsn;
2251 1.3.8.1 tls return 6;
2252 1.3.8.1 tls }
2253 1.3.8.1 tls else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
2254 1.3.8.1 tls {
2255 1.3.8.1 tls /* This is a 32-bit microMIPS instruction. */
2256 1.3.8.1 tls higher = insn;
2257 1.3.8.1 tls
2258 1.3.8.1 tls status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
2259 1.3.8.1 tls if (status != 0)
2260 1.3.8.1 tls {
2261 1.3.8.1 tls infprintf (is, "micromips 0x%x", higher);
2262 1.3.8.1 tls (*info->memory_error_func) (status, memaddr + 2, info);
2263 1.3.8.1 tls return -1;
2264 1.3.8.1 tls }
2265 1.3.8.1 tls
2266 1.3.8.1 tls if (info->endian == BFD_ENDIAN_BIG)
2267 1.3.8.1 tls insn = bfd_getb16 (buffer);
2268 1.3.8.1 tls else
2269 1.3.8.1 tls insn = bfd_getl16 (buffer);
2270 1.3.8.1 tls
2271 1.3.8.1 tls insn = insn | (higher << 16);
2272 1.3.8.1 tls
2273 1.3.8.1 tls length += 2;
2274 1.3.8.1 tls }
2275 1.3.8.1 tls
2276 1.3.8.1 tls /* FIXME: Should probably use a hash table on the major opcode here. */
2277 1.3.8.1 tls
2278 1.3.8.1 tls #define GET_OP(insn, field) \
2279 1.3.8.1 tls (((insn) >> MICROMIPSOP_SH_##field) & MICROMIPSOP_MASK_##field)
2280 1.3.8.1 tls #define GET_OP_S(insn, field) \
2281 1.3.8.1 tls ((GET_OP (insn, field) ^ ((MICROMIPSOP_MASK_##field >> 1) + 1)) \
2282 1.3.8.1 tls - ((MICROMIPSOP_MASK_##field >> 1) + 1))
2283 1.3.8.1 tls opend = micromips_opcodes + bfd_micromips_num_opcodes;
2284 1.3.8.1 tls for (op = micromips_opcodes; op < opend; op++)
2285 1.3.8.1 tls {
2286 1.3.8.1 tls if (op->pinfo != INSN_MACRO
2287 1.3.8.1 tls && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
2288 1.3.8.1 tls && (insn & op->mask) == op->match
2289 1.3.8.1 tls && ((length == 2 && (op->mask & 0xffff0000) == 0)
2290 1.3.8.1 tls || (length == 4 && (op->mask & 0xffff0000) != 0)))
2291 1.3.8.1 tls {
2292 1.3.8.1 tls const char *s;
2293 1.3.8.1 tls
2294 1.3.8.1 tls infprintf (is, "%s", op->name);
2295 1.3.8.1 tls if (op->args[0] != '\0')
2296 1.3.8.1 tls infprintf (is, "\t");
2297 1.3.8.1 tls
2298 1.3.8.1 tls for (s = op->args; *s != '\0'; s++)
2299 1.3.8.1 tls {
2300 1.3.8.1 tls switch (*s)
2301 1.3.8.1 tls {
2302 1.3.8.1 tls case ',':
2303 1.3.8.1 tls case '(':
2304 1.3.8.1 tls case ')':
2305 1.3.8.1 tls infprintf (is, "%c", *s);
2306 1.3.8.1 tls break;
2307 1.3.8.1 tls
2308 1.3.8.1 tls case '.':
2309 1.3.8.1 tls infprintf (is, "%d", GET_OP_S (insn, OFFSET10));
2310 1.3.8.1 tls break;
2311 1.3.8.1 tls
2312 1.3.8.1 tls case '1':
2313 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, STYPE));
2314 1.3.8.1 tls break;
2315 1.3.8.1 tls
2316 1.3.8.1 tls case '2':
2317 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, BP));
2318 1.3.8.1 tls break;
2319 1.3.8.1 tls
2320 1.3.8.1 tls case '3':
2321 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, SA3));
2322 1.3.8.1 tls break;
2323 1.3.8.1 tls
2324 1.3.8.1 tls case '4':
2325 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, SA4));
2326 1.3.8.1 tls break;
2327 1.3.8.1 tls
2328 1.3.8.1 tls case '5':
2329 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, IMM8));
2330 1.3.8.1 tls break;
2331 1.3.8.1 tls
2332 1.3.8.1 tls case '6':
2333 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, RS));
2334 1.3.8.1 tls break;
2335 1.3.8.1 tls
2336 1.3.8.1 tls case '7':
2337 1.3.8.1 tls infprintf (is, "$ac%d", GET_OP (insn, DSPACC));
2338 1.3.8.1 tls break;
2339 1.3.8.1 tls
2340 1.3.8.1 tls case '8':
2341 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, WRDSP));
2342 1.3.8.1 tls break;
2343 1.3.8.1 tls
2344 1.3.8.1 tls case '0': /* DSP 6-bit signed immediate in bit 16. */
2345 1.3.8.1 tls delta = (GET_OP (insn, DSPSFT) ^ 0x20) - 0x20;
2346 1.3.8.1 tls infprintf (is, "%d", delta);
2347 1.3.8.1 tls break;
2348 1.3.8.1 tls
2349 1.3.8.1 tls case '<':
2350 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, SHAMT));
2351 1.3.8.1 tls break;
2352 1.3.8.1 tls
2353 1.3.8.1 tls case '\\':
2354 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, 3BITPOS));
2355 1.3.8.1 tls break;
2356 1.3.8.1 tls
2357 1.3.8.1 tls case '^':
2358 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, RD));
2359 1.3.8.1 tls break;
2360 1.3.8.1 tls
2361 1.3.8.1 tls case '|':
2362 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, TRAP));
2363 1.3.8.1 tls break;
2364 1.3.8.1 tls
2365 1.3.8.1 tls case '~':
2366 1.3.8.1 tls infprintf (is, "%d", GET_OP_S (insn, OFFSET12));
2367 1.3.8.1 tls break;
2368 1.3.8.1 tls
2369 1.3.8.1 tls case 'a':
2370 1.3.8.1 tls if (strcmp (op->name, "jalx") == 0)
2371 1.3.8.1 tls info->target = (((memaddr + 4) & ~(bfd_vma) 0x0fffffff)
2372 1.3.8.1 tls | (GET_OP (insn, TARGET) << 2));
2373 1.3.8.1 tls else
2374 1.3.8.1 tls info->target = (((memaddr + 4) & ~(bfd_vma) 0x07ffffff)
2375 1.3.8.1 tls | (GET_OP (insn, TARGET) << 1));
2376 1.3.8.1 tls /* For gdb disassembler, force odd address on jalx. */
2377 1.3.8.1 tls if (info->flavour == bfd_target_unknown_flavour
2378 1.3.8.1 tls && strcmp (op->name, "jalx") == 0)
2379 1.3.8.1 tls info->target |= 1;
2380 1.3.8.1 tls (*info->print_address_func) (info->target, info);
2381 1.3.8.1 tls break;
2382 1.3.8.1 tls
2383 1.3.8.1 tls case 'b':
2384 1.3.8.1 tls case 'r':
2385 1.3.8.1 tls case 's':
2386 1.3.8.1 tls case 'v':
2387 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]);
2388 1.3.8.1 tls break;
2389 1.3.8.1 tls
2390 1.3.8.1 tls case 'c':
2391 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, CODE));
2392 1.3.8.1 tls break;
2393 1.3.8.1 tls
2394 1.3.8.1 tls case 'd':
2395 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]);
2396 1.3.8.1 tls break;
2397 1.3.8.1 tls
2398 1.3.8.1 tls case 'h':
2399 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, PREFX));
2400 1.3.8.1 tls break;
2401 1.3.8.1 tls
2402 1.3.8.1 tls case 'i':
2403 1.3.8.1 tls case 'u':
2404 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, IMMEDIATE));
2405 1.3.8.1 tls break;
2406 1.3.8.1 tls
2407 1.3.8.1 tls case 'j': /* Same as i, but sign-extended. */
2408 1.3.8.1 tls case 'o':
2409 1.3.8.1 tls infprintf (is, "%d", GET_OP_S (insn, DELTA));
2410 1.3.8.1 tls break;
2411 1.3.8.1 tls
2412 1.3.8.1 tls case 'k':
2413 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, CACHE));
2414 1.3.8.1 tls break;
2415 1.3.8.1 tls
2416 1.3.8.1 tls case 'n':
2417 1.3.8.1 tls {
2418 1.3.8.1 tls int s_reg_encode;
2419 1.3.8.1 tls
2420 1.3.8.1 tls immed = GET_OP (insn, RT);
2421 1.3.8.1 tls s_reg_encode = immed & 0xf;
2422 1.3.8.1 tls if (s_reg_encode != 0)
2423 1.3.8.1 tls {
2424 1.3.8.1 tls if (s_reg_encode == 1)
2425 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[16]);
2426 1.3.8.1 tls else if (s_reg_encode < 9)
2427 1.3.8.1 tls infprintf (is, "%s-%s",
2428 1.3.8.1 tls mips_gpr_names[16],
2429 1.3.8.1 tls mips_gpr_names[15 + s_reg_encode]);
2430 1.3.8.1 tls else if (s_reg_encode == 9)
2431 1.3.8.1 tls infprintf (is, "%s-%s,%s",
2432 1.3.8.1 tls mips_gpr_names[16],
2433 1.3.8.1 tls mips_gpr_names[23],
2434 1.3.8.1 tls mips_gpr_names[30]);
2435 1.3.8.1 tls else
2436 1.3.8.1 tls infprintf (is, "UNKNOWN");
2437 1.3.8.1 tls }
2438 1.3.8.1 tls
2439 1.3.8.1 tls if (immed & 0x10) /* For ra. */
2440 1.3.8.1 tls {
2441 1.3.8.1 tls if (s_reg_encode == 0)
2442 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[31]);
2443 1.3.8.1 tls else
2444 1.3.8.1 tls infprintf (is, ",%s", mips_gpr_names[31]);
2445 1.3.8.1 tls }
2446 1.3.8.1 tls break;
2447 1.3.8.1 tls }
2448 1.3.8.1 tls
2449 1.3.8.1 tls case 'p':
2450 1.3.8.1 tls /* Sign-extend the displacement. */
2451 1.3.8.1 tls delta = GET_OP_S (insn, DELTA);
2452 1.3.8.1 tls info->target = (delta << 1) + memaddr + length;
2453 1.3.8.1 tls (*info->print_address_func) (info->target, info);
2454 1.3.8.1 tls break;
2455 1.3.8.1 tls
2456 1.3.8.1 tls case 'q':
2457 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, CODE2));
2458 1.3.8.1 tls break;
2459 1.3.8.1 tls
2460 1.3.8.1 tls case 't':
2461 1.3.8.1 tls case 'w':
2462 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]);
2463 1.3.8.1 tls break;
2464 1.3.8.1 tls
2465 1.3.8.1 tls case 'y':
2466 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]);
2467 1.3.8.1 tls break;
2468 1.3.8.1 tls
2469 1.3.8.1 tls case 'z':
2470 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[0]);
2471 1.3.8.1 tls break;
2472 1.3.8.1 tls
2473 1.3.8.1 tls case '@': /* DSP 10-bit signed immediate in bit 16. */
2474 1.3.8.1 tls delta = (GET_OP (insn, IMM10) ^ 0x200) - 0x200;
2475 1.3.8.1 tls infprintf (is, "%d", delta);
2476 1.3.8.1 tls break;
2477 1.3.8.1 tls
2478 1.3.8.1 tls case 'B':
2479 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, CODE10));
2480 1.3.8.1 tls break;
2481 1.3.8.1 tls
2482 1.3.8.1 tls case 'C':
2483 1.3.8.1 tls infprintf (is, "0x%x", GET_OP (insn, COPZ));
2484 1.3.8.1 tls break;
2485 1.3.8.1 tls
2486 1.3.8.1 tls case 'D':
2487 1.3.8.1 tls infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]);
2488 1.3.8.1 tls break;
2489 1.3.8.1 tls
2490 1.3.8.1 tls case 'E':
2491 1.3.8.1 tls /* Coprocessor register for lwcN instructions, et al.
2492 1.3.8.1 tls
2493 1.3.8.1 tls Note that there is no load/store cp0 instructions, and
2494 1.3.8.1 tls that FPU (cp1) instructions disassemble this field using
2495 1.3.8.1 tls 'T' format. Therefore, until we gain understanding of
2496 1.3.8.1 tls cp2 register names, we can simply print the register
2497 1.3.8.1 tls numbers. */
2498 1.3.8.1 tls infprintf (is, "$%d", GET_OP (insn, RT));
2499 1.3.8.1 tls break;
2500 1.3.8.1 tls
2501 1.3.8.1 tls case 'G':
2502 1.3.8.1 tls /* Coprocessor register for mtcN instructions, et al. Note
2503 1.3.8.1 tls that FPU (cp1) instructions disassemble this field using
2504 1.3.8.1 tls 'S' format. Therefore, we only need to worry about cp0,
2505 1.3.8.1 tls cp2, and cp3.
2506 1.3.8.1 tls The microMIPS encoding does not have a coprocessor
2507 1.3.8.1 tls identifier field as such, so we must work out the
2508 1.3.8.1 tls coprocessor number by looking at the opcode. */
2509 1.3.8.1 tls switch (insn
2510 1.3.8.1 tls & ~((MICROMIPSOP_MASK_RT << MICROMIPSOP_SH_RT)
2511 1.3.8.1 tls | (MICROMIPSOP_MASK_RS << MICROMIPSOP_SH_RS)))
2512 1.3.8.1 tls {
2513 1.3.8.1 tls case 0x000000fc: /* mfc0 */
2514 1.3.8.1 tls case 0x000002fc: /* mtc0 */
2515 1.3.8.1 tls case 0x580000fc: /* dmfc0 */
2516 1.3.8.1 tls case 0x580002fc: /* dmtc0 */
2517 1.3.8.1 tls infprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]);
2518 1.3.8.1 tls break;
2519 1.3.8.1 tls default:
2520 1.3.8.1 tls infprintf (is, "$%d", GET_OP (insn, RS));
2521 1.3.8.1 tls break;
2522 1.3.8.1 tls }
2523 1.3.8.1 tls break;
2524 1.3.8.1 tls
2525 1.3.8.1 tls case 'H':
2526 1.3.8.1 tls infprintf (is, "%d", GET_OP (insn, SEL));
2527 1.3.8.1 tls break;
2528 1.3.8.1 tls
2529 1.3.8.1 tls case 'K':
2530 1.3.8.1 tls infprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]);
2531 1.3.8.1 tls break;
2532 1.3.8.1 tls
2533 1.3.8.1 tls case 'M':
2534 1.3.8.1 tls infprintf (is, "$fcc%d", GET_OP (insn, CCC));
2535 1.3.8.1 tls break;
2536 1.3.8.1 tls
2537 1.3.8.1 tls case 'N':
2538 1.3.8.1 tls infprintf (is,
2539 1.3.8.1 tls (op->pinfo & (FP_D | FP_S)) != 0
2540 1.3.8.1 tls ? "$fcc%d" : "$cc%d",
2541 1.3.8.1 tls GET_OP (insn, BCC));
2542 1.3.8.1 tls break;
2543 1.3.8.1 tls
2544 1.3.8.1 tls case 'R':
2545 1.3.8.1 tls infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]);
2546 1.3.8.1 tls break;
2547 1.3.8.1 tls
2548 1.3.8.1 tls case 'S':
2549 1.3.8.1 tls case 'V':
2550 1.3.8.1 tls infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]);
2551 1.3.8.1 tls break;
2552 1.3.8.1 tls
2553 1.3.8.1 tls case 'T':
2554 1.3.8.1 tls infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]);
2555 1.3.8.1 tls break;
2556 1.3.8.1 tls
2557 1.3.8.1 tls case '+':
2558 1.3.8.1 tls /* Extension character; switch for second char. */
2559 1.3.8.1 tls s++;
2560 1.3.8.1 tls switch (*s)
2561 1.3.8.1 tls {
2562 1.3.8.1 tls case 'A':
2563 1.3.8.1 tls lsb = GET_OP (insn, EXTLSB);
2564 1.3.8.1 tls infprintf (is, "0x%x", lsb);
2565 1.3.8.1 tls break;
2566 1.3.8.1 tls
2567 1.3.8.1 tls case 'B':
2568 1.3.8.1 tls msb = GET_OP (insn, INSMSB);
2569 1.3.8.1 tls infprintf (is, "0x%x", msb - lsb + 1);
2570 1.3.8.1 tls break;
2571 1.3.8.1 tls
2572 1.3.8.1 tls case 'C':
2573 1.3.8.1 tls case 'H':
2574 1.3.8.1 tls msbd = GET_OP (insn, EXTMSBD);
2575 1.3.8.1 tls infprintf (is, "0x%x", msbd + 1);
2576 1.3.8.1 tls break;
2577 1.3.8.1 tls
2578 1.3.8.1 tls case 'D':
2579 1.3.8.1 tls {
2580 1.3.8.1 tls const struct mips_cp0sel_name *n;
2581 1.3.8.1 tls unsigned int cp0reg, sel;
2582 1.3.8.1 tls
2583 1.3.8.1 tls cp0reg = GET_OP (insn, RS);
2584 1.3.8.1 tls sel = GET_OP (insn, SEL);
2585 1.3.8.1 tls
2586 1.3.8.1 tls /* CP0 register including 'sel' code for mtcN
2587 1.3.8.1 tls (et al.), to be printed textually if known.
2588 1.3.8.1 tls If not known, print both CP0 register name and
2589 1.3.8.1 tls sel numerically since CP0 register with sel 0 may
2590 1.3.8.1 tls have a name unrelated to register being printed. */
2591 1.3.8.1 tls n = lookup_mips_cp0sel_name (mips_cp0sel_names,
2592 1.3.8.1 tls mips_cp0sel_names_len,
2593 1.3.8.1 tls cp0reg, sel);
2594 1.3.8.1 tls if (n != NULL)
2595 1.3.8.1 tls infprintf (is, "%s", n->name);
2596 1.3.8.1 tls else
2597 1.3.8.1 tls infprintf (is, "$%d,%d", cp0reg, sel);
2598 1.3.8.1 tls break;
2599 1.3.8.1 tls }
2600 1.3.8.1 tls
2601 1.3.8.1 tls case 'E':
2602 1.3.8.1 tls lsb = GET_OP (insn, EXTLSB) + 32;
2603 1.3.8.1 tls infprintf (is, "0x%x", lsb);
2604 1.3.8.1 tls break;
2605 1.3.8.1 tls
2606 1.3.8.1 tls case 'F':
2607 1.3.8.1 tls msb = GET_OP (insn, INSMSB) + 32;
2608 1.3.8.1 tls infprintf (is, "0x%x", msb - lsb + 1);
2609 1.3.8.1 tls break;
2610 1.3.8.1 tls
2611 1.3.8.1 tls case 'G':
2612 1.3.8.1 tls msbd = GET_OP (insn, EXTMSBD) + 32;
2613 1.3.8.1 tls infprintf (is, "0x%x", msbd + 1);
2614 1.3.8.1 tls break;
2615 1.3.8.1 tls
2616 1.3.8.1 tls default:
2617 1.3.8.1 tls /* xgettext:c-format */
2618 1.3.8.1 tls infprintf (is,
2619 1.3.8.1 tls _("# internal disassembler error, "
2620 1.3.8.1 tls "unrecognized modifier (+%c)"),
2621 1.3.8.1 tls *s);
2622 1.3.8.1 tls abort ();
2623 1.3.8.1 tls }
2624 1.3.8.1 tls break;
2625 1.3.8.1 tls
2626 1.3.8.1 tls case 'm':
2627 1.3.8.1 tls /* Extension character; switch for second char. */
2628 1.3.8.1 tls s++;
2629 1.3.8.1 tls switch (*s)
2630 1.3.8.1 tls {
2631 1.3.8.1 tls case 'a': /* global pointer. */
2632 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[28]);
2633 1.3.8.1 tls break;
2634 1.3.8.1 tls
2635 1.3.8.1 tls case 'b':
2636 1.3.8.1 tls regno = micromips_to_32_reg_b_map[GET_OP (insn, MB)];
2637 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2638 1.3.8.1 tls break;
2639 1.3.8.1 tls
2640 1.3.8.1 tls case 'c':
2641 1.3.8.1 tls regno = micromips_to_32_reg_c_map[GET_OP (insn, MC)];
2642 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2643 1.3.8.1 tls break;
2644 1.3.8.1 tls
2645 1.3.8.1 tls case 'd':
2646 1.3.8.1 tls regno = micromips_to_32_reg_d_map[GET_OP (insn, MD)];
2647 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2648 1.3.8.1 tls break;
2649 1.3.8.1 tls
2650 1.3.8.1 tls case 'e':
2651 1.3.8.1 tls regno = micromips_to_32_reg_e_map[GET_OP (insn, ME)];
2652 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2653 1.3.8.1 tls break;
2654 1.3.8.1 tls
2655 1.3.8.1 tls case 'f':
2656 1.3.8.1 tls /* Save lastregno for "mt" to print out later. */
2657 1.3.8.1 tls lastregno = micromips_to_32_reg_f_map[GET_OP (insn, MF)];
2658 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[lastregno]);
2659 1.3.8.1 tls break;
2660 1.3.8.1 tls
2661 1.3.8.1 tls case 'g':
2662 1.3.8.1 tls regno = micromips_to_32_reg_g_map[GET_OP (insn, MG)];
2663 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2664 1.3.8.1 tls break;
2665 1.3.8.1 tls
2666 1.3.8.1 tls case 'h':
2667 1.3.8.1 tls regno = micromips_to_32_reg_h_map[GET_OP (insn, MH)];
2668 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2669 1.3.8.1 tls break;
2670 1.3.8.1 tls
2671 1.3.8.1 tls case 'i':
2672 1.3.8.1 tls regno = micromips_to_32_reg_i_map[GET_OP (insn, MI)];
2673 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2674 1.3.8.1 tls break;
2675 1.3.8.1 tls
2676 1.3.8.1 tls case 'j':
2677 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]);
2678 1.3.8.1 tls break;
2679 1.3.8.1 tls
2680 1.3.8.1 tls case 'l':
2681 1.3.8.1 tls regno = micromips_to_32_reg_l_map[GET_OP (insn, ML)];
2682 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2683 1.3.8.1 tls break;
2684 1.3.8.1 tls
2685 1.3.8.1 tls case 'm':
2686 1.3.8.1 tls regno = micromips_to_32_reg_m_map[GET_OP (insn, MM)];
2687 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2688 1.3.8.1 tls break;
2689 1.3.8.1 tls
2690 1.3.8.1 tls case 'n':
2691 1.3.8.1 tls regno = micromips_to_32_reg_n_map[GET_OP (insn, MN)];
2692 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2693 1.3.8.1 tls break;
2694 1.3.8.1 tls
2695 1.3.8.1 tls case 'p':
2696 1.3.8.1 tls /* Save lastregno for "mt" to print out later. */
2697 1.3.8.1 tls lastregno = GET_OP (insn, MP);
2698 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[lastregno]);
2699 1.3.8.1 tls break;
2700 1.3.8.1 tls
2701 1.3.8.1 tls case 'q':
2702 1.3.8.1 tls regno = micromips_to_32_reg_q_map[GET_OP (insn, MQ)];
2703 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[regno]);
2704 1.3.8.1 tls break;
2705 1.3.8.1 tls
2706 1.3.8.1 tls case 'r': /* program counter. */
2707 1.3.8.1 tls infprintf (is, "$pc");
2708 1.3.8.1 tls break;
2709 1.3.8.1 tls
2710 1.3.8.1 tls case 's': /* stack pointer. */
2711 1.3.8.1 tls lastregno = 29;
2712 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[29]);
2713 1.3.8.1 tls break;
2714 1.3.8.1 tls
2715 1.3.8.1 tls case 't':
2716 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[lastregno]);
2717 1.3.8.1 tls break;
2718 1.3.8.1 tls
2719 1.3.8.1 tls case 'z': /* $0. */
2720 1.3.8.1 tls infprintf (is, "%s", mips_gpr_names[0]);
2721 1.3.8.1 tls break;
2722 1.3.8.1 tls
2723 1.3.8.1 tls case 'A':
2724 1.3.8.1 tls /* Sign-extend the immediate. */
2725 1.3.8.1 tls immed = GET_OP_S (insn, IMMA) << 2;
2726 1.3.8.1 tls infprintf (is, "%d", immed);
2727 1.3.8.1 tls break;
2728 1.3.8.1 tls
2729 1.3.8.1 tls case 'B':
2730 1.3.8.1 tls immed = micromips_imm_b_map[GET_OP (insn, IMMB)];
2731 1.3.8.1 tls infprintf (is, "%d", immed);
2732 1.3.8.1 tls break;
2733 1.3.8.1 tls
2734 1.3.8.1 tls case 'C':
2735 1.3.8.1 tls immed = micromips_imm_c_map[GET_OP (insn, IMMC)];
2736 1.3.8.1 tls infprintf (is, "0x%x", immed);
2737 1.3.8.1 tls break;
2738 1.3.8.1 tls
2739 1.3.8.1 tls case 'D':
2740 1.3.8.1 tls /* Sign-extend the displacement. */
2741 1.3.8.1 tls delta = GET_OP_S (insn, IMMD);
2742 1.3.8.1 tls info->target = (delta << 1) + memaddr + length;
2743 1.3.8.1 tls (*info->print_address_func) (info->target, info);
2744 1.3.8.1 tls break;
2745 1.3.8.1 tls
2746 1.3.8.1 tls case 'E':
2747 1.3.8.1 tls /* Sign-extend the displacement. */
2748 1.3.8.1 tls delta = GET_OP_S (insn, IMME);
2749 1.3.8.1 tls info->target = (delta << 1) + memaddr + length;
2750 1.3.8.1 tls (*info->print_address_func) (info->target, info);
2751 1.3.8.1 tls break;
2752 1.3.8.1 tls
2753 1.3.8.1 tls case 'F':
2754 1.3.8.1 tls immed = GET_OP (insn, IMMF);
2755 1.3.8.1 tls infprintf (is, "0x%x", immed);
2756 1.3.8.1 tls break;
2757 1.3.8.1 tls
2758 1.3.8.1 tls case 'G':
2759 1.3.8.1 tls immed = (insn >> MICROMIPSOP_SH_IMMG) + 1;
2760 1.3.8.1 tls immed = (immed & MICROMIPSOP_MASK_IMMG) - 1;
2761 1.3.8.1 tls infprintf (is, "%d", immed);
2762 1.3.8.1 tls break;
2763 1.3.8.1 tls
2764 1.3.8.1 tls case 'H':
2765 1.3.8.1 tls immed = GET_OP (insn, IMMH) << 1;
2766 1.3.8.1 tls infprintf (is, "%d", immed);
2767 1.3.8.1 tls break;
2768 1.3.8.1 tls
2769 1.3.8.1 tls case 'I':
2770 1.3.8.1 tls immed = (insn >> MICROMIPSOP_SH_IMMI) + 1;
2771 1.3.8.1 tls immed = (immed & MICROMIPSOP_MASK_IMMI) - 1;
2772 1.3.8.1 tls infprintf (is, "%d", immed);
2773 1.3.8.1 tls break;
2774 1.3.8.1 tls
2775 1.3.8.1 tls case 'J':
2776 1.3.8.1 tls immed = GET_OP (insn, IMMJ) << 2;
2777 1.3.8.1 tls infprintf (is, "%d", immed);
2778 1.3.8.1 tls break;
2779 1.3.8.1 tls
2780 1.3.8.1 tls case 'L':
2781 1.3.8.1 tls immed = GET_OP (insn, IMML);
2782 1.3.8.1 tls infprintf (is, "%d", immed);
2783 1.3.8.1 tls break;
2784 1.3.8.1 tls
2785 1.3.8.1 tls case 'M':
2786 1.3.8.1 tls immed = (insn >> MICROMIPSOP_SH_IMMM) - 1;
2787 1.3.8.1 tls immed = (immed & MICROMIPSOP_MASK_IMMM) + 1;
2788 1.3.8.1 tls infprintf (is, "%d", immed);
2789 1.3.8.1 tls break;
2790 1.3.8.1 tls
2791 1.3.8.1 tls case 'N':
2792 1.3.8.1 tls immed = GET_OP (insn, IMMN);
2793 1.3.8.1 tls if (immed == 0)
2794 1.3.8.1 tls infprintf (is, "%s,%s",
2795 1.3.8.1 tls mips_gpr_names[16],
2796 1.3.8.1 tls mips_gpr_names[31]);
2797 1.3.8.1 tls else
2798 1.3.8.1 tls infprintf (is, "%s-%s,%s",
2799 1.3.8.1 tls mips_gpr_names[16],
2800 1.3.8.1 tls mips_gpr_names[16 + immed],
2801 1.3.8.1 tls mips_gpr_names[31]);
2802 1.3.8.1 tls break;
2803 1.3.8.1 tls
2804 1.3.8.1 tls case 'O':
2805 1.3.8.1 tls immed = GET_OP (insn, IMMO);
2806 1.3.8.1 tls infprintf (is, "0x%x", immed);
2807 1.3.8.1 tls break;
2808 1.3.8.1 tls
2809 1.3.8.1 tls case 'P':
2810 1.3.8.1 tls immed = GET_OP (insn, IMMP) << 2;
2811 1.3.8.1 tls infprintf (is, "%d", immed);
2812 1.3.8.1 tls break;
2813 1.3.8.1 tls
2814 1.3.8.1 tls case 'Q':
2815 1.3.8.1 tls /* Sign-extend the immediate. */
2816 1.3.8.1 tls immed = GET_OP_S (insn, IMMQ) << 2;
2817 1.3.8.1 tls infprintf (is, "%d", immed);
2818 1.3.8.1 tls break;
2819 1.3.8.1 tls
2820 1.3.8.1 tls case 'U':
2821 1.3.8.1 tls immed = GET_OP (insn, IMMU) << 2;
2822 1.3.8.1 tls infprintf (is, "%d", immed);
2823 1.3.8.1 tls break;
2824 1.3.8.1 tls
2825 1.3.8.1 tls case 'W':
2826 1.3.8.1 tls immed = GET_OP (insn, IMMW) << 2;
2827 1.3.8.1 tls infprintf (is, "%d", immed);
2828 1.3.8.1 tls break;
2829 1.3.8.1 tls
2830 1.3.8.1 tls case 'X':
2831 1.3.8.1 tls /* Sign-extend the immediate. */
2832 1.3.8.1 tls immed = GET_OP_S (insn, IMMX);
2833 1.3.8.1 tls infprintf (is, "%d", immed);
2834 1.3.8.1 tls break;
2835 1.3.8.1 tls
2836 1.3.8.1 tls case 'Y':
2837 1.3.8.1 tls /* Sign-extend the immediate. */
2838 1.3.8.1 tls immed = GET_OP_S (insn, IMMY) << 2;
2839 1.3.8.1 tls if ((unsigned int) (immed + 8) < 16)
2840 1.3.8.1 tls immed ^= 0x400;
2841 1.3.8.1 tls infprintf (is, "%d", immed);
2842 1.3.8.1 tls break;
2843 1.3.8.1 tls
2844 1.3.8.1 tls default:
2845 1.3.8.1 tls /* xgettext:c-format */
2846 1.3.8.1 tls infprintf (is,
2847 1.3.8.1 tls _("# internal disassembler error, "
2848 1.3.8.1 tls "unrecognized modifier (m%c)"),
2849 1.3.8.1 tls *s);
2850 1.3.8.1 tls abort ();
2851 1.3.8.1 tls }
2852 1.3.8.1 tls break;
2853 1.3.8.1 tls
2854 1.3.8.1 tls default:
2855 1.3.8.1 tls /* xgettext:c-format */
2856 1.3.8.1 tls infprintf (is,
2857 1.3.8.1 tls _("# internal disassembler error, "
2858 1.3.8.1 tls "unrecognized modifier (%c)"),
2859 1.3.8.1 tls *s);
2860 1.3.8.1 tls abort ();
2861 1.3.8.1 tls }
2862 1.3.8.1 tls }
2863 1.3.8.1 tls
2864 1.3.8.1 tls /* Figure out instruction type and branch delay information. */
2865 1.3.8.1 tls if ((op->pinfo
2866 1.3.8.1 tls & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
2867 1.3.8.1 tls info->branch_delay_insns = 1;
2868 1.3.8.1 tls if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
2869 1.3.8.1 tls | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
2870 1.3.8.1 tls {
2871 1.3.8.1 tls if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_GPR_T)) != 0)
2872 1.3.8.1 tls info->insn_type = dis_jsr;
2873 1.3.8.1 tls else
2874 1.3.8.1 tls info->insn_type = dis_branch;
2875 1.3.8.1 tls }
2876 1.3.8.1 tls else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
2877 1.3.8.1 tls | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
2878 1.3.8.1 tls {
2879 1.3.8.1 tls if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
2880 1.3.8.1 tls info->insn_type = dis_condjsr;
2881 1.3.8.1 tls else
2882 1.3.8.1 tls info->insn_type = dis_condbranch;
2883 1.3.8.1 tls }
2884 1.3.8.1 tls else if ((op->pinfo
2885 1.3.8.1 tls & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY_DELAY)) != 0)
2886 1.3.8.1 tls info->insn_type = dis_dref;
2887 1.3.8.1 tls
2888 1.3.8.1 tls return length;
2889 1.3.8.1 tls }
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.3.8.1 tls info->insn_type = dis_noninsn;
2896 1.3.8.1 tls
2897 1.3.8.1 tls return length;
2898 1.3.8.1 tls }
2899 1.3.8.1 tls
2900 1.3.8.1 tls /* Return 1 if a symbol associated with the location being disassembled
2901 1.3.8.1 tls indicates a compressed (MIPS16 or microMIPS) mode. We iterate over
2902 1.3.8.1 tls all the symbols at the address being considered assuming if at least
2903 1.3.8.1 tls one of them indicates code compression, then such code has been
2904 1.3.8.1 tls genuinely produced here (other symbols could have been derived from
2905 1.3.8.1 tls function symbols defined elsewhere or could define data). Otherwise,
2906 1.3.8.1 tls return 0. */
2907 1.3.8.1 tls
2908 1.3.8.1 tls static bfd_boolean
2909 1.3.8.1 tls is_compressed_mode_p (struct disassemble_info *info)
2910 1.3.8.1 tls {
2911 1.3.8.1 tls elf_symbol_type *symbol;
2912 1.3.8.1 tls int pos;
2913 1.3.8.1 tls int i;
2914 1.3.8.1 tls
2915 1.3.8.1 tls for (i = 0; i < info->num_symbols; i++)
2916 1.3.8.1 tls {
2917 1.3.8.1 tls pos = info->symtab_pos + i;
2918 1.3.8.1 tls
2919 1.3.8.1 tls if (bfd_asymbol_flavour (info->symtab[pos]) != bfd_target_elf_flavour)
2920 1.3.8.1 tls continue;
2921 1.3.8.1 tls
2922 1.3.8.1 tls symbol = (elf_symbol_type *) info->symtab[pos];
2923 1.3.8.1 tls if ((!micromips_ase
2924 1.3.8.1 tls && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
2925 1.3.8.1 tls || (micromips_ase
2926 1.3.8.1 tls && ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
2927 1.3.8.1 tls 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.3.8.1 tls 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.3.8.1 tls int status;
2947 1.3.8.1 tls
2948 1.3.8.1 tls set_default_mips_dis_options (info);
2949 1.3.8.1 tls parse_mips_dis_options (info->disassembler_options);
2950 1.3.8.1 tls
2951 1.3.8.1 tls if (info->mach == bfd_mach_mips16)
2952 1.3.8.1 tls return print_insn_mips16 (memaddr, info);
2953 1.1 skrll if (info->mach == bfd_mach_mips_micromips)
2954 1.3.8.1 tls 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.3.8.1 tls
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.3.8.1 tls if (memaddr & 0x01)
2962 1.3.8.1 tls 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.3.8.1 tls #endif
2969 1.1 skrll
2970 1.1 skrll status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
2971 1.3.8.1 tls if (status == 0)
2972 1.1 skrll {
2973 1.3.8.1 tls 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