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