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