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