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